mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +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;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user