The branch, v3-4-test has been updated
       via  5b5df3d... s3:passdb: only use gid_to_sid() result if the result is 
a group of our local sam
       via  0b2dd73... s3:pdb_ldap: don't search for the users primary group, 
if we already know it
       via  8f1c7c1... s3:pdb_ldap: optimize ldapsam_alias_memberships() and 
cache ldap searches.
       via  a2ff5f0... s3:pdb_ldap: try to build the full unix_pw structure 
with ldapsam:trusted support
       via  5d97d57... s3:passdb: speed up pdb_get_group_sid()
       via  66b472f... s3: Make pdb_copy_sam_account also copy the group sid
       via  4790877... s3: shortcut gid_to_sid when "ldapsam:trusted = yes"
       via  c48405e... s3:is_trusted_domain: shortcut if domain name == 
global_sam_name
       via  85d8565... s3:is_trusted_domain: shortcut if domain name is NULL or 
empty
       via  91e40df... s3: shortcut uid_to_sid when "ldapsam:trusted = yes"
       via  05f23a8... s3:smbd: also fill the memcache with sid<->id mappings 
in ldapsam_sid_to_id()
       via  c7220ff... s3:smbd: make idmap cache persistent for 
"ldapsam:trusted".
       via  cc529f4... Fix large paged search
       via  4e66860... 
=?utf-8?q?=D1=953:ldap:=20search=20for=20account=20policies=20in=20objectclass=20sambaDomain,=20not=20*
       via  0b7d7e7... s3:ldap: don't search when no values where found (cherry 
picked from commit 70063522065ab3e5a21fb11db0097b808aa11100)
      from  8ac6085... Fix bug #7122 - Reading a large browselist fails (server 
returns invalid values in subsequent SMBtrans replies)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test


- Log -----------------------------------------------------------------
commit 5b5df3d1223d15d4fde9a2a2db83c60aaa266ca4
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue Feb 9 12:57:01 2010 +0100

    s3:passdb: only use gid_to_sid() result if the result is a group of our 
local sam
    
    Otherwise retry with pdb_gid_to_sid().
    
    metze
    (cherry picked from commit 4dc2be2264926fe415e4e40e212f94793c9831d1)
    
    Last seven patches address bug #7116 (pdb_ldap performance fixes).
    (cherry picked from commit 8946a47fcebe57f459c59ee2cb163e15901ff996)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 0b2dd730a52ae9dbd622c50fb70492398f6503d9
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Feb 5 16:20:21 2010 +0100

    s3:pdb_ldap: don't search for the users primary group, if we already know it
    
    metze
    (cherry picked from commit 6753fb1cf6a834b12b2a9dce3b1a9555390c17be)
    (cherry picked from commit da7cb9feacc7cb84499c73ef463d187a7b2754e8)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 8f1c7c117b3bca058024daa34f777efa5ece88f8
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Feb 3 11:32:41 2010 +0100

    s3:pdb_ldap: optimize ldapsam_alias_memberships() and cache ldap searches.
    
    ldapsam_alias_memberships() does the same LDAP search twice, triggered
    via add_aliases() from create_local_nt_token().
    
    This happens when no domain aliases are used.
    
    metze
    (cherry picked from commit 49ace81e19de231825216cbf07c7422687131bb6)
    (cherry picked from commit cb31c1df92b195b3fb80b6e21bfba83b8cd867fd)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit a2ff5f0dd08c40fdbea8cb11e1b18d996a4d8c39
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Feb 4 17:19:57 2010 +0100

    s3:pdb_ldap: try to build the full unix_pw structure with ldapsam:trusted 
