diff options
-rw-r--r-- | source4/libnet/libnet_join.c | 11 | ||||
-rw-r--r-- | source4/libnet/libnet_join.h | 1 | ||||
-rw-r--r-- | source4/torture/rpc/drsuapi.c | 57 | ||||
-rw-r--r-- | source4/torture/rpc/drsuapi_cracknames.c | 110 | ||||
-rw-r--r-- | source4/torture/rpc/testjoin.c | 18 |
5 files changed, 137 insertions, 60 deletions
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index df61df7f10..627cc97e32 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -76,6 +76,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J "msDS-KeyVersionNumber", "servicePrincipalName", "dNSHostName", + "objectGUID", NULL, }; @@ -264,9 +265,6 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_UNSUCCESSFUL; } - /* If we have a kvno recorded in AD, we need it locally as well */ - kvno = ldb_msg_find_attr_as_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); - /* Prepare a new message, for the modify */ msg = ldb_msg_new(tmp_ctx); if (!msg) { @@ -383,7 +381,12 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J r->out.domain_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name; talloc_steal(r, r_crack_names.out.ctr.ctr1->array[0].result_name); - r->out.kvno = kvno; + /* Store the KVNO of the account, critical for some kerberos + * operations */ + r->out.kvno = ldb_msg_find_attr_as_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); + + /* Store the account GUID. */ + r->out.account_guid = samdb_result_guid(res->msgs[0], "objectGUID"); if (r->in.acct_type == ACB_SVRTRUST) { status = libnet_JoinSite(remote_ldb, r); diff --git a/source4/libnet/libnet_join.h b/source4/libnet/libnet_join.h index aa0b244f6d..9e7748b4dd 100644 --- a/source4/libnet/libnet_join.h +++ b/source4/libnet/libnet_join.h @@ -60,6 +60,7 @@ struct libnet_JoinDomain { struct dcerpc_binding *samr_binding; struct policy_handle *user_handle; struct dom_sid *account_sid; + struct GUID account_guid; } out; }; diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c index ea7cf8d8bd..fbe62ae7d4 100644 --- a/source4/torture/rpc/drsuapi.c +++ b/source4/torture/rpc/drsuapi.c @@ -60,7 +60,7 @@ BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return ret; } -static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, +static BOOL test_DsGetDomainControllerInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct DsPrivate *priv) { NTSTATUS status; @@ -324,7 +324,7 @@ static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, }; if (lp_parm_bool(-1, "torture", "samba4", False)) { - printf("skipping DsGetDCInfo test against Samba4\n"); + printf("skipping DsReplicaGetInfo test against Samba4\n"); return True; } @@ -684,9 +684,9 @@ BOOL torture_rpc_drsuapi(struct torture_context *torture) ret &= test_DsBind(p, mem_ctx, &priv); - ret &= test_DsGetDCInfo(p, mem_ctx, &priv); + ret &= test_DsGetDomainControllerInfo(p, mem_ctx, &priv); - ret &= test_DsCrackNames(p, mem_ctx, &priv, TEST_MACHINE_NAME); + ret &= test_DsCrackNames(p, mem_ctx, &priv); ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv); @@ -707,3 +707,52 @@ BOOL torture_rpc_drsuapi(struct torture_context *torture) return ret; } + +BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + TALLOC_CTX *mem_ctx; + BOOL ret = True; + struct DsPrivate priv; + struct cli_credentials *machine_credentials; + + 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, + &machine_credentials); + if (!priv.join) { + talloc_free(mem_ctx); + printf("Failed to join as BDC\n"); + return False; + } + + status = torture_rpc_connection(mem_ctx, + &p, + &dcerpc_table_drsuapi); + if (!NT_STATUS_IS_OK(status)) { + torture_leave_domain(priv.join); + talloc_free(mem_ctx); + return False; + } + + ret &= test_DsBind(p, mem_ctx, &priv); + + if (ret) { + ret &= test_DsGetDomainControllerInfo(p, mem_ctx, &priv); + + ret &= test_DsCrackNames(p, mem_ctx, &priv); + + ret &= test_DsUnbind(p, mem_ctx, &priv); + } + talloc_free(mem_ctx); + + torture_leave_domain(priv.join); + + return ret; +} + diff --git a/source4/torture/rpc/drsuapi_cracknames.c b/source4/torture/rpc/drsuapi_cracknames.c index adf14461c0..b66fbf09c3 100644 --- a/source4/torture/rpc/drsuapi_cracknames.c +++ b/source4/torture/rpc/drsuapi_cracknames.c @@ -202,7 +202,7 @@ static BOOL test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, - struct DsPrivate *priv, const char *test_dc) + struct DsPrivate *priv) { NTSTATUS status; struct drsuapi_DsCrackNames r; @@ -222,7 +222,8 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *service_principal_name; const char *canonical_name; const char *canonical_ex_name; - const char *dc_sid; + const char *dom_sid; + const char *test_dc = torture_join_netbios_name(priv->join); ZERO_STRUCT(r); r.in.bind_handle = &priv->bind_handle; @@ -236,9 +237,9 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY; r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; - dc_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join)); + dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join)); - names[0].str = dc_sid; + names[0].str = dom_sid; printf("testing DsCrackNames with name '%s' desired format:%d\n", names[0].str, r.in.req.req1.format_desired); @@ -378,7 +379,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc); printf("testing DsCrackNames with name '%s' desired format:%d\n", - names[0].str, r.in.req.req1.format_desired); + names[0].str, r.in.req.req1.format_desired); status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -530,17 +531,43 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, .comment = "display name for Microsoft Support Account", .status = DRSUAPI_DS_NAME_STATUS_OK }, + { + .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID, + .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, + .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)), + .comment = "Account GUID -> DN", + .expected_str = FQDN_1779_name, + .status = DRSUAPI_DS_NAME_STATUS_OK + }, + { + .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID, + .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, + .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)), + .comment = "Account GUID -> NT4 Account", + .expected_str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc), + .status = DRSUAPI_DS_NAME_STATUS_OK + }, { .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid), .comment = "Site GUID", + .expected_str = priv->dcinfo.site_dn, .status = DRSUAPI_DS_NAME_STATUS_OK }, { - .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, + .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID, + .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid), .comment = "Computer GUID", + .expected_str = priv->dcinfo.computer_dn, + .status = DRSUAPI_DS_NAME_STATUS_OK + }, + { + .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID, + .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, + .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid), + .comment = "Computer GUID -> NT4 Account", .status = DRSUAPI_DS_NAME_STATUS_OK }, { @@ -548,6 +575,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid), .comment = "Server GUID", + .expected_str = priv->dcinfo.server_dn, .status = DRSUAPI_DS_NAME_STATUS_OK }, { @@ -555,13 +583,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid), .comment = "NTDS GUID", - .status = DRSUAPI_DS_NAME_STATUS_OK - }, - { - .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, - .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, - .str = SID_BUILTIN, - .comment = "BUILTIN domain SID", + .expected_str = priv->dcinfo.ntds_dn, .status = DRSUAPI_DS_NAME_STATUS_OK }, { @@ -705,6 +727,13 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND }, { + .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, + .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, + .comment = "BUILTIN\\ -> DN", + .str = "BUILTIN\\", + .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND + }, + { .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, .comment = "BUITIN SID -> NT4 account", @@ -714,28 +743,39 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, + .str = SID_BUILTIN, + .comment = "Builtin Domain SID -> DN", + .status = DRSUAPI_DS_NAME_STATUS_OK, + .expected_str = talloc_asprintf(mem_ctx, "CN=Builtin,%s", realm_dn_str) + }, + { + .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, + .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, .str = SID_BUILTIN_ADMINISTRATORS, + .comment = "Builtin Administrors SID -> DN", .status = DRSUAPI_DS_NAME_STATUS_OK }, { .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, .str = SID_BUILTIN_ADMINISTRATORS, + .comment = "Builtin Administrors SID -> NT4 Account", .status = DRSUAPI_DS_NAME_STATUS_OK }, { .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779, - .comment = "DC SID -> DN", - .str = dc_sid, - .expected_str = FQDN_1779_name, + .comment = "Domain SID -> DN", + .str = dom_sid, + .expected_str = realm_dn_str, .status = DRSUAPI_DS_NAME_STATUS_OK }, { .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, - .comment = "DC SID -> NT4 account", - .str = dc_sid, + .comment = "Domain SID -> NT4 account", + .str = dom_sid, + .expected_str = nt4_domain, .status = DRSUAPI_DS_NAME_STATUS_OK }, { @@ -795,37 +835,3 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return ret; } - -BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture) -{ - NTSTATUS status; - struct dcerpc_pipe *p; - TALLOC_CTX *mem_ctx; - BOOL ret = True; - struct DsPrivate priv; - - mem_ctx = talloc_init("torture_rpc_drsuapi"); - - status = torture_rpc_connection(mem_ctx, - &p, - &dcerpc_table_drsuapi); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return False; - } - - printf("Connected to DRSUAPI pipe\n"); - - ZERO_STRUCT(priv); - - ret &= test_DsBind(p, mem_ctx, &priv); - - ret &= test_DsCrackNames(p, mem_ctx, &priv, - torture_setting_string(torture, "host", NULL)); - - ret &= test_DsUnbind(p, mem_ctx, &priv); - - talloc_free(mem_ctx); - - return ret; -} diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 40192b6ac1..261412cf92 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -46,6 +46,8 @@ struct test_join { const char *dom_netbios_name; const char *dom_dns_name; struct dom_sid *user_sid; + struct GUID user_guid; + const char *netbios_name; }; @@ -346,6 +348,12 @@ _PUBLIC_ struct test_join *torture_join_domain(const char *machine_name, talloc_steal(tj, libnet_r->out.domain_name); tj->dom_dns_name = libnet_r->out.realm; talloc_steal(tj, libnet_r->out.realm); + tj->user_guid = libnet_r->out.account_guid; + tj->netbios_name = talloc_strdup(tj, machine_name); + if (!tj->netbios_name) { + talloc_free(tj); + return NULL; + } ZERO_STRUCT(u); s.in.user_handle = &tj->user_handle; @@ -511,6 +519,16 @@ const struct dom_sid *torture_join_user_sid(struct test_join *join) return join->user_sid; } +const char *torture_join_netbios_name(struct test_join *join) +{ + return join->netbios_name; +} + +const struct GUID *torture_join_user_guid(struct test_join *join) +{ + return &join->user_guid; +} + const char *torture_join_dom_netbios_name(struct test_join *join) { return join->dom_netbios_name; |