diff options
-rw-r--r-- | source4/librpc/idl/drsblobs.idl | 52 | ||||
-rw-r--r-- | source4/librpc/idl/lsa.idl | 40 | ||||
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 6 | ||||
-rw-r--r-- | source4/torture/rpc/lsa.c | 130 |
4 files changed, 183 insertions, 45 deletions
diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl index eb85989eda..39c9680bdb 100644 --- a/source4/librpc/idl/drsblobs.idl +++ b/source4/librpc/idl/drsblobs.idl @@ -1,6 +1,6 @@ #include "idl_types.h" -import "drsuapi.idl", "misc.idl", "samr.idl"; +import "drsuapi.idl", "misc.idl", "samr.idl", "lsa.idl"; [ uuid("12345778-1234-abcd-0001-00000001"), @@ -12,7 +12,7 @@ interface drsblobs { typedef bitmap drsuapi_DsReplicaSyncOptions drsuapi_DsReplicaSyncOptions; typedef bitmap drsuapi_DsReplicaNeighbourFlags drsuapi_DsReplicaNeighbourFlags; typedef [v1_enum] enum drsuapi_DsAttributeId drsuapi_DsAttributeId; - + typedef [v1_enum] enum lsa_TrustAuthType lsa_TrustAuthType; /* * replPropertyMetaData * w2k uses version 1 @@ -357,25 +357,6 @@ interface drsblobs { ); typedef struct { - NTTIME time1; - uint32 unknown1; - DATA_BLOB value; - [flag(NDR_ALIGN4)] DATA_BLOB _pad; - } trustAuthInOutSecret1; - - typedef struct { - [relative] trustAuthInOutSecret1 *value1; - [relative] trustAuthInOutSecret1 *value2; - } trustAuthInOutCtr1; - - typedef [v1_enum] enum { - TRUST_AUTH_TYPE_NONE = 0, - TRUST_AUTH_TYPE_NT4OWF = 1, - TRUST_AUTH_TYPE_CLEAR = 2, - TRUST_AUTH_TYPE_VERSION = 3 - } trustAuthType; - - typedef struct { [value(0)] uint32 size; } AuthInfoNone; @@ -384,6 +365,20 @@ interface drsblobs { samr_Password password; } AuthInfoNT4Owf; + /* + * the secret value is encoded as UTF16 if it's a string + * but depending the AuthType, it might also be krb5 trusts have random bytes here, so converting to UTF16 + * mayfail... + * + * TODO: We should try handle the case of a random buffer in all places + * we deal with cleartext passwords from windows + * + * so we don't use this: + * + * uint32 value_len; + * [charset(UTF16)] uint8 value[value_len]; + */ + typedef struct { uint32 size; uint8 password[size]; @@ -403,21 +398,8 @@ interface drsblobs { typedef [public] struct { NTTIME LastUpdateTime; - trustAuthType AuthType; + lsa_TrustAuthType AuthType; - /* - * the secret value is encoded as UTF16 if it's a string - * but depending the AuthType, it might also be krb5 trusts have random bytes here, so converting to UTF16 - * mayfail... - * - * TODO: We should try handle the case of a random buffer in all places - * we deal with cleartext passwords from windows - * - * so we don't use this: - * - * uint32 value_len; - * [charset(UTF16)] uint8 value[value_len]; - */ [switch_is(AuthType)] AuthInfo AuthInfo; [flag(NDR_ALIGN4)] DATA_BLOB _pad; } AuthenticationInformation; diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index 408956b3fa..81931ae02a 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -578,9 +578,16 @@ import "misc.idl", "security.idl"; lsa_TrustAttributes trust_attributes; } lsa_TrustDomainInfoInfoEx; + typedef [public,v1_enum] enum { + TRUST_AUTH_TYPE_NONE = 0, + TRUST_AUTH_TYPE_NT4OWF = 1, + TRUST_AUTH_TYPE_CLEAR = 2, + TRUST_AUTH_TYPE_VERSION = 3 + } lsa_TrustAuthType; + typedef struct { NTTIME_hyper last_update_time; - uint32 secret_type; + lsa_TrustAuthType AuthType; lsa_DATA_BUF2 data; } lsa_TrustDomainInfoBuffer; @@ -652,7 +659,11 @@ import "misc.idl", "security.idl"; ); /* Function: 0x1b */ - [todo] NTSTATUS lsa_SetInformationTrustedDomain(); + NTSTATUS lsa_SetInformationTrustedDomain( + [in] policy_handle *trustdom_handle, + [in] lsa_TrustDomInfoEnum level, + [in,switch_is(level)] lsa_TrustedDomainInfo *info + ); /* Function: 0x1c */ [public] NTSTATUS lsa_OpenSecret( @@ -770,7 +781,12 @@ import "misc.idl", "security.idl"; ); /* Function: 0x28 */ - [todo] NTSTATUS lsa_SetTrustedDomainInfo(); + NTSTATUS lsa_SetTrustedDomainInfo( + [in] policy_handle *handle, + [in] dom_sid2 *dom_sid, + [in] lsa_TrustDomInfoEnum level, + [in,switch_is(level)] lsa_TrustedDomainInfo *info + ); /* Function: 0x29 */ NTSTATUS lsa_DeleteTrustedDomain( [in] policy_handle *handle, @@ -855,9 +871,15 @@ import "misc.idl", "security.idl"; [in] uint32 max_size ); - /* Function 0x33 */ - [todo] NTSTATUS lsa_CreateTrustedDomainEx(); + NTSTATUS lsa_CreateTrustedDomainEx( + [in] policy_handle *policy_handle, + [in] lsa_TrustDomainInfoInfoEx *info, + [in] lsa_TrustDomainInfoAuthInfo *auth_info, + [in] uint32 access_mask, + [out] policy_handle *trustdom_handle + ); + /* Function 0x34 */ NTSTATUS lsa_CloseTrustedDomainEx( @@ -971,7 +993,13 @@ import "misc.idl", "security.idl"; ); /* Function 0x3b */ - [todo] NTSTATUS lsa_CreateTrustedDomainEx2(); + NTSTATUS lsa_CreateTrustedDomainEx2( + [in] policy_handle *policy_handle, + [in] lsa_TrustDomainInfoInfoEx *info, + [in] lsa_TrustDomainInfoAuthInfo *auth_info, + [in] uint32 access_mask, + [out] policy_handle *trustdom_handle + ); /* Function 0x3c */ [todo] NTSTATUS lsa_CREDRWRITE(); diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index f67b5dee10..923b1e400c 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -672,6 +672,12 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_cal } samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain"); + + samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", LSA_TRUST_TYPE_DOWNLEVEL); + + samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", 0); + + samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", LSA_TRUST_DIRECTION_OUTBOUND); trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn); diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index ec74426ac6..1e35d94235 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2016,7 +2016,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, } else { q.in.trustdom_handle = &trustdom_handle[i]; - q.in.level = LSA_TRUSTED_DOMAIN_INFO_NAME; + q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX; status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); @@ -2024,9 +2024,127 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, } else if (!q.out.info) { ret = false; } else { - if (strcmp(q.out.info->name.netbios_name.string, trustinfo.name.string) != 0) { + if (strcmp(q.out.info->info_ex.netbios_name.string, trustinfo.name.string) != 0) { printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", - q.out.info->name.netbios_name.string, trustinfo.name.string); + q.out.info->info_ex.netbios_name.string, trustinfo.name.string); + ret = false; + } + if (q.out.info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", + trust_name, q.out.info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL); + ret = false; + } + if (q.out.info->info_ex.trust_attributes != 0) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", + trust_name, q.out.info->info_ex.trust_attributes, 0); + ret = false; + } + if (q.out.info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", + trust_name, q.out.info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND); + ret = false; + } + } + } + } + + /* now that we have some domains to look over, we can test the enum calls */ + if (!test_EnumTrustDom(p, mem_ctx, handle)) { + ret = false; + } + + for (i=0; i<12; i++) { + if (!test_DeleteTrustedDomainBySid(p, mem_ctx, handle, domsid[i])) { + ret = false; + } + } + + return ret; +} + +static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle) +{ + NTSTATUS status; + bool ret = true; + struct lsa_CreateTrustedDomainEx2 r; + struct lsa_TrustDomainInfoInfoEx trustinfo; + struct dom_sid *domsid[12]; + struct policy_handle trustdom_handle[12]; + struct lsa_QueryTrustedDomainInfo q; + int i; + + printf("Testing CreateTrustedDomainEx2 for 12 domains\n"); + + for (i=0; i< 12; i++) { + char *trust_name = talloc_asprintf(mem_ctx, "torturedom%02d", i); + char *trust_name_dns = talloc_asprintf(mem_ctx, "torturedom%02d.samba.example.com", i); + char *trust_sid = talloc_asprintf(mem_ctx, "S-1-5-21-97398-379795-100%02d", i); + + domsid[i] = dom_sid_parse_talloc(mem_ctx, trust_sid); + + trustinfo.sid = domsid[i]; + trustinfo.netbios_name.string = trust_name; + trustinfo.domain_name.string = trust_name_dns; + + /* Create inbound, some outbound, and some + * bi-directional trusts in a repeating pattern based + * on i */ + + /* 1 == inbound, 2 == outbound, 3 == both */ + trustinfo.trust_direction = (i % 3) + 1; + + /* Try different trust types too */ + + /* 1 == downleven (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ + trustinfo.trust_type = (((i / 3) + 1) % 3) + 1; + + trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION; + + r.in.policy_handle = handle; + r.in.info = &trustinfo; + r.in.auth_info = NULL; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.trustdom_handle = &trustdom_handle[i]; + + status = dcerpc_lsa_CreateTrustedDomainEx2(p, mem_ctx, &r); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + test_DeleteTrustedDomain(p, mem_ctx, handle, trustinfo.netbios_name); + status = dcerpc_lsa_CreateTrustedDomainEx2(p, mem_ctx, &r); + } + if (!NT_STATUS_IS_OK(status)) { + printf("CreateTrustedDomainEx failed - %s\n", nt_errstr(status)); + ret = false; + } else { + + q.in.trustdom_handle = &trustdom_handle[i]; + q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX; + status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q); + if (!NT_STATUS_IS_OK(status)) { + printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); + ret = false; + } else if (!q.out.info) { + ret = false; + } else { + if (strcmp(q.out.info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) { + printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", + q.out.info->info_ex.netbios_name.string, trustinfo.netbios_name.string); + ret = false; + } + if (q.out.info->info_ex.trust_type != trustinfo.trust_type) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", + trust_name, q.out.info->info_ex.trust_type, trustinfo.trust_type); + ret = false; + } + if (q.out.info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", + trust_name, q.out.info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION); + ret = false; + } + if (q.out.info->info_ex.trust_direction != trustinfo.trust_direction) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", + trust_name, q.out.info->info_ex.trust_direction, trustinfo.trust_direction); ret = false; } } @@ -2333,7 +2451,11 @@ bool torture_rpc_lsa(struct torture_context *tctx) if (!test_CreateTrustedDomain(p, tctx, handle)) { ret = false; } - + + if (!test_CreateTrustedDomainEx2(p, tctx, handle)) { + ret = false; + } + if (!test_EnumAccounts(p, tctx, handle)) { ret = false; } |