s3-auth Change type of num_sids to uint32_t
[samba.git] / source3 / passdb / pdb_ldap.c
index 2c8d0518d551d96aa391d145a4c28af95ec5e18b..658d774fefd03d100e8e89d6fe7e97c426db0bea 100644 (file)
@@ -45,6 +45,8 @@
 
 #include "includes.h"
 #include "../libcli/auth/libcli_auth.h"
+#include "secrets.h"
+#include "idmap_cache.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_PASSDB
@@ -376,7 +378,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
 ******************************************************************/
 
 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
-                                        uint32 rid, LDAPMessage ** result,
+                                        uint32_t rid, LDAPMessage ** result,
                                         const char **attr)
 {
        char *filter = NULL;
@@ -399,7 +401,7 @@ static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
 ******************************************************************/
 
 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
-                                const DOM_SID *sid, LDAPMessage ** result,
+                                const struct dom_sid *sid, LDAPMessage ** result,
                                 const char **attr)
 {
        char *filter = NULL;
@@ -529,19 +531,19 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                        *acct_desc = NULL,
                        *workstations = NULL,
                        *munged_dial = NULL;
-       uint32          user_rid;
+       uint32_t                user_rid;
        uint8           smblmpwd[LM_HASH_LEN],
                        smbntpwd[NT_HASH_LEN];
        bool            use_samba_attrs = True;
-       uint32          acct_ctrl = 0;
-       uint16          logon_divs;
-       uint16          bad_password_count = 0,
+       uint32_t                acct_ctrl = 0;
+       uint16_t                logon_divs;
+       uint16_t                bad_password_count = 0,
                        logon_count = 0;
-       uint32 hours_len;
+       uint32_t hours_len;
        uint8           hours[MAX_HOURS_LEN];
        char *temp = NULL;
-       LOGIN_CACHE     *cache_entry = NULL;
-       uint32          pwHistLen;
+       struct login_cache cache_entry;
+       uint32_t                pwHistLen;
        bool expand_explicit = lp_passdb_expand_explicit();
        bool ret = false;
        TALLOC_CTX *ctx = talloc_init("init_sam_from_ldap");
@@ -560,7 +562,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                goto fn_exit;
        }
 
-       if (!(username = smbldap_talloc_smallest_attribute(priv2ld(ldap_state),
+       if (!(username = smbldap_talloc_first_attribute(priv2ld(ldap_state),
                                        entry,
                                        "uid",
                                        ctx))) {
@@ -604,12 +606,12 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                                get_userattr_key2string(ldap_state->schema_ver,
                                        LDAP_ATTR_USER_RID),
                                ctx))!=NULL) {
-                       user_rid = (uint32)atol(temp);
+                       user_rid = (uint32_t)atol(temp);
                        pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
                }
        }
 
-       if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
+       if (IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
                DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n", 
                        get_userattr_key2string(ldap_state->schema_ver,
                                LDAP_ATTR_USER_SID),
@@ -915,9 +917,9 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 
                pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
 
-               if ((pwhist = TALLOC_ARRAY(ctx, uint8,
-                                       pwHistLen * PW_HISTORY_ENTRY_LEN)) ==
-                               NULL){
+               pwhist = TALLOC_ARRAY(ctx, uint8,
+                                     pwHistLen * PW_HISTORY_ENTRY_LEN);
+               if (pwhist == NULL) {
                        DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
                        goto fn_exit;
                }
@@ -985,7 +987,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                                LDAP_ATTR_BAD_PASSWORD_COUNT),
                        ctx);
        if (temp) {
-               bad_password_count = (uint32) atol(temp);
+               bad_password_count = (uint32_t) atol(temp);
                pdb_set_bad_password_count(sampass,
                                bad_password_count, PDB_SET);
        }
@@ -1009,7 +1011,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                                LDAP_ATTR_LOGON_COUNT),
                        ctx);
        if (temp) {
-               logon_count = (uint32) atol(temp);
+               logon_count = (uint32_t) atol(temp);
                pdb_set_logon_count(sampass, logon_count, PDB_SET);
        }
 
@@ -1029,6 +1031,17 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
        }
 
        if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
+               struct passwd unix_pw;
+               bool have_uid = false;
+               bool have_gid = false;
+               struct dom_sid mapped_gsid;
+               const struct dom_sid *primary_gsid;
+
+               ZERO_STRUCT(unix_pw);
+
+               unix_pw.pw_name = username;
+               unix_pw.pw_passwd = discard_const_p(char, "x");
+
                temp = smbldap_talloc_single_attribute(
                                priv2ld(ldap_state),
                                entry,
@@ -1036,8 +1049,68 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                                ctx);
                if (temp) {
                        /* We've got a uid, feed the cache */
-                       uid_t uid = strtoul(temp, NULL, 10);
-                       store_uid_sid_cache(pdb_get_user_sid(sampass), uid);
+                       unix_pw.pw_uid = strtoul(temp, NULL, 10);
+                       have_uid = true;
+               }
+               temp = smbldap_talloc_single_attribute(
+                               priv2ld(ldap_state),
+                               entry,
+                               "gidNumber",
+                               ctx);
+               if (temp) {
+                       /* We've got a uid, feed the cache */
+                       unix_pw.pw_gid = strtoul(temp, NULL, 10);
+                       have_gid = true;
+               }
+               unix_pw.pw_gecos = smbldap_talloc_single_attribute(
+                               priv2ld(ldap_state),
+                               entry,
+                               "gecos",
+                               ctx);
+               if (unix_pw.pw_gecos) {
+                       unix_pw.pw_gecos = fullname;
+               }
+               unix_pw.pw_dir = smbldap_talloc_single_attribute(
+                               priv2ld(ldap_state),
+                               entry,
+                               "homeDirectory",
+                               ctx);
+               if (unix_pw.pw_dir) {
+                       unix_pw.pw_dir = discard_const_p(char, "");
+               }
+               unix_pw.pw_shell = smbldap_talloc_single_attribute(
+                               priv2ld(ldap_state),
+                               entry,
+                               "loginShell",
+                               ctx);
+               if (unix_pw.pw_shell) {
+                       unix_pw.pw_shell = discard_const_p(char, "");
+               }
+
+               if (have_uid && have_gid) {
+                       sampass->unix_pw = tcopy_passwd(sampass, &unix_pw);
+               } else {
+                       sampass->unix_pw = Get_Pwnam_alloc(sampass, unix_pw.pw_name);
+               }
+
+               if (sampass->unix_pw == NULL) {
+                       DEBUG(0,("init_sam_from_ldap: Failed to find Unix account for %s\n",
+                                pdb_get_username(sampass)));
+                       goto fn_exit;
+               }
+
+               store_uid_sid_cache(pdb_get_user_sid(sampass),
+                                   sampass->unix_pw->pw_uid);
+               idmap_cache_set_sid2uid(pdb_get_user_sid(sampass),
+                                       sampass->unix_pw->pw_uid);
+
+               gid_to_sid(&mapped_gsid, sampass->unix_pw->pw_gid);
+               primary_gsid = pdb_get_group_sid(sampass);
+               if (primary_gsid && sid_equal(primary_gsid, &mapped_gsid)) {
+                       store_gid_sid_cache(primary_gsid,
+                                           sampass->unix_pw->pw_gid);
+                       idmap_cache_set_sid2gid(primary_gsid,
+                                               sampass->unix_pw->pw_gid);
                }
        }
 