support
    
    And also store the gid_to_sid mappings in the idmap_cache.
    
    metze
    (cherry picked from commit 25038fa85ff69962ca0975f31802218a897aa1ec)
    (cherry picked from commit 66a48d2226d245c373b744c7edea60b3daa57f0f)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 5d97d5703dcf62f2c610316b2ba47483652368b3
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Feb 4 17:16:59 2010 +0100

    s3:passdb: speed up pdb_get_group_sid()
    
    Use the cached version gid_to_sid() instead
    of pdb_gid_to_sid().
    
    And also avoid the expensive lookup_sid() call
    for wellkown domain groups.
    
    metze
    (cherry picked from commit e10d0869567436902c8b8cfb50f8c64148d554cb)
    (cherry picked from commit b0c8ff971934ef8aa21abece8693807e0a2ca722)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 66b472fdd6e55550abe4db04b0666d56ec700a0e
Author: Volker Lendecke <v...@samba.org>
Date:   Sun Jan 31 15:18:51 2010 +0100

    s3: Make pdb_copy_sam_account also copy the group sid
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    (cherry picked from commit b99046fed1bf4a908ed856afb17c3c934c6d305d)
    (cherry picked from commit a1862c23346959cd0aa77653bf488e0686d14376)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 479087716f50e8a1961163750b1d651dcd23dfc2
Author: Stefan Metzmacher <me...@samba.org>
Date:   Sat Jan 30 22:28:19 2010 +0100

    s3: shortcut gid_to_sid when "ldapsam:trusted = yes"
    
    The normal gid_to_sid behaviour is to call sys_getgrgid()
    to get the name for the given gid and then call the
    getsamgrnam passdb method for the resulting name.
    
    In the ldapsam:trusted case we can reduce the gid_to_sid
    operation to one simple search for the gidNumber attribute
    and only get the sambaSID attribute from the correspoinding
    LDAP object. This reduces the number of ldap roundtrips
    for this operation.
    
    metze
    (similar to commit 0fb99386d41241f62312d4bb535976344e5d6492)

commit c48405ed0ab0e3c3a0c1472e3bf874a4a64c0261
Author: Michael Adam <ob...@samba.org>
Date:   Sat Nov 14 01:21:42 2009 +0100

    s3:is_trusted_domain: shortcut if domain name == global_sam_name
    
    A domain can't have a trust with itself.
    This saves some roundtrips to the ldap server for ldapsam.
    
    Michael
    (cherry picked from commit dc3a90cf21813526854c12db126d08ebf32f8ae5)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 85d8565e8c5a290698d0f0599f851dc0bee50245
Author: Michael Adam <ob...@samba.org>
Date:   Sat Nov 14 01:12:22 2009 +0100

    s3:is_trusted_domain: shortcut if domain name is NULL or empty
    
    This saves some roundtrips to LDAP in an ldapsm setup.
    
    Michael
    (cherry picked from commit 0aa5a60d3033fddd652eb4ea89abdf97db912df3)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 91e40dfde99b08158b809590c44c22b503403157
Author: Michael Adam <ob...@samba.org>
Date:   Mon Nov 16 11:37:18 2009 +0100

    s3: shortcut uid_to_sid when "ldapsam:trusted = yes"
    
    The normal uid_to_sid behaviour is to call sys_getpwuid()
    to get the name for the given uid and then call the
    getsampwnam passdb method for the resulting name.
    
    In the ldapsam:trusted case we can reduce the uid_to_sid
    operation to one simple search for the uidNumber attribute
    and only get the sambaSID attribute from the correspoinding
    LDAP object. This reduces the number of ldap roundtrips
    for this operation.
    
    Michael
    (cherry picked from commit 37dcc8a400ea41fb0a0559c9922cc41ac28ad045)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 05f23a8dd6824bb6af3f60304096e621e534f4d4
Author: Michael Adam <ob...@samba.org>
Date:   Fri Nov 13 16:16:50 2009 +0100

    s3:smbd: also fill the memcache with sid<->id mappings in 
ldapsam_sid_to_id()
    
    not only the persistent idmap cache.
    
    Michael
    (cherry picked from commit ee2565bd461ccfb916c5290c883e5ced3af72141)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit c7220ff3a8281867ffc1a3bcaa992ca9eafba6ed
