clientgen.c: Added cli_ulogoff().
authorJeremy Allison <jra@samba.org>
Wed, 22 Apr 1998 17:40:22 +0000 (17:40 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 22 Apr 1998 17:40:22 +0000 (17:40 +0000)
password.c: Added new two-level security=server code.
Jeremy.

source/include/proto.h
source/libsmb/clientgen.c
source/smbd/password.c

index 17e358e61b0a24f06154b3f542aed25399044961..a639e18cd9335e1a503a1e0f96668bf53991c224 100644 (file)
@@ -71,6 +71,7 @@ BOOL cli_session_setup(struct cli_state *cli,
                       char *pass, int passlen,
                       char *ntpass, int ntpasslen,
                       char *workgroup);
+BOOL cli_ulogoff(struct cli_state *cli);
 BOOL cli_send_tconX(struct cli_state *cli, 
                    char *share, char *dev, char *pass, int passlen);
 BOOL cli_tdis(struct cli_state *cli);
index ba7253bf989c5c7909725a7faeecede4ff5aa702..7347c8aebde2e84f4460cf6aa68565c5dbac8c14 100644 (file)
@@ -499,6 +499,25 @@ BOOL cli_session_setup(struct cli_state *cli,
       return True;
 }
 
+/****************************************************************************
+ Send a uloggoff.
+*****************************************************************************/
+
+BOOL cli_ulogoff(struct cli_state *cli)
+{
+        bzero(cli->outbuf,smb_size);
+        set_message(cli->outbuf,2,0,True);
+        CVAL(cli->outbuf,smb_com) = SMBulogoffX;
+        cli_setup_packet(cli);
+        SSVAL(cli->outbuf,smb_vwv0,0xFF);
+        SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
+
+        send_smb(cli->fd,cli->outbuf);
+        if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+                return False;
+        return CVAL(cli->inbuf,smb_rcls) == 0;
+}
 
 /****************************************************************************
 send a tconX
index 9bccb465074db1e7d350e0fe7b4833d251bf9f99..9f33b0253735ac490fb5eca53847cca5c71f01c5 100644 (file)
@@ -1612,12 +1612,48 @@ BOOL server_validate(char *user, char *domain,
                     char *ntpass, int ntpasslen)
 {
        extern fstring local_machine;
+        static unsigned char badpass[24];
 
        if (!cli.initialised) {
                DEBUG(1,("password server %s is not connected\n", cli.desthost));
                return(False);
        }  
 
+        if(badpass[0] == 0) {
+          memset(badpass, 0x1f, sizeof(badpass));
+        }
+
+        if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) {
+          /* Very unlikely, our random bad password is the same as the users
+             password. */
+          memset(badpass, badpass[0]+1, sizeof(badpass));
+        }
+
+        /*
+         * Attempt a session setup with a totally incorrect password.
+         * If this succeeds with the guest bit *NOT* set then the password
+         * server is broken and is not correctly setting the guest bit. We
+         * need to detect this as some versions of NT4.x are broken. JRA.
+         */
+
+        if (cli_session_setup(&cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass),
+                                                         domain)) {
+          if ((SVAL(cli.inbuf,smb_vwv2) & 1) == 0) {
+            DEBUG(0,("server_validate: password server %s allows users as non-guest \
+with a bad password.\n", cli.desthost));
+            DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \
+use this machine as the password server.\n"));
+            cli_ulogoff(&cli);
+            return False;
+          }
+          cli_ulogoff(&cli);
+        }
+
+        /*
+         * Now we know the password server will correctly set the guest bit, or is
+         * not guest enabled, we can try with the real password.
+         */
+
        if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) {
                DEBUG(1,("password server %s rejected the password\n", cli.desthost));
                return False;
@@ -1673,6 +1709,7 @@ BOOL server_validate(char *user, char *domain,
        DEBUG(3,("password server %s accepted the password\n", cli.desthost));
 
        cli_tdis(&cli);
+        cli_ulogoff(&cli);
 
        return(True);
 }