@@ -1049,7 +1122,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
        }
 
        /* see if we have newer updates */
-       if (!(cache_entry = login_cache_read(sampass))) {
+       if (!login_cache_read(sampass, &cache_entry)) {
                DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
                           (unsigned int)pdb_get_bad_password_count(sampass),
                           (unsigned int)pdb_get_bad_password_time(sampass)));
@@ -1059,10 +1132,10 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 
        DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
                  (unsigned int)ldap_entry_time,
-                 (unsigned int)cache_entry->entry_timestamp,
-                 (unsigned int)cache_entry->bad_password_time));
+                 (unsigned int)cache_entry.entry_timestamp,
+                 (unsigned int)cache_entry.bad_password_time));
 
-       if (ldap_entry_time > cache_entry->entry_timestamp) {
+       if (ldap_entry_time > cache_entry.entry_timestamp) {
                /* cache is older than directory , so
                   we need to delete the entry but allow the
                   fields to be written out */
@@ -1071,13 +1144,13 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
                /* read cache in */
                pdb_set_acct_ctrl(sampass,
                                  pdb_get_acct_ctrl(sampass) |
-                                 (cache_entry->acct_ctrl & ACB_AUTOLOCK),
+                                 (cache_entry.acct_ctrl & ACB_AUTOLOCK),
                                  PDB_SET);
                pdb_set_bad_password_count(sampass,
-                                          cache_entry->bad_password_count,
+                                          cache_entry.bad_password_count,
                                           PDB_SET);
                pdb_set_bad_password_time(sampass,
-                                         cache_entry->bad_password_time,
+                                         cache_entry.bad_password_time,
                                          PDB_SET);
        }
 
@@ -1086,7 +1159,6 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
   fn_exit:
 
        TALLOC_FREE(ctx);
-       SAFE_FREE(cache_entry);
        return ret;
 }
 
@@ -1102,7 +1174,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                                                    enum pdb_elements))
 {
        char *temp = NULL;
-       uint32 rid;
+       uint32_t rid;
 
        if (mods == NULL || sampass == NULL) {
                DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
@@ -1131,7 +1203,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
        /* only update the RID if we actually need to */
        if (need_update(sampass, PDB_USERSID)) {
                fstring sid_string;
-               const DOM_SID *user_sid = pdb_get_user_sid(sampass);
+               const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
 
                switch ( ldap_state->schema_ver ) {
                        case SCHEMAVER_SAMBAACCOUNT:
@@ -1168,7 +1240,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
 
        if (need_update(sampass, PDB_GROUPSID)) {
                fstring sid_string;
-               const DOM_SID *group_sid = pdb_get_group_sid(sampass);
+               const struct dom_sid *group_sid = pdb_get_group_sid(sampass);
 
                switch ( ldap_state->schema_ver ) {
                        case SCHEMAVER_SAMBAACCOUNT:
@@ -1326,7 +1398,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
 
                if (need_update(sampass, PDB_PWHISTORY)) {
                        char *pwstr = NULL;
-                       uint32 pwHistLen = 0;
+                       uint32_t pwHistLen = 0;
                        pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
 
                        pwstr = SMB_MALLOC_ARRAY(char, 1024);
@@ -1339,7 +1411,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                                pwstr[64] = '\0';
                        } else {
                                int i;
-                               uint32 currHistLen = 0;
+                               uint32_t currHistLen = 0;
                                const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
                                if (pwhist != NULL) {
                                        /* We can only store (1024-1/64 password history entries. */
@@ -1401,9 +1473,9 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
 
        if (need_update(sampass, PDB_BAD_PASSWORD_COUNT))  /* &&
            need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
-               uint16 badcount = pdb_get_bad_password_count(sampass);
+               uint16_t badcount = pdb_get_bad_password_count(sampass);
                time_t badtime = pdb_get_bad_password_time(sampass);
-               uint32 pol;
+               uint32_t pol;
                pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
 
                DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
@@ -1440,7 +1512,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                        DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
                        login_cache_delentry(sampass);
                } else {
-                       LOGIN_CACHE cache_entry;
+                       struct login_cache cache_entry;
 
                        cache_entry.entry_timestamp = time(NULL);
                        cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
@@ -1448,7 +1520,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                        cache_entry.bad_password_time = badtime;
 
                        DEBUG(7, ("Updating bad password count and time in login cache\n"));
-                       login_cache_write(sampass, cache_entry);
+                       login_cache_write(sampass, &cache_entry);
                }
        }
 
@@ -1488,6 +1560,16 @@ static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
        (*attr_list)[i+1] = NULL;
 }
 
+static void ldapsam_add_unix_attributes(TALLOC_CTX *mem_ctx,
+                                       const char ***attr_list)
+{
+       append_attr(mem_ctx, attr_list, "uidNumber");
+       append_attr(mem_ctx, attr_list, "gidNumber");
+       append_attr(mem_ctx, attr_list, "homeDirectory");
+       append_attr(mem_ctx, attr_list, "loginShell");
+       append_attr(mem_ctx, attr_list, "gecos");
+}
+
 /**********************************************************************
 Get struct samu entry from LDAP by username.
 *********************************************************************/
@@ -1506,7 +1588,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu
        append_attr(user, &attr_list,
                    get_userattr_key2string(ldap_state->schema_ver,
                                            LDAP_ATTR_MOD_TIMESTAMP));
-       append_attr(user, &attr_list, "uidNumber");
+       ldapsam_add_unix_attributes(user, &attr_list);
        rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
                                           attr_list);
        TALLOC_FREE( attr_list );
@@ -1544,11 +1626,11 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu
 }
 
 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state, 
-                                  const DOM_SID *sid, LDAPMessage **result) 
+                                  const struct dom_sid *sid, LDAPMessage **result)
 {
        int rc = -1;
        const char ** attr_list;
-       uint32 rid;
+       uint32_t rid;
 
        switch ( ldap_state->schema_ver ) {
                case SCHEMAVER_SAMBASAMACCOUNT: {
@@ -1563,7 +1645,7 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
                                    get_userattr_key2string(
                                            ldap_state->schema_ver,
                                            LDAP_ATTR_MOD_TIMESTAMP));
-                       append_attr(tmp_ctx, &attr_list, "uidNumber");
+                       ldapsam_add_unix_attributes(tmp_ctx, &attr_list);
                        rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
                                                          result, attr_list);
                        TALLOC_FREE(tmp_ctx);
@@ -1594,7 +1676,7 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
  Get struct samu entry from LDAP by SID.
 *********************************************************************/
 
-static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
+static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const struct dom_sid *sid)
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAPMessage *result = NULL;
@@ -1657,39 +1739,6 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!mods) {
-               DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
-               /* may be password change below however */
-       } else {
-               switch(ldap_op) {
-                       case LDAP_MOD_ADD:
-                               if (ldap_state->is_nds_ldap) {
-                                       smbldap_set_mod(&mods, LDAP_MOD_ADD, 
-                                                       "objectclass", 
-                                                       "inetOrgPerson");
-                               } else {
-                                       smbldap_set_mod(&mods, LDAP_MOD_ADD, 
-                                                       "objectclass", 
-                                                       LDAP_OBJ_ACCOUNT);
-                               }
-                               rc = smbldap_add(ldap_state->smbldap_state, 
-                                                dn, mods);
-                               break;
-                       case LDAP_MOD_REPLACE: 
-                               rc = smbldap_modify(ldap_state->smbldap_state, 
-                                                   dn ,mods);
-                               break;
-                       default:        
-                               DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n", 
-                                        ldap_op));
-                               return NT_STATUS_INVALID_PARAMETER;
-               }
-
-               if (rc!=LDAP_SUCCESS) {
-                       return NT_STATUS_UNSUCCESSFUL;
-               }  
-       }
-
        if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
                        (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
                        need_update(newpwd, PDB_PLAINTEXT_PW) &&
@@ -1815,6 +1864,40 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                }
                ber_bvfree(bv);
        }
