diff options
author | Andrew Bartlett <abartlet@samba.org> | 2006-12-22 07:04:06 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:29:38 -0500 |
commit | 400a56d6dd2f02569a626f4507ec06fa49cf0839 (patch) | |
tree | 586fed5b62e073d28f81ae3eeded797dcd1f8b8d /source4/dsdb | |
parent | 0738c192a3ea4aef50945fe3836dab796906b739 (diff) | |
download | samba-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.c | 37 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb.c | 89 |
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); + +} |