summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-07-06 05:23:29 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:09:48 -0500
commitf2e8b3202c99065dafca3ba36a43450c509d0bd8 (patch)
tree4775c5023eab78b1a3f8e95bea249f40b6d8cc26 /source4/dsdb
parent3aa8a700e6b838ffc32bb7e9aebbb197e91c4704 (diff)
downloadsamba-f2e8b3202c99065dafca3ba36a43450c509d0bd8.tar.gz
samba-f2e8b3202c99065dafca3ba36a43450c509d0bd8.tar.bz2
samba-f2e8b3202c99065dafca3ba36a43450c509d0bd8.zip
r16827: Factor out some code into common samdb functions:
- creation of ForeignSecurityPrincipals - template duplication code Rework much of the LSA server to pass the RPC-LSA test. Much of the server code was untested. In implementing the LSA Accounts feature, I have opted to have it only create entires when privilages are applied, and not to delete entries, but to delete the privilages. We skip some parts of the test, but it is much better than not testing it at all. Andrew Bartlett (This used to be commit 10eeea6da465564ed9f785d06e2d2ed06cfe29a4)
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c173
-rw-r--r--source4/dsdb/samdb/samdb.c182
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;
+}