sync'ing up for 3.0alpha20 release
[gd/samba/.git] / source3 / passdb / passdb.c
index fdcda0268dc9bf7b6d39c7909c5e46b317cab29b..b78f26a8e81704308a47032ae0be611f840211c9 100644 (file)
@@ -75,11 +75,19 @@ static void pdb_fill_default_sam(SAM_ACCOUNT *user)
        user->private.workstations = "";
        user->private.unknown_str = "";
        user->private.munged_dial = "";
+
+       user->private.plaintext_pw = NULL;
+
 }      
 
 static void destroy_pdb_talloc(SAM_ACCOUNT **user) 
 {
        if (*user) {
+               data_blob_clear_free(&((*user)->private.lm_pw));
+               data_blob_clear_free(&((*user)->private.nt_pw));
+
+               if((*user)->private.plaintext_pw!=NULL)
+                       memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw));
                talloc_destroy((*user)->mem_ctx);
                *user = NULL;
        }
@@ -157,6 +165,12 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
 {
        GROUP_MAP map;
 
+       const char *guest_account = lp_guestaccount();
+       if (!(guest_account && *guest_account)) {
+               DEBUG(1, ("NULL guest account!?!?\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
        if (!pwd) {
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -183,24 +197,36 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
           -- abartlet 11-May-02
        */
 
-       if (!pdb_set_user_sid_from_rid(sam_account, 
-                                      fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
-               DEBUG(0,("Can't set User SID from RID!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
 
-       /* call the mapping code here */
-       if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
-               if (!pdb_set_group_sid(sam_account,&map.sid)){
-                       DEBUG(0,("Can't set Group SID!\n"));
-                       return NT_STATUS_INVALID_PARAMETER;
+       /* Ensure this *must* be set right */
+       if (strcmp(pwd->pw_name, guest_account) == 0) {
+               if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST)) {
+                       return NT_STATUS_UNSUCCESSFUL;
                }
-       } 
-       else {
-               if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
-                       DEBUG(0,("Can't set Group SID\n"));
+               if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS)) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       } else {
+
+               if (!pdb_set_user_sid_from_rid(sam_account, 
+                                              fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
+                       DEBUG(0,("Can't set User SID from RID!\n"));
                        return NT_STATUS_INVALID_PARAMETER;
                }
+               
+               /* call the mapping code here */
+               if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
+                       if (!pdb_set_group_sid(sam_account,&map.sid)){
+                               DEBUG(0,("Can't set Group SID!\n"));
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+               } 
+               else {
+                       if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
+                               DEBUG(0,("Can't set Group SID\n"));
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+               }
        }
 
        /* check if this is a user account or a machine account */
@@ -233,6 +259,15 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
                                                            pwd->pw_name, global_myname, 
                                                            pwd->pw_uid, pwd->pw_gid), 
                                     False);
+               if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL)) {
+                       DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       } else {
+               if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST)) {
+                       DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
        }
        return NT_STATUS_OK;
 }
@@ -283,7 +318,8 @@ static void pdb_free_sam_contents(SAM_ACCOUNT *user)
 
        data_blob_clear_free(&(user->private.lm_pw));
        data_blob_clear_free(&(user->private.nt_pw));
-       data_blob_clear_free(&(user->private.plaintext_pw));
+       if (user->private.plaintext_pw!=NULL)
+               memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw));
 }
 
 
@@ -574,14 +610,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
                        fstrcpy(name, "Administrator");
                }
                return True;
-
-       } else if (rid == DOMAIN_USER_RID_GUEST) {
-               char *p = lp_guestaccount();
-               *psid_name_use = SID_NAME_USER;
-               if(!next_token(&p, name, NULL, sizeof(fstring)))
-                       fstrcpy(name, "Guest");
-               return True;
-
        }
 
        /*
@@ -597,6 +625,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
        }
                
        /* This now does the 'generic' mapping in pdb_unix */
+       /* 'guest' is also handled there */
        if (pdb_getsampwsid(sam_account, sid)) {
                fstrcpy(name, pdb_get_username(sam_account));
                *psid_name_use = SID_NAME_USER;
@@ -812,11 +841,14 @@ BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_
                return False;
        
        if (pdb_getsampwsid(sam_user, psid)) {
-               *puid = pdb_get_uid(sam_user);
-               if (*puid == -1) {
+               
+               if (!(pdb_get_init_flag(sam_user) & FLAG_SAM_UID)) { 
                        pdb_free_sam(&sam_user);
                        return False;
                }
+
+               *puid = pdb_get_uid(sam_user);
+                       
                DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
                          (unsigned int)*puid, pdb_get_username(sam_user)));
                pdb_free_sam(&sam_user);
@@ -845,23 +877,10 @@ BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_
                        return False;
                }
                
-               if (rid == DOMAIN_USER_RID_GUEST) {
-                       struct passwd *pw = getpwnam_alloc(lp_guestaccount());
-                       if (!pw) {
-                               DEBUG(1, ("getpwnam on guest account '%s' failed!\n", lp_guestaccount())); 
-                               return False;
-                       }
-                       *puid = pw->pw_uid;
-                       passwd_free(&pw);
-                       DEBUG(5,("local_sid_to_uid: Guest account (SID %s) mapped to guest account id %ld.\n", 
-                                sid_to_string(str, psid), (signed long int)(*puid)));
-               } else {
-                       
-                       *puid = fallback_pdb_user_rid_to_uid(rid);
-                       
-                       DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", 
-                                sid_to_string(str, psid), (signed long int)(*puid)));
-               }
+               *puid = fallback_pdb_user_rid_to_uid(rid);
+               
+               DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", 
+                        sid_to_string(str, psid), (signed long int)(*puid)));
        }
 
        *name_type = SID_NAME_USER;
@@ -984,6 +1003,7 @@ BOOL local_password_change(const char *user_name, int local_flags,
 {
        struct passwd  *pwd = NULL;
        SAM_ACCOUNT     *sam_pass=NULL;
+       uint16 other_acb;
 
        *err_str = '\0';
        *msg_str = '\0';
@@ -1023,31 +1043,33 @@ BOOL local_password_change(const char *user_name, int local_flags,
                                return False;
                        }
                }
-               if (local_flags & LOCAL_TRUST_ACCOUNT) {
-                       if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST)) {
-                               slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
-                               pdb_free_sam(&sam_pass);
-                               return False;
-                       }
-               } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
-                       if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST)) {
-                               slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
-                               pdb_free_sam(&sam_pass);
-                               return False;
-                       }
-               } else {
-                       if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL)) {
-                               slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
-                               pdb_free_sam(&sam_pass);
-                               return False;
-                       }
-               }
-
        } else {
                /* the entry already existed */
                local_flags &= ~LOCAL_ADD_USER;
        }
 
+       /* the 'other' acb bits not being changed here */
+       other_acb =  (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
+       if (local_flags & LOCAL_TRUST_ACCOUNT) {
+               if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb) ) {
+                       slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
+                       pdb_free_sam(&sam_pass);
+                       return False;
+               }
+       } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
+               if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb)) {
+                       slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
+                       pdb_free_sam(&sam_pass);
+                       return False;
+               }
+       } else {
+               if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb)) {
+                       slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
+                       pdb_free_sam(&sam_pass);
+                       return False;
+               }
+       }
+
        /*
         * We are root - just write the new password
         * and the valid last change time.