Fixes to our LDAP/vampire codepaths:
authorAndrew Bartlett <abartlet@samba.org>
Sat, 5 Jul 2003 09:46:12 +0000 (09:46 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 5 Jul 2003 09:46:12 +0000 (09:46 +0000)
 - Try better to add the appropriate mapping between UID and SIDs, based
   on Get_Pwnam()
 - Look for previous users (lookup by SID) and correctly modify the existing
   entry in that case
 - Map the root user to the Admin SID as a 'well known user'
 - Save the LDAPMessage result on the SAM_ACCOUNT for use in the next 'update'
   call on that user.  This means that VL's very nice work on atomic LDAP
   updates now really gets used properly!
 - This also means that we know the right DN to update, without the extra
   round-trips to the server.

Andrew Bartlett

source/include/passdb.h
source/lib/smbldap.c
source/passdb/passdb.c
source/passdb/pdb_get_set.c
source/passdb/pdb_ldap.c
source/sam/idmap_util.c
source/utils/net_rpc_samsync.c

index aeddcbcb3ae583b863dceeb6ce318b2bd35507ca..bf2fd6f6ce48de5462dda00c2934a10a055672fb 100644 (file)
@@ -61,6 +61,7 @@ enum pdb_elements {
        PDB_UNKNOWN6,
        PDB_LMPASSWD,
        PDB_NTPASSWD,
+       PDB_BACKEND_PRIVATE_DATA,
 
        /* this must be the last element */
        PDB_COUNT
@@ -137,6 +138,8 @@ typedef struct sam_passwd
                
                uint32 unknown_5; /* 0x0002 0000 */
                uint32 unknown_6; /* 0x0000 04ec */
+               void *backend_private_data; 
+               void (*backend_private_data_free_fn)(void **);
        } private;
 
        /* Lets see if the remaining code can get the hint that you
index f65860d1b8f7e783d61e05b0e3f206f49d024c26..e0c6aab617f2c1719431cc46ca67b9a3c77bb60c 100644 (file)
@@ -107,6 +107,7 @@ ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
        { LDAP_ATTR_NEXT_GROUPRID,      "sambaNextGroupRid"     },
        { LDAP_ATTR_DOM_SID,            LDAP_ATTRIBUTE_SID      },
        { LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},
+       { LDAP_ATTR_OBJCLASS,           "objectClass"           },
        { LDAP_ATTR_LIST_END,           NULL                    },
 };
 
@@ -119,6 +120,7 @@ ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
        { LDAP_ATTR_DESC,               "description"           },
        { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
        { LDAP_ATTR_CN,                 "cn"                    },
+       { LDAP_ATTR_OBJCLASS,           "objectClass"           },
        { LDAP_ATTR_LIST_END,           NULL                    }       
 };
 
@@ -135,6 +137,7 @@ ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
 ATTRIB_MAP_ENTRY idpool_attr_list[] = {
        { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
        { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
+       { LDAP_ATTR_OBJCLASS,           "objectClass"           },
        { LDAP_ATTR_LIST_END,           NULL                    }       
 };
 
@@ -142,6 +145,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
        { LDAP_ATTR_SID,                LDAP_ATTRIBUTE_SID      },
        { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
        { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
+       { LDAP_ATTR_OBJCLASS,           "objectClass"           },
        { LDAP_ATTR_LIST_END,           NULL                    }       
 };
 
index 54a852601a4bd7786c09cc8d9c6042941e5521d2..de919ef6f96252bd9b6ccf2d1b56180f4c034940 100644 (file)
@@ -347,6 +347,10 @@ static void pdb_free_sam_contents(SAM_ACCOUNT *user)
        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));
+
+       if (user->private.backend_private_data && user->private.backend_private_data_free_fn) {
+               user->private.backend_private_data_free_fn(&user->private.backend_private_data);
+       }
 }
 
 
index c95719451a231a511f50a888c64a7fd6da7cd9eb..e0b9f0e0ec42c4b2dffcb99be29f9564204efad3 100644 (file)
@@ -330,6 +330,14 @@ uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass)
                return (-1);
 }
 
+void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods)
+{
+       if (sampass && my_methods == sampass->methods)
+               return sampass->private.backend_private_data;
+       else
+               return NULL;
+}
+
 /*********************************************************************
  Collection of set...() functions for SAM_ACCOUNT.
  ********************************************************************/
@@ -1011,6 +1019,28 @@ BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_sta
        return pdb_set_init_flags(sampass, PDB_HOURS, flag);
 }
 
+BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, 
+                                  void (*free_fn)(void **), 
+                                  const struct pdb_methods *my_methods, 
+                                  enum pdb_value_state flag)
+{
+       if (!sampass)
+               return False;
+
+       /* does this backend 'own' this SAM_ACCOUNT? */
+       if (my_methods != sampass->methods)
+               return False;
+
+       if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) {
+               sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data);
+       }
+
+       sampass->private.backend_private_data = private_data;
+       sampass->private.backend_private_data_free_fn = free_fn;
+
+       return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
+}
+
 
 /* Helpful interfaces to the above */
 
index 6911cea369f01e885c9ff3429b7f0340d2c9e9db..140b87afb94e21c3de84dc537dc590aa4944c752 100644 (file)
@@ -107,6 +107,16 @@ struct ldapsam_privates {
 
 };
 
+/**********************************************************************
+ Free a LDAPMessage (one is stored on the SAM_ACCOUNT)
+ **********************************************************************/
+static void private_data_free_fn(void **result) 
+{
+       ldap_memfree(*result);
+       *result = NULL;
+}
+
 /**********************************************************************
  get the attribute name given a user schame version 
  **********************************************************************/
@@ -1503,7 +1513,9 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
                        ldap_msgfree(result);
                        return NT_STATUS_NO_SUCH_USER;
                }
-               ldap_msgfree(result);
+               pdb_set_backend_private_data(user, result, 
+                                            private_data_free_fn, 
+                                            my_methods, PDB_CHANGED);
                ret = NT_STATUS_OK;
        } else {
                ldap_msgfree(result);
@@ -1591,9 +1603,13 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT
                        ldap_msgfree(result);
                        return NT_STATUS_NO_SUCH_USER;
                }
+               pdb_set_backend_private_data(user, result, 
+                                            private_data_free_fn, 
+                                            my_methods, PDB_CHANGED);
                ret = NT_STATUS_OK;
+       } else {
+               ldap_msgfree(result);
        }
-       ldap_msgfree(result);
        return ret;
 }      
 
@@ -1789,15 +1805,18 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
        LDAPMod **mods;
        char **attr_list;
 
-       attr_list = get_userattr_list(ldap_state->schema_ver);
-       rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
-       free_attr_list( attr_list );
-       if (rc != LDAP_SUCCESS) 
-               return NT_STATUS_UNSUCCESSFUL;
+       result = pdb_get_backend_private_data(newpwd, my_methods);
+       if (!result) {
+               attr_list = get_userattr_list(ldap_state->schema_ver);
+               rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
+               free_attr_list( attr_list );
+               if (rc != LDAP_SUCCESS) 
+                       return NT_STATUS_UNSUCCESSFUL;
+               pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED);
+       }
 
        if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
                DEBUG(0, ("No user to modify!\n"));
-               ldap_msgfree(result);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -1807,12 +1826,9 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
        if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
                                element_is_changed)) {
                DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
-               ldap_msgfree(result);
                return NT_STATUS_UNSUCCESSFUL;
        }
        
-        ldap_msgfree(result);
-       
        if (mods == NULL) {
                DEBUG(4,("mods is empty: nothing to update for user: %s\n",
                         pdb_get_username(newpwd)));
index 3125c647d6c6e35e32546ac83ee4438db33cf40f..8c66ef9ab02342fb770994928ea5aad0416ce765 100644 (file)
@@ -402,5 +402,16 @@ BOOL idmap_init_wellknown_sids(void)
                SAFE_FREE(map);
        }
 
+       /* Fill in the SID for the administrator account. */
+       id.uid = 0;
+       sid_copy(&sid, get_global_sam_sid());
+       sid_append_rid(&sid, DOMAIN_USER_RID_ADMIN);
+
+       if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
+               DEBUG(0, ("Failed to setup UID mapping for ADMINISTRATOR (%s) to (%u)\n", 
+                         sid_to_string(sid_string, &sid), (unsigned int)id.uid));
+               return False;
+       }
+
        return True;
 }
index ada2d274ba1e5d4deec6f64f1f84d78afcb552a5..881ea96db613a29d134fbb5c2056015eb06d9387 100644 (file)
@@ -409,10 +409,11 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
        SAM_ACCOUNT *sam_account=NULL;
        GROUP_MAP map;
        struct group *grp;
