Code duplication is bad. So add an add_signiture() function and just refernce
[ira/wip.git] / source3 / smbd / sesssetup.c
index ce0e0d585ea66b61fad2730d99e8ed0a8f3a215a..291685e9fc6ac3570718182e80644d9b1ef115ab 100644 (file)
 
 #include "includes.h"
 
+uint32 global_client_caps = 0;
+
+/****************************************************************************
+ Add the standard 'Samba' signiture to the end of the session setup.
+****************************************************************************/
+static void add_signiture(char *outbuf) 
+{
+       char *p;
+       p = smb_buf(outbuf);
+       p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
+       p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
+       p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
+       set_message_end(outbuf,p);
+}
+
 #if HAVE_KRB5
 /****************************************************************************
 reply to a session setup spnego negotiate packet for kerberos
@@ -105,7 +120,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
                return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
        
-       sess_vuid = register_vuid(server_info, user, False);
+       sess_vuid = register_vuid(server_info, user);
 
        free_server_info(&server_info);
 
@@ -115,11 +130,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
 
        set_message(outbuf,4,0,True);
        SSVAL(outbuf, smb_vwv3, 0);
-       p = smb_buf(outbuf);
-       p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
-       p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
-       p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
-       set_message_end(outbuf,p);
+       add_signiture(outbuf);
  
        SSVAL(outbuf,smb_uid,sess_vuid);
        SSVAL(inbuf,smb_uid,sess_vuid);
@@ -271,7 +282,6 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
        uint32 ntlmssp_command, neg_flags;
        NTSTATUS nt_status;
        int sess_vuid;
-       char *p;
        char chal[8];
 
        auth_usersupplied_info *user_info = NULL;
@@ -339,7 +349,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
                return ERROR_NT(nt_status_squash(nt_status));
        }
 
-       sess_vuid = register_vuid(server_info, user, False);
+       sess_vuid = register_vuid(server_info, user);
 
        free_server_info(&server_info);
   
@@ -349,11 +359,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
 
        set_message(outbuf,4,0,True);
        SSVAL(outbuf, smb_vwv3, 0);
-       p = smb_buf(outbuf);
-       p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
-       p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
-       p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
-       set_message_end(outbuf,p);
+       add_signiture(outbuf);
  
        SSVAL(outbuf,smb_uid,sess_vuid);
        SSVAL(inbuf,smb_uid,sess_vuid);
@@ -369,13 +375,18 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou
                                  int length, int bufsize)
 {
        int sess_vuid;
-       char *p;
+       auth_usersupplied_info *user_info = NULL;
        auth_serversupplied_info *server_info = NULL;
 
+       NTSTATUS nt_status;
+
        DEBUG(3,("Got anonymous request\n"));
 
-       make_server_info_guest(&server_info);
-       sess_vuid = register_vuid(server_info, lp_guestaccount(-1), False);
+       make_user_info_guest(&user_info);
+
+       nt_status = check_password(user_info, &server_info);
+
+       sess_vuid = register_vuid(server_info, lp_guestaccount());
        free_server_info(&server_info);
   
        if (sess_vuid == -1) {
@@ -384,11 +395,7 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou
 
        set_message(outbuf,4,0,True);
        SSVAL(outbuf, smb_vwv3, 0);
-       p = smb_buf(outbuf);
-       p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
-       p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
-       p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
-       set_message_end(outbuf,p);
+       add_signiture(outbuf);
  
        SSVAL(outbuf,smb_uid,sess_vuid);
        SSVAL(inbuf,smb_uid,sess_vuid);
@@ -405,7 +412,6 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha
 {
        uint8 *p;
        DATA_BLOB blob1;
-       extern uint32 global_client_caps;
        int ret;
 
        DEBUG(3,("Doing spnego session setup\n"));
@@ -463,14 +469,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        DATA_BLOB nt_resp;
        DATA_BLOB plaintext_password;
        pstring user;
+       pstring sub_user; /* Sainitised username for substituion */
        fstring domain;
        fstring native_os;
        fstring native_lanman;
-       BOOL guest=False;
        static BOOL done_sesssetup = False;
        extern BOOL global_encrypted_passwords_negotiated;
        extern BOOL global_spnego_negotiated;
-       extern uint32 global_client_caps;
        extern int Protocol;
        extern fstring remote_machine;
        extern userdom_struct current_user_info;
@@ -479,6 +484,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        auth_usersupplied_info *user_info = NULL;
        auth_serversupplied_info *server_info = NULL;
 
+       NTSTATUS nt_status;
+
        BOOL doencrypt = global_encrypted_passwords_negotiated;
 
        START_PROFILE(SMBsesssetupX);
@@ -563,32 +570,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                                passlen2 = 0;
                }
                
-               if (lp_restrict_anonymous()) {
-                       /* there seems to be no reason behind the
-                        * differences in MS clients formatting
-                        * various info like the domain, NativeOS, and
-                        * NativeLanMan fields. Win95 in particular
-                        * seems to have an extra null byte between
-                        * the username and the domain, or the
-                        * password length calculation is wrong, which
-                        * throws off the string extraction routines
-                        * below.  This makes the value of domain be
-                        * the empty string, which fails the restrict
-                        * anonymous check further down.  This
-                        * compensates for that, and allows browsing
-                        * to work in mixed NT and win95 environments
-                        * even when restrict anonymous is true. AAB
-                        * */
-                       dump_data(100, p, 0x70);
-                       DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2));
-                       if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) {
-                               DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n"));
-                               DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n"));
-                               DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n"));
-                               passlen1 = 1;
-                       }
-               }
-               
                /* Save the lanman2 password and the NT md4 password. */
                
                if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
