s3:auth Change 'make_user_info' to be talloc based
authorAndrew Bartlett <abartlet@samba.org>
Mon, 17 May 2010 08:10:13 +0000 (18:10 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 10 Aug 2010 22:42:43 +0000 (08:42 +1000)
This is an ideal candidate, as it already uses a free function.  It
now uses talloc destructors to clear the passwords if required.

Andrew Bartlett

source3/auth/user_info.c

index 55a6f96e40d8dbbbcc5287f302ef6962f9eeec5c..5db0705fcfe58a4bc220579988cee6f381b1bad3 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
+static int clear_samr_Password(struct samr_Password *password)
+{
+       memset(password->hash, '\0', sizeof(password->hash));
+       return 0;
+}
+
+static int clear_string(char *password)
+{
+       memset(password, '\0', strlen(password));
+       return 0;
+}
+
 /****************************************************************************
  Create an auth_usersupplied_data structure
 ****************************************************************************/
 
-NTSTATUS make_user_info(struct auth_usersupplied_info **user_info,
+NTSTATUS make_user_info(struct auth_usersupplied_info **ret_user_info,
                        const char *smb_name,
                        const char *internal_username,
                        const char *client_domain,
@@ -39,74 +51,75 @@ NTSTATUS make_user_info(struct auth_usersupplied_info **user_info,
                        const char *plaintext_password,
                        enum auth_password_state password_state)
 {
+       struct auth_usersupplied_info *user_info;
+       *ret_user_info = NULL;
 
        DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
 
-       *user_info = SMB_MALLOC_P(struct auth_usersupplied_info);
-       if (*user_info == NULL) {
-               DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
+       /* FIXME: Have the caller provide a talloc context of the
+        * correct lifetime (possibly talloc_tos(), but it depends on
+        * the caller) */
+       user_info = talloc_zero(NULL, struct auth_usersupplied_info);
+       if (user_info == NULL) {
+               DEBUG(0,("talloc failed for user_info\n"));
                return NT_STATUS_NO_MEMORY;
        }
 
-       ZERO_STRUCTP(*user_info);
-
        DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
 
-       (*user_info)->client.account_name = SMB_STRDUP(smb_name);
-       if ((*user_info)->client.account_name == NULL) {
-               free_user_info(user_info);
-               return NT_STATUS_NO_MEMORY;
-       }
+       user_info->client.account_name = talloc_strdup(user_info, smb_name);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->client.account_name, user_info);
 
-       (*user_info)->mapped.account_name = SMB_STRDUP(internal_username);
-       if ((*user_info)->mapped.account_name == NULL) {
-               free_user_info(user_info);
-               return NT_STATUS_NO_MEMORY;
-       }
+       user_info->mapped.account_name = talloc_strdup(user_info, internal_username);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->mapped.account_name, user_info);
 
-       (*user_info)->mapped.domain_name = SMB_STRDUP(domain);
-       if ((*user_info)->mapped.domain_name == NULL) {
-               free_user_info(user_info);
-               return NT_STATUS_NO_MEMORY;
-       }
+       user_info->mapped.domain_name = talloc_strdup(user_info, domain);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->mapped.domain_name, user_info);
 
-       (*user_info)->client.domain_name = SMB_STRDUP(client_domain);
-       if ((*user_info)->client.domain_name == NULL) {
-               free_user_info(user_info);
-               return NT_STATUS_NO_MEMORY;
-       }
+       user_info->client.domain_name = talloc_strdup(user_info, client_domain);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->client.domain_name, user_info);
 
-       (*user_info)->workstation_name = SMB_STRDUP(workstation_name);
-       if ((*user_info)->workstation_name == NULL) {
-               free_user_info(user_info);
-               return NT_STATUS_NO_MEMORY;
-       }
+       user_info->workstation_name = talloc_strdup(user_info, workstation_name);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->workstation_name, user_info);
 
        DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
 
