diff options
-rw-r--r-- | source4/dsdb/samdb/cracknames.c | 67 | ||||
-rw-r--r-- | source4/torture/rpc/drsuapi.c | 5 | ||||
-rw-r--r-- | source4/torture/rpc/drsuapi_cracknames.c | 42 |
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; } } } |