+
+       if (!mods) {
+               DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
+               /* may be password change below however */
+       } else {
+               switch(ldap_op) {
+                       case LDAP_MOD_ADD:
+                               if (ldap_state->is_nds_ldap) {
+                                       smbldap_set_mod(&mods, LDAP_MOD_ADD,
+                                                       "objectclass",
+                                                       "inetOrgPerson");
+                               } else {
+                                       smbldap_set_mod(&mods, LDAP_MOD_ADD,
+                                                       "objectclass",
+                                                       LDAP_OBJ_ACCOUNT);
+                               }
+                               rc = smbldap_add(ldap_state->smbldap_state,
+                                                dn, mods);
+                               break;
+                       case LDAP_MOD_REPLACE:
+                               rc = smbldap_modify(ldap_state->smbldap_state,
+                                                   dn ,mods);
+                               break;
+                       default:
+                               DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
+                                        ldap_op));
+                               return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               if (rc!=LDAP_SUCCESS) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -1988,13 +2071,13 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc
 
 static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
                                     TALLOC_CTX *tmp_ctx,
-                                    uint32 group_rid,
-                                    uint32 member_rid);
+                                    uint32_t group_rid,
+                                    uint32_t member_rid);
 
 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
                                               TALLOC_CTX *mem_ctx,
                                               struct samu *user,
-                                              DOM_SID **pp_sids,
+                                              struct dom_sid **pp_sids,
                                               gid_t **pp_gids,
                                               size_t *p_num_groups);
 
@@ -2095,11 +2178,11 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
        LDAPMessage     *entry  = NULL;
        LDAPMod         **mods = NULL;
        int             ldap_op = LDAP_MOD_REPLACE;
-       uint32          num_result;
+       uint32_t                num_result;
        const char      **attr_list;
        char *escape_user = NULL;
        const char      *username = pdb_get_username(newpwd);
-       const DOM_SID   *sid = pdb_get_user_sid(newpwd);
+       const struct dom_sid    *sid = pdb_get_user_sid(newpwd);
        char *filter = NULL;
        char *dn = NULL;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -2449,6 +2532,7 @@ for gidNumber(%lu)\n",(unsigned long)map->gid));
 
        if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
                store_gid_sid_cache(&map->sid, map->gid);
+               idmap_cache_set_sid2gid(&map->sid, map->gid);
        }
 
        TALLOC_FREE(ctx);
