summaryrefslogtreecommitdiff
path: root/source4/libnet
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libnet')
-rw-r--r--source4/libnet/libnet_rpc.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index 5d5bf194fa..3e66a5c27c 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -70,13 +70,18 @@ static struct composite_context* libnet_RpcConnectSrv_send(struct libnet_context
case LIBNET_RPC_CONNECT_DC:
case LIBNET_RPC_CONNECT_PDC:
case LIBNET_RPC_CONNECT_SERVER:
- case LIBNET_RPC_CONNECT_DC_INFO:
s->binding = talloc_asprintf(s, "ncacn_np:%s", r->in.name);
break;
case LIBNET_RPC_CONNECT_BINDING:
s->binding = talloc_strdup(s, r->in.binding);
break;
+
+ case LIBNET_RPC_CONNECT_DC_INFO:
+ /* this should never happen - DC_INFO level has a separate
+ composite function */
+ composite_error(c, NT_STATUS_INVALID_LEVEL);
+ return c;
}
/* connect to remote dcerpc pipe */
@@ -346,6 +351,7 @@ static struct composite_context* libnet_RpcConnectDCInfo_send(struct libnet_cont
struct composite_context *c, *conn_req;
struct rpc_connect_dci_state *s;
+ /* composite context allocation and setup */
c = talloc_zero(mem_ctx, struct composite_context);
if (c == NULL) return NULL;
@@ -369,6 +375,7 @@ static struct composite_context* libnet_RpcConnectDCInfo_send(struct libnet_cont
s->rpc_conn.level = LIBNET_RPC_CONNECT_BINDING;
}
+ /* we need to query information on lsarpc interface first */
s->rpc_conn.in.dcerpc_iface = &dcerpc_table_lsarpc;
/* request connection to the lsa pipe on the pdc */
@@ -376,7 +383,6 @@ static struct composite_context* libnet_RpcConnectDCInfo_send(struct libnet_cont
if (composite_nomem(c, conn_req)) return c;
composite_continue(c, conn_req, continue_dci_rpc_connect, c);
-
return c;
}
@@ -400,21 +406,22 @@ static void continue_dci_rpc_connect(struct composite_context *ctx)
return;
}
+ /* prepare to open a policy handle on lsa pipe */
s->lsa_pipe = s->ctx->pipe;
- s->qos.len = 0;
+ s->qos.len = 0;
s->qos.impersonation_level = 2;
- s->qos.context_mode = 1;
- s->qos.effective_only = 0;
+ s->qos.context_mode = 1;
+ s->qos.effective_only = 0;
s->attr.sec_qos = &s->qos;
- s->lsa_open_policy.in.attr = &s->attr;
+ s->lsa_open_policy.in.attr = &s->attr;
s->lsa_open_policy.in.system_name = talloc_asprintf(c, "\\");
if (composite_nomem(s->lsa_open_policy.in.system_name, c)) return;
s->lsa_open_policy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->lsa_open_policy.out.handle = &s->lsa_handle;
+ s->lsa_open_policy.out.handle = &s->lsa_handle;
open_pol_req = dcerpc_lsa_OpenPolicy2_send(s->lsa_pipe, c, &s->lsa_open_policy);
if (composite_nomem(open_pol_req, c)) return;
@@ -442,6 +449,7 @@ static void continue_lsa_policy(struct rpc_request *req)
return;
}
+ /* query lsa info for dns domain name and guid */
s->lsa_query_info2.in.handle = &s->lsa_handle;
s->lsa_query_info2.in.level = LSA_POLICY_INFO_DNS;
@@ -466,6 +474,11 @@ static void continue_lsa_query_info2(struct rpc_request *req)
s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
c->status = dcerpc_ndr_request_recv(req);
+
+ /* In case of error just null the realm and guid and proceed
+ to the next step. After all, it doesn't have to be AD domain
+ controller we talking to - NT-style PDC also counts */
+
if (NT_STATUS_EQUAL(c->status, NT_STATUS_NET_WRITE_FAULT)) {
s->r.out.realm = NULL;
s->r.out.guid = NULL;
@@ -479,6 +492,8 @@ static void continue_lsa_query_info2(struct rpc_request *req)
return;
}
+ /* Copy the dns domain name and guid from the query result */
+
/* this should actually be a conversion from lsa_StringLarge */
s->r.out.realm = s->lsa_query_info2.out.info->dns.dns_domain.string;
s->r.out.guid = talloc(c, struct GUID);
@@ -489,6 +504,7 @@ static void continue_lsa_query_info2(struct rpc_request *req)
*s->r.out.guid = s->lsa_query_info2.out.info->dns.domain_guid;
}
+ /* query lsa info for domain name and sid */
s->lsa_query_info.in.handle = &s->lsa_handle;
s->lsa_query_info.in.level = LSA_POLICY_INFO_DOMAIN;
@@ -520,9 +536,12 @@ static void continue_lsa_query_info(struct rpc_request *req)
return;
}
+ /* Copy the domain name and sid from the query result */
s->r.out.domain_sid = s->lsa_query_info.out.info->domain.sid;
s->r.out.domain_name = s->lsa_query_info.out.info->domain.name.string;
+
+ /* prepare to get endpoint mapping for the requested interface */
s->final_binding = talloc(s, struct dcerpc_binding);
if (composite_nomem(s->final_binding, c)) return;
@@ -540,7 +559,8 @@ static void continue_lsa_query_info(struct rpc_request *req)
/*
Step 6 of RpcConnectDCInfo: Receive endpoint mapping and create secondary
- lsa pipe connection derived from already used pipe
+ rpc connection derived from already used pipe but connected to the requested
+ one (as specified in libnet_RpcConnect structure)
*/
static void continue_epm_map_binding(struct composite_context *ctx)
{
@@ -558,7 +578,8 @@ static void continue_epm_map_binding(struct composite_context *ctx)
composite_error(c, c->status);
return;
}
-
+
+ /* create secondary connection derived from lsa pipe */
sec_conn_req = dcerpc_secondary_connection_send(s->lsa_pipe, s->final_binding);
if (composite_nomem(sec_conn_req, c)) return;
@@ -646,13 +667,10 @@ struct composite_context* libnet_RpcConnect_send(struct libnet_context *ctx,
switch (r->level) {
case LIBNET_RPC_CONNECT_SERVER:
- c = libnet_RpcConnectSrv_send(ctx, mem_ctx, r);
- break;
-
case LIBNET_RPC_CONNECT_BINDING:
c = libnet_RpcConnectSrv_send(ctx, mem_ctx, r);
break;
-
+
case LIBNET_RPC_CONNECT_PDC:
case LIBNET_RPC_CONNECT_DC:
c = libnet_RpcConnectDC_send(ctx, mem_ctx, r);