summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}
}