@@ -2511,7 +2595,7 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
-                                DOM_SID sid)
+                                struct dom_sid sid)
 {
        char *filter = NULL;
        NTSTATUS status;
@@ -2581,11 +2665,11 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
 
 static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
                                           LDAPMessage *entry,
-                                          const DOM_SID *domain_sid,
-                                          uint32 *rid)
+                                          const struct dom_sid *domain_sid,
+                                          uint32_t *rid)
 {
        fstring str;
-       DOM_SID sid;
+       struct dom_sid sid;
 
        if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
                                          str, sizeof(str)-1)) {
@@ -2614,8 +2698,8 @@ static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
 
 static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
                                           TALLOC_CTX *mem_ctx,
-                                          const DOM_SID *group,
-                                          uint32 **pp_member_rids,
+                                          const struct dom_sid *group,
+                                          uint32_t **pp_member_rids,
                                           size_t *p_num_members)
 {
        struct ldapsam_privates *ldap_state =
@@ -2683,7 +2767,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
 
        values = ldap_get_values(conn->ldap_struct, entry, "memberUid");
 
-       if (values) {
+       if ((values != NULL) && (values[0] != NULL)) {
 
                filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBASAMACCOUNT);
                if (filter == NULL) {
@@ -2732,8 +2816,8 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
                     entry = ldap_next_entry(conn->ldap_struct, entry))
                {
                        char *sidstr;
-                       DOM_SID sid;
-                       uint32 rid;
+                       struct dom_sid sid;
+                       uint32_t rid;
 
                        sidstr = smbldap_talloc_single_attribute(conn->ldap_struct,
                                                                 entry, "sambaSID",
@@ -2784,7 +2868,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
             entry != NULL;
             entry = ldap_next_entry(conn->ldap_struct, entry))
        {
-               uint32 rid;
+               uint32_t rid;
 
                if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
                                                    entry,
@@ -2815,7 +2899,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
                                               TALLOC_CTX *mem_ctx,
                                               struct samu *user,
-                                              DOM_SID **pp_sids,
+                                              struct dom_sid **pp_sids,
                                               gid_t **pp_gids,
                                               size_t *p_num_groups)
 {
@@ -2829,7 +2913,8 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
        LDAPMessage *result = NULL;
        LDAPMessage *entry;
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       size_t num_sids, num_gids;
+       uint32_t num_sids;
+       size_t num_gids;
        char *gidstr;
        gid_t primary_gid = -1;
 
@@ -2844,46 +2929,50 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
        if (escape_name == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       /* retrieve the users primary gid */
-       filter = talloc_asprintf(mem_ctx,
-                                "(&(objectClass=%s)(uid=%s))",
-                                LDAP_OBJ_SAMBASAMACCOUNT,
-                                escape_name);
-       if (filter == NULL) {
-               ret = NT_STATUS_NO_MEMORY;
-               goto done;
-       }
+       if (user->unix_pw) {
+               primary_gid = user->unix_pw->pw_gid;
+       } else {
+               /* retrieve the users primary gid */
+               filter = talloc_asprintf(mem_ctx,
+                                        "(&(objectClass=%s)(uid=%s))",
+                                        LDAP_OBJ_SAMBASAMACCOUNT,
+                                        escape_name);
+               if (filter == NULL) {
+                       ret = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
 
-       rc = smbldap_search(conn, lp_ldap_suffix(),
-                           LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
+               rc = smbldap_search(conn, lp_ldap_suffix(),
+                                   LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
 
-       if (rc != LDAP_SUCCESS)
-               goto done;
+               if (rc != LDAP_SUCCESS)
+                       goto done;
 
-       talloc_autofree_ldapmsg(mem_ctx, result);
+               talloc_autofree_ldapmsg(mem_ctx, result);
 
-       count = ldap_count_entries(priv2ld(ldap_state), result);
+               count = ldap_count_entries(priv2ld(ldap_state), result);
 
-       switch (count) {
-       case 0: 
-               DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
-               ret = NT_STATUS_NO_SUCH_USER;
-               goto done;
-       case 1:
-               entry = ldap_first_entry(priv2ld(ldap_state), result);
+               switch (count) {
+               case 0:
+                       DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
+                       ret = NT_STATUS_NO_SUCH_USER;
+                       goto done;
+               case 1:
+                       entry = ldap_first_entry(priv2ld(ldap_state), result);
 
-               gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
-               if (!gidstr) {
-                       DEBUG (1, ("Unable to find the member's gid!\n"));
+                       gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
+                       if (!gidstr) {
+                               DEBUG (1, ("Unable to find the member's gid!\n"));
+                               ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+                               goto done;
+                       }
+                       primary_gid = strtoul(gidstr, NULL, 10);
+                       break;
+               default:
+                       DEBUG(1, ("found more than one account with the same user name ?!\n"));
                        ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
                        goto done;
                }
-               primary_gid = strtoul(gidstr, NULL, 10);
-               break;
-       default:
-               DEBUG(1, ("found more than one account with the same user name ?!\n"));
-               ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
-               goto done;
        }
 
        filter = talloc_asprintf(mem_ctx,
@@ -2928,7 +3017,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
             entry = ldap_next_entry(conn->ldap_struct, entry))
        {
                fstring str;
-               DOM_SID sid;
+               struct dom_sid sid;
                gid_t gid;
                char *end;
 
@@ -3053,7 +3142,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
        TALLOC_CTX *mem_ctx;
        NTSTATUS result;
 
-       DOM_SID sid;
+       struct dom_sid sid;
 
        int rc;
 
@@ -3258,7 +3347,7 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
-                                                  DOM_SID sid)
+                                                  struct dom_sid sid)
 {
        struct ldapsam_privates *priv =
                (struct ldapsam_privates *)methods->private_data;
@@ -3421,7 +3510,7 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
  *********************************************************************/
 
 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
-                                          const DOM_SID *domsid, enum lsa_SidType sid_name_use,
+                                          const struct dom_sid *domsid, enum lsa_SidType sid_name_use,
                                           GROUP_MAP **pp_rmap,
                                           size_t *p_num_entries,
                                           bool unix_only)
@@ -3471,8 +3560,8 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
 }
 
 static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
-                                       const DOM_SID *alias,
-                                       const DOM_SID *member,
+                                       const struct dom_sid *alias,
+                                       const struct dom_sid *member,
                                        int modop)
 {
        struct ldapsam_privates *ldap_state =
@@ -3576,24 +3665,24 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
 }
 
 static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
-                                    const DOM_SID *alias,
-                                    const DOM_SID *member)
+                                    const struct dom_sid *alias,
+                                    const struct dom_sid *member)
 {
        return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
 }
 
 static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
-                                    const DOM_SID *alias,
-                                    const DOM_SID *member)
+                                    const struct dom_sid *alias,
+                                    const struct dom_sid *member)
 {
        return ldapsam_modify_aliasmem(methods, alias, member,
                                       LDAP_MOD_DELETE);
 }
 
 static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
-                                     const DOM_SID *alias,
+                                     const struct dom_sid *alias,
                                      TALLOC_CTX *mem_ctx,
-                                     DOM_SID **pp_members,
+                                     struct dom_sid **pp_members,
                                      size_t *p_num_members)
 {
        struct ldapsam_privates *ldap_state =
@@ -3604,7 +3693,7 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
        char **values = NULL;
        int i;
        char *filter = NULL;
-       size_t num_members = 0;
+       uint32_t num_members = 0;
        enum lsa_SidType type = SID_NAME_USE_NONE;
        fstring tmp;
 
@@ -3679,7 +3768,7 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
        count = ldap_count_values(values);
 
        for (i=0; i<count; i++) {
-               DOM_SID member;
+               struct dom_sid member;
                NTSTATUS status;
 
                if (!string_to_sid(&member, values[i]))
@@ -3703,10 +3792,10 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
 
 static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
                                          TALLOC_CTX *mem_ctx,
-                                         const DOM_SID *domain_sid,
-                                         const DOM_SID *members,
+                                         const struct dom_sid *domain_sid,
+                                         const struct dom_sid *members,
                                          size_t num_members,
-                                         uint32 **pp_alias_rids,
+                                         uint32_t **pp_alias_rids,
                                          size_t *p_num_alias_rids)
 {
        struct ldapsam_privates *ldap_state =
@@ -3721,11 +3810,14 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        int rc;
        char *filter;
        enum lsa_SidType type = SID_NAME_USE_NONE;
+       bool is_builtin = false;
+       bool sid_added = false;
 
        *pp_alias_rids = NULL;
        *p_num_alias_rids = 0;
 
        if (sid_check_is_builtin(domain_sid)) {
+               is_builtin = true;
                type = SID_NAME_ALIAS;
        }
 
@@ -3744,7 +3836,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        }
 
        filter = talloc_asprintf(mem_ctx,
-                                "(&(|(objectclass=%s)(sambaGroupType=%d))(|",
+                                "(&(objectclass=%s)(sambaGroupType=%d)(|",
                                 LDAP_OBJ_GROUPMAP, type);
 
        for (i=0; i<num_members; i++)
@@ -3759,11 +3851,20 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
                return NT_STATUS_NO_MEMORY;
        }
 
-       rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
-                           LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
-
-       if (rc != LDAP_SUCCESS)
-               return NT_STATUS_UNSUCCESSFUL;
+       if (is_builtin &&
+           ldap_state->search_cache.filter &&
+           strcmp(ldap_state->search_cache.filter, filter) == 0) {
+               filter = talloc_move(filter, &ldap_state->search_cache.filter);
+               result = ldap_state->search_cache.result;
+               ldap_state->search_cache.result = NULL;
+       } else {
+               rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
+                                   LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
+               if (rc != LDAP_SUCCESS) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+               talloc_autofree_ldapmsg(filter, result);
+       }
 
        ldap_struct = ldap_state->smbldap_state->ldap_struct;
 
@@ -3772,8 +3873,8 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
             entry = ldap_next_entry(ldap_struct, entry))
        {
                fstring sid_str;
-               DOM_SID sid;
-               uint32 rid;
+               struct dom_sid sid;
+               uint32_t rid;
 
                if (!smbldap_get_single_attribute(ldap_struct, entry,
                                                  LDAP_ATTRIBUTE_SID,
@@ -3787,20 +3888,30 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
                if (!sid_peek_check_rid(domain_sid, &sid, &rid))
                        continue;
 
+               sid_added = true;
+
                if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
                                        p_num_alias_rids)) {
-                       ldap_msgfree(result);
                        return NT_STATUS_NO_MEMORY;
                }
        }
 
-       ldap_msgfree(result);
+       if (!is_builtin && !sid_added) {
+               TALLOC_FREE(ldap_state->search_cache.filter);
+               /*
+                * Note: result is a talloc child of filter because of the
+                * talloc_autofree_ldapmsg() usage
+                */
+               ldap_state->search_cache.filter = talloc_move(ldap_state, &filter);
+               ldap_state->search_cache.result = result;
+       }
+
        return NT_STATUS_OK;
 }
 
 static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
                                                   enum pdb_policy_type type,
