The Samba-Bugzilla – Attachment 5296 Details for
Bug 7116
pdb_ldap performance fixes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Backport from master to v3-5-test
tmp.diff (text/plain), 17.56 KB, created by
Stefan Metzmacher
on 2010-02-08 06:38:47 UTC
(
hide
)
Description:
Backport from master to v3-5-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2010-02-08 06:38:47 UTC
Size:
17.56 KB
patch
obsolete
>From 422fcf193977849dced1f600fea444605092675f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 30 Jan 2010 22:28:19 +0100 >Subject: [PATCH 1/6] 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 >(cherry picked from commit 779821df8ecfe3ed2392582b500d26332f0b80fc) >--- > source3/passdb/pdb_ldap.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 71 insertions(+), 0 deletions(-) > >diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c >index a8d220d..2259905 100644 >--- a/source3/passdb/pdb_ldap.c >+++ b/source3/passdb/pdb_ldap.c >@@ -5070,6 +5070,76 @@ static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid, > 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, >+ 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; >+ 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 are called only if >@@ -6420,6 +6490,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location) > (*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; >-- >1.6.3.3 > > >From 3d79d2cae2086f2c4f048a64e9d24c56542d4195 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 31 Jan 2010 15:18:51 +0100 >Subject: [PATCH 2/6] s3: Make pdb_copy_sam_account also copy the group sid > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit b99046fed1bf4a908ed856afb17c3c934c6d305d) >--- > source3/passdb/passdb.c | 4 ++++ > 1 files changed, 4 insertions(+), 0 deletions(-) > >diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c >index b2c3b94..0255edc 100644 >--- a/source3/passdb/passdb.c >+++ b/source3/passdb/passdb.c >@@ -2080,6 +2080,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; > } >-- >1.6.3.3 > > >From 6410ded8bc82f43c9a5bf9d32ad98c7a37824498 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 4 Feb 2010 17:16:59 +0100 >Subject: [PATCH 3/6] 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) >--- > source3/passdb/pdb_get_set.c | 33 ++++++++++++++++++++++++++++----- > 1 files changed, 28 insertions(+), 5 deletions(-) > >diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c >index 74ed018..5c1139b 100644 >--- a/source3/passdb/pdb_get_set.c >+++ b/source3/passdb/pdb_get_set.c >@@ -192,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; > } > >@@ -212,15 +212,38 @@ 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)) { > 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); >+ 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; >+ } >+ } > >+ 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); >@@ -232,8 +255,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 >-- >1.6.3.3 > > >From c9791ec1e8c6901ef76829d776837dc1634d9f85 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 4 Feb 2010 17:19:57 +0100 >Subject: [PATCH 4/6] 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) >--- > source3/passdb/pdb_ldap.c | 90 ++++++++++++++++++++++++++++++++++++++++++-- > 1 files changed, 85 insertions(+), 5 deletions(-) > >diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c >index 2259905..e489a2a 100644 >--- a/source3/passdb/pdb_ldap.c >+++ b/source3/passdb/pdb_ldap.c >@@ -1029,6 +1029,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, >@@ -1036,9 +1047,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); >- idmap_cache_set_sid2uid(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); > } > } > >@@ -1489,6 +1559,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. > *********************************************************************/ >@@ -1507,7 +1587,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 ); >@@ -1564,7 +1644,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); >-- >1.6.3.3 > > >From 2a3221159010539fa7155eda47e9f0cd4b1c6a1b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 3 Feb 2010 11:32:41 +0100 >Subject: [PATCH 5/6] 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) >--- > source3/include/smbldap.h | 5 +++++ > source3/passdb/pdb_ldap.c | 36 +++++++++++++++++++++++++++++------- > 2 files changed, 34 insertions(+), 7 deletions(-) > >diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h >index e3b03d4..ec0e9f5 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/pdb_ldap.c b/source3/passdb/pdb_ldap.c >index e489a2a..fb4d374 100644 >--- a/source3/passdb/pdb_ldap.c >+++ b/source3/passdb/pdb_ldap.c >@@ -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; > } > >-- >1.6.3.3 > > >From abbf26b7c982bdab9ccd41bfb9f282e8b0f0d7e4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 5 Feb 2010 16:20:21 +0100 >Subject: [PATCH 6/6] s3:pdb_ldap: don't search for the users primary group, if we already know it > >metze >(cherry picked from commit 6753fb1cf6a834b12b2a9dce3b1a9555390c17be) >--- > source3/passdb/pdb_ldap.c | 66 ++++++++++++++++++++++++--------------------- > 1 files changed, 35 insertions(+), 31 deletions(-) > >diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c >index fb4d374..ad60228 100644 >--- a/source3/passdb/pdb_ldap.c >+++ b/source3/passdb/pdb_ldap.c >@@ -2926,46 +2926,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, >-- >1.6.3.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
gd
:
review+
Actions:
View
Attachments on
bug 7116
: 5296 |
5301
|
5318
|
5319