Add a touch of 'const' to some auth components, and move the simple plaintext
[ira/wip.git] / source3 / auth / auth_util.c
index 4265e77093db06b0c6dab58f5b92b43d66b562a1..5b252f42cdb4cfccc9a43c2b998894d6c692557b 100644 (file)
@@ -50,7 +50,7 @@ static int smb_create_user(const char *unix_user, const char *homedir)
  Delete a UNIX user on demand.
 ****************************************************************************/
 
-int smb_delete_user(char *unix_user)
+int smb_delete_user(const char *unix_user)
 {
        pstring del_script;
        int ret;
@@ -111,7 +111,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
                           const char *wksta_name, 
                           DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
                           DATA_BLOB plaintext, 
-                          uint32 ntlmssp_flags, BOOL encrypted)
+                          uint32 auth_flags, BOOL encrypted)
 {
 
        DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
@@ -173,7 +173,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
        (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
 
        (*user_info)->encrypted = encrypted;
-       (*user_info)->ntlmssp_flags = ntlmssp_flags;
+       (*user_info)->auth_flags = auth_flags;
 
        DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
 
@@ -198,7 +198,6 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
        map_username(internal_username); 
        
        if (lp_allow_trusted_domains()) {
-               char *user;
                /* the client could have given us a workstation name
                   or other crap for the workgroup - we really need a
                   way of telling if this domain name is one of our
@@ -209,15 +208,19 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
                   on winbind, but until we have a better method this
                   will have to do 
                */
-               asprintf(&user, "%s%s%s", 
-                        client_domain, lp_winbind_separator(), 
-                        smb_name);
-               if (Get_Pwnam(user) != NULL) {
-                       domain = client_domain;
-               } else {
-                       domain = lp_workgroup();
+
+               domain = client_domain;
+
+               if ((smb_name) && (*smb_name)) { /* Don't do this for guests */
+                       char *user;
+                       asprintf(&user, "%s%s%s", 
+                                client_domain, lp_winbind_separator(), 
+                                smb_name);
+                       if (Get_Pwnam(user) == NULL) {
+                               domain = lp_workgroup();
+                       }
+                       free(user);
                }
-               free(user);
        } else {
                domain = lp_workgroup();
        }
@@ -238,24 +241,24 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
-                                    char *smb_name, 
-                                    char *client_domain, 
-                                    char *wksta_name, 
-                                    uchar *lm_network_pwd, int lm_pwd_len,
-                                    uchar *nt_network_pwd, int nt_pwd_len)
+                                    const char *smb_name, 
+                                    const char *client_domain, 
+                                    const char *wksta_name, 
+                                    const uchar *lm_network_pwd, int lm_pwd_len,
+                                    const uchar *nt_network_pwd, int nt_pwd_len)
 {
        BOOL ret;
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
 
        if (lm_pwd_len)
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+               auth_flags |= AUTH_FLAG_LM_RESP;
        if (nt_pwd_len == 24) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM
+               auth_flags |= AUTH_FLAG_NTLM_RESP
        } else if (nt_pwd_len != 0) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2
+               auth_flags |= AUTH_FLAG_NTLMv2_RESP
        }
 
        ret = make_user_info_map(user_info, 
@@ -263,7 +266,7 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
                                 wksta_name, 
                                 lm_blob, nt_blob,
                                 plaintext_blob, 
-                                ntlmssp_flags, True);
+                                auth_flags, True);
                
        data_blob_free(&lm_blob);
        data_blob_free(&nt_blob);