@@ -626,18 +607,20 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
 
        DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
 
-       /* If no username is sent use the guest account */
-       if (!*user) {
-               pstrcpy(user,lp_guestaccount(-1));
-               guest = True;
-       } else {
+       if (*user) {
                if (global_spnego_negotiated) {
                        DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
                        return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
                }
        }
 
-       pstrcpy(current_user_info.smb_name,user);
+       if (*user) {
+               pstrcpy(sub_user, user);
+       } else {
+               pstrcpy(sub_user, lp_guestaccount());
+       }
+
+       pstrcpy(current_user_info.smb_name,sub_user);
 
        reload_services(True);
        
@@ -648,93 +631,61 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                data_blob_free(&nt_resp);
                data_blob_clear_free(&plaintext_password);
 
-               guest = True;
-               map_username(user);
-               add_session_user(user);
+               map_username(sub_user);
+               add_session_user(sub_user);
+               /* Then force it to null for the benfit of the code below */
+               *user = 0;
        }
        
-       if (done_sesssetup && lp_restrict_anonymous()) {
-               /* tests show that even if browsing is done over
-                * already validated connections without a username
-                * and password the domain is still provided, which it
-                * wouldn't be if it was a purely anonymous
-                * connection.  So, in order to restrict anonymous, we
-                * only deny connections that have no session
-                * information.  If a domain has been provided, then
-                * it's not a purely anonymous connection. AAB */
-               if (!*user && !*domain) {
-                       DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
-                       
-                       data_blob_free(&lm_resp);
-                       data_blob_free(&nt_resp);
-                       data_blob_clear_free(&plaintext_password);
-
-                       END_PROFILE(SMBsesssetupX);
-                       return ERROR_DOS(ERRDOS,ERRnoaccess);
-               }
+       if (!make_user_info_for_reply(&user_info, 
+                                     user, domain, 
+                                     lm_resp, nt_resp,
+                                     plaintext_password, doencrypt)) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
        
-       if (!guest) {
-               NTSTATUS nt_status;
-               if (!make_user_info_for_reply(&user_info, 
-                                             user, domain, 
-                                             lm_resp, nt_resp,
-                                             plaintext_password, doencrypt)) {
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
-               }
-               
-               nt_status = check_password(user_info, &server_info); 
-               
-               free_user_info(&user_info);
-               
-               data_blob_free(&lm_resp);
-               data_blob_free(&nt_resp);
-               data_blob_clear_free(&plaintext_password);
-               
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
-                               if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || 
-                                   (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
-                                       DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
-                                       pstrcpy(user,lp_guestaccount(-1));
-                                       guest = True;
-                                       
-                               }
-                       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
-                               if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
-                                       pstrcpy(user,lp_guestaccount(-1));
-                                       DEBUG(3,("Registered username %s for guest access\n",user));
-                                       guest = True;
-                               }
-                               /* Match WinXP and don't give the game away */
-                               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+       nt_status = check_password(user_info, &server_info); 
+       
+       free_user_info(&user_info);
+       
+       data_blob_free(&lm_resp);
+       data_blob_free(&nt_resp);
+       data_blob_clear_free(&plaintext_password);
+       
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+                       if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || 
+                           (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
+                               
+                               DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
+                               make_server_info_guest(&server_info);
+                               nt_status = NT_STATUS_OK;
+                       }
+
+               } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {                        
+                       if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {                                
+                               DEBUG(3,("Registered username %s for guest access\n",user));
+                               make_server_info_guest(&server_info);
+                               nt_status = NT_STATUS_OK;
                        }
-                       
-                       if (!guest) {
-                               free_server_info(&server_info);
-                               return ERROR_NT(nt_status_squash(nt_status));
-                       }  
                }
        }
        
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return ERROR_NT(nt_status_squash(nt_status));
+       }
+       
        /* it's ok - setup a reply */
        if (Protocol < PROTOCOL_NT1) {
                set_message(outbuf,3,0,True);
        } else {
-               char *p;
                set_message(outbuf,3,0,True);
-               p = smb_buf(outbuf);
-               p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
-               p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
-               p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
-               set_message_end(outbuf,p);
+               add_signiture(outbuf);
                /* perhaps grab OS version here?? */
        }
        
-       if (guest) {
+       if (server_info->guest) {
                SSVAL(outbuf,smb_vwv2,1);
-               free_server_info(&server_info);
-               make_server_info_guest(&server_info);
        } else {
                const char *home_dir = pdb_get_homedir(server_info->sam_account);
                const char *username = pdb_get_username(server_info->sam_account);
@@ -747,7 +698,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        /* register the name and uid as being validated, so further connections
           to a uid can get through without a password, on the same VC */
 
-       sess_vuid = register_vuid(server_info, user, guest);
+       sess_vuid = register_vuid(server_info, sub_user);
 
        free_server_info(&server_info);