summaryrefslogtreecommitdiffstats
path: root/source4/dsdb/samdb/samdb.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-11-13 22:38:55 +0100
committerStefan Metzmacher <metze@samba.org>2007-12-21 05:45:10 +0100
commit3f2ca10d2d86f0cd64822f9e5f95633f41263237 (patch)
treee1d80eb274d2fdbed3c3be52e08027bce655db38 /source4/dsdb/samdb/samdb.c
parentcadf696f8b9cda131f7b5a46169c2f5f3b47ab0a (diff)
downloadsamba-3f2ca10d2d86f0cd64822f9e5f95633f41263237.tar.gz
samba-3f2ca10d2d86f0cd64822f9e5f95633f41263237.tar.xz
samba-3f2ca10d2d86f0cd64822f9e5f95633f41263237.zip
r25940: Rework the samldb and templates handling.
Templates just don't belong in the sam.ldb, as they don't obey any of the other rules. This moves them to a seperate templates.ldb. In samldb, this patch reworks the duplicate SID and Name detection code, to use ldb_search_exp_fmt() rather than gendb_search. This returns far more useful errors, which we now handle and report better. The call to samdb_search_for_parent_domain() has been moved in samldb, to allow both the account and SID uniqueness checks to be in the same domain. This function also returns better errors. dcesrv_drsuapi.c is updated for the new prototype of samdb_search_for_parent_domain() Andrew Bartlett (This used to be commit f1ab90c88c782c693b41795d70368650806543b5)
Diffstat (limited to 'source4/dsdb/samdb/samdb.c')
-rw-r--r--source4/dsdb/samdb/samdb.c87
1 files changed, 77 insertions, 10 deletions
diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c
index 36e12e859e..96e526d319 100644
--- a/source4/dsdb/samdb/samdb.c
+++ b/source4/dsdb/samdb/samdb.c
@@ -37,6 +37,34 @@
#include "dsdb/common/flags.h"
#include "param/param.h"
+char *samdb_relative_path(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ const char *name)
+{
+ const char *base_url =
+ (const char *)ldb_get_opaque(ldb, "ldb_url");
+ char *path, *p, *full_name;
+ if (name == NULL) {
+ return NULL;
+ }
+ if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
+ return talloc_strdup(mem_ctx, name);
+ }
+ path = talloc_strdup(mem_ctx, base_url);
+ if (path == NULL) {
+ return NULL;
+ }
+ if ( (p = strrchr(path, '/')) != NULL) {
+ p[0] = '\0';
+ full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name);
+ } else {
+ full_name = talloc_asprintf(mem_ctx, "./%s", name);
+ }
+ talloc_free(path);
+ return full_name;
+}
+
+
/*
connect to the SAM database
return an opaque context pointer on success, or NULL on failure
@@ -682,21 +710,49 @@ int samdb_copy_template(struct ldb_context *ldb,
struct ldb_result *res;
struct ldb_message *t;
int ret, i, j;
- struct ldb_dn *basedn = ldb_dn_new(ldb, ldb, "cn=Templates");
+ struct ldb_context *templates_ldb;
+ char *templates_ldb_path;
+ struct ldb_dn *basedn;
+
+ templates_ldb = talloc_get_type(ldb_get_opaque(ldb, "templates_ldb"), struct ldb_context);
+
+ if (!templates_ldb) {
+ templates_ldb_path = samdb_relative_path(ldb,
+ msg,
+ "templates.ldb");
+ if (!templates_ldb_path) {
+ *errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: Failed to contruct path for template db");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ templates_ldb = ldb_wrap_connect(ldb, global_loadparm,
+ templates_ldb_path, NULL,
+ NULL, 0, NULL);
+ talloc_free(templates_ldb_path);
+ if (!templates_ldb) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_set_opaque(ldb, "templates_ldb", templates_ldb);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
*errstring = NULL;
+ basedn = ldb_dn_new(templates_ldb, ldb, "cn=Templates");
if (!ldb_dn_add_child_fmt(basedn, "CN=Template%s", name)) {
+ talloc_free(basedn);
*errstring = talloc_asprintf(msg, "samdb_copy_template: ERROR: Failed to contruct DN for template '%s'",
name);
return LDB_ERR_OPERATIONS_ERROR;
}
/* pull the template record */
- ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, "cn=*", NULL, &res);
+ ret = ldb_search(templates_ldb, basedn, LDB_SCOPE_BASE, "(dn=*)", NULL, &res);
talloc_free(basedn);
if (ret != LDB_SUCCESS) {
- *errstring = talloc_steal(msg, ldb_errstring(ldb));
+ *errstring = talloc_steal(msg, ldb_errstring(templates_ldb));
return ret;
}
if (res->count != 1) {
@@ -1439,7 +1495,8 @@ failed:
/* Find a domain object in the parents of a particular DN. */
-struct ldb_dn *samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
+int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
+ struct ldb_dn **parent_dn, const char **errstring)
{
TALLOC_CTX *local_ctx;
struct ldb_dn *sdn = dn;
@@ -1448,7 +1505,7 @@ struct ldb_dn *samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CT
const char *attrs[] = { NULL };
local_ctx = talloc_new(mem_ctx);
- if (local_ctx == NULL) return NULL;
+ if (local_ctx == NULL) return LDB_ERR_OPERATIONS_ERROR;
while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
ret = ldb_search(ldb, sdn, LDB_SCOPE_BASE,
@@ -1458,18 +1515,28 @@ struct ldb_dn *samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CT
if (res->count == 1) {
break;
}
+ } else {
+ break;
}
}
- if (ret != LDB_SUCCESS || res->count != 1) {
+ if (ret != LDB_SUCCESS) {
+ *errstring = talloc_asprintf(mem_ctx, "Error searching for parent domain of %s: %s",
+ ldb_dn_get_linearized(sdn),
+ ldb_errstring(ldb));
talloc_free(local_ctx);
- return NULL;
+ return ret;
+ }
+ if (res->count != 1) {
+ *errstring = talloc_asprintf(mem_ctx, "Invalid dn (%s), not child of a domain object",
+ ldb_dn_get_linearized(sdn));
+ talloc_free(local_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
}
- talloc_steal(mem_ctx, sdn);
+ *parent_dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
talloc_free(local_ctx);
-
- return sdn;
+ return ret;
}
/*