The branch, master has been updated via 9ee5887 s4:rpc_server: add support for DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM via efebf3c s4:rpc_server: pass the remote address to gensec_set_remote_address() via 12a6c32 s4:rpc_server/lsa: add dcesrv_lsa_OpenTrustedDomain_common() via 459d1d3 s4:rpc_server/netlogon: fix bugs in dcesrv_netr_DsRGetDCNameEx2() from b66e4be Fix a couple of DEBUG statements that were copied from elsewhere. Removed the misleading function name since the DEBUG message will print out the function name anyway.
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 9ee5887a36fd77b389049bf1465388e4f5a1faaf Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jan 22 11:24:31 2015 +0000 s4:rpc_server: add support for DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Mon Jan 26 14:23:50 CET 2015 on sn-devel-104 commit efebf3c80c9d89d012942d99ce955225c218790a Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jan 22 13:05:15 2015 +0000 s4:rpc_server: pass the remote address to gensec_set_remote_address() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 12a6c325c85a37e208e93d85c65e119eaa293742 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jan 22 14:57:15 2015 +0000 s4:rpc_server/lsa: add dcesrv_lsa_OpenTrustedDomain_common() dcesrv_lsa_OpenTrustedDomain() and dcesrv_lsa_OpenTrustedDomainByName() need to use the same logic and make sure trusted_domain_user_dn is valid. Otherwise dcesrv_lsa_OpenTrustedDomainByName() followed by dcesrv_lsa_DeleteObject() will leave the trust domain account in the database. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 459d1d3fb9a5282d19121eaacba9d611896b37ff Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jan 22 11:22:25 2015 +0000 s4:rpc_server/netlogon: fix bugs in dcesrv_netr_DsRGetDCNameEx2() We should return the our ip address the client is connected too. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> ----------------------------------------------------------------------- Summary of changes: source4/rpc_server/dcerpc_server.c | 32 +++++ source4/rpc_server/dcerpc_server.h | 7 + source4/rpc_server/dcesrv_auth.c | 16 ++- source4/rpc_server/lsa/dcesrv_lsa.c | 176 +++++++++++++++----------- source4/rpc_server/netlogon/dcerpc_netlogon.c | 22 ++-- 5 files changed, 169 insertions(+), 84 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4d5e166..5eac9ee 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1198,6 +1198,7 @@ _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, dce_ctx = talloc(mem_ctx, struct dcesrv_context); NT_STATUS_HAVE_NO_MEMORY(dce_ctx); + dce_ctx->initial_euid = geteuid(); dce_ctx->endpoint_list = NULL; dce_ctx->lp_ctx = lp_ctx; dce_ctx->assoc_groups_idr = idr_init(dce_ctx); @@ -1547,6 +1548,37 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn) dcesrv_conn->local_address = srv_conn->local_address; dcesrv_conn->remote_address = srv_conn->remote_address; + if (transport == NCALRPC) { + uid_t uid; + gid_t gid; + + ret = getpeereid(socket_get_fd(srv_conn->socket), &uid, &gid); + if (ret == -1) { + status = map_nt_error_from_unix_common(errno); + DEBUG(0, ("dcesrv_sock_accept: " + "getpeereid() failed for NCALRPC: %s\n", + nt_errstr(status))); + stream_terminate_connection(srv_conn, nt_errstr(status)); + return; + } + if (uid == dcesrv_conn->dce_ctx->initial_euid) { + struct tsocket_address *r = NULL; + + ret = tsocket_address_unix_from_path(dcesrv_conn, + "/root/ncalrpc_as_system", + &r); + if (ret == -1) { + status = map_nt_error_from_unix_common(errno); + DEBUG(0, ("dcesrv_sock_accept: " + "tsocket_address_unix_from_path() failed for NCALRPC: %s\n", + nt_errstr(status))); + stream_terminate_connection(srv_conn, nt_errstr(status)); + return; + } + dcesrv_conn->remote_address = r; + } + } + srv_conn->private_data = dcesrv_conn; irpc_add_name(srv_conn->msg_ctx, "rpc_server"); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index c5d8632..7b00418 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -273,6 +273,13 @@ struct dcesrv_assoc_group { /* server-wide context information for the dcerpc server */ struct dcesrv_context { + /* + * The euid at startup time. + * + * This is required for DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM + */ + uid_t initial_euid; + /* the list of endpoints that have registered * by the configured endpoint servers */ diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index d3c317b..d5aef49 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -80,10 +80,24 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) server_credentials, NULL, &auth->gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to call samba_server_gensec_start %s\n", + nt_errstr(status))); + return false; + } + + if (call->conn->remote_address != NULL) { + status = gensec_set_remote_address(auth->gensec_security, + call->conn->remote_address); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to call gensec_set_remote_address() %s\n", + nt_errstr(status))); + return false; + } + } status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_info->auth_type, auth->auth_info->auth_level); - if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", (int)auth->auth_info->auth_type, diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index b7936b8..2ab1a2b 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1204,15 +1204,14 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_cal return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN, NULL); } -/* - lsa_OpenTrustedDomain -*/ -static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct lsa_OpenTrustedDomain *r) +static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common( + struct dcesrv_call_state *dce_call, + TALLOC_CTX *tmp_mem, + struct lsa_policy_state *policy_state, + const char *filter, + uint32_t access_mask, + struct dcesrv_handle **_handle) { - struct dcesrv_handle *policy_handle; - - struct lsa_policy_state *policy_state; struct lsa_trusted_domain_state *trusted_domain_state; struct dcesrv_handle *handle; struct ldb_message **msgs; @@ -1221,55 +1220,56 @@ static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, "flatname", NULL }; - - const char *sid_string; + uint32_t direction; int ret; - DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); - ZERO_STRUCTP(r->out.trustdom_handle); - policy_state = policy_handle->data; - - trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); - if (!trusted_domain_state) { - return NT_STATUS_NO_MEMORY; - } - trusted_domain_state->policy = policy_state; - - sid_string = dom_sid_string(mem_ctx, r->in.sid); - if (!sid_string) { - return NT_STATUS_NO_MEMORY; - } + /* TODO: perform access checks */ /* search for the trusted_domain record */ - ret = gendb_search(trusted_domain_state->policy->sam_ldb, - mem_ctx, policy_state->system_dn, &msgs, attrs, - "(&(securityIdentifier=%s)(objectclass=trustedDomain))", - sid_string); + ret = gendb_search(policy_state->sam_ldb, tmp_mem, + policy_state->system_dn, + &msgs, attrs, "%s", filter); if (ret == 0) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } if (ret != 1) { - DEBUG(0,("Found %d records matching DN %s\n", ret, + DEBUG(0,("Found %d records matching %s under %s\n", ret, + filter, ldb_dn_get_linearized(policy_state->system_dn))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn); + trusted_domain_state = talloc_zero(tmp_mem, + struct lsa_trusted_domain_state); + if (!trusted_domain_state) { + return NT_STATUS_NO_MEMORY; + } + trusted_domain_state->policy = policy_state; - trusted_domain_state->trusted_domain_user_dn = NULL; + trusted_domain_state->trusted_domain_dn = + talloc_steal(trusted_domain_state, msgs[0]->dn); - if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) { - const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL)); - /* search for the trusted_domain record */ - ret = gendb_search(trusted_domain_state->policy->sam_ldb, - mem_ctx, policy_state->domain_dn, &msgs, attrs, - "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%u))", - flatname, UF_INTERDOMAIN_TRUST_ACCOUNT); + direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0); + if (direction & LSA_TRUST_DIRECTION_INBOUND) { + const char *flatname = ldb_msg_find_attr_as_string(msgs[0], + "flatname", NULL); + + /* search for the trusted_domain account */ + ret = gendb_search(policy_state->sam_ldb, tmp_mem, + policy_state->domain_dn, + &msgs, attrs, + "(&(samaccountname=%s$)(objectclass=user)" + "(userAccountControl:%s:=%u))", + flatname, + LDB_OID_COMPARATOR_AND, + UF_INTERDOMAIN_TRUST_ACCOUNT); if (ret == 1) { - trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn); + trusted_domain_state->trusted_domain_user_dn = + talloc_steal(trusted_domain_state, msgs[0]->dn); } } + handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); if (!handle) { return NT_STATUS_NO_MEMORY; @@ -1277,8 +1277,53 @@ static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, handle->data = talloc_steal(handle, trusted_domain_state); - trusted_domain_state->access_mask = r->in.access_mask; - trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state); + trusted_domain_state->access_mask = access_mask; + trusted_domain_state->policy = talloc_reference(trusted_domain_state, + policy_state); + + *_handle = handle; + + return NT_STATUS_OK; +} + +/* + lsa_OpenTrustedDomain +*/ +static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct lsa_OpenTrustedDomain *r) +{ + struct dcesrv_handle *policy_handle; + struct lsa_policy_state *policy_state; + struct dcesrv_handle *handle; + const char *sid_string; + char *filter; + NTSTATUS status; + + DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); + ZERO_STRUCTP(r->out.trustdom_handle); + policy_state = policy_handle->data; + + sid_string = dom_sid_string(mem_ctx, r->in.sid); + if (!sid_string) { + return NT_STATUS_NO_MEMORY; + } + + filter = talloc_asprintf(mem_ctx, + "(&(securityIdentifier=%s)" + "(objectclass=trustedDomain))", + sid_string); + if (filter == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx, + policy_state, + filter, + r->in.access_mask, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } *r->out.trustdom_handle = handle->wire_handle; @@ -1294,16 +1339,11 @@ static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce struct lsa_OpenTrustedDomainByName *r) { struct dcesrv_handle *policy_handle; - struct lsa_policy_state *policy_state; - struct lsa_trusted_domain_state *trusted_domain_state; struct dcesrv_handle *handle; - struct ldb_message **msgs; - const char *attrs[] = { - NULL - }; char *td_name; - int ret; + char *filter; + NTSTATUS status; DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); ZERO_STRUCTP(r->out.trustdom_handle); @@ -1313,42 +1353,28 @@ static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce return NT_STATUS_INVALID_PARAMETER; } - trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); - if (!trusted_domain_state) { + /* search for the trusted_domain record */ + td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string); + if (td_name == NULL) { return NT_STATUS_NO_MEMORY; } - trusted_domain_state->policy = policy_state; - /* search for the trusted_domain record */ - td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string); - ret = gendb_search(trusted_domain_state->policy->sam_ldb, - mem_ctx, policy_state->system_dn, &msgs, attrs, + filter = talloc_asprintf(mem_ctx, "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))" "(objectclass=trustedDomain))", td_name, td_name, td_name); - if (ret == 0) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - if (ret != 1) { - DEBUG(0,("Found %d records matching DN %s\n", ret, - ldb_dn_get_linearized(policy_state->system_dn))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - /* TODO: perform access checks */ - - trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn); - - handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); - if (!handle) { + if (filter == NULL) { return NT_STATUS_NO_MEMORY; } - handle->data = talloc_steal(handle, trusted_domain_state); - - trusted_domain_state->access_mask = r->in.access_mask; - trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state); + status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx, + policy_state, + filter, + r->in.access_mask, + &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } *r->out.trustdom_handle = handle->wire_handle; diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index c5740f6..c60a262 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1828,15 +1828,16 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, struct ldb_context *sam_ctx; struct netr_DsRGetDCNameInfo *info; struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct tsocket_address *local_address; + char *local_addr = NULL; const struct tsocket_address *remote_address; - char *addr = NULL; + char *remote_addr = NULL; const char *server_site_name; char *guid_str; struct netlogon_samlogon_response response; NTSTATUS status; const char *dc_name = NULL; const char *domain_name = NULL; - struct interface *ifaces; const char *pdc_ip; ZERO_STRUCTP(r->out.info); @@ -1847,10 +1848,16 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, return WERR_DS_UNAVAILABLE; } + local_address = dcesrv_connection_get_local_address(dce_call->conn); + if (tsocket_address_is_inet(local_address, "ip")) { + local_addr = tsocket_address_inet_addr_string(local_address, mem_ctx); + W_ERROR_HAVE_NO_MEMORY(local_addr); + } + remote_address = dcesrv_connection_get_remote_address(dce_call->conn); if (tsocket_address_is_inet(remote_address, "ip")) { - addr = tsocket_address_inet_addr_string(remote_address, mem_ctx); - W_ERROR_HAVE_NO_MEMORY(addr); + remote_addr = tsocket_address_inet_addr_string(remote_address, mem_ctx); + W_ERROR_HAVE_NO_MEMORY(remote_addr); } /* "server_unc" is ignored by w2k3 */ @@ -1908,7 +1915,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, r->in.domain_name, NULL, guid_str, r->in.client_account, - r->in.mask, addr, + r->in.mask, remote_addr, NETLOGON_NT_VERSION_5EX_WITH_IP, lp_ctx, &response, true); if (!NT_STATUS_IS_OK(status)) { @@ -1956,12 +1963,11 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo); W_ERROR_HAVE_NO_MEMORY(info); info->dc_unc = talloc_asprintf(mem_ctx, "%s%s", - dc_name[0] == '\\'? "\\\\":"", + dc_name[0] != '\\'? "\\\\":"", talloc_strdup(mem_ctx, dc_name)); W_ERROR_HAVE_NO_MEMORY(info->dc_unc); - load_interface_list(mem_ctx, lp_ctx, &ifaces); - pdc_ip = iface_list_best_ip(ifaces, addr); + pdc_ip = local_addr; if (pdc_ip == NULL) { pdc_ip = "127.0.0.1"; } -- Samba Shared Repository