Author: Michael Adam <ob...@samba.org>
Date:   Fri Nov 13 15:51:33 2009 +0100

    s3:smbd: make idmap cache persistent for "ldapsam:trusted".
    
    This stores the mappings found in the idmap cache (which lives
    inside gencache). This cache is already read in sid_to_Xid()
    and Xid_to_sid() for ldapsam:trusted, this fills the opposite
    direction, massively reducing the number of ldap roundtrips
    across smbd restarts.
    
    Michael
    (cherry picked from commit d5537cbbf931f0bca519371bfd084fb0051acd57)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit cc529f47e10a87ef6688b14ec399edcd2e4e884d
Author: Volker Lendecke <v...@samba.org>
Date:   Mon May 18 16:04:04 2009 +0200

    Fix large paged search
    
    Signed-off-by: Michael Adam <ob...@samba.org>
    (cherry picked from commit afb06a8af3c4e86ef9960c8beb19a22f5fd0f3c2)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 4e66860d89872d2ba808761e0d58ed18e7ed428e
Author: Björn Jacke <b...@sernet.de>
Date:   Fri Oct 30 21:50:41 2009 +0100

    
=?utf-8?q?=D1=953:ldap:=20search=20for=20account=20policies=20in=20objectclass=20sambaDomain,=20not=20*
    
    
=20(cherry=20picked=20from=20commit=20e5f41591504769b5c7beb5a35bb0f95b33d27a8b)?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

commit 0b7d7e7c3d6a5abe94a0864f1ccaf9d1c00b8b7d
Author: Björn Jacke <b...@sernet.de>
Date:   Sat Oct 31 00:45:09 2009 +0100

    s3:ldap: don't search when no values where found (cherry picked from commit 
70063522065ab3e5a21fb11db0097b808aa11100)
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/auth/auth_util.c     |    8 +
 source3/include/smbldap.h    |    5 +
 source3/passdb/passdb.c      |    4 +
 source3/passdb/pdb_get_set.c |   45 +++++-
 source3/passdb/pdb_ldap.c    |  353 ++++++++++++++++++++++++++++++++++++------
 5 files changed, 366 insertions(+), 49 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index b743c12..89aa4a3 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -2176,6 +2176,14 @@ bool is_trusted_domain(const char* dom_name)
        if ( lp_server_role() == ROLE_STANDALONE )
                return False;
 
+       if (dom_name == NULL || dom_name[0] == '\0') {
+               return false;
+       }
+
+       if (strequal(dom_name, get_global_sam_name())) {
+               return false;
+       }
+
        /* if we are a DC, then check for a direct trust relationships */
 
        if ( IS_DC ) {
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h
index 726d5f7..7383670 100644
--- a/source3/include/smbldap.h
+++ b/source3/include/smbldap.h
@@ -196,6 +196,11 @@ struct ldapsam_privates {
 
        /* ldap server location parameter */
        char *location;
+
+       struct {
+               char *filter;
+               LDAPMessage *result;
+       } search_cache;
 };
 
 /* Functions shared between pdb_ldap.c and pdb_nds.c. */
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index aad16da..6ba67ef 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -2077,6 +2077,10 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu 
*src )
                }
        }
 
