mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r24914: In response to bug #4892 by Matthias Wallnöfer <mwallnoefer@yahoo.de>,
allow the objectclass module to reconstruct the objectclass hierarchy, rather than using templates. The issue being fixed in particular is that 'top' was not being set on containers. This should ensure we do this right for all objects. Andrew Bartlett
This commit is contained in:
parent
4634bb282b
commit
d17a0058ba
@ -92,6 +92,7 @@ static struct ldb_handle *oc_init_handle(struct ldb_request *req, struct ldb_mod
|
||||
}
|
||||
|
||||
static int objectclass_sort(struct ldb_module *module,
|
||||
struct ldb_message *msg, /* so that when we create new elements, we put it on the right parent */
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ldb_message_element *objectclass_element,
|
||||
struct class_list **sorted_out)
|
||||
@ -100,7 +101,7 @@ static int objectclass_sort(struct ldb_module *module,
|
||||
int layer;
|
||||
const struct dsdb_schema *schema = dsdb_get_schema(module->ldb);
|
||||
struct class_list *sorted = NULL, *parent_class = NULL,
|
||||
*subclass = NULL, *unsorted = NULL, *current, *poss_subclass;
|
||||
*subclass = NULL, *unsorted = NULL, *current, *poss_subclass, *poss_parent, *new_parent;
|
||||
/* DESIGN:
|
||||
*
|
||||
* We work on 4 different 'bins' (implemented here as linked lists):
|
||||
@ -149,6 +150,34 @@ static int objectclass_sort(struct ldb_module *module,
|
||||
}
|
||||
}
|
||||
|
||||
if (parent_class == NULL) {
|
||||
current = talloc(mem_ctx, struct class_list);
|
||||
current->objectclass = talloc_strdup(msg, "top");
|
||||
DLIST_ADD_END(parent_class, current, struct class_list *);
|
||||
}
|
||||
|
||||
/* For each object: find parent chain */
|
||||
for (current = unsorted; schema && current; current = current->next) {
|
||||
const struct dsdb_class *class = dsdb_class_by_lDAPDisplayName(schema, current->objectclass);
|
||||
if (!class) {
|
||||
ldb_asprintf_errstring(module->ldb, "objectclass %s is not a valid objectClass in schema", current->objectclass);
|
||||
return LDB_ERR_OBJECT_CLASS_VIOLATION;
|
||||
}
|
||||
for (poss_parent = unsorted; poss_parent; poss_parent = poss_parent->next) {
|
||||
if (ldb_attr_cmp(poss_parent->objectclass, class->subClassOf) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If we didn't get to the end of the list, we need to add this parent */
|
||||
if (poss_parent || (ldb_attr_cmp("top", class->subClassOf) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_parent = talloc(mem_ctx, struct class_list);
|
||||
new_parent->objectclass = talloc_strdup(msg, class->subClassOf);
|
||||
DLIST_ADD_END(unsorted, new_parent, struct class_list *);
|
||||
}
|
||||
|
||||
/* DEBUGGING aid: how many layers are we down now? */
|
||||
layer = 0;
|
||||
do {
|
||||
@ -265,11 +294,6 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = objectclass_sort(module, mem_ctx, objectclass_element, &sorted);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* prepare the first operation */
|
||||
down_req = talloc(req, struct ldb_request);
|
||||
if (down_req == NULL) {
|
||||
@ -287,6 +311,12 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = objectclass_sort(module, msg, mem_ctx, objectclass_element, &sorted);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ldb_msg_remove_attr(msg, "objectClass");
|
||||
ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL);
|
||||
|
||||
@ -398,7 +428,7 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = objectclass_sort(module, mem_ctx, objectclass_element, &sorted);
|
||||
ret = objectclass_sort(module, msg, mem_ctx, objectclass_element, &sorted);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
@ -579,7 +609,7 @@ static int objectclass_do_mod(struct ldb_handle *h) {
|
||||
/* modify dn */
|
||||
msg->dn = ac->orig_req->op.mod.message->dn;
|
||||
|
||||
ret = objectclass_sort(ac->module, mem_ctx, objectclass_element, &sorted);
|
||||
ret = objectclass_sort(ac->module, msg, mem_ctx, objectclass_element, &sorted);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_
|
||||
}
|
||||
|
||||
ret = samdb_copy_template(module->ldb, msg2,
|
||||
"(&(CN=TemplateGroup)(objectclass=groupTemplate))",
|
||||
"group",
|
||||
&errstr);
|
||||
if (ret != 0) {
|
||||
|
||||
@ -476,7 +476,7 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
|
||||
if (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL) {
|
||||
|
||||
ret = samdb_copy_template(module->ldb, msg2,
|
||||
"(&(CN=TemplateComputer)(objectclass=userTemplate))",
|
||||
"computer",
|
||||
&errstr);
|
||||
if (ret) {
|
||||
ldb_asprintf_errstring(module->ldb,
|
||||
@ -486,22 +486,9 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* readd user and then computer objectclasses */
|
||||
ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "user");
|
||||
if (ret) {
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "computer");
|
||||
if (ret) {
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = samdb_copy_template(module->ldb, msg2,
|
||||
"(&(CN=TemplateUser)(objectclass=userTemplate))",
|
||||
"user",
|
||||
&errstr);
|
||||
if (ret) {
|
||||
ldb_asprintf_errstring(module->ldb,
|
||||
@ -582,7 +569,7 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module
|
||||
}
|
||||
|
||||
ret = samdb_copy_template(module->ldb, msg2,
|
||||
"(&(CN=TemplateForeignSecurityPrincipal)(objectclass=foreignSecurityPrincipalTemplate))",
|
||||
"ForeignSecurityPrincipal",
|
||||
&errstr);
|
||||
if (ret != 0) {
|
||||
ldb_asprintf_errstring(module->ldb,
|
||||
|
@ -680,7 +680,7 @@ int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg
|
||||
copy from a template record to a message
|
||||
*/
|
||||
int samdb_copy_template(struct ldb_context *ldb,
|
||||
struct ldb_message *msg, const char *filter,
|
||||
struct ldb_message *msg, const char *name,
|
||||
const char **errstring)
|
||||
{
|
||||
struct ldb_result *res;
|
||||
@ -690,15 +690,20 @@ int samdb_copy_template(struct ldb_context *ldb,
|
||||
|
||||
*errstring = NULL;
|
||||
|
||||
if (!ldb_dn_add_child_fmt(basedn, "CN=Template%s", name)) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
/* pull the template record */
|
||||
ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, filter, NULL, &res);
|
||||
ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, "cn=*", NULL, &res);
|
||||
talloc_free(basedn);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
*errstring = talloc_steal(msg, ldb_errstring(ldb));
|
||||
return ret;
|
||||
}
|
||||
if (res->count != 1) {
|
||||
*errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: template '%s' matched %d records, expected 1\n", filter,
|
||||
*errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: template '%s' matched %d records, expected 1\n",
|
||||
name,
|
||||
res->count);
|
||||
talloc_free(res);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
@ -708,40 +713,22 @@ int samdb_copy_template(struct ldb_context *ldb,
|
||||
for (i = 0; i < t->num_elements; i++) {
|
||||
struct ldb_message_element *el = &t->elements[i];
|
||||
/* some elements should not be copied from the template */
|
||||
if (strcasecmp(el->name, "cn") == 0 ||
|
||||
strcasecmp(el->name, "name") == 0 ||
|
||||
strcasecmp(el->name, "sAMAccountName") == 0 ||
|
||||
strcasecmp(el->name, "sAMAccountName") == 0 ||
|
||||
strcasecmp(el->name, "distinguishedName") == 0 ||
|
||||
strcasecmp(el->name, "objectGUID") == 0) {
|
||||
if (ldb_attr_cmp(el->name, "cn") == 0 ||
|
||||
ldb_attr_cmp(el->name, "name") == 0 ||
|
||||
ldb_attr_cmp(el->name, "objectClass") == 0 ||
|
||||
ldb_attr_cmp(el->name, "sAMAccountName") == 0 ||
|
||||
ldb_attr_cmp(el->name, "sAMAccountName") == 0 ||
|
||||
ldb_attr_cmp(el->name, "distinguishedName") == 0 ||
|
||||
ldb_attr_cmp(el->name, "objectGUID") == 0) {
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < el->num_values; j++) {
|
||||
if (strcasecmp(el->name, "objectClass") == 0) {
|
||||
if (strcasecmp((char *)el->values[j].data, "Template") == 0 ||
|
||||
strcasecmp((char *)el->values[j].data, "userTemplate") == 0 ||
|
||||
strcasecmp((char *)el->values[j].data, "groupTemplate") == 0 ||
|
||||
strcasecmp((char *)el->values[j].data, "foreignSecurityPrincipalTemplate") == 0 ||
|
||||
strcasecmp((char *)el->values[j].data, "aliasTemplate") == 0 ||
|
||||
strcasecmp((char *)el->values[j].data, "trustedDomainTemplate") == 0 ||
|
||||
strcasecmp((char *)el->values[j].data, "secretTemplate") == 0) {
|
||||
continue;
|
||||
}
|
||||
ret = samdb_find_or_add_value(ldb, msg, el->name,
|
||||
(char *)el->values[j].data);
|
||||
if (ret) {
|
||||
*errstring = talloc_asprintf(msg, "Adding objectClass %s failed.\n", el->values[j].data);
|
||||
talloc_free(res);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = samdb_find_or_add_attribute(ldb, msg, el->name,
|
||||
(char *)el->values[j].data);
|
||||
if (ret) {
|
||||
*errstring = talloc_asprintf(msg, "Adding attribute %s failed.\n", el->name);
|
||||
talloc_free(res);
|
||||
return ret;
|
||||
}
|
||||
ret = samdb_find_or_add_attribute(ldb, msg, el->name,
|
||||
(char *)el->values[j].data);
|
||||
if (ret) {
|
||||
*errstring = talloc_asprintf(msg, "Adding attribute %s failed.\n", el->name);
|
||||
talloc_free(res);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,6 @@ isCriticalSystemObject: TRUE
|
||||
###
|
||||
|
||||
dn: CN=TemplateUser,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: Template
|
||||
objectClass: userTemplate
|
||||
userAccountControl: 514
|
||||
badPwdCount: 0
|
||||
codePage: 0
|
||||
@ -31,11 +26,6 @@ logonCount: 0
|
||||
sAMAccountType: 805306368
|
||||
|
||||
dn: CN=TemplateComputer,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: Template
|
||||
objectClass: userTemplate
|
||||
userAccountControl: 4098
|
||||
badPwdCount: 0
|
||||
codePage: 0
|
||||
@ -50,9 +40,6 @@ logonCount: 0
|
||||
sAMAccountType: 805306369
|
||||
|
||||
dn: CN=TemplateTrustingDomain,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: Template
|
||||
objectClass: userTemplate
|
||||
userAccountControl: 2080
|
||||
badPwdCount: 0
|
||||
codePage: 0
|
||||
@ -66,38 +53,21 @@ logonCount: 0
|
||||
sAMAccountType: 805306370
|
||||
|
||||
dn: CN=TemplateGroup,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: Template
|
||||
objectClass: groupTemplate
|
||||
groupType: -2147483646
|
||||
sAMAccountType: 268435456
|
||||
|
||||
# Currently this isn't used, we don't have a way to detect it different from an incoming alias
|
||||
#
|
||||
# dn: CN=TemplateAlias,CN=Templates
|
||||
# objectClass: top
|
||||
# objectClass: Template
|
||||
# objectClass: aliasTemplate
|
||||
# cn: TemplateAlias
|
||||
# instanceType: 4
|
||||
# groupType: -2147483644
|
||||
# sAMAccountType: 268435456
|
||||
|
||||
dn: CN=TemplateForeignSecurityPrincipal,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: Template
|
||||
objectClass: foreignSecurityPrincipalTemplate
|
||||
showInAdvancedViewOnly: TRUE
|
||||
|
||||
dn: CN=TemplateSecret,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: leaf
|
||||
objectClass: Template
|
||||
objectClass: secretTemplate
|
||||
|
||||
dn: CN=TemplateTrustedDomain,CN=Templates
|
||||
objectClass: top
|
||||
objectClass: leaf
|
||||
objectClass: Template
|
||||
objectClass: trustedDomainTemplate
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user