The branch, master has been updated via 9b0780c... s4:dsdb Use ldb_match_msg_objectclass in operational.c via 54ea4b1... s4:ldb Add a function to match a message against an objectClass via b2db28b... s4:ldap.py Improve testsuite for primaryGroupToken behaviour via 354b80b3.. s4:dsdb Make primaryGroupToken calculation more efficient and correct via 45cd4c9... s4:dsdb Make parentGUID handler use dsdb_module_search_dn() via a4725f5... s4:build torturedir and -DTORTUREDIR is unused via 972ee4b... s4:dsdb Hide the LM password by default too from 7050764... streamline some log levels for invalid servicenames
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 9b0780cf00e966a8df3dce698f37b6acaa28050d Author: Andrew Bartlett <abart...@samba.org> Date: Mon Dec 7 15:28:51 2009 +1100 s4:dsdb Use ldb_match_msg_objectclass in operational.c This avoids not only a possibly non-portable compiler expression, but also the need to look up the schema each time. Andrew Bartlett commit 54ea4b17f06a6f2fb343111be22f28191d21fdf1 Author: Andrew Bartlett <abart...@samba.org> Date: Mon Dec 7 15:27:43 2009 +1100 s4:ldb Add a function to match a message against an objectClass (as objectClass will always be a case insensitive ascii string, we can make a much simpler match function here than for the general case). Andrew Bartlett commit b2db28b634bceccb4c87e3f764649a5ed1f3217a Author: Andrew Bartlett <abart...@samba.org> Date: Mon Dec 7 12:44:07 2009 +1100 s4:ldap.py Improve testsuite for primaryGroupToken behaviour This tries to show that the domain object should not have a primaryGroupToken, for example. (This passes against the old and new code, as the failure case requires an object with an objectSid, and exactly one group in it's subtree. Sadly I don't know of a valid structure that I can construct to test this). Andrew Bartlett commit 354b80b3ae3fd918d65f6425d054630d51ee18e0 Author: Andrew Bartlett <abart...@samba.org> Date: Mon Dec 7 12:41:43 2009 +1100 s4:dsdb Make primaryGroupToken calculation more efficient and correct The original code here would do a subtree search under each object, attempting to determine if it was a group. This was incorrect, and inefficient - we just need to ask for the objectClass attribute, and check that value before returning the group's RID. (Much of this patch reworks operational.c to allow a search for 2 attributes for this calculation). Andrew Bartlett commit 45cd4c93fbcabe8e5c66f57f8ded08a860af1bce Author: Andrew Bartlett <abart...@samba.org> Date: Fri Dec 4 10:15:15 2009 +1100 s4:dsdb Make parentGUID handler use dsdb_module_search_dn() This avoids doing a new search from the top of the module stack. This also removes the helper function dsdb_find_parentguid_by_dn() which is now unused. Andrew Bartlett commit a4725f5880a3cebca83f0e0091403a4b80100e38 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Dec 4 07:29:29 2009 +1100 s4:build torturedir and -DTORTUREDIR is unused (And made building RPMs much more difficult for JHT) commit 972ee4b97b4e5d691dfe209366b639932bf02d43 Author: Andrew Bartlett <abart...@samba.org> Date: Wed Dec 2 08:53:32 2009 +1100 s4:dsdb Hide the LM password by default too ----------------------------------------------------------------------- Summary of changes: source4/Makefile | 3 - source4/dsdb/common/util.c | 58 ------------- source4/dsdb/samdb/ldb_modules/operational.c | 111 +++++++++++++++++--------- source4/dynconfig/config.mk | 1 - source4/lib/ldb/common/ldb_match.c | 19 +++++ source4/lib/ldb/include/ldb_module.h | 3 + source4/lib/ldb/tests/python/ldap.py | 22 +++++ 7 files changed, 116 insertions(+), 101 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/Makefile b/source4/Makefile index 8e4895b..6a99ea3 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -11,7 +11,6 @@ include mkconfig.mk pidldir := $(srcdir)/../pidl basedir = $(prefix) -torturedir = ../lib/torture swatdir = $(datadir)/swat setupdir = $(datadir)/setup ncalrpcdir = $(localstatedir)/ncalrpc @@ -182,7 +181,6 @@ showlayout:: @echo ' setupdir: $(setupdir)' @echo ' swatdir: $(swatdir)' @echo ' mandir: $(mandir)' - @echo ' torturedir: $(torturedir)' @echo ' datadir: $(datadir)' @echo ' winbindd_socket_dir: $(winbindd_socket_dir)' @echo ' ntp_signd_socket_dir: $(ntp_signd_socket_dir)' @@ -210,7 +208,6 @@ installdirs:: $(DESTDIR)$(basedir) \ $(DESTDIR)$(bindir) \ $(DESTDIR)$(sbindir) \ - $(DESTDIR)$(torturedir) \ $(DESTDIR)$(libdir) \ $(DESTDIR)$(modulesdir) \ $(DESTDIR)$(modulesdir)/ldb \ diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 8c9c982..d9e03ce 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -2286,64 +2286,6 @@ int dsdb_find_guid_by_dn(struct ldb_context *ldb, } -/* - Use a DN to find it's parentGUID - - Results - LDB_ERR_OPERATIONS_ERROR for out of memory - LDB_ERR_NO_SUCH_OBJECT if there is no parent object for the given DN - LDB_ERR_NO_SUCH_ATTRIBUTE if couldn't get the ObjectGUID from the parent - LDB_SUCCESS if it could find the parentGUID correctly - */ -int dsdb_find_parentguid_by_dn(struct ldb_context *ldb, - struct ldb_dn *dn, - struct GUID *parent_guid) -{ - - int ret; - struct ldb_result *res; - struct ldb_dn *parent_dn; - const char *attrs[] = { "objectGUID", NULL }; - TALLOC_CTX *tmp_ctx = talloc_new(ldb); - - - parent_dn = ldb_dn_get_parent(tmp_ctx, dn); - - if (parent_dn == NULL){ - DEBUG(4,(__location__ ": Failed to find parent for dn %s\n", - ldb_dn_get_linearized(dn))); - ret = LDB_ERR_NO_SUCH_OBJECT; - goto done; - } - - /* - The few lines of code bellow are very similar to the - dsdb_find_guid_by_dn() function implementation, but this way we can - differ situations when the parent_dn doesn't exist from when there is - an error on returning it's GUID. - */ - ret = dsdb_search_dn_with_deleted(ldb, tmp_ctx, &res, parent_dn, attrs); - if (ret != LDB_SUCCESS) { - DEBUG(4,(__location__ ": Parent dn for %s does not exist \n", - ldb_dn_get_linearized(dn))); - /* When there is no parent dn, it simply doesn't return a parentGUID */ - ret = LDB_ERR_NO_SUCH_OBJECT; - goto done; - } - if (res->count < 1) { - DEBUG(4,(__location__ ": Failed to find GUID for dn %s\n", - ldb_dn_get_linearized(parent_dn))); - ret = LDB_ERR_NO_SUCH_ATTRIBUTE; - goto done; - } - - *parent_guid = samdb_result_guid(res->msgs[0], "objectGUID"); - ret = LDB_SUCCESS; - -done: - talloc_free(tmp_ctx); - return ret; -} /* adds the given GUID to the given ldb_message. This value is added diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c index cc29476..badc0c5 100644 --- a/source4/dsdb/samdb/ldb_modules/operational.c +++ b/source4/dsdb/samdb/ldb_modules/operational.c @@ -70,6 +70,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "param/param.h" #include "dsdb/samdb/samdb.h" +#include "dsdb/samdb/ldb_modules/util.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) @@ -97,19 +98,19 @@ static int construct_canonical_name(struct ldb_module *module, construct a primary group token for groups from a message */ static int construct_primary_group_token(struct ldb_module *module, - struct ldb_message *msg) + struct ldb_message *msg) { struct ldb_context *ldb; uint32_t primary_group_token; - + ldb = ldb_module_get_ctx(module); - - /* this is horrendously inefficient! we're doing a subtree - * search for every DN we return. So that's N^2 in the - * total number of objects! */ - if (samdb_search_count(ldb, msg->dn, "(objectclass=group)") == 1) { + if (ldb_match_msg_objectclass(msg, "group") == 1) { primary_group_token = samdb_result_rid_from_sid(ldb, msg, "objectSid", 0); + if (primary_group_token == 0) { + return LDB_SUCCESS; + } + return samdb_msg_add_int(ldb, ldb, msg, "primaryGroupToken", primary_group_token); } else { @@ -118,32 +119,42 @@ static int construct_primary_group_token(struct ldb_module *module, } static int construct_parent_guid(struct ldb_module *module, - struct ldb_message *msg) + struct ldb_message *msg) { - struct ldb_context *ldb; - struct GUID parent_guid; + struct ldb_result *res; + const struct ldb_val *parent_guid; + const char *attrs[] = { "objectGUID", NULL }; int ret; - ldb = ldb_module_get_ctx(module); - - ret = dsdb_find_parentguid_by_dn(ldb, msg->dn, &parent_guid); - - - if (ret != LDB_SUCCESS){ - - /* if there is no parentGUID for this object, then return */ - if (ret == LDB_ERR_NO_SUCH_OBJECT){ - return LDB_SUCCESS; - }else{ - return ret; - } + /* TODO: In the future, this needs to honour the partition boundaries */ + struct ldb_dn *parent_dn = ldb_dn_get_parent(msg, msg->dn); + if (parent_dn == NULL){ + DEBUG(4,(__location__ ": Failed to find parent for dn %s\n", + ldb_dn_get_linearized(msg->dn))); + return LDB_SUCCESS; } - ret = dsdb_msg_add_guid(msg, &parent_guid, "parentGUID"); + ret = dsdb_module_search_dn(module, msg, &res, parent_dn, attrs, DSDB_SEARCH_SHOW_DELETED); + talloc_free(parent_dn); + /* if there is no parentGUID for this object, then return */ + if (ret == LDB_ERR_NO_SUCH_OBJECT){ + DEBUG(4,(__location__ ": Parent dn for %s does not exist \n", + ldb_dn_get_linearized(msg->dn))); + return LDB_SUCCESS; + } else if (ret != LDB_SUCCESS) { + return ret; + } - return ret; + parent_guid = ldb_msg_find_ldb_val(res->msgs[0], "objectGUID"); + if (!parent_guid) { + talloc_free(res); + return LDB_SUCCESS; + } + talloc_steal(msg->elements, parent_guid->data); + talloc_free(res); + return ldb_msg_add_value(msg, "parentGUID", parent_guid, 0); } /* @@ -182,15 +193,16 @@ static const struct { static const struct { const char *attr; const char *replace; + const char *extra_attr; int (*constructor)(struct ldb_module *, struct ldb_message *); } search_sub[] = { - { "createTimestamp", "whenCreated", NULL }, - { "modifyTimestamp", "whenChanged", NULL }, - { "structuralObjectClass", "objectClass", NULL }, - { "canonicalName", "distinguishedName", construct_canonical_name }, - { "primaryGroupToken", "objectSid", construct_primary_group_token }, - { "parentGUID", NULL, construct_parent_guid }, - { "subSchemaSubEntry", NULL, construct_subschema_subentry } + { "createTimestamp", "whenCreated", NULL , NULL }, + { "modifyTimestamp", "whenChanged", NULL , NULL }, + { "structuralObjectClass", "objectClass", NULL , NULL }, + { "canonicalName", "distinguishedName", NULL , construct_canonical_name }, + { "primaryGroupToken", "objectClass", "objectSid", construct_primary_group_token }, + { "parentGUID", NULL, NULL, construct_parent_guid }, + { "subSchemaSubEntry", NULL, NULL, construct_subschema_subentry } }; @@ -213,7 +225,8 @@ static const struct { { "ntPwdHistory", OPERATIONAL_REMOVE_UNASKED }, { "lmPwdHistory", OPERATIONAL_REMOVE_UNASKED }, { "unicodePwd", OPERATIONAL_REMOVE_UNASKED }, - { "supplementalCredentials", OPERATIONAL_REMOVE_UNASKED } + { "supplementalCredentials", OPERATIONAL_REMOVE_UNASKED }, + { "dBCSPwd", OPERATIONAL_REMOVE_UNASKED } }; @@ -270,13 +283,16 @@ static int operational_search_post_process(struct ldb_module *module, /* remove the added search attribute, unless it was asked for by the user */ - if (search_sub[i].replace == NULL || - ldb_attr_in_list(attrs, search_sub[i].replace) || - ldb_attr_in_list(attrs, "*")) { - continue; + if (search_sub[i].replace != NULL && + !ldb_attr_in_list(attrs, search_sub[i].replace) && + !ldb_attr_in_list(attrs, "*")) { + ldb_msg_remove_attr(msg, search_sub[i].replace); + } + if (search_sub[i].extra_attr != NULL && + !ldb_attr_in_list(attrs, search_sub[i].extra_attr) && + !ldb_attr_in_list(attrs, "*")) { + ldb_msg_remove_attr(msg, search_sub[i].extra_attr); } - - ldb_msg_remove_attr(msg, search_sub[i].replace); } } @@ -382,12 +398,29 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req for (i=0;i<ARRAY_SIZE(search_sub);i++) { if (ldb_attr_cmp(ac->attrs[a], search_sub[i].attr) == 0 && search_sub[i].replace) { + + if (search_sub[i].extra_attr) { + const char **search_attrs2; + /* Only adds to the end of the list */ + search_attrs2 = ldb_attr_list_copy_add(req, search_attrs + ? search_attrs + : ac->attrs, + search_sub[i].extra_attr); + if (search_attrs2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* may be NULL, talloc_free() doesn't mind */ + talloc_free(search_attrs); + search_attrs = search_attrs2; + } + if (!search_attrs) { search_attrs = ldb_attr_list_copy(req, ac->attrs); if (search_attrs == NULL) { return LDB_ERR_OPERATIONS_ERROR; } } + /* Despite the ldb_attr_list_copy_add, this is safe as that fn only adds to the end */ search_attrs[a] = search_sub[i].replace; } } diff --git a/source4/dynconfig/config.mk b/source4/dynconfig/config.mk index f79cdb8..d800004 100644 --- a/source4/dynconfig/config.mk +++ b/source4/dynconfig/config.mk @@ -17,7 +17,6 @@ $(dynconfigsrcdir)/dynconfig.o: CFLAGS+=-DCONFIGFILE=\"$(CONFIG4FILE)\" -DBINDIR -DSWATDIR=\"$(swatdir)\" \ -DPRIVATE_DIR=\"$(privatedir)\" \ -DMODULESDIR=\"$(modulesdir)\" \ - -DTORTUREDIR=\"$(torturedir)\" \ -DSETUPDIR=\"$(setupdir)\" \ -DWINBINDD_PRIVILEGED_SOCKET_DIR=\"$(winbindd_privileged_socket_dir)\" \ -DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\" \ diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c index e6ee0de..f639eff 100644 --- a/source4/lib/ldb/common/ldb_match.c +++ b/source4/lib/ldb/common/ldb_match.c @@ -426,3 +426,22 @@ int ldb_match_msg(struct ldb_context *ldb, return ldb_match_message(ldb, msg, tree, scope); } + +int ldb_match_msg_objectclass(const struct ldb_message *msg, + const char *objectclass) +{ + int i; + struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); + if (!el) { + return 0; + } + for (i=0; i < el->num_values; i++) { + if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { + return 1; + } + } + return 0; +} + + + diff --git a/source4/lib/ldb/include/ldb_module.h b/source4/lib/ldb/include/ldb_module.h index 7c18683..0b0f863 100644 --- a/source4/lib/ldb/include/ldb_module.h +++ b/source4/lib/ldb/include/ldb_module.h @@ -126,6 +126,9 @@ int ldb_match_msg(struct ldb_context *ldb, struct ldb_dn *base, enum ldb_scope scope); +int ldb_match_msg_objectclass(const struct ldb_message *msg, + const char *objectclass); + /* The following definitions come from lib/ldb/common/ldb_modules.c */ struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py index 384e69e..d0a0ed2 100755 --- a/source4/lib/ldb/tests/python/ldap.py +++ b/source4/lib/ldb/tests/python/ldap.py @@ -806,6 +806,28 @@ objectClass: container "dn": "cn=ldaptestgroup,cn=users," + self.base_dn, "objectclass": "group"}) + # Testing for one invalid, and one valid operational attribute, but also the things they are built from + res1 = ldb.search(self.base_dn, + scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"]) + self.assertTrue(len(res1) == 1) + self.assertFalse("primaryGroupToken" in res1[0]) + self.assertTrue("canonicalName" in res1[0]) + self.assertTrue("objectClass" in res1[0]) + self.assertTrue("objectSid" in res1[0]) + + res1 = ldb.search(self.base_dn, + scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"]) + self.assertTrue(len(res1) == 1) + self.assertFalse("primaryGroupToken" in res1[0]) + self.assertFalse("objectSid" in res1[0]) + self.assertFalse("objectClass" in res1[0]) + self.assertTrue("canonicalName" in res1[0]) + + res1 = ldb.search("cn=users,"+self.base_dn, + scope=SCOPE_BASE, attrs=["primaryGroupToken"]) + self.assertTrue(len(res1) == 1) + self.assertFalse("primaryGroupToken" in res1[0]) + res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn, scope=SCOPE_BASE, attrs=["primaryGroupToken"]) self.assertTrue(len(res1) == 1) -- Samba Shared Repository