-                                                  uint32 value)
+                                                  uint32_t value)
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
        int rc;
@@ -3856,7 +3967,7 @@ static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
 
 static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
                                                     enum pdb_policy_type type,
-                                                    uint32 *value)
+                                                    uint32_t *value)
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
        LDAPMessage *result = NULL;
@@ -3864,6 +3975,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
        int count;
        int rc;
        char **vals = NULL;
+       char *filter;
        const char *policy_attr = NULL;
 
        struct ldapsam_privates *ldap_state =
@@ -3887,10 +3999,14 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
        attrs[0] = policy_attr;
        attrs[1] = NULL;
 
+       filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)", LDAP_OBJ_DOMINFO);
+       if (filter == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
        rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
-                           LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
+                           LDAP_SCOPE_BASE, filter, attrs, 0,
                            &result);
-
+       TALLOC_FREE(filter);
        if (rc != LDAP_SUCCESS) {
                return ntstatus;
        }
@@ -3910,7 +4026,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
                goto out;
        }
 
-       *value = (uint32)atol(vals[0]);
+       *value = (uint32_t)atol(vals[0]);
 
        ntstatus = NT_STATUS_OK;
 
@@ -3986,9 +4102,9 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
 }
 
 static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
-                                   const DOM_SID *domain_sid,
+                                   const struct dom_sid *domain_sid,
                                    int num_rids,