@@ -276,20 +279,20 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
-                                        char *smb_name, 
-                                        char *client_domain, 
-                                        char *wksta_name, 
-                                        uchar chal[8], 
-                                        uchar lm_interactive_pwd[16], 
-                                        uchar nt_interactive_pwd[16], 
-                                        uchar *dc_sess_key)
+                                        const char *smb_name, 
+                                        const char *client_domain, 
+                                        const char *wksta_name, 
+                                        const uchar chal[8], 
+                                        const uchar lm_interactive_pwd[16], 
+                                        const uchar nt_interactive_pwd[16], 
+                                        const uchar *dc_sess_key)
 {
        char lm_pwd[16];
        char nt_pwd[16];
        unsigned char local_lm_response[24];
        unsigned char local_nt_response[24];
        unsigned char key[16];
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
        
        ZERO_STRUCT(key);
        memcpy(key, dc_sess_key, 8);
@@ -334,9 +337,9 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
                DATA_BLOB plaintext_blob = data_blob(NULL, 0);
 
                if (lm_interactive_pwd)
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+                       auth_flags |= AUTH_FLAG_LM_RESP;
                if (nt_interactive_pwd)
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM
+                       auth_flags |= AUTH_FLAG_NTLM_RESP
 
                ret = make_user_info_map(user_info, 
                                         smb_name, client_domain, 
@@ -344,138 +347,30 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
                                         local_lm_blob,
                                         local_nt_blob,
                                         plaintext_blob, 
-                                        ntlmssp_flags, True);
-               
-               data_blob_free(&local_lm_blob);
-               data_blob_free(&local_nt_blob);
-               return ret;
-       }
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data structure
-****************************************************************************/
-
-BOOL make_user_info_winbind(auth_usersupplied_info **user_info, 
-                            const char *username,
-                            const char *domain, 
-                            const char *password,
-                           uchar chal[8] /* Give winbind back the challenge we used */
-       )
-{
-       unsigned char local_lm_response[24];
-       unsigned char local_nt_response[24];
-       DATA_BLOB local_lm_blob;
-       DATA_BLOB local_nt_blob;
-       DATA_BLOB plaintext_blob;
-       uint32 ntlmssp_flags = 0;
-
-       /*
-        * Not encrypted - do so.
-        */
-       
-       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
-       
-       generate_random_buffer(chal, 8, False);
-
-       if (*password) {
-               SMBencrypt( (const uchar *)password, chal, local_lm_response);
-               
-               /* This encrypts the lm_pwd field, which actually contains
-                  the password rather than the nt_pwd field because that
-                  contains nothing */
-               
-               /* WATCH OUT. This doesn't work if the incoming password is
-                  incorrectly cased.  We might want to add a check here
-                  and only do an LM in that case */
-               
-               SMBNTencrypt((const uchar *)password, chal, local_nt_response);
-
-               local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
-               local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
-               plaintext_blob = data_blob(password, strlen(password)+1);
-               if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
-                       data_blob_free(&local_lm_blob);
-                       data_blob_free(&local_nt_blob);
-                       data_blob_clear_free(&plaintext_blob);
-                       return False;
-               }
-               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
-       } else {
-               local_lm_blob = data_blob(NULL, 0);
-               local_nt_blob = data_blob(NULL, 0);
-               plaintext_blob = data_blob(NULL, 0);
-       }
-
-       {
-               BOOL ret;
-
-               ret = make_user_info(user_info, 
-                                    username, username,
-                                    domain, domain, 
-                                    global_myname, 
-                                    local_lm_blob,
-                                    local_nt_blob,
-                                    plaintext_blob, 
-                                    ntlmssp_flags, False);
+                                        auth_flags, True);
                
                data_blob_free(&local_lm_blob);
                data_blob_free(&local_nt_blob);
-               data_blob_clear_free(&plaintext_blob);
                return ret;
        }
 }
 
-/****************************************************************************
- Create an auth_usersupplied_data, making the DATA_BLOBs here. 
- Decrypt and encrypt the passwords.
-****************************************************************************/
-
-BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
-                                char *smb_name, 
-                                char *client_domain, 
-                                uchar *lm_network_pwd, int lm_pwd_len,
-                                uchar *nt_network_pwd, int nt_pwd_len)
-{
-       BOOL ret;
-       DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
-       DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
-       DATA_BLOB plaintext_blob = data_blob(NULL, 0);
-       uint32 ntlmssp_flags = 0;
-
-       if (lm_pwd_len)
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
-       if (nt_pwd_len)
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
-       
-       ret = make_user_info(user_info, 
-                            smb_name, smb_name, 
-                            client_domain, client_domain, 
-                            global_myname, 
-                            lm_blob, nt_blob,
-                            plaintext_blob, 
-                            ntlmssp_flags, True);
-
-       data_blob_free(&lm_blob);
-       data_blob_free(&nt_blob);
-       return ret;
-}
 
 /****************************************************************************
  Create an auth_usersupplied_data structure
 ****************************************************************************/
 
 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
-                             char *smb_name, 
-                             char *client_domain,
-                             unsigned char chal[8],
+                             const char *smb_name, 
+                             const char *client_domain,
+                             const uint8 chal[8],
                              DATA_BLOB plaintext_password)
 {
 
        DATA_BLOB local_lm_blob;
        DATA_BLOB local_nt_blob;
        BOOL ret = False;
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
                        
        /*
         * Not encrypted - do so.
@@ -491,14 +386,14 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
                dump_data(100, plaintext_password.data, plaintext_password.length);
 #endif
 
-               SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
+               SMBencrypt( (const uchar *)plaintext_password.data, (const uchar*)chal, local_lm_response);
                local_lm_blob = data_blob(local_lm_response, 24);
                
                /* We can't do an NT hash here, as the password needs to be
                   case insensitive */
                local_nt_blob = data_blob(NULL, 0); 
                
-               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
+               auth_flags = (AUTH_FLAG_PLAINTEXT | AUTH_FLAG_LM_RESP);
        } else {
                local_lm_blob = data_blob(NULL, 0); 
                local_nt_blob = data_blob(NULL, 0); 
@@ -510,7 +405,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
                                 local_lm_blob,
                                 local_nt_blob,
                                 plaintext_password, 
-                                ntlmssp_flags, False);
+                                auth_flags, False);
        
        data_blob_free(&local_lm_blob);
        return ret;
