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)
committerStefan Metzmacher <metze@samba.org>
Mon, 8 Feb 2010 10:10:19 +0000 (11:10 +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

source3/include/smbldap.h
source3/passdb/pdb_ldap.c

index e3b03d4948d1fbdff20fe8aeee7f6dc94a1a7b0c..ec0e9f5c186bd90864799e22372c64b2acb5f981 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 6585645c27e1e443c76b014dafbf6357f396b05c..26a67e14d22b0607be11524af5f106dba22e1497 100644 (file)
@@ -3803,11 +3803,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;
        }
 
@@ -3841,11 +3844,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;
 
@@ -3869,14 +3881,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;
 }