summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-11-15 01:12:10 +0100
committerStefan Metzmacher <metze@samba.org>2007-12-21 05:45:17 +0100
commit3f7dcaceba0adbc4a436780bad776255425bf1b2 (patch)
treeb593824a5b9bda9dee2bc71e1346bfaf472f9f3a /source4/dsdb/samdb
parent36a1640b277c88c6725b8325e43e309a20e7a94f (diff)
downloadsamba-3f7dcaceba0adbc4a436780bad776255425bf1b2.tar.gz
samba-3f7dcaceba0adbc4a436780bad776255425bf1b2.tar.bz2
samba-3f7dcaceba0adbc4a436780bad776255425bf1b2.zip
r25957: Rework the cracknames code to use less gendb_search() and instead call
ldb_search_exp_fmt(). While it is a bit more verbose to code with, it returns better error codes, and allows us to handle the case where the base DN doesn't exist better. Andrew Bartlett (This used to be commit be6ef043a3f811e6b08d3e5fe7094a72d974134a)
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r--source4/dsdb/samdb/cracknames.c163
1 files changed, 116 insertions, 47 deletions
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index 3754be2e96..a4565844ec 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -107,12 +107,12 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru
ret = ldb_search(ldb_ctx, service_dn, LDB_SCOPE_BASE, "(objectClass=nTDSService)",
directory_attrs, &res);
- if (ret != LDB_SUCCESS) {
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
DEBUG(1, ("ldb_search: dn: %s not found: %s", service_dn_str, ldb_errstring(ldb_ctx)));
return DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
- } else if (res->count != 1) {
+ } else if (ret == LDB_ERR_NO_SUCH_OBJECT || res->count != 1) {
talloc_free(res);
- DEBUG(1, ("ldb_search: dn: %s found %d times!", service_dn_str, res->count));
+ DEBUG(1, ("ldb_search: dn: %s not found", service_dn_str));
return DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
}
talloc_steal(tmp_ctx, res);
@@ -269,7 +269,7 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
char **realm;
char *unparsed_name_short;
const char *domain_attrs[] = { NULL };
- struct ldb_message **domain_res = NULL;
+ struct ldb_result *domain_res = NULL;
/* Prevent recursion */
if (!name) {
@@ -284,26 +284,28 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
return WERR_OK;
}
- domain_filter = NULL;
realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal);
- domain_filter = talloc_asprintf(mem_ctx,
- "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
- ldb_binary_encode_string(mem_ctx, *realm),
- ldb_binary_encode_string(mem_ctx, *realm));
-
- ldb_ret = gendb_search(sam_ctx, mem_ctx, samdb_partitions_dn(sam_ctx, mem_ctx),
- &domain_res, domain_attrs,
- "%s", domain_filter);
- switch (ldb_ret) {
+
+ ldb_ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &domain_res,
+ samdb_partitions_dn(sam_ctx, mem_ctx),
+ LDB_SCOPE_ONELEVEL,
+ domain_attrs,
+ "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
+ ldb_binary_encode_string(mem_ctx, *realm),
+ ldb_binary_encode_string(mem_ctx, *realm));
+
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(2, ("DsCrackNameUPN domain ref search failed: %s", ldb_errstring(sam_ctx)));
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ return WERR_OK;
+ }
+
+ switch (domain_res->count) {
case 1:
break;
case 0:
return dns_domain_from_principal(mem_ctx, smb_krb5_context,
name, info1);
- case -1:
- DEBUG(2, ("DsCrackNameUPN domain ref search failed: %s", ldb_errstring(sam_ctx)));
- info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
- return WERR_OK;
default:
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
return WERR_OK;
@@ -321,6 +323,9 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
/* This may need to be extended for more userPrincipalName variations */
result_filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))",
ldb_binary_encode_string(mem_ctx, unparsed_name_short));
+
+ domain_filter = talloc_asprintf(mem_ctx, "(dn=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));
+
if (!result_filter || !domain_filter) {
free(unparsed_name_short);
return WERR_NOMEM;
@@ -666,15 +671,15 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
struct drsuapi_DsNameInfo1 *info1)
{
int ldb_ret;
- struct ldb_message **domain_res = NULL;
+ struct ldb_result *domain_res = NULL;
const char * const *domain_attrs;
const char * const *result_attrs;
struct ldb_message **result_res = NULL;
struct ldb_message *result = NULL;
struct ldb_dn *result_basedn = NULL;
- struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
int i;
char *p;
+ struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
const char * const _domain_attrs_1779[] = { "ncName", "dnsRoot", NULL};
const char * const _result_attrs_null[] = { NULL };
@@ -725,24 +730,30 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
if (domain_filter) {
/* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */
- ldb_ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &domain_res, domain_attrs,
- "%s", domain_filter);
- switch (ldb_ret) {
+ ldb_ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &domain_res,
+ partitions_basedn,
+ LDB_SCOPE_ONELEVEL,
+ domain_attrs,
+ "%s", domain_filter);
+
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s", ldb_errstring(sam_ctx)));
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ return WERR_OK;
+ }
+
+ switch (domain_res->count) {
case 1:
break;
case 0:
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
return WERR_OK;
- case -1:
- DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s", ldb_errstring(sam_ctx)));
- info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
- return WERR_OK;
default:
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
return WERR_OK;
}
- info1->dns_domain_name = samdb_result_string(domain_res[0], "dnsRoot", NULL);
+ info1->dns_domain_name = samdb_result_string(domain_res->msgs[0], "dnsRoot", NULL);
W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
} else {
@@ -751,16 +762,24 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
}
if (result_filter) {
+ int ret;
+ struct ldb_result *res;
if (domain_res) {
- result_basedn = samdb_result_dn(sam_ctx, mem_ctx, domain_res[0], "ncName", NULL);
+ result_basedn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
- ldb_ret = gendb_search(sam_ctx, mem_ctx, result_basedn, &result_res,
- result_attrs, "%s", result_filter);
+ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &res,
+ result_basedn, LDB_SCOPE_SUBTREE,
+ result_attrs, "%s", result_filter);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(result_res);
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ return WERR_OK;
+ }
+ ldb_ret = res->count;
+ result_res = res->msgs;
} else {
/* search with the 'phantom root' flag */
struct ldb_request *req;
- int ret;
- struct ldb_result *res;
res = talloc_zero(mem_ctx, struct ldb_result);
W_ERROR_HAVE_NO_MEMORY(res);
@@ -810,7 +829,7 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
result_attrs);
} else if (domain_res) {
- name_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res[0], "ncName", NULL);
+ name_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
result_attrs);
} else {
@@ -909,13 +928,30 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
const char *_acc = "", *_dom = "";
if (samdb_find_attribute(sam_ctx, result, "objectClass", "domain")) {
- ldb_ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &domain_res, domain_attrs,
- "(ncName=%s)", ldb_dn_get_linearized(result->dn));
- if (ldb_ret != 1) {
+
+ ldb_ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &domain_res,
+ partitions_basedn,
+ LDB_SCOPE_ONELEVEL,
+ domain_attrs,
+ "(ncName=%s)", ldb_dn_get_linearized(result->dn));
+
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s", ldb_errstring(sam_ctx)));
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ return WERR_OK;
+ }
+
+ switch (domain_res->count) {
+ case 1:
+ break;
+ case 0:
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
return WERR_OK;
+ default:
+ info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+ return WERR_OK;
}
- _dom = samdb_result_string(domain_res[0], "nETBIOSName", NULL);
+ _dom = samdb_result_string(domain_res->msgs[0], "nETBIOSName", NULL);
W_ERROR_HAVE_NO_MEMORY(_dom);
} else {
_acc = samdb_result_string(result, "sAMAccountName", NULL);
@@ -927,26 +963,59 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
_dom = "BUILTIN";
} else {
const char *attrs[] = { NULL };
- struct ldb_message **domain_res2;
+ struct ldb_result *domain_res2;
struct dom_sid *dom_sid = dom_sid_dup(mem_ctx, sid);
if (!dom_sid) {
return WERR_OK;
}
dom_sid->num_auths--;
- ldb_ret = gendb_search(sam_ctx, mem_ctx, NULL, &domain_res, attrs,
- "(&(objectSid=%s)(objectClass=domain))", ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
- if (ldb_ret != 1) {
- info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+ ldb_ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &domain_res,
+ NULL,
+ LDB_SCOPE_BASE,
+ attrs,
+ "(&(objectSid=%s)(objectClass=domain))",
+ ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
+
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(2, ("DsCrackNameOneFilter domain search failed: %s", ldb_errstring(sam_ctx)));
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
return WERR_OK;
}
- ldb_ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &domain_res2, domain_attrs,
- "(ncName=%s)", ldb_dn_get_linearized(domain_res[0]->dn));
- if (ldb_ret != 1) {
+
+ switch (domain_res->count) {
+ case 1:
+ break;
+ case 0:
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
return WERR_OK;
+ default:
+ info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+ return WERR_OK;
}
+
+ ldb_ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &domain_res2,
+ partitions_basedn,
+ LDB_SCOPE_ONELEVEL,
+ domain_attrs,
+ "(ncName=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));
- _dom = samdb_result_string(domain_res2[0], "nETBIOSName", NULL);
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s", ldb_errstring(sam_ctx)));
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ return WERR_OK;
+ }
+
+ switch (domain_res2->count) {
+ case 1:
+ break;
+ case 0:
+ info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+ return WERR_OK;
+ default:
+ info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+ return WERR_OK;
+ }
+ _dom = samdb_result_string(domain_res2->msgs[0], "nETBIOSName", NULL);
W_ERROR_HAVE_NO_MEMORY(_dom);
}
}