s3:pdb_ldap: optimize ldapsam_alias_memberships() and cache ldap searches.
authorStefan Metzmacher <metze@samba.org>
Wed, 3 Feb 2010 10:32:41 +0000 (11:32 +0100)
committerKarolin Seeger <kseeger@samba.org>
Thu, 11 Feb 2010 11:02:47 +0000 (12:02 +0100)
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 <metze@samba.org>
source3/include/smbldap.h
source3/passdb/pdb_ldap.c

index 726d5f7ce418832889c2d75a47f71ab7fc7bc7bc..7383670a0a49d44fbdb482379481caa1d764ee47 100644 (file)
@@ -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. */
index 5423e322164eb5e7a76c416e184b7978d30d16eb..e1ae8a3f9138ec6143e3df65203e2fdabe992fa3 100644 (file)
@@ -3791,8 +3791,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;
        }
 
@@ -3822,11 +3825,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;
 
@@ -3850,14 +3862,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;
 }