summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/cracknames.c67
-rw-r--r--source4/torture/rpc/drsuapi.c5
-rw-r--r--source4/torture/rpc/drsuapi_cracknames.c42
3 files changed, 89 insertions, 25 deletions
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index 7135b483de..eec27c6668 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -60,7 +60,7 @@ static WERROR dns_domain_from_principal(struct smb_krb5_context *smb_krb5_contex
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
return WERR_OK;
}
-
+
/* This isn't an allocation assignemnt, so it is free'ed with the krb5_free_principal */
realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal);
@@ -179,7 +179,7 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c
WERROR wret;
krb5_error_code ret;
krb5_principal principal;
- const char *service;
+ const char *service, *dns_name;
char *new_service;
char *new_princ;
enum drsuapi_DsNameStatus namestatus;
@@ -202,19 +202,24 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c
return WERR_OK;
}
service = principal->name.name_string.val[0];
+ dns_name = principal->name.name_string.val[1];
/* MAP it */
namestatus = LDB_lookup_spn_alias(smb_krb5_context->krb5_context,
sam_ctx, mem_ctx,
service, &new_service);
- if (namestatus != DRSUAPI_DS_NAME_STATUS_OK) {
- info1->status = namestatus;
+ if (namestatus == DRSUAPI_DS_NAME_STATUS_NOT_FOUND) {
+ info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
+ info1->dns_domain_name = talloc_strdup(mem_ctx, dns_name);
+ if (!info1->dns_domain_name) {
+ krb5_free_principal(smb_krb5_context->krb5_context, principal);
+ return WERR_NOMEM;
+ }
return WERR_OK;
- }
-
- if (ret != 0) {
- info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ } else if (namestatus != DRSUAPI_DS_NAME_STATUS_OK) {
+ info1->status = namestatus;
+ krb5_free_principal(smb_krb5_context->krb5_context, principal);
return WERR_OK;
}
@@ -230,15 +235,22 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c
ret = krb5_unparse_name_flags(smb_krb5_context->krb5_context, principal,
KRB5_PRINCIPAL_UNPARSE_NO_REALM, &new_princ);
- krb5_free_principal(smb_krb5_context->krb5_context, principal);
-
if (ret) {
+ krb5_free_principal(smb_krb5_context->krb5_context, principal);
return WERR_NOMEM;
}
wret = DsCrackNameOneName(sam_ctx, mem_ctx, format_flags, format_offered, format_desired,
new_princ, info1);
free(new_princ);
+ if (W_ERROR_IS_OK(wret) && (info1->status == DRSUAPI_DS_NAME_STATUS_NOT_FOUND)) {
+ info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
+ info1->dns_domain_name = talloc_strdup(mem_ctx, dns_name);
+ if (!info1->dns_domain_name) {
+ wret = WERR_NOMEM;
+ }
+ }
+ krb5_free_principal(smb_krb5_context->krb5_context, principal);
return wret;
}
@@ -287,7 +299,8 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
case 1:
break;
case 0:
- return dns_domain_from_principal(smb_krb5_context, name, info1);
+ return dns_domain_from_principal(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;
@@ -535,13 +548,19 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
krb5_principal principal;
char *unparsed_name_short;
char *service;
+ ret = krb5_parse_name(smb_krb5_context->krb5_context, name, &principal);
+ if (ret == 0 && principal->name.name_string.len < 2) {
+ info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+ krb5_free_principal(smb_krb5_context->krb5_context, principal);
+ return WERR_OK;
+ }
ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name,
KRB5_PRINCIPAL_PARSE_NO_REALM, &principal);
if (ret) {
- return dns_domain_from_principal(smb_krb5_context, name, info1);
- } else if (principal->name.name_string.len < 2) {
- info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
- return WERR_OK;
+ krb5_free_principal(smb_krb5_context->krb5_context, principal);
+
+ return dns_domain_from_principal(smb_krb5_context,
+ name, info1);
}
domain_filter = NULL;
@@ -671,6 +690,9 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
const char * const _domain_attrs_display[] = { "ncName", "dnsRoot", NULL};
const char * const _result_attrs_display[] = { "displayName", "samAccountName", NULL};
+ const char * const _domain_attrs_none[] = { "ncName", "dnsRoot" };
+ const char * const _result_attrs_none[] = { NULL};
+
/* here we need to set the attrs lists for domain and result lookups */
switch (format_desired) {
case DRSUAPI_DS_NAME_FORMAT_FQDN_1779:
@@ -695,7 +717,9 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
result_attrs = _result_attrs_display;
break;
default:
- return WERR_OK;
+ domain_attrs = _domain_attrs_none;
+ result_attrs = _result_attrs_none;
+ break;
}
if (domain_filter) {
@@ -955,12 +979,19 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
}
return WERR_OK;
}
+ case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: {
+ info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+ return WERR_OK;
+ }
+ case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:
+ case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: {
+ info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+ return WERR_OK;
+ }
default:
info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
return WERR_OK;
}
-
- return WERR_INVALID_PARAM;
}
/* Given a user Principal Name (such as foo@bar.com),
diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c
index c0ed2953f2..0129fe9b63 100644
--- a/source4/torture/rpc/drsuapi.c
+++ b/source4/torture/rpc/drsuapi.c
@@ -686,8 +686,6 @@ BOOL torture_rpc_drsuapi(struct torture_context *torture)
mem_ctx = talloc_init("torture_rpc_drsuapi");
- printf("Connected to DRAUAPI pipe\n");
-
ZERO_STRUCT(priv);
priv.join = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST,
@@ -768,7 +766,8 @@ BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture)
ret &= test_DsBind(p, mem_ctx, &priv);
if (ret) {
- ret &= test_DsGetDomainControllerInfo(p, mem_ctx, &priv);
+ /* We don't care if this fails, we just need some info from it */
+ test_DsGetDomainControllerInfo(p, mem_ctx, &priv);
ret &= test_DsCrackNames(p, mem_ctx, &priv);
diff --git a/source4/torture/rpc/drsuapi_cracknames.c b/source4/torture/rpc/drsuapi_cracknames.c
index e78f55eb5f..9d231be0e1 100644
--- a/source4/torture/rpc/drsuapi_cracknames.c
+++ b/source4/torture/rpc/drsuapi_cracknames.c
@@ -459,6 +459,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
const char *comment;
const char *str;
const char *expected_str;
+ const char *expected_dns;
enum drsuapi_DsNameStatus status;
enum drsuapi_DsNameStatus alternate_status;
enum drsuapi_DsNameFlags flags;
@@ -479,6 +480,12 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
.status = DRSUAPI_DS_NAME_STATUS_OK
},
{
+ .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+ .format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+ .str = FQDN_1779_name,
+ .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
+ },
+ {
.format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
.str = service_principal_name,
@@ -652,7 +659,24 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
.str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
.comment = "Looking for KRBTGT as a serivce principal",
- .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
+ .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+ .expected_dns = dns_domain
+ },
+ {
+ .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+ .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+ .str = talloc_asprintf(mem_ctx, "bogus/%s", dns_domain),
+ .comment = "Looking for bogus serivce principal",
+ .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+ .expected_dns = dns_domain
+ },
+ {
+ .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+ .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+ .str = talloc_asprintf(mem_ctx, "bogus/%s.%s", test_dc, dns_domain),
+ .comment = "Looking for bogus serivce on test DC",
+ .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+ .expected_dns = talloc_asprintf(mem_ctx, "%s.%s", test_dc, dns_domain)
},
{
.format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
@@ -683,7 +707,8 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
.str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
test_dc, dns_domain,
"BOGUS"),
- .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
+ .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+ .expected_dns = "BOGUS"
},
{
.format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
@@ -691,7 +716,8 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
.str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s",
test_dc, "REALLY",
"BOGUS"),
- .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
+ .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+ .expected_dns = "BOGUS"
},
{
.format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
@@ -842,7 +868,8 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
.comment = "invalid user principal name",
.str = "foo@bar",
- .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
+ .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+ .expected_dns = "bar"
},
{
.format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
@@ -907,6 +934,13 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.out.ctr.ctr1->array[0].result_name,
crack[i].expected_str, comment);
ret = False;
+ } else if (crack[i].expected_dns
+ && (strcmp(r.out.ctr.ctr1->array[0].dns_domain_name,
+ crack[i].expected_dns) != 0)) {
+ printf("DsCrackNames failed - got DNS name %s, expected %s on %s\n",
+ r.out.ctr.ctr1->array[0].result_name,
+ crack[i].expected_str, comment);
+ ret = False;
}
}
}