+       if (src->group_sid) {
+               pdb_set_group_sid(dst, src->group_sid, PDB_SET);
+       }
+
        free(buf);
        return True;
 }
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index c79caf2..1155050 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -183,6 +183,7 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
 {
        DOM_SID *gsid;
        struct passwd *pwd;
+       bool need_lookup_sid = false;
 
        /* Return the cached group SID if we have that */
        if ( sampass->group_sid ) {
@@ -191,7 +192,7 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
 
        /* generate the group SID from the user's primary Unix group */
 
-       if ( !(gsid  = TALLOC_P( sampass, DOM_SID )) ) {
+       if ( !(gsid  = TALLOC_ZERO_P( sampass, DOM_SID )) ) {
                return NULL;
        }
 
@@ -211,15 +212,49 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
                return NULL;
        }
 
-       if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
+       gid_to_sid(gsid, pwd->pw_gid);
+       if (!is_null_sid(gsid)) {
+               DOM_SID dgsid;
+               uint32_t rid;
+
+               sid_copy(&dgsid, gsid);
+               sid_split_rid(&dgsid, &rid);
+               if (sid_equal(&dgsid, get_global_sam_sid())) {
+                       /*
+                        * As shortcut for the expensive lookup_sid call
+                        * compare the domain sid part
+                        */
+                       switch (rid) {
+                       case DOMAIN_RID_ADMINS:
+                       case DOMAIN_RID_USERS:
+                               sampass->group_sid = gsid;
+                               return sampass->group_sid;
+                       default:
+                               need_lookup_sid = true;
+                               break;
+                       }
+               } else {
+                       ZERO_STRUCTP(gsid);
+                       if (pdb_gid_to_sid(pwd->pw_gid, gsid)) {
+                               need_lookup_sid = true;
+                       }
+               }
+       }
+
+       if (need_lookup_sid) {
                enum lsa_SidType type = SID_NAME_UNKNOWN;
-               TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
+               TALLOC_CTX *mem_ctx;
                bool lookup_ret;
+               const DOM_SID *usid = pdb_get_user_sid(sampass);
 
+               mem_ctx = talloc_init("pdb_get_group_sid");
                if (!mem_ctx) {
                        return NULL;
                }
 
+               DEBUG(10,("do lookup_sid(%s) for group of user %s\n",
+                         sid_string_dbg(gsid), sid_string_dbg(usid)));
+
                /* Now check that it's actually a domain group and not 
something else */
 
                lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
@@ -231,8 +266,8 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
                        return sampass->group_sid;
                }
 
-               DEBUG(3, ("Primary group for user %s is a %s and not a domain 
group\n", 
-                       pwd->pw_name, sid_type_lookup(type)));
+               DEBUG(3, ("Primary group %s for user %s is a %s and not a 
domain group\n",
+                       sid_string_dbg(gsid), pwd->pw_name, 
sid_type_lookup(type)));
        }
 
        /* Just set it to the 'Domain Users' RID of 512 which will 
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 0d498c8..f95f912 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -1028,6 +1028,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;
+               DOM_SID mapped_gsid;
+               const 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,
@@ -1035,8 +1046,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_sid2uid(primary_gsid,
+                                               sampass->unix_pw->pw_gid);
                }
        }
 
@@ -1487,6 +1558,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.
 *********************************************************************/
@@ -1505,7 +1586,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 );
@@ -1562,7 +1643,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);
@@ -2437,6 +2518,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);
@@ -2671,7 +2753,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) {
@@ -2833,46 +2915,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,
@@ -3709,8 +3795,11 @@ 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;
 
        if (sid_check_is_builtin(domain_sid)) {
+               is_builtin = true;
                type = SID_NAME_ALIAS;
        }
 
@@ -3740,11 +3829,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;
 
@@ -3768,14 +3866,24 @@ 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;
 }
 
@@ -3844,6 +3952,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 =
@@ -3867,8 +3976,12 @@ static NTSTATUS 
ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
        attrs[0] = policy_attr;
        attrs[1] = NULL;
 
+       filter = talloc_asprintf(NULL, "(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);
 
        if (rc != LDAP_SUCCESS) {
@@ -4306,6 +4419,7 @@ static bool ldapsam_search_firstpage(struct pdb_search 
*search)
        if (state->current_entry == NULL) {
                ldap_msgfree(state->entries);
                state->entries = NULL;
+               return false;
        }
 
        return True;
@@ -4936,6 +5050,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;
        }
@@ -4952,6 +5068,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:
@@ -4959,6 +5077,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,
+                              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;
+       DOM_SID *user_sid;
+       int rc;
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+       filter = talloc_asprintf(tmp_ctx,
+                                "(&(uidNumber=%u)"
+                                "(objectClass=%s)"


-- 
Samba Shared Repository

Reply via email to