@@ -521,23 +416,22 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
-                             char *smb_name,
-                             char *client_domain, 
-                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
-                             DATA_BLOB plaintext_password)
+                                 const char *smb_name,
+                                 const char *client_domain, 
+                                 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
 {
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
 
        DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
        
        if (lm_resp.length == 24) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+               auth_flags |= AUTH_FLAG_LM_RESP;
        }
        if (nt_resp.length == 0) {
        } else if (nt_resp.length == 24) {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+               auth_flags |= AUTH_FLAG_NTLM_RESP;
        } else {
-               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+               auth_flags |= AUTH_FLAG_NTLMv2_RESP;
        }
 
        return make_user_info_map(user_info, smb_name, 
@@ -546,7 +440,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
                                 lm_resp, 
                                 nt_resp, 
                                 no_plaintext_blob, 
-                                ntlmssp_flags, True);
+                                auth_flags, True);
 }
 
 /****************************************************************************
@@ -558,7 +452,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
        DATA_BLOB lm_blob = data_blob(NULL, 0);
        DATA_BLOB nt_blob = data_blob(NULL, 0);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
-       uint32 ntlmssp_flags = 0;
+       uint32 auth_flags = AUTH_FLAG_NONE;
 
        return make_user_info(user_info, 
                              "","", 
@@ -566,7 +460,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
                              "", 
                              nt_blob, lm_blob,
                              plaintext_blob, 
-                             ntlmssp_flags, True);
+                             auth_flags, True);
 }
 
 /***************************************************************************
@@ -610,7 +504,7 @@ BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *s
 BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
 {
        SAM_ACCOUNT *sampass = NULL;
-       if (!pdb_init_sam_pw(&sampass, pwd)) {          
+       if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sampass, pwd))) {         
                return False;
        }
        return make_server_info_sam(server_info, sampass);
@@ -663,16 +557,18 @@ void free_server_info(auth_serversupplied_info **server_info)
 
 BOOL make_server_info_guest(auth_serversupplied_info **server_info) 
 {
-       struct passwd *pass = sys_getpwnam(lp_guestaccount());
+       struct passwd *pass = getpwnam_alloc(lp_guestaccount());
        
        if (pass) {
                if (!make_server_info_pw(server_info, pass)) {
+                       passwd_free(&pass);
                        return False;
                }
                (*server_info)->guest = True;
+               passwd_free(&pass);
                return True;
        }
-       DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n")); 
+       DEBUG(0,("make_server_info_guest: getpwnam_alloc() failed on guest account!\n")); 
        return False;
 }
 
@@ -680,9 +576,17 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
  Make an auth_methods struct
 ***************************************************************************/
 
-BOOL make_auth_methods(auth_methods **auth_method) 
+BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       *auth_method = malloc(sizeof(**auth_method));
+       if (!auth_context) {
+               smb_panic("no auth_context supplied to make_auth_methods()!\n");
+       }
+
+       if (!auth_method) {
+               smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
+       }
+
+       *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
        if (!*auth_method) {
                DEBUG(0,("make_auth_method: malloc failed!\n"));
                return False;
@@ -731,3 +635,33 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
 
        return token;
 }
+
+/**
+ * Squash an NT_STATUS in line with security requirements.
+ * In an attempt to avoid giving the whole game away when users
+ * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
+ * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
+ * (session setups in particular).
+ *
+ * @param nt_status NTSTATUS input for squashing.
+ * @return the 'squashed' nt_status
+ **/
+
+NTSTATUS nt_status_squash(NTSTATUS nt_status)
+{
+       if NT_STATUS_IS_OK(nt_status) {
+               return nt_status;               
+       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+               /* Match WinXP and don't give the game away */
+               return NT_STATUS_LOGON_FAILURE;
+               
+       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
+               /* Match WinXP and don't give the game away */
+               return NT_STATUS_LOGON_FAILURE;
+       } else {
+               return nt_status;
+       }  
+}
+
+
+