-                                   uint32 *rids,
+                                   uint32_t *rids,
                                    const char **names,
                                    enum lsa_SidType *attrs)
 {
@@ -4029,7 +4145,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
        }
 
        for (i=0; i<num_rids; i++) {
-               DOM_SID sid;
+               struct dom_sid sid;
                sid_compose(&sid, domain_sid, rids[i]);
                allsids = talloc_asprintf_append_buffer(
                        allsids, "(sambaSid=%s)",
@@ -4069,7 +4185,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
        for (entry = ldap_first_entry(ld, msg);
             entry != NULL;
             entry = ldap_next_entry(ld, entry)) {
-               uint32 rid;
+               uint32_t rid;
                int rid_index;
                const char *name;
 
@@ -4143,7 +4259,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
             entry != NULL;
             entry = ldap_next_entry(ld, entry))
        {
-               uint32 rid;
+               uint32_t rid;
                int rid_index;
                const char *attr;
                enum lsa_SidType type;
@@ -4234,7 +4350,7 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
        return result;
 }
 
-const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
+static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
 {
        int i, num = 0;
        va_list ap;
@@ -4267,8 +4383,8 @@ const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
 struct ldap_search_state {
        struct smbldap_state *connection;
 
-       uint32 acct_flags;
-       uint16 group_type;
+       uint32_t acct_flags;
+       uint16_t group_type;
 
        const char *base;
        int scope;
@@ -4329,11 +4445,6 @@ static bool ldapsam_search_firstpage(struct pdb_search *search)
         }
         state->current_entry = ldap_first_entry(ld, state->entries);
 
-       if (state->current_entry == NULL) {
-               ldap_msgfree(state->entries);
-               state->entries = NULL;
-       }
-
        return True;
 }
 
@@ -4362,6 +4473,7 @@ static bool ldapsam_search_nextpage(struct pdb_search *search)
        if (state->current_entry == NULL) {
                ldap_msgfree(state->entries);
                state->entries = NULL;
+               return false;
        }
 
        return True;
@@ -4382,6 +4494,10 @@ static bool ldapsam_search_next_entry(struct pdb_search *search,
            !ldapsam_search_nextpage(search))
                    return False;
 
+       if (state->current_entry == NULL) {
+               return false;
+       }
+
        result = state->ldap2displayentry(state, search,
                                          state->connection->ldap_struct,
                                          state->current_entry, entry);
@@ -4443,8 +4559,8 @@ static bool ldapuser2displayentry(struct ldap_search_state *state,
 {
        char **vals;
        size_t converted_size;
-       DOM_SID sid;
-       uint32 acct_flags;
+       struct dom_sid sid;
+       uint32_t acct_flags;
 
        vals = ldap_get_values(ld, entry, "sambaAcctFlags");
        if ((vals == NULL) || (vals[0] == NULL)) {
@@ -4536,7 +4652,7 @@ static bool ldapuser2displayentry(struct ldap_search_state *state,
 
 static bool ldapsam_search_users(struct pdb_methods *methods,
                                 struct pdb_search *search,
-                                uint32 acct_flags)
+                                uint32_t acct_flags)
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
@@ -4589,8 +4705,8 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state,
 {
        char **vals;
        size_t converted_size;
-       DOM_SID sid;
-       uint16 group_type;
+       struct dom_sid sid;
+       uint16_t group_type;
 
        result->account_name = "";
        result->fullname = "";
@@ -4708,7 +4824,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state,
 
 static bool ldapsam_search_grouptype(struct pdb_methods *methods,
                                     struct pdb_search *search,
-                                     const DOM_SID *sid,
+                                     const struct dom_sid *sid,
                                     enum lsa_SidType type)
 {
        struct ldapsam_privates *ldap_state =
@@ -4760,7 +4876,7 @@ static bool ldapsam_search_groups(struct pdb_methods *methods,
 
 static bool ldapsam_search_aliases(struct pdb_methods *methods,
                                   struct pdb_search *search,
-                                  const DOM_SID *sid)
+                                  const struct dom_sid *sid)
 {
        return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
 }
@@ -4771,7 +4887,7 @@ static uint32_t ldapsam_capabilities(struct pdb_methods *methods)
 }
 
 static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
-                                   uint32 *rid)
+                                   uint32_t *rid)
 {
        struct smbldap_state *smbldap_state = priv->smbldap_state;
 
@@ -4781,7 +4897,7 @@ static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
        NTSTATUS status;
        char *value;
        int rc;
-       uint32 nextRid = 0;
+       uint32_t nextRid = 0;
        const char *dn;
 
        TALLOC_CTX *mem_ctx;
@@ -4818,21 +4934,21 @@ static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
        value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
                                                "sambaNextRid", mem_ctx);
        if (value != NULL) {
-               uint32 tmp = (uint32)strtoul(value, NULL, 10);
+               uint32_t tmp = (uint32_t)strtoul(value, NULL, 10);
                nextRid = MAX(nextRid, tmp);
        }
 
        value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
                                                "sambaNextUserRid", mem_ctx);
        if (value != NULL) {
-               uint32 tmp = (uint32)strtoul(value, NULL, 10);
+               uint32_t tmp = (uint32_t)strtoul(value, NULL, 10);
                nextRid = MAX(nextRid, tmp);
        }
 
        value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
                                                "sambaNextGroupRid", mem_ctx);
        if (value != NULL) {
-               uint32 tmp = (uint32)strtoul(value, NULL, 10);
+               uint32_t tmp = (uint32_t)strtoul(value, NULL, 10);
                nextRid = MAX(nextRid, tmp);
        }
 
@@ -4867,7 +4983,7 @@ static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
        return status;
 }
 
-static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32 *rid)
+static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32_t *rid)
 {
        int i;
 
@@ -4889,14 +5005,14 @@ static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32 *ri
        return NT_STATUS_ACCESS_DENIED;
 }
 
-static bool ldapsam_new_rid(struct pdb_methods *methods, uint32 *rid)
+static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid)
 {
        NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
        return NT_STATUS_IS_OK(result) ? True : False;
 }
 
 static bool ldapsam_sid_to_id(struct pdb_methods *methods,
-                             const DOM_SID *sid,
+                             const struct dom_sid *sid,
                              union unid_t *id, enum lsa_SidType *type)
 {
        struct ldapsam_privates *priv =
@@ -4961,6 +5077,8 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods,
 
                id->gid = strtoul(gid_str, NULL, 10);
                *type = (enum lsa_SidType)strtoul(value, NULL, 10);
+               store_gid_sid_cache(sid, id->gid);
+               idmap_cache_set_sid2gid(sid, id->gid);
                ret = True;
                goto done;
        }
@@ -4977,6 +5095,8 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods,
 
        id->uid = strtoul(value, NULL, 10);
        *type = SID_NAME_USER;
+       store_uid_sid_cache(sid, id->uid);
+       idmap_cache_set_sid2uid(sid, id->uid);
 
        ret = True;
  done:
@@ -4984,8 +5104,151 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods,
        return ret;
 }
 
