summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-12-22 07:04:06 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:29:38 -0500
commit400a56d6dd2f02569a626f4507ec06fa49cf0839 (patch)
tree586fed5b62e073d28f81ae3eeded797dcd1f8b8d /source4/dsdb
parent0738c192a3ea4aef50945fe3836dab796906b739 (diff)
downloadsamba-400a56d6dd2f02569a626f4507ec06fa49cf0839.tar.gz
samba-400a56d6dd2f02569a626f4507ec06fa49cf0839.tar.bz2
samba-400a56d6dd2f02569a626f4507ec06fa49cf0839.zip
r20315: Implement the server side of DsGetDomainControllerInfo. This is a
supprisingly complex call... It turns out that the in/out parameter 'level' is not in/out, but set seperatly by the server-side code from r->req.req1.level. This commit also breaks out some common code from samldb into samdb. Andrew Bartlett (This used to be commit 2eb9e6445c64840399171f4f56b1e43786dbcfa7)
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c37
-rw-r--r--source4/dsdb/samdb/samdb.c89
2 files changed, 81 insertions, 45 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 26560c361e..1c1ff0ea6e 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -184,41 +184,6 @@ static int samldb_allocate_next_rid(struct ldb_module *module, TALLOC_CTX *mem_c
return ret;
}
-/* Find a domain object in the parents of a particular DN. */
-static struct ldb_dn *samldb_search_domain(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
-{
- TALLOC_CTX *local_ctx;
- struct ldb_dn *sdn;
- struct ldb_result *res = NULL;
- int ret = 0;
- const char *attrs[] = { NULL };
-
- local_ctx = talloc_new(mem_ctx);
- if (local_ctx == NULL) return NULL;
-
- sdn = ldb_dn_copy(local_ctx, dn);
- do {
- ret = ldb_search(module->ldb, sdn, LDB_SCOPE_BASE,
- "(|(objectClass=domain)(objectClass=builtinDomain))", attrs, &res);
- if (ret == LDB_SUCCESS) {
- talloc_steal(local_ctx, res);
- if (res->count == 1) {
- break;
- }
- }
- } while ((sdn = ldb_dn_get_parent(local_ctx, sdn)));
-
- if (ret != LDB_SUCCESS || res->count != 1) {
- talloc_free(local_ctx);
- return NULL;
- }
-
- talloc_steal(mem_ctx, sdn);
- talloc_free(local_ctx);
-
- return sdn;
-}
-
/* search the domain related to the provided dn
allocate a new RID for the domain
return the new sid string
@@ -235,7 +200,7 @@ static int samldb_get_new_sid(struct ldb_module *module,
/* get the domain component part of the provided dn */
- dom_dn = samldb_search_domain(module, mem_ctx, obj_dn);
+ dom_dn = samdb_search_for_parent_domain(module->ldb, mem_ctx, obj_dn);
if (dom_dn == NULL) {
ldb_asprintf_errstring(module->ldb,
"Invalid dn (%s) not child of a domain object!\n",
diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c
index 9296352b0b..2d811094ff 100644
--- a/source4/dsdb/samdb/samdb.c
+++ b/source4/dsdb/samdb/samdb.c
@@ -353,15 +353,11 @@ const char *samdb_result_string(const struct ldb_message *msg, const char *attr,
struct ldb_dn *samdb_result_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
const char *attr, struct ldb_dn *default_value)
{
- struct ldb_dn *res_dn;
- const char *string = samdb_result_string(msg, attr, NULL);
- if (string == NULL) return default_value;
- res_dn = ldb_dn_new(mem_ctx, ldb, string);
- if ( ! ldb_dn_validate(res_dn)) {
- talloc_free(res_dn);
- return NULL;
+ struct ldb_dn *ret_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, msg, attr);
+ if (!ret_dn) {
+ return default_value;
}
- return res_dn;
+ return ret_dn;
}
/*
@@ -1182,7 +1178,7 @@ struct ldb_dn *samdb_server_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
}
/*
- work out the domain sid for the current open ldb
+ work out if we are the PDC for the domain of the current open ldb
*/
BOOL samdb_is_pdc(struct ldb_context *ldb)
{
@@ -1225,6 +1221,41 @@ failed:
return False;
}
+
+/* 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)
+{
+ TALLOC_CTX *local_ctx;
+ struct ldb_dn *sdn = dn;
+ struct ldb_result *res = NULL;
+ int ret = 0;
+ const char *attrs[] = { NULL };
+
+ local_ctx = talloc_new(mem_ctx);
+ if (local_ctx == NULL) return NULL;
+
+ while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
+ ret = ldb_search(ldb, sdn, LDB_SCOPE_BASE,
+ "(|(objectClass=domain)(objectClass=builtinDomain))", attrs, &res);
+ if (ret == LDB_SUCCESS) {
+ talloc_steal(local_ctx, res);
+ if (res->count == 1) {
+ break;
+ }
+ }
+ }
+
+ if (ret != LDB_SUCCESS || res->count != 1) {
+ talloc_free(local_ctx);
+ return NULL;
+ }
+
+ talloc_steal(mem_ctx, sdn);
+ talloc_free(local_ctx);
+
+ return sdn;
+}
+
/*
check that a password is sufficiently complex
*/
@@ -1681,3 +1712,43 @@ NTSTATUS samdb_create_foreign_security_principal(struct ldb_context *sam_ctx, TA
*ret_dn = msg->dn;
return NT_STATUS_OK;
}
+
+/*
+ Find the DN of a domain, be it the netbios or DNS name
+*/
+
+struct ldb_dn *samdb_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
+ const char *domain_name)
+{
+ const char * const domain_ref_attrs[] = {
+ "ncName", NULL
+ };
+ struct ldb_result *res_domain_ref;
+ char *escaped_domain = ldb_binary_encode_string(mem_ctx, domain_name);
+ /* find the domain's DN */
+ int ret_domain = ldb_search_exp_fmt(ldb, mem_ctx,
+ &res_domain_ref,
+ samdb_partitions_dn(ldb, mem_ctx),
+ LDB_SCOPE_ONELEVEL,
+ domain_ref_attrs,
+ "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
+ escaped_domain, escaped_domain);
+ if (ret_domain != 0) {
+ return NULL;
+ }
+
+ if (res_domain_ref->count == 0) {
+ DEBUG(3,("sam_search_user: Couldn't find domain [%s] in samdb.\n",
+ domain_name));
+ return NULL;
+ }
+
+ if (res_domain_ref->count > 1) {
+ DEBUG(0,("Found %d records matching domain [%s]\n",
+ ret_domain, domain_name));
+ return NULL;
+ }
+
+ return samdb_result_dn(ldb, mem_ctx, res_domain_ref->msgs[0], "nCName", NULL);
+
+}