diff options
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 173 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb.c | 182 |
2 files changed, 179 insertions, 176 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 2f0c6f2d17..c95fb70820 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -45,45 +45,6 @@ int samldb_notice_sid(struct ldb_module *module, TALLOC_CTX *mem_ctx, const struct dom_sid *sid); -/* if value is not null also check for attribute to have exactly that value */ -static struct ldb_message_element *samldb_find_attribute(const struct ldb_message *msg, const char *name, const char *value) -{ - int j; - struct ldb_message_element *el = ldb_msg_find_element(msg, name); - if (!el) { - return NULL; - } - - if (!value) { - return el; - } - - for (j = 0; j < el->num_values; j++) { - if (strcasecmp(value, - (char *)el->values[j].data) == 0) { - return el; - } - } - - return NULL; -} - -static BOOL samldb_msg_add_string(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value) -{ - char *aval = talloc_strdup(msg, value); - - if (aval == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_msg_add_string: talloc_strdup failed!\n"); - return False; - } - - if (ldb_msg_add_string(msg, name, aval) != 0) { - return False; - } - - return True; -} - static BOOL samldb_msg_add_sid(struct ldb_module *module, struct ldb_message *msg, const char *name, const struct dom_sid *sid) { struct ldb_val v; @@ -96,34 +57,6 @@ static BOOL samldb_msg_add_sid(struct ldb_module *module, struct ldb_message *ms return (ldb_msg_add_value(msg, name, &v) == 0); } -static BOOL samldb_find_or_add_value(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value) -{ - if (msg == NULL || name == NULL || value == NULL || set_value == NULL) { - return False; - } - - if (samldb_find_attribute(msg, name, value) == NULL) { - return samldb_msg_add_string(module, msg, name, set_value); - } - return True; -} - -static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *set_value) -{ - struct ldb_message_element *el; - - if (msg == NULL || name == NULL || set_value == NULL) { - return False; - } - - el = ldb_msg_find_element(msg, name); - if (el) { - return True; - } - - return samldb_msg_add_string(module, msg, name, set_value); -} - /* allocate a new id, attempting to do it atomically return 0 on failure, the id on success @@ -484,69 +417,6 @@ static char *samldb_generate_samAccountName(struct ldb_module *module, TALLOC_CT } while (1); } -static int samldb_copy_template(struct ldb_module *module, struct ldb_message *msg, const char *filter) -{ - struct ldb_result *res; - struct ldb_message *t; - int ret, i, j; - - struct ldb_dn *basedn = ldb_dn_explode(msg, "cn=Templates"); - - /* pull the template record */ - ret = ldb_search(module->ldb, basedn, LDB_SCOPE_SUBTREE, filter, NULL, &res); - if (ret != LDB_SUCCESS) { - return ret; - } - if (res->count != 1) { - ldb_set_errstring(module->ldb, talloc_asprintf(module, "samldb_copy_template: ERROR: template '%s' matched %d records, expected 1\n", filter, - res->count)); - return LDB_ERR_OPERATIONS_ERROR; - } - t = res->msgs[0]; - - 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, "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; - } - if ( ! samldb_find_or_add_value(module, msg, el->name, - (char *)el->values[j].data, - (char *)el->values[j].data)) { - ldb_set_errstring(module->ldb, talloc_asprintf(module, "Adding objectClass %s failed.\n", el->values[j].data)); - talloc_free(res); - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - if ( ! samldb_find_or_add_attribute(module, msg, el->name, - (char *)el->values[j].data)) { - ldb_set_errstring(module->ldb, talloc_asprintf(module, "Adding attribute %s failed.\n", el->name)); - talloc_free(res); - return LDB_ERR_OPERATIONS_ERROR; - } - } - } - } - - talloc_free(res); - - return LDB_SUCCESS; -} - static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_message *msg, struct ldb_message **ret_msg) { @@ -567,7 +437,7 @@ static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_ return LDB_ERR_OPERATIONS_ERROR; } - ret = samldb_copy_template(module, msg2, "(&(CN=TemplateGroup)(objectclass=groupTemplate))"); + ret = samdb_copy_template(module->ldb, msg2, "(&(CN=TemplateGroup)(objectclass=groupTemplate))"); if (ret != 0) { talloc_free(mem_ctx); return ret; @@ -588,9 +458,10 @@ static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_ talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } - if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", name)) { + ret = samdb_find_or_add_attribute(module->ldb, msg2, "sAMAccountName", name); + if (ret) { talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } } @@ -625,9 +496,9 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const return LDB_ERR_OPERATIONS_ERROR; } - if (samldb_find_attribute(msg, "objectclass", "computer") != NULL) { + if (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL) { - ret = samldb_copy_template(module, msg2, "(&(CN=TemplateComputer)(objectclass=userTemplate))"); + ret = samdb_copy_template(module->ldb, msg2, "(&(CN=TemplateComputer)(objectclass=userTemplate))"); if (ret) { ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_user_or_computer_object: Error copying computer template!\n"); talloc_free(mem_ctx); @@ -635,26 +506,29 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const } /* readd user and then computer objectclasses */ - if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) { + ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "user"); + if (ret) { talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } - if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "computer", "computer")) { + ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "computer"); + if (ret) { talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } } else { - ret = samldb_copy_template(module, msg2, "(&(CN=TemplateUser)(objectclass=userTemplate))"); + ret = samdb_copy_template(module->ldb, msg2, "(&(CN=TemplateUser)(objectclass=userTemplate))"); if (ret) { ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_user_or_computer_object: Error copying user template!\n"); talloc_free(mem_ctx); return ret; } /* readd user objectclass */ - if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) { + ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", "user"); + if (ret) { talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } } @@ -672,9 +546,10 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } - if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", name)) { + ret = samdb_find_or_add_attribute(module->ldb, msg2, "sAMAccountName", name); + if (ret) { talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ret; } } @@ -719,7 +594,7 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module return LDB_ERR_OPERATIONS_ERROR; } - ret = samldb_copy_template(module, msg2, "(&(CN=TemplateForeignSecurityPrincipal)(objectclass=foreignSecurityPrincipalTemplate))"); + ret = samdb_copy_template(module->ldb, msg2, "(&(CN=TemplateForeignSecurityPrincipal)(objectclass=foreignSecurityPrincipalTemplate))"); if (ret != 0) { ldb_debug(module->ldb, LDB_DEBUG_WARNING, "samldb_fill_foreignSecurityPrincipal_object: Error copying template!\n"); talloc_free(mem_ctx); @@ -815,8 +690,8 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) } /* is user or computer? */ - if ((samldb_find_attribute(msg, "objectclass", "user") != NULL) || - (samldb_find_attribute(msg, "objectclass", "computer") != NULL)) { + if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != NULL) || + (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL)) { /* add all relevant missing objects */ ret = samldb_fill_user_or_computer_object(module, msg, &msg2); if (ret) { @@ -826,7 +701,7 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) /* is group? add all relevant missing objects */ if ( ! msg2 ) { - if (samldb_find_attribute(msg, "objectclass", "group") != NULL) { + if (samdb_find_attribute(module->ldb, msg, "objectclass", "group") != NULL) { ret = samldb_fill_group_object(module, msg, &msg2); if (ret) { return ret; @@ -836,7 +711,7 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req) /* perhaps a foreignSecurityPrincipal? */ if ( ! msg2 ) { - if (samldb_find_attribute(msg, "objectclass", "foreignSecurityPrincipal") != NULL) { + if (samdb_find_attribute(module->ldb, msg, "objectclass", "foreignSecurityPrincipal") != NULL) { ret = samldb_fill_foreignSecurityPrincipal_object(module, msg, &msg2); if (ret) { return ret; diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index ba73a039af..2136294661 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -4,7 +4,9 @@ interface functions for the sam database Copyright (C) Andrew Tridgell 2004 - + Copyright (C) Volker Lendecke 2004 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -25,6 +27,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_security.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_private.h" #include "lib/ldb/include/ldb_errors.h" #include "libcli/security/security.h" #include "auth/credentials/credentials.h" @@ -621,51 +624,121 @@ uint16_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr) return samdb_uf2acb(userAccountControl); } + +/* Find an attribute, with a particular value */ +struct ldb_message_element *samdb_find_attribute(struct ldb_context *ldb, + const struct ldb_message *msg, + const char *name, const char *value) +{ + int i; + struct ldb_message_element *el = ldb_msg_find_element(msg, name); + struct ldb_val v; + + v.data = discard_const_p(uint8_t, value); + v.length = strlen(value); + + if (!el) { + return NULL; + } + + for (i=0;i<el->num_values;i++) { + if (strcasecmp(value, (char *)el->values[i].data) == 0) { + return el; + } + } + + return NULL; +} + +int samdb_find_or_add_value(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value) +{ + if (samdb_find_attribute(ldb, msg, name, set_value) == NULL) { + return samdb_msg_add_string(ldb, msg, msg, name, set_value); + } + return LDB_SUCCESS; +} + +int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value) +{ + struct ldb_message_element *el; + + el = ldb_msg_find_element(msg, name); + if (el) { + return LDB_SUCCESS; + } + + return samdb_msg_add_string(ldb, msg, msg, name, set_value); +} + + /* copy from a template record to a message */ -int samdb_copy_template(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, - struct ldb_message *msg, const char *expression) +int samdb_copy_template(struct ldb_context *ldb, + struct ldb_message *msg, const char *filter) { - struct ldb_message **res, *t; + struct ldb_result *res; + struct ldb_message *t; int ret, i, j; - struct ldb_dn *basedn = ldb_dn_explode(msg, "cn=Templates"); + struct ldb_dn *basedn = ldb_dn_explode(ldb, "cn=Templates"); /* pull the template record */ - ret = gendb_search(sam_ldb, mem_ctx, basedn, &res, NULL, "%s", expression); - if (ret != 1) { - DEBUG(1,("samdb: ERROR: template '%s' matched %d records\n", - expression, ret)); - return -1; + ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, filter, NULL, &res); + talloc_free(basedn); + if (ret != LDB_SUCCESS) { + return ret; + } + if (res->count != 1) { + ldb_set_errstring(ldb, talloc_asprintf(ldb, "samdb_copy_template: ERROR: template '%s' matched %d records, expected 1\n", filter, + res->count)); + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; } - t = res[0]; + t = res->msgs[0]; - for (i=0;i<t->num_elements;i++) { + 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, "objectGUID") == 0) { continue; } - for (j=0;j<el->num_values;j++) { - if (strcasecmp(el->name, "objectClass") == 0 && - (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, "foreignSecurityTemplate") == 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; + 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) { + ldb_set_errstring(ldb, talloc_asprintf(ldb, "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) { + ldb_set_errstring(ldb, talloc_asprintf(ldb, "Adding attribute %s failed.\n", el->name)); + talloc_free(res); + return ret; + } } - samdb_msg_add_string(sam_ldb, mem_ctx, msg, el->name, - (char *)el->values[j].data); } } - return 0; + talloc_free(res); + + return LDB_SUCCESS; } @@ -678,7 +751,7 @@ int samdb_msg_add_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struc char *s = talloc_strdup(mem_ctx, str); char *a = talloc_strdup(mem_ctx, attr_name); if (s == NULL || a == NULL) { - return -1; + return LDB_ERR_OPERATIONS_ERROR; } return ldb_msg_add_string(msg, a, s); } @@ -1446,3 +1519,58 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, } +NTSTATUS samdb_create_foreign_security_principal(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, + struct dom_sid *sid, struct ldb_dn **ret_dn) +{ + struct ldb_message *msg; + struct ldb_dn *basedn; + const char *sidstr; + int ret; + + sidstr = dom_sid_string(mem_ctx, sid); + NT_STATUS_HAVE_NO_MEMORY(sidstr); + + /* We might have to create a ForeignSecurityPrincipal, even if this user + * is in our own domain */ + + msg = ldb_msg_new(mem_ctx); + if (msg == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* TODO: Hmmm. This feels wrong. How do I find the base dn to + * put the ForeignSecurityPrincipals? d_state->domain_dn does + * not work, this is wrong for the Builtin domain, there's no + * cn=For...,cn=Builtin,dc={BASEDN}. -- vl + */ + + basedn = samdb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), + "(&(objectClass=container)(cn=ForeignSecurityPrincipals))"); + + if (basedn == NULL) { + DEBUG(0, ("Failed to find DN for " + "ForeignSecurityPrincipal container\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* add core elements to the ldb_message for the alias */ + msg->dn = ldb_dn_build_child(mem_ctx, "CN", sidstr, basedn); + if (msg->dn == NULL) + return NT_STATUS_NO_MEMORY; + + samdb_msg_add_string(sam_ctx, mem_ctx, msg, + "objectClass", + "foreignSecurityPrincipal"); + + /* create the alias */ + ret = samdb_add(sam_ctx, mem_ctx, msg); + if (ret != 0) { + DEBUG(0,("Failed to create foreignSecurityPrincipal " + "record %s: %s\n", + ldb_dn_linearize(mem_ctx, msg->dn), + ldb_errstring(sam_ctx))); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + *ret_dn = msg->dn; + return NT_STATUS_OK; +} |