+/**
+ * Find the SID for a uid.
+ * This is shortcut is only used if ldapsam:trusted is set to true.
+ */
+static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
+                              struct dom_sid *sid)
+{
+       struct ldapsam_privates *priv =
+               (struct ldapsam_privates *)methods->private_data;
+       char *filter;
+       const char *attrs[] = { "sambaSID", NULL };
+       LDAPMessage *result = NULL;
+       LDAPMessage *entry = NULL;
+       bool ret = false;
+       char *user_sid_string;
+       struct dom_sid user_sid;
+       int rc;
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+       filter = talloc_asprintf(tmp_ctx,
+                                "(&(uidNumber=%u)"
+                                "(objectClass=%s)"
+                                "(objectClass=%s))",
+                                (unsigned int)uid,
+                                LDAP_OBJ_POSIXACCOUNT,
+                                LDAP_OBJ_SAMBASAMACCOUNT);
+       if (filter == NULL) {
+               DEBUG(3, ("talloc_asprintf failed\n"));
+               goto done;
+       }
+
+       rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
+       if (rc != LDAP_SUCCESS) {
+               goto done;
+       }
+       talloc_autofree_ldapmsg(tmp_ctx, result);
+
+       if (ldap_count_entries(priv2ld(priv), result) != 1) {
+               DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
+                          ldap_count_entries(priv2ld(priv), result),
+                          (unsigned int)uid));
+               goto done;
+       }
+
+       entry = ldap_first_entry(priv2ld(priv), result);
+
+       user_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+                                                         "sambaSID", tmp_ctx);
+       if (user_sid_string == NULL) {
+               DEBUG(1, ("Could not find sambaSID in object '%s'\n",
+                         smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
+               goto done;
+       }
+
+       if (!string_to_sid(&user_sid, user_sid_string)) {
+               DEBUG(3, ("Error calling sid_string_talloc for sid '%s'\n",
+                         user_sid_string));
+               goto done;
+       }
+
+       sid_copy(sid, &user_sid);
+
+       store_uid_sid_cache(sid, uid);
+       idmap_cache_set_sid2uid(sid, uid);
+
+       ret = true;
+
+ done:
+       TALLOC_FREE(tmp_ctx);
+       return ret;
+}
+
+/**
+ * Find the SID for a gid.
+ * This is shortcut is only used if ldapsam:trusted is set to true.
+ */
+static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
+                              struct dom_sid *sid)
+{
+       struct ldapsam_privates *priv =
+               (struct ldapsam_privates *)methods->private_data;
+       char *filter;
+       const char *attrs[] = { "sambaSID", NULL };
+       LDAPMessage *result = NULL;
+       LDAPMessage *entry = NULL;
+       bool ret = false;
+       char *group_sid_string;
+       struct dom_sid group_sid;
+       int rc;
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+       filter = talloc_asprintf(tmp_ctx,
+                                "(&(gidNumber=%u)"
+                                "(objectClass=%s))",
+                                (unsigned int)gid,
+                                LDAP_OBJ_GROUPMAP);
+       if (filter == NULL) {
+               DEBUG(3, ("talloc_asprintf failed\n"));
+               goto done;
+       }
+
+       rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
+       if (rc != LDAP_SUCCESS) {
+               goto done;
+       }
+       talloc_autofree_ldapmsg(tmp_ctx, result);
+
+       if (ldap_count_entries(priv2ld(priv), result) != 1) {
+               DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
+                          ldap_count_entries(priv2ld(priv), result),
+                          (unsigned int)gid));
+               goto done;
+       }
+
+       entry = ldap_first_entry(priv2ld(priv), result);
+
+       group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+                                                         "sambaSID", tmp_ctx);
+       if (group_sid_string == NULL) {
+               DEBUG(1, ("Could not find sambaSID in object '%s'\n",
+                         smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
+               goto done;
+       }
+
+       if (!string_to_sid(&group_sid, group_sid_string)) {
+               DEBUG(3, ("Error calling sid_string_talloc for sid '%s'\n",
+                         group_sid_string));
+               goto done;
+       }
+
+       sid_copy(sid, &group_sid);
+
+       store_gid_sid_cache(sid, gid);
+       idmap_cache_set_sid2gid(sid, gid);
+
+       ret = true;
+
+ done:
+       TALLOC_FREE(tmp_ctx);
+       return ret;
+}
+
+
 /*
- * The following functions is called only if
+ * The following functions are called only if
  * ldapsam:trusted and ldapsam:editposix are
  * set to true
  */
@@ -5000,12 +5263,12 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods,
 
 static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
                                    TALLOC_CTX *tmp_ctx, const char *name,
-                                   uint32 acb_info, uint32 *rid)
+                                   uint32_t acb_info, uint32_t *rid)
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
-       uint32 num_result;
+       uint32_t num_result;
        bool is_machine = False;
        bool add_posix = False;
        LDAPMod **mods = NULL;
@@ -5017,8 +5280,8 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
        char *uidstr;
        char *shell;
        const char *dn = NULL;
-       DOM_SID group_sid;
-       DOM_SID user_sid;
+       struct dom_sid group_sid;
+       struct dom_sid user_sid;
        gid_t gid = -1;
        uid_t uid = -1;
        NTSTATUS ret;
@@ -5141,7 +5404,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
                DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
 
                /* retrieve the Domain Users group gid */
-               if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS) ||
+               if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS) ||
                    !sid_to_gid(&group_sid, &gid)) {
                        DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
                        return NT_STATUS_INVALID_PRIMARY_GROUP;
@@ -5322,13 +5585,13 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *
 static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
                                         TALLOC_CTX *tmp_ctx,
                                         const char *name,
-                                        uint32 *rid)
+                                        uint32_t *rid)
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        NTSTATUS ret;
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
-       uint32 num_result;
+       uint32_t num_result;
        bool is_new_entry = False;
        LDAPMod **mods = NULL;
        char *filter;
@@ -5337,7 +5600,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        char *grouptype;
        char *gidstr;
        const char *dn = NULL;
-       DOM_SID group_sid;
+       struct dom_sid group_sid;
        gid_t gid = -1;
        int rc;
 
