The branch, master has been updated via d9e311d... s4:lsa Functions to set Domain Trust Information via 668e7db... s4:lsa move code to add trusted domain user into its own function via 650a62d... s4:lsa Abstract crypto (un)wrapping in separate functions from a6f5e49... s4:registry - "LDB backend" - revert the length check for UTF16 strings
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit d9e311ddce50a6decc55ea442f562d11f06e2f78 Author: Simo Sorce <i...@samba.org> Date: Tue Mar 16 16:15:39 2010 -0400 s4:lsa Functions to set Domain Trust Information commit 668e7db9d69c8ad62fe817fd057542149937a55f Author: Simo Sorce <i...@samba.org> Date: Mon Mar 22 16:37:24 2010 -0400 s4:lsa move code to add trusted domain user into its own function commit 650a62d1cb72428c190dbc55e9e279746c796c78 Author: Simo Sorce <i...@samba.org> Date: Mon Mar 22 10:48:31 2010 -0400 s4:lsa Abstract crypto (un)wrapping in separate functions ----------------------------------------------------------------------- Summary of changes: librpc/gen_ndr/lsa.h | 2 +- librpc/gen_ndr/ndr_lsa.c | 4 +- librpc/gen_ndr/ndr_lsa.h | 2 + librpc/idl/lsa.idl | 2 +- source4/rpc_server/lsa/dcesrv_lsa.c | 942 +++++++++++++++++++++++++++++------ 5 files changed, 788 insertions(+), 164 deletions(-) Changeset truncated at 500 lines: diff --git a/librpc/gen_ndr/lsa.h b/librpc/gen_ndr/lsa.h index a03fdc2..f48d875 100644 --- a/librpc/gen_ndr/lsa.h +++ b/librpc/gen_ndr/lsa.h @@ -564,7 +564,7 @@ struct lsa_TrustDomainInfoAuthInfo { uint32_t outgoing_count; struct lsa_TrustDomainInfoBuffer *outgoing_current_auth_info;/* [unique] */ struct lsa_TrustDomainInfoBuffer *outgoing_previous_auth_info;/* [unique] */ -}; +}/* [public] */; struct lsa_TrustDomainInfoFullInfo { struct lsa_TrustDomainInfoInfoEx info_ex; diff --git a/librpc/gen_ndr/ndr_lsa.c b/librpc/gen_ndr/ndr_lsa.c index 9d1fb09..5ed3e2d 100644 --- a/librpc/gen_ndr/ndr_lsa.c +++ b/librpc/gen_ndr/ndr_lsa.c @@ -3316,7 +3316,7 @@ _PUBLIC_ void ndr_print_lsa_TrustDomainInfoBuffer(struct ndr_print *ndr, const c ndr->depth--; } -static enum ndr_err_code ndr_push_lsa_TrustDomainInfoAuthInfo(struct ndr_push *ndr, int ndr_flags, const struct lsa_TrustDomainInfoAuthInfo *r) +_PUBLIC_ enum ndr_err_code ndr_push_lsa_TrustDomainInfoAuthInfo(struct ndr_push *ndr, int ndr_flags, const struct lsa_TrustDomainInfoAuthInfo *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 5)); @@ -3345,7 +3345,7 @@ static enum ndr_err_code ndr_push_lsa_TrustDomainInfoAuthInfo(struct ndr_push *n return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_lsa_TrustDomainInfoAuthInfo(struct ndr_pull *ndr, int ndr_flags, struct lsa_TrustDomainInfoAuthInfo *r) +_PUBLIC_ enum ndr_err_code ndr_pull_lsa_TrustDomainInfoAuthInfo(struct ndr_pull *ndr, int ndr_flags, struct lsa_TrustDomainInfoAuthInfo *r) { uint32_t _ptr_incoming_current_auth_info; TALLOC_CTX *_mem_save_incoming_current_auth_info_0; diff --git a/librpc/gen_ndr/ndr_lsa.h b/librpc/gen_ndr/ndr_lsa.h index c6bfa71..4a2392e 100644 --- a/librpc/gen_ndr/ndr_lsa.h +++ b/librpc/gen_ndr/ndr_lsa.h @@ -262,6 +262,8 @@ enum ndr_err_code ndr_push_lsa_TrustAuthType(struct ndr_push *ndr, int ndr_flags enum ndr_err_code ndr_pull_lsa_TrustAuthType(struct ndr_pull *ndr, int ndr_flags, enum lsa_TrustAuthType *r); void ndr_print_lsa_TrustAuthType(struct ndr_print *ndr, const char *name, enum lsa_TrustAuthType r); void ndr_print_lsa_TrustDomainInfoBuffer(struct ndr_print *ndr, const char *name, const struct lsa_TrustDomainInfoBuffer *r); +enum ndr_err_code ndr_push_lsa_TrustDomainInfoAuthInfo(struct ndr_push *ndr, int ndr_flags, const struct lsa_TrustDomainInfoAuthInfo *r); +enum ndr_err_code ndr_pull_lsa_TrustDomainInfoAuthInfo(struct ndr_pull *ndr, int ndr_flags, struct lsa_TrustDomainInfoAuthInfo *r); void ndr_print_lsa_TrustDomainInfoAuthInfo(struct ndr_print *ndr, const char *name, const struct lsa_TrustDomainInfoAuthInfo *r); void ndr_print_lsa_TrustDomainInfoFullInfo(struct ndr_print *ndr, const char *name, const struct lsa_TrustDomainInfoFullInfo *r); void ndr_print_lsa_TrustDomainInfoAuthInfoInternal(struct ndr_print *ndr, const char *name, const struct lsa_TrustDomainInfoAuthInfoInternal *r); diff --git a/librpc/idl/lsa.idl b/librpc/idl/lsa.idl index 3560fa1..e9c6504 100644 --- a/librpc/idl/lsa.idl +++ b/librpc/idl/lsa.idl @@ -770,7 +770,7 @@ import "misc.idl", "security.idl"; lsa_DATA_BUF2 data; } lsa_TrustDomainInfoBuffer; - typedef struct { + typedef [public] struct { uint32 incoming_count; lsa_TrustDomainInfoBuffer *incoming_current_auth_info; lsa_TrustDomainInfoBuffer *incoming_previous_auth_info; diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 88b9c08..c2805c2 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -733,6 +733,168 @@ static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALL } +/* This decrypts and returns Trusted Domain Auth Information Internal data */ +static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob, + struct trustDomainPasswords *auth_struct) +{ + DATA_BLOB session_key = data_blob(NULL, 0); + enum ndr_err_code ndr_err; + NTSTATUS nt_status; + + nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key); + ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx, + lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), + auth_struct, + (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return NT_STATUS_INVALID_PARAMETER; + } + + return NT_STATUS_OK; +} + +static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct trustCurrentPasswords *iopw, + DATA_BLOB *trustauth_blob) +{ + uint32_t i; + struct trustAuthInOutBlob ioblob; + enum ndr_err_code ndr_err; + + ioblob.count = iopw->count; + ioblob.current = talloc(mem_ctx, + struct AuthenticationInformationArray); + if (!ioblob.current) { + return NT_STATUS_NO_MEMORY; + } + + ioblob.current->array = *iopw->current; + if (!ioblob.current->array) { + return NT_STATUS_NO_MEMORY; + } + + ioblob.previous = talloc(mem_ctx, + struct AuthenticationInformationArray); + if (!ioblob.previous) { + return NT_STATUS_NO_MEMORY; + } + ioblob.previous->array = talloc_array(mem_ctx, + struct AuthenticationInformation, + ioblob.count); + if (!ioblob.previous->array) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < ioblob.count; i++) { + ioblob.previous->array[i].LastUpdateTime = 0; + ioblob.previous->array[i].AuthType = 0; + } + ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx, + lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), + &ioblob, + (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return NT_STATUS_INVALID_PARAMETER; + } + + return NT_STATUS_OK; +} + +static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx, + struct ldb_context *sam_ldb, + struct ldb_dn *base_dn, + const char *netbios_name, + struct trustCurrentPasswords *in, + struct ldb_dn **user_dn) +{ + struct ldb_message *msg; + struct ldb_dn *dn; + uint32_t i; + int ret; + + dn = ldb_dn_copy(mem_ctx, base_dn); + if (!dn) { + return NT_STATUS_NO_MEMORY; + } + if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) { + return NT_STATUS_NO_MEMORY; + } + + msg = ldb_msg_new(mem_ctx); + if (!msg) { + return NT_STATUS_NO_MEMORY; + } + msg->dn = dn; + + ret = ldb_msg_add_string(msg, "objectClass", "user"); + if (ret != LDB_SUCCESS) { + return NT_STATUS_NO_MEMORY; + } + + ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name); + if (ret != LDB_SUCCESS) { + return NT_STATUS_NO_MEMORY; + } + + ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u", + UF_INTERDOMAIN_TRUST_ACCOUNT); + if (ret != LDB_SUCCESS) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < in->count; i++) { + const char *attribute; + struct ldb_val v; + switch (in->current[i]->AuthType) { + case TRUST_AUTH_TYPE_NT4OWF: + attribute = "unicodePwd"; + v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password; + v.length = 16; + break; + case TRUST_AUTH_TYPE_CLEAR: + attribute = "clearTextPassword"; + v.data = in->current[i]->AuthInfo.clear.password; + v.length = in->current[i]->AuthInfo.clear.size; + break; + default: + continue; + } + + ret = ldb_msg_add_value(msg, attribute, &v, NULL); + if (ret != LDB_SUCCESS) { + return NT_STATUS_NO_MEMORY; + } + } + + /* create the trusted_domain user account */ + ret = ldb_add(sam_ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(0,("Failed to create user record %s: %s\n", + ldb_dn_get_linearized(msg->dn), + ldb_errstring(sam_ldb))); + + switch (ret) { + case LDB_ERR_ENTRY_ALREADY_EXISTS: + return NT_STATUS_DOMAIN_EXISTS; + case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: + return NT_STATUS_ACCESS_DENIED; + default: + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + if (user_dn) { + *user_dn = dn; + } + return NT_STATUS_OK; +} /* lsa_CreateTrustedDomainEx2 @@ -746,19 +908,17 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc struct lsa_policy_state *policy_state; struct lsa_trusted_domain_state *trusted_domain_state; struct dcesrv_handle *handle; - struct ldb_message **msgs, *msg, *msg_user; + struct ldb_message **msgs, *msg; const char *attrs[] = { NULL }; const char *netbios_name; const char *dns_name; const char *name; - DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; struct trustDomainPasswords auth_struct; int ret; NTSTATUS nt_status; - enum ndr_err_code ndr_err; struct ldb_context *sam_ldb; DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY); @@ -767,11 +927,6 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc policy_state = policy_handle->data; sam_ldb = policy_state->sam_ldb; - nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - netbios_name = r->in.info->netbios_name.string; if (!netbios_name) { return NT_STATUS_INVALID_PARAMETER; @@ -788,7 +943,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc if (strcasecmp(netbios_name, "BUILTIN") == 0 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0) || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) { - return NT_STATUS_INVALID_PARAMETER;; + return NT_STATUS_INVALID_PARAMETER; } if (strcasecmp(netbios_name, policy_state->domain_name) == 0 @@ -805,14 +960,12 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc auth_struct.outgoing.count = 0; auth_struct.incoming.count = 0; } else { - auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size); - arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key); - ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx, - lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &auth_struct, - (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NT_STATUS_INVALID_PARAMETER; + auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, + r->in.auth_info->auth_blob.size); + nt_status = get_trustdom_auth_blob(dce_call, mem_ctx, + &auth_blob, &auth_struct); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) { @@ -823,78 +976,22 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc } if (auth_struct.incoming.count) { - uint32_t i; - struct trustAuthInOutBlob incoming; - - incoming.count = auth_struct.incoming.count; - incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray); - if (!incoming.current) { - return NT_STATUS_NO_MEMORY; - } - - incoming.current->array = *auth_struct.incoming.current; - if (!incoming.current->array) { - return NT_STATUS_NO_MEMORY; - } - - incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray); - if (!incoming.previous) { - return NT_STATUS_NO_MEMORY; - } - incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count); - if (!incoming.previous->array) { - return NT_STATUS_NO_MEMORY; - } - - for (i = 0; i < incoming.count; i++) { - incoming.previous->array[i].LastUpdateTime = 0; - incoming.previous->array[i].AuthType = 0; - } - ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx, - lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &incoming, - (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NT_STATUS_INVALID_PARAMETER; + nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, + &auth_struct.incoming, + &trustAuthIncoming); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } } else { trustAuthIncoming = data_blob(NULL, 0); } if (auth_struct.outgoing.count) { - uint32_t i; - struct trustAuthInOutBlob outgoing; - - outgoing.count = auth_struct.outgoing.count; - outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray); - if (!outgoing.current) { - return NT_STATUS_NO_MEMORY; - } - - outgoing.current->array = *auth_struct.outgoing.current; - if (!outgoing.current->array) { - return NT_STATUS_NO_MEMORY; - } - - outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray); - if (!outgoing.previous) { - return NT_STATUS_NO_MEMORY; - } - outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count); - if (!outgoing.previous->array) { - return NT_STATUS_NO_MEMORY; - } - - for (i = 0; i < outgoing.count; i++) { - outgoing.previous->array[i].LastUpdateTime = 0; - outgoing.previous->array[i].AuthType = 0; - } - ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx, - lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &outgoing, - (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NT_STATUS_INVALID_PARAMETER; + nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, + &auth_struct.outgoing, + &trustAuthOutgoing); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } } else { trustAuthOutgoing = data_blob(NULL, 0); @@ -1013,81 +1110,21 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc } if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) { - msg_user = ldb_msg_new(mem_ctx); - if (msg_user == NULL) { - ldb_transaction_cancel(sam_ldb); - return NT_STATUS_NO_MEMORY; - } - + struct ldb_dn *user_dn; /* Inbound trusts must also create a cn=users object to match */ - - trusted_domain_state->trusted_domain_user_dn = msg_user->dn - = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn); - if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) { - ldb_transaction_cancel(sam_ldb); - return NT_STATUS_NO_MEMORY; - } - - if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) { - ldb_transaction_cancel(sam_ldb); - return NT_STATUS_NO_MEMORY; - } - - ldb_msg_add_string(msg_user, "objectClass", "user"); - - ldb_msg_add_steal_string(msg_user, "samAccountName", - talloc_asprintf(mem_ctx, "%s$", netbios_name)); - - if (samdb_msg_add_uint(sam_ldb, mem_ctx, msg_user, - "userAccountControl", - UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) { + nt_status = add_trust_user(mem_ctx, sam_ldb, + policy_state->domain_dn, + netbios_name, + &auth_struct.incoming, + &user_dn); + if (!NT_STATUS_IS_OK(nt_status)) { ldb_transaction_cancel(sam_ldb); - return NT_STATUS_NO_MEMORY; - } - - if (auth_struct.incoming.count) { - uint32_t i; - for (i=0; i < auth_struct.incoming.count; i++ ) { - if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) { - samdb_msg_add_hash(sam_ldb, - mem_ctx, msg_user, "unicodePwd", - &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password); - } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) { - DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password, - auth_struct.incoming.current[i]->AuthInfo.clear.size); - ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL); - if (ret != LDB_SUCCESS) { - ldb_transaction_cancel(sam_ldb); - return NT_STATUS_NO_MEMORY; - } - } - } + return nt_status; } - /* create the cn=users trusted_domain account */ - ret = ldb_add(sam_ldb, msg_user); - switch (ret) { - case LDB_SUCCESS: - break; - case LDB_ERR_ENTRY_ALREADY_EXISTS: - ldb_transaction_cancel(sam_ldb); - DEBUG(0,("Failed to create trusted domain record %s: %s\n", - ldb_dn_get_linearized(msg_user->dn), - ldb_errstring(sam_ldb))); - return NT_STATUS_DOMAIN_EXISTS; - case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: - ldb_transaction_cancel(sam_ldb); - DEBUG(0,("Failed to create trusted domain record %s: %s\n", - ldb_dn_get_linearized(msg_user->dn), - ldb_errstring(sam_ldb))); - return NT_STATUS_ACCESS_DENIED; - default: - ldb_transaction_cancel(sam_ldb); - DEBUG(0,("Failed to create user record %s: %s\n", - ldb_dn_get_linearized(msg_user->dn), - ldb_errstring(sam_ldb))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } + /* save the trust user dn */ + trusted_domain_state->trusted_domain_user_dn + = talloc_steal(trusted_domain_state, user_dn); } ret = ldb_transaction_commit(sam_ldb); @@ -1327,14 +1364,576 @@ static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_ca -/* +/* parameters 4 to 6 are optional if the dn is a dn of a TDO object, + * otherwise at least one must be provided */ +static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx, + struct ldb_dn *basedn, const char *dns_domain, + const char *netbios, struct dom_sid2 *sid, + struct ldb_message ***msgs) +{ + const char *attrs[] = { "flatname", "trustPartner", + "securityIdentifier", "trustDirection", + "trustType", "trustAttributes", + "trustPosixOffset", + "msDs-supportedEncryptionTypes", NULL }; + char *dns = NULL; + char *nbn = NULL; + char *sidstr = NULL; + char *filter; -- Samba Shared Repository