-       DOM_SID sid;
+       DOM_SID user_sid;
+       DOM_SID group_sid;
        struct passwd *passwd;
        unid_t id;
-       int u_type;
+       int u_type = ID_USERID | ID_QUERY_ONLY;
 
        fstrcpy(account, unistr2_static(&delta->uni_acct_name));
        d_printf("Creating account: %s\n", account);
@@ -444,55 +445,56 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                        passwd = Get_Pwnam(account);
                }
        }
+       
+       sid_copy(&user_sid, get_global_sam_sid());
+       sid_append_rid(&user_sid, delta->user_rid);
 
-       sam_account_from_delta(sam_account, delta);
-       if (!pdb_add_sam_account(sam_account)) {
-               DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
-                         account));
+       if (!pdb_getsampwsid(sam_account, &user_sid)) {
+               sam_account_from_delta(sam_account, delta);
+               if (!pdb_add_sam_account(sam_account)) {
+                       DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
+                                 account));
+                       return NT_STATUS_ACCESS_DENIED; 
+               }
+       } else {
+               sam_account_from_delta(sam_account, delta);
                if (!pdb_update_sam_account(sam_account)) {
                        DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
                                  account));
                        pdb_free_sam(&sam_account);
-                       return NT_STATUS_OK;
-/*                     return NT_STATUS_ACCESS_DENIED; */
+                       return NT_STATUS_ACCESS_DENIED; 
                }
        }
 
-       sid = *pdb_get_group_sid(sam_account);
+       group_sid = *pdb_get_group_sid(sam_account);
 
-       if (!pdb_getgrsid(&map, sid)) {
+       if (!pdb_getgrsid(&map, group_sid)) {
                DEBUG(0, ("Primary group of %s has no mapping!\n",
                          pdb_get_username(sam_account)));
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_SUCH_GROUP;
-       }
-       
+       } else {
+               if (map.gid != passwd->pw_gid) {
+                       if (!(grp = getgrgid(map.gid))) {
+                               DEBUG(0, ("Could not find unix group %d for user %s (group SID=%s)\n", 
+                                         map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid)));
+                       } else {
+                               smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
+                       }
+               }
+       }       
+
        if (!passwd) {
+               DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n", pdb_get_username(sam_account)));
                /* if no unix user, changing the mapping won't help */
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_OK;
-       }
-               
-       if (map.gid != passwd->pw_gid) {
-               if (!(grp = getgrgid(map.gid))) {
-                       DEBUG(0, ("Could not find unix group %d for user %s (group SID=%s)\n", 
-                                 map.gid, pdb_get_username(sam_account), sid_string_static(&sid)));
-                       pdb_free_sam(&sam_account);
-                       return NT_STATUS_NO_SUCH_GROUP;
+       } else {
+               nt_ret = idmap_get_id_from_sid(&id, &u_type, pdb_get_user_sid(sam_account));
+               if (NT_STATUS_IS_OK(nt_ret) && (u_type == ID_USERID) && (id.uid == passwd->pw_uid)) {
+                       
+               } else {
+                       /* set mapping */
+                       
+                       id.uid = passwd->pw_uid;
+                       nt_ret = idmap_set_mapping(pdb_get_user_sid(sam_account), id, ID_USERID);
                }
-               
-               smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
-       }
-       
-       nt_ret = idmap_get_id_from_sid(&id, &u_type, pdb_get_user_sid(sam_account));
-       if (!NT_STATUS_IS_OK(nt_ret)) {
-               pdb_free_sam(&sam_account);
-               return nt_ret;
-       }
-
-       if ((u_type != ID_USERID) || (id.uid != passwd->pw_uid)) {
-               id.uid = passwd->pw_uid;
-               nt_ret = idmap_set_mapping(pdb_get_user_sid(sam_account), id, ID_USERID);
        }
 
        pdb_free_sam(&sam_account);
@@ -980,6 +982,11 @@ int rpc_vampire(int argc, const char **argv)
 
        ZERO_STRUCT(ret_creds);
 
+       if (!idmap_init(lp_idmap_backend())) {
+               d_printf("Could not init idmap\n");
+               return -1;
+       }
+
        /* Connect to remote machine */
        if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS |
                                            NET_FLAGS_PDC))) {