@@ -5394,12 +5657,35 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        }
 
        if (num_result == 0) {
+               is_new_entry = true;
+       }
+
+       if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
+               DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
+               return ret;
+       }
+
+       sid_compose(&group_sid, get_global_sam_sid(), *rid);
+
+       groupsidstr = talloc_strdup(tmp_ctx, sid_string_talloc(tmp_ctx,
+                                                              &group_sid));
+       grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
+
+       if (!groupsidstr || !grouptype) {
+               DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
+       smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
+
+       if (is_new_entry) {
                char *escape_name;
 
                DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
 
-               is_new_entry = True;
-
                /* lets allocate a new groupid for this group */
                if (!winbind_allocate_gid(&gid)) {
                        DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
@@ -5428,26 +5714,6 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
        }
 
-       if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
-               DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
-               return ret;
-       }
-
-       sid_compose(&group_sid, get_global_sam_sid(), *rid);
-
-       groupsidstr = talloc_strdup(tmp_ctx, sid_string_talloc(tmp_ctx,
-                                                              &group_sid));
-       grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
-
-       if (!groupsidstr || !grouptype) {
-               DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
-       smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
        talloc_autofree_ldapmod(tmp_ctx, mods);
 
        if (is_new_entry) {     
@@ -5474,7 +5740,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32 rid)
+static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32_t rid)
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAPMessage *result = NULL;
@@ -5483,7 +5749,7 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_
        const char *dn;
        char *gidstr;
        char *filter;
-       DOM_SID group_sid;
+       struct dom_sid group_sid;
        int rc;
 
        /* get the group sid */
@@ -5570,20 +5836,20 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_
 
 static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
                                        TALLOC_CTX *tmp_ctx,
-                                       uint32 group_rid,
-                                       uint32 member_rid,
+                                       uint32_t group_rid,
+                                       uint32_t member_rid,
                                        int modop)
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
-       uint32 num_result;
+       uint32_t num_result;
        LDAPMod **mods = NULL;
        char *filter;
        char *uidstr;
        const char *dn = NULL;
-       DOM_SID group_sid;
-       DOM_SID member_sid;
+       struct dom_sid group_sid;
+       struct dom_sid member_sid;
        int rc;
 
        switch (modop) {
@@ -5732,15 +5998,15 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
 
 static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
                                     TALLOC_CTX *tmp_ctx,
-                                    uint32 group_rid,
-                                    uint32 member_rid)
+                                    uint32_t group_rid,
+                                    uint32_t member_rid)
 {
        return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
 }
 static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
                                     TALLOC_CTX *tmp_ctx,
-                                    uint32 group_rid,
-                                    uint32 member_rid)
+                                    uint32_t group_rid,
+                                    uint32_t member_rid)
 {
        return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
 }
@@ -5752,7 +6018,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAPMessage *entry = NULL;
        LDAPMessage *result = NULL;
-       uint32 num_result;
+       uint32_t num_result;
        LDAPMod **mods = NULL;
        char *filter;
        char *escape_username;
@@ -5867,7 +6133,7 @@ static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
        int attrsonly = 0; /* 0: return values too */
        LDAPMessage *result = NULL;
        char *trusted_dn;
-       uint32 num_result;
+       uint32_t num_result;
 
        filter = talloc_asprintf(talloc_tos(),
                                 "(&(objectClass=%s)(sambaDomainName=%s))",
@@ -5917,7 +6183,7 @@ static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
 static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
                                      const char *domain,
                                      char** pwd,
-                                     DOM_SID *sid,
+                                     struct dom_sid *sid,
                                      time_t *pass_last_set_time)
 {
        struct ldapsam_privates *ldap_state =
@@ -5961,18 +6227,17 @@ static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
        /* domain sid */
        if (sid != NULL) {
                char *sid_str;
-               DOM_SID *dom_sid;
+               struct dom_sid dom_sid;
                sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
                                                          entry, "sambaSID",
                                                          talloc_tos());
                if (sid_str == NULL) {
                        return False;
                }
-               dom_sid = string_sid_talloc(talloc_tos(), sid_str);
-               if (dom_sid == NULL) {
+               if (!string_to_sid(&dom_sid, sid_str)) {
                        return False;
                }
-               sid_copy(sid, dom_sid);
+               sid_copy(sid, &dom_sid);
        }
 
        return True;
@@ -5981,7 +6246,7 @@ static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
 static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
                                      const char* domain,
                                      const char* pwd,
-                                     const DOM_SID *sid)
+                                     const struct dom_sid *sid)
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
@@ -6013,8 +6278,6 @@ static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
        smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
                         "sambaClearTextPassword", pwd);
 
-       talloc_autofree_ldapmod(talloc_tos(), mods);
-
        if (entry != NULL) {
                prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
                                entry, "sambaClearTextPassword", talloc_tos());
@@ -6025,6 +6288,8 @@ static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
                }
        }
 
+       talloc_autofree_ldapmod(talloc_tos(), mods);
+
        trusted_dn = trusteddom_dn(ldap_state, domain);
        if (trusted_dn == NULL) {
                return False;
@@ -6079,7 +6344,7 @@ static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
 
 static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
                                         TALLOC_CTX *mem_ctx,
-                                        uint32 *num_domains,
+                                        uint32_t *num_domains,
                                         struct trustdom_info ***domains)
 {
        int rc;
@@ -6296,21 +6561,20 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
 {
        NTSTATUS nt_status;
        struct ldapsam_privates *ldap_state = NULL;
-       uint32 alg_rid_base;
+       uint32_t alg_rid_base;
        char *alg_rid_base_string = NULL;
        LDAPMessage *result = NULL;
        LDAPMessage *entry = NULL;
-       DOM_SID ldap_domain_sid;
-       DOM_SID secrets_domain_sid;
+       struct dom_sid ldap_domain_sid;
+       struct dom_sid secrets_domain_sid;
        char *domain_sid_string = NULL;
        char *dn = NULL;
        char *uri = talloc_strdup( NULL, location );
 
        trim_char( uri, '\"', '\"' );
        nt_status = pdb_init_ldapsam_common(pdb_method, uri);
-       if (uri) {
-               TALLOC_FREE(uri);
-       }
+
+       TALLOC_FREE(uri);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
@@ -6332,6 +6596,8 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
                        ldapsam_enum_group_memberships;
                (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
                (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
+               (*pdb_method)->uid_to_sid = ldapsam_uid_to_sid;
+               (*pdb_method)->gid_to_sid = ldapsam_gid_to_sid;
 
                if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
                        (*pdb_method)->create_user = ldapsam_create_user;
@@ -6427,7 +6693,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
                                         LDAP_ATTR_ALGORITHMIC_RID_BASE ),
                    talloc_tos());
        if (alg_rid_base_string) {
-               alg_rid_base = (uint32)atol(alg_rid_base_string);
+               alg_rid_base = (uint32_t)atol(alg_rid_base_string);
                if (alg_rid_base != algorithmic_rid_base()) {
                        DEBUG(0, ("The value of 'algorithmic RID base' has "
                                  "changed since the LDAP\n"