mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
s4:rpc_server: Implement dcesrv_lsa_CreateTrustedDomain_common()
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
dad8c78edc
commit
6d90397ff2
@ -1149,6 +1149,285 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_precheck(
|
|||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS dcesrv_lsa_CreateTrustedDomain_common(struct dcesrv_call_state *dce_call,
|
||||||
|
TALLOC_CTX *mem_ctx,
|
||||||
|
struct dcesrv_handle *policy_handle,
|
||||||
|
uint32_t access_mask,
|
||||||
|
struct lsa_TrustDomainInfoInfoEx *info,
|
||||||
|
struct trustDomainPasswords *auth_struct,
|
||||||
|
struct policy_handle **ptrustdom_handle)
|
||||||
|
{
|
||||||
|
struct lsa_policy_state *policy_state = policy_handle->data;
|
||||||
|
struct ldb_context *sam_ldb = policy_state->sam_ldb;
|
||||||
|
struct lsa_trusted_domain_state *trusted_domain_state = NULL;
|
||||||
|
struct ldb_message **msgs, *msg;
|
||||||
|
const char *attrs[] = {
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const char *netbios_name = info->netbios_name.string;
|
||||||
|
const char *dns_name = info->domain_name.string;
|
||||||
|
DATA_BLOB trustAuthIncoming = data_blob_null;
|
||||||
|
DATA_BLOB trustAuthOutgoing = data_blob_null;
|
||||||
|
struct dcesrv_handle *handle = NULL;
|
||||||
|
struct server_id *server_ids = NULL;
|
||||||
|
uint32_t num_server_ids = 0;
|
||||||
|
char *dns_encoded = NULL;
|
||||||
|
char *netbios_encoded = NULL;
|
||||||
|
char *sid_encoded = NULL;
|
||||||
|
struct imessaging_context *imsg_ctx =
|
||||||
|
dcesrv_imessaging_context(dce_call->conn);
|
||||||
|
NTSTATUS status;
|
||||||
|
bool ok;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (auth_struct->incoming.count) {
|
||||||
|
status = get_trustauth_inout_blob(dce_call,
|
||||||
|
mem_ctx,
|
||||||
|
&auth_struct->incoming,
|
||||||
|
&trustAuthIncoming);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth_struct->outgoing.count) {
|
||||||
|
status = get_trustauth_inout_blob(dce_call,
|
||||||
|
mem_ctx,
|
||||||
|
&auth_struct->outgoing,
|
||||||
|
&trustAuthOutgoing);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name);
|
||||||
|
if (dns_encoded == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
|
||||||
|
if (netbios_encoded == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, info->sid);
|
||||||
|
if (sid_encoded == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
trusted_domain_state = talloc_zero(mem_ctx,
|
||||||
|
struct lsa_trusted_domain_state);
|
||||||
|
if (trusted_domain_state == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
trusted_domain_state->policy = policy_state;
|
||||||
|
|
||||||
|
ret = ldb_transaction_start(sam_ldb);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search for the trusted_domain record */
|
||||||
|
ret = gendb_search(sam_ldb,
|
||||||
|
mem_ctx,
|
||||||
|
policy_state->system_dn,
|
||||||
|
&msgs,
|
||||||
|
attrs,
|
||||||
|
"(&(objectClass=trustedDomain)(|"
|
||||||
|
"(flatname=%s)(trustPartner=%s)"
|
||||||
|
"(flatname=%s)(trustPartner=%s)"
|
||||||
|
"(securityIdentifier=%s)))",
|
||||||
|
dns_encoded,
|
||||||
|
dns_encoded,
|
||||||
|
netbios_encoded,
|
||||||
|
netbios_encoded,
|
||||||
|
sid_encoded);
|
||||||
|
if (ret > 0) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = ldb_msg_new(mem_ctx);
|
||||||
|
if (msg == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
|
||||||
|
if (msg->dn == NULL) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name);
|
||||||
|
if (!ok) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_msg_add_string(msg, "flatname", netbios_name);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_msg_add_string(msg, "trustPartner", dns_name);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = samdb_msg_add_dom_sid(
|
||||||
|
sam_ldb, mem_ctx, msg, "securityIdentifier", info->sid);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = samdb_msg_add_int(
|
||||||
|
sam_ldb, mem_ctx, msg, "trustType", info->trust_type);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = samdb_msg_add_int(sam_ldb,
|
||||||
|
mem_ctx,
|
||||||
|
msg,
|
||||||
|
"trustAttributes",
|
||||||
|
info->trust_attributes);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = samdb_msg_add_int(sam_ldb,
|
||||||
|
mem_ctx,
|
||||||
|
msg,
|
||||||
|
"trustDirection",
|
||||||
|
info->trust_direction);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustAuthIncoming.length > 0) {
|
||||||
|
ret = ldb_msg_add_value(msg,
|
||||||
|
"trustAuthIncoming",
|
||||||
|
&trustAuthIncoming,
|
||||||
|
NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trustAuthOutgoing.length > 0) {
|
||||||
|
ret = ldb_msg_add_value(msg,
|
||||||
|
"trustAuthOutgoing",
|
||||||
|
&trustAuthOutgoing,
|
||||||
|
NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trusted_domain_state->trusted_domain_dn = ldb_dn_copy(
|
||||||
|
trusted_domain_state, msg->dn);
|
||||||
|
|
||||||
|
/* create the trusted_domain */
|
||||||
|
ret = ldb_add(sam_ldb, msg);
|
||||||
|
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->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->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->dn),
|
||||||
|
ldb_errstring(sam_ldb)));
|
||||||
|
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
|
||||||
|
struct ldb_dn *user_dn;
|
||||||
|
/* Inbound trusts must also create a cn=users object to match */
|
||||||
|
status = add_trust_user(mem_ctx, sam_ldb,
|
||||||
|
policy_state->domain_dn,
|
||||||
|
netbios_name,
|
||||||
|
&auth_struct->incoming,
|
||||||
|
&user_dn);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
ldb_transaction_cancel(sam_ldb);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify winbindd that we have a new trust
|
||||||
|
*/
|
||||||
|
status = irpc_servers_byname(imsg_ctx,
|
||||||
|
mem_ctx,
|
||||||
|
"winbind_server",
|
||||||
|
&num_server_ids,
|
||||||
|
&server_ids);
|
||||||
|
if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
|
||||||
|
imessaging_send(imsg_ctx,
|
||||||
|
server_ids[0],
|
||||||
|
MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
TALLOC_FREE(server_ids);
|
||||||
|
|
||||||
|
handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
|
||||||
|
if (handle == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->data = talloc_steal(handle, trusted_domain_state);
|
||||||
|
|
||||||
|
trusted_domain_state->access_mask = access_mask;
|
||||||
|
|
||||||
|
/* FIXME don't use talloc_reference */
|
||||||
|
trusted_domain_state->policy = talloc_reference(trusted_domain_state,
|
||||||
|
policy_state);
|
||||||
|
NT_STATUS_HAVE_NO_MEMORY(trusted_domain_state->policy);
|
||||||
|
|
||||||
|
*ptrustdom_handle = talloc_zero(mem_ctx, struct policy_handle);
|
||||||
|
NT_STATUS_HAVE_NO_MEMORY(*ptrustdom_handle);
|
||||||
|
|
||||||
|
**ptrustdom_handle = handle->wire_handle;
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
lsa_CreateTrustedDomainEx2
|
lsa_CreateTrustedDomainEx2
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user