-       if (lm_pwd)
-               (*user_info)->password.response.lanman = data_blob(lm_pwd->data, lm_pwd->length);
-       if (nt_pwd)
-               (*user_info)->password.response.nt = data_blob(nt_pwd->data, nt_pwd->length);
+       if (lm_pwd && lm_pwd->data) {
+               user_info->password.response.lanman = data_blob_talloc(user_info, lm_pwd->data, lm_pwd->length);
+               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->password.response.lanman.data, user_info);
+       }
+       if (nt_pwd) {
+               user_info->password.response.nt = data_blob_talloc(user_info, nt_pwd->data, nt_pwd->length);
+               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->password.response.nt.data, user_info);
+       }
        if (lm_interactive_pwd) {
-               (*user_info)->password.hash.lanman = SMB_MALLOC_P(struct samr_Password);
-               memcpy((*user_info)->password.hash.lanman->hash, lm_interactive_pwd->hash, sizeof((*user_info)->password.hash.lanman->hash));
+               user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
+               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->password.hash.lanman, user_info);
+               memcpy(user_info->password.hash.lanman->hash, lm_interactive_pwd->hash,
+                      sizeof(user_info->password.hash.lanman->hash));
+               talloc_set_destructor(user_info->password.hash.lanman, clear_samr_Password);
        }
 
        if (nt_interactive_pwd) {
-               (*user_info)->password.hash.nt = SMB_MALLOC_P(struct samr_Password);
-               memcpy((*user_info)->password.hash.nt->hash, nt_interactive_pwd->hash, sizeof((*user_info)->password.hash.nt->hash));
+               user_info->password.hash.nt = talloc(user_info, struct samr_Password);
+               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->password.hash.nt, user_info);
+               memcpy(user_info->password.hash.nt->hash, nt_interactive_pwd->hash,
+                      sizeof(user_info->password.hash.nt->hash));
+               talloc_set_destructor(user_info->password.hash.lanman, clear_samr_Password);
        }
 
-       if (plaintext_password)
-               (*user_info)->password.plaintext = SMB_STRDUP(plaintext_password);
+       if (plaintext_password) {
+               user_info->password.plaintext = talloc_strdup(user_info, plaintext_password);
+               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info->password.plaintext, user_info);
+               talloc_set_destructor(user_info->password.plaintext, clear_string);
+       }
 
-       (*user_info)->password_state = password_state;
+       user_info->password_state = password_state;
 
-       (*user_info)->logon_parameters = 0;
+       user_info->logon_parameters = 0;
 
        DEBUG(10,("made a user_info for %s (%s)\n", internal_username, smb_name));
-
+       *ret_user_info = user_info;
        return NT_STATUS_OK;
 }
 
@@ -116,32 +129,5 @@ NTSTATUS make_user_info(struct auth_usersupplied_info **user_info,
 
 void free_user_info(struct auth_usersupplied_info **user_info)
 {
-       DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
-       if (*user_info != NULL) {
-               if ((*user_info)->client.account_name) {
-                       DEBUG(10,("structure was created for %s\n",
-                                 (*user_info)->client.account_name));
-               }
-               SAFE_FREE((*user_info)->client.account_name);
-               SAFE_FREE((*user_info)->mapped.account_name);
-               SAFE_FREE((*user_info)->client.domain_name);
-               SAFE_FREE((*user_info)->mapped.domain_name);
-               SAFE_FREE((*user_info)->workstation_name);
-               data_blob_free(&(*user_info)->password.response.lanman);
-               data_blob_free(&(*user_info)->password.response.nt);
-               if ((*user_info)->password.hash.lanman) {
-                       ZERO_STRUCTP((*user_info)->password.hash.lanman);
-                       SAFE_FREE((*user_info)->password.hash.lanman);
-               }
-               if ((*user_info)->password.hash.nt) {
-                       ZERO_STRUCTP((*user_info)->password.hash.nt);
-                       SAFE_FREE((*user_info)->password.hash.nt);
-               }
-               if ((*user_info)->password.plaintext) {
-                       memset((*user_info)->password.plaintext, '\0', strlen(((*user_info)->password.plaintext)));
-                       SAFE_FREE((*user_info)->password.plaintext);
-               }
-               ZERO_STRUCT(**user_info);
-       }
-       SAFE_FREE(*user_info);
+       TALLOC_FREE(*user_info);
 }