summaryrefslogtreecommitdiff
path: root/source4/libnet
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libnet')
-rw-r--r--source4/libnet/libnet_join.c11
-rw-r--r--source4/libnet/libnet_rpc.c438
-rw-r--r--source4/libnet/libnet_rpc.h13
-rw-r--r--source4/libnet/libnet_vampire.c13
4 files changed, 296 insertions, 179 deletions
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 743076ee72..fb28eaed2f 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -404,7 +404,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
NTSTATUS status, cu_status;
- struct libnet_RpcConnectDCInfo *connect_with_info;
+ struct libnet_RpcConnect *connect_with_info;
struct dcerpc_pipe *samr_pipe;
struct samr_Connect sc;
@@ -445,7 +445,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return NT_STATUS_NO_MEMORY;
}
- connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnectDCInfo);
+ connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnect);
if (!connect_with_info) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
@@ -454,19 +454,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* prepare connect to the LSA pipe of PDC */
if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) {
- connect_with_info->level = LIBNET_RPC_CONNECT_PDC;
connect_with_info->in.name = r->in.domain_name;
} else {
- connect_with_info->level = LIBNET_RPC_CONNECT_BINDING;
connect_with_info->in.binding = r->in.binding;
}
+ connect_with_info->level = LIBNET_RPC_CONNECT_DC_INFO;
connect_with_info->in.dcerpc_iface = &dcerpc_table_samr;
+
/*
establish a SAMR connection, on the same CIFS transport
*/
-
- status = libnet_RpcConnectDCInfo(ctx, connect_with_info);
+ status = libnet_RpcConnect(ctx, tmp_ctx, connect_with_info);
if (!NT_STATUS_IS_OK(status)) {
if (r->in.binding) {
r->out.error_string = talloc_asprintf(mem_ctx,
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index 53f3a7e1cf..e2b5b06035 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -70,6 +70,7 @@ 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;
@@ -333,6 +334,10 @@ struct composite_context* libnet_RpcConnect_send(struct libnet_context *ctx,
c = libnet_RpcConnectDC_send(ctx, mem_ctx, r);
break;
+ case LIBNET_RPC_CONNECT_DC_INFO:
+ c = libnet_RpcConnectDCInfo_send(ctx, mem_ctx, r);
+ break;
+
default:
c = talloc_zero(mem_ctx, struct composite_context);
composite_error(c, NT_STATUS_INVALID_LEVEL);
@@ -364,6 +369,9 @@ NTSTATUS libnet_RpcConnect_recv(struct composite_context *c, struct libnet_conte
case LIBNET_RPC_CONNECT_DC:
return libnet_RpcConnectDC_recv(c, ctx, mem_ctx, r);
+ case LIBNET_RPC_CONNECT_DC_INFO:
+ return libnet_RpcConnectDCInfo_recv(c, ctx, mem_ctx, r);
+
default:
return NT_STATUS_INVALID_LEVEL;
}
@@ -389,196 +397,294 @@ NTSTATUS libnet_RpcConnect(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
}
-/**
- * Connects to rpc pipe on remote server or pdc, and returns info on the domain name, domain sid and realm
- *
- * @param ctx initialised libnet context
- * @param r data structure containing necessary parameters and return values. Must be a talloc context
- * @return nt status of the call
- **/
-
-NTSTATUS libnet_RpcConnectDCInfo(struct libnet_context *ctx,
- struct libnet_RpcConnectDCInfo *r)
-{
- TALLOC_CTX *tmp_ctx;
- NTSTATUS status;
-
- struct libnet_RpcConnect *c;
- struct lsa_ObjectAttribute attr;
+struct rpc_connect_dci_state {
+ struct libnet_context *ctx;
+ struct libnet_RpcConnect r;
+ struct libnet_RpcConnect rpc_conn;
+ struct policy_handle lsa_handle;
struct lsa_QosInfo qos;
+ struct lsa_ObjectAttribute attr;
struct lsa_OpenPolicy2 lsa_open_policy;
- struct policy_handle lsa_p_handle;
+ struct dcerpc_pipe *lsa_pipe;
struct lsa_QueryInfoPolicy2 lsa_query_info2;
struct lsa_QueryInfoPolicy lsa_query_info;
-
- struct dcerpc_pipe *lsa_pipe;
-
struct dcerpc_binding *final_binding;
struct dcerpc_pipe *final_pipe;
+};
- tmp_ctx = talloc_new(r);
- if (!tmp_ctx) {
- r->out.error_string = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- c = talloc(tmp_ctx, struct libnet_RpcConnect);
- if (!c) {
- r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- c->level = r->level;
- if (r->level != LIBNET_RPC_CONNECT_BINDING) {
- c->in.name = r->in.name;
- } else {
- c->in.binding = r->in.binding;
+static void continue_dci_rpc_connect(struct composite_context *ctx);
+static void continue_lsa_policy(struct rpc_request *req);
+static void continue_lsa_query_info(struct rpc_request *req);
+static void continue_lsa_query_info2(struct rpc_request *req);
+static void continue_epm_map_binding(struct composite_context *ctx);
+static void continue_secondary_conn(struct composite_context *ctx);
+
+
+static void continue_dci_rpc_connect(struct composite_context *ctx)
+{
+ struct composite_context *c;
+ struct rpc_connect_dci_state *s;
+ struct rpc_request *open_pol_req;
+
+ c = talloc_get_type(ctx->async.private_data, struct composite_context);
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ c->status = libnet_RpcConnect_recv(ctx, s->ctx, c, &s->rpc_conn);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ composite_error(c, c->status);
+ return;
}
+
+ s->lsa_pipe = s->ctx->pipe;
- c->in.dcerpc_iface = &dcerpc_table_lsarpc;
-
- /* connect to the LSA pipe of the PDC */
-
- status = libnet_RpcConnect(ctx, c, c);
- if (!NT_STATUS_IS_OK(status)) {
- if (r->level != LIBNET_RPC_CONNECT_BINDING) {
- r->out.error_string = talloc_asprintf(r,
- "Connection to LSA pipe of DC failed: %s",
- c->out.error_string);
- } else {
- r->out.error_string = talloc_asprintf(r,
- "Connection to LSA pipe with binding '%s' failed: %s",
- r->in.binding, c->out.error_string);
- }
- talloc_free(tmp_ctx);
- return status;
- }
- lsa_pipe = c->out.dcerpc_pipe;
-
- /* Get an LSA policy handle */
-
- ZERO_STRUCT(lsa_p_handle);
- qos.len = 0;
- qos.impersonation_level = 2;
- qos.context_mode = 1;
- qos.effective_only = 0;
-
- attr.len = 0;
- attr.root_dir = NULL;
- attr.object_name = NULL;
- attr.attributes = 0;
- attr.sec_desc = NULL;
- attr.sec_qos = &qos;
-
- lsa_open_policy.in.attr = &attr;
-
- lsa_open_policy.in.system_name = talloc_asprintf(tmp_ctx, "\\");
- if (!lsa_open_policy.in.system_name) {
- r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
+ s->qos.len = 0;
+ s->qos.impersonation_level = 2;
+ 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.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;
+
+ open_pol_req = dcerpc_lsa_OpenPolicy2_send(s->lsa_pipe, c, &s->lsa_open_policy);
+ if (composite_nomem(open_pol_req, c)) return;
+
+ composite_continue_rpc(c, open_pol_req, continue_lsa_policy, c);
+}
+
+
+static void continue_lsa_policy(struct rpc_request *req)
+{
+ struct composite_context *c;
+ struct rpc_connect_dci_state *s;
+ struct rpc_request *query_info_req;
+
+ c = talloc_get_type(req->async.private, struct composite_context);
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ c->status = dcerpc_ndr_request_recv(req);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ composite_error(c, c->status);
+ return;
}
- lsa_open_policy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- lsa_open_policy.out.handle = &lsa_p_handle;
+ s->lsa_query_info2.in.handle = &s->lsa_handle;
+ s->lsa_query_info2.in.level = LSA_POLICY_INFO_DNS;
- status = dcerpc_lsa_OpenPolicy2(lsa_pipe, tmp_ctx, &lsa_open_policy);
+ query_info_req = dcerpc_lsa_QueryInfoPolicy2_send(s->lsa_pipe, c, &s->lsa_query_info2);
+ if (composite_nomem(query_info_req, c)) return;
- /* This now fails on ncacn_ip_tcp against Win2k3 SP1 */
- if (NT_STATUS_IS_OK(status)) {
- /* Look to see if this is ADS (a fault indicates NT4 or Samba 3.0) */
-
- lsa_query_info2.in.handle = &lsa_p_handle;
- lsa_query_info2.in.level = LSA_POLICY_INFO_DNS;
-
- status = dcerpc_lsa_QueryInfoPolicy2(lsa_pipe, tmp_ctx,
- &lsa_query_info2);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(r,
- "lsa_QueryInfoPolicy2 failed: %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
- }
- r->out.realm = lsa_query_info2.out.info->dns.dns_domain.string;
- r->out.guid = talloc(r, struct GUID);
- if (!r->out.guid) {
- r->out.error_string = NULL;
- return NT_STATUS_NO_MEMORY;
- }
- *r->out.guid = lsa_query_info2.out.info->dns.domain_guid;
- } else {
- r->out.realm = NULL;
- r->out.guid = NULL;
+ composite_continue_rpc(c, query_info_req, continue_lsa_query_info2, c);
+}
+
+
+static void continue_lsa_query_info2(struct rpc_request *req)
+{
+ struct composite_context *c;
+ struct rpc_connect_dci_state *s;
+ struct rpc_request *query_info_req;
+
+ c = talloc_get_type(req->async.private, struct composite_context);
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ c->status = dcerpc_ndr_request_recv(req);
+ if (NT_STATUS_EQUAL(c->status, NT_STATUS_NET_WRITE_FAULT)) {
+ s->r.out.realm = NULL;
+ s->r.out.guid = NULL;
+
+ } else {
+ if (!NT_STATUS_IS_OK(c->status)) {
+ s->r.out.error_string = talloc_asprintf(c,
+ "lsa_QueryInfoPolicy2 failed: %s",
+ nt_errstr(c->status));
+ composite_error(c, c->status);
+ return;
}
-
- /* Grab the domain SID (regardless of the result of the previous call */
-
- lsa_query_info.in.handle = &lsa_p_handle;
- lsa_query_info.in.level = LSA_POLICY_INFO_DOMAIN;
-
- status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, tmp_ctx,
- &lsa_query_info);
-
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(r,
- "lsa_QueryInfoPolicy2 failed: %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
+
+ /* 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);
+ if (composite_nomem(s->r.out.guid, c)) {
+ s->r.out.error_string = NULL;
+ return;
}
-
- r->out.domain_sid = lsa_query_info.out.info->domain.sid;
- r->out.domain_name = lsa_query_info.out.info->domain.name.string;
- } else {
- /* Cause the code further down to try this with just SAMR */
- r->out.domain_sid = NULL;
- r->out.domain_name = NULL;
- r->out.realm = NULL;
+ *s->r.out.guid = s->lsa_query_info2.out.info->dns.domain_guid;
}
- /* Find the original binding string */
- final_binding = talloc(tmp_ctx, struct dcerpc_binding);
- if (!final_binding) {
- return NT_STATUS_NO_MEMORY;
+ s->lsa_query_info.in.handle = &s->lsa_handle;
+ s->lsa_query_info.in.level = LSA_POLICY_INFO_DOMAIN;
+
+ query_info_req = dcerpc_lsa_QueryInfoPolicy_send(s->lsa_pipe, c, &s->lsa_query_info);
+ if (composite_nomem(query_info_req, c)) return;
+
+ composite_continue_rpc(c, query_info_req, continue_lsa_query_info, c);
+}
+
+
+static void continue_lsa_query_info(struct rpc_request *req)
+{
+ struct composite_context *c, *epm_map_req;
+ struct rpc_connect_dci_state *s;
+
+ c = talloc_get_type(req->async.private, struct composite_context);
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ c->status = dcerpc_ndr_request_recv(req);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ s->r.out.error_string = talloc_asprintf(c,
+ "lsa_QueryInfoPolicy failed: %s",
+ nt_errstr(c->status));
+ composite_error(c, c->status);
+ return;
}
- *final_binding = *lsa_pipe->binding;
+
+ 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;
+
+ s->final_binding = talloc(s, struct dcerpc_binding);
+ if (composite_nomem(s->final_binding, c)) return;
+
+ *s->final_binding = *s->lsa_pipe->binding;
/* Ensure we keep hold of the member elements */
- talloc_reference(final_binding, lsa_pipe->binding);
-
- /* Make binding string for samr, not the other pipe */
- status = dcerpc_epm_map_binding(tmp_ctx, final_binding,
- r->in.dcerpc_iface,
- lsa_pipe->conn->event_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(r,
- "Failed to map pipe with endpoint mapper - %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
+ talloc_reference(s->final_binding, s->lsa_pipe->binding);
+
+ epm_map_req = dcerpc_epm_map_binding_send(c, s->final_binding, s->r.in.dcerpc_iface,
+ s->lsa_pipe->conn->event_ctx);
+ if (composite_nomem(epm_map_req, c)) return;
+
+ composite_continue(c, epm_map_req, continue_epm_map_binding, c);
+}
+
+
+static void continue_epm_map_binding(struct composite_context *ctx)
+{
+ struct composite_context *c, *sec_conn_req;
+ struct rpc_connect_dci_state *s;
+
+ c = talloc_get_type(ctx->async.private_data, struct composite_context);
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ c->status = dcerpc_epm_map_binding_recv(ctx);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ s->r.out.error_string = talloc_asprintf(c,
+ "failed to map pipe with endpoint mapper - %s",
+ nt_errstr(c->status));
+ composite_error(c, c->status);
+ return;
}
+
+ sec_conn_req = dcerpc_secondary_connection_send(s->lsa_pipe, s->final_binding);
+ if (composite_nomem(sec_conn_req, c)) return;
+
+ composite_continue(c, sec_conn_req, continue_secondary_conn, c);
+}
+
+
+static void continue_secondary_conn(struct composite_context *ctx)
+{
+ struct composite_context *c;
+ struct rpc_connect_dci_state *s;
+
+ c = talloc_get_type(ctx->async.private_data, struct composite_context);
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ c->status = dcerpc_secondary_connection_recv(ctx, &s->final_pipe);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ s->r.out.error_string = talloc_asprintf(c,
+ "secondary connection failed: %s",
+ nt_errstr(c->status));
+
+ composite_error(c, c->status);
+ return;
+ }
+
+ s->r.out.dcerpc_pipe = s->final_pipe;
+ composite_done(c);
+}
+
+
+struct composite_context* libnet_RpcConnectDCInfo_send(struct libnet_context *ctx,
+ TALLOC_CTX *mem_ctx,
+ struct libnet_RpcConnect *r)
+{
+ struct composite_context *c, *conn_req;
+ struct rpc_connect_dci_state *s;
+
+ c = talloc_zero(mem_ctx, struct composite_context);
+ if (c == NULL) return NULL;
+
+ s = talloc_zero(c, struct rpc_connect_dci_state);
+ if (composite_nomem(s, c)) return c;
+
+ c->state = COMPOSITE_STATE_IN_PROGRESS;
+ c->private_data = s;
+ c->event_ctx = ctx->event_ctx;
+
+ s->r = *r;
+ s->ctx = ctx;
+
+ s->rpc_conn.level = r->level;
- /* Now that we have the info setup a final connection to the pipe they wanted */
- status = dcerpc_secondary_connection(lsa_pipe, &final_pipe, final_binding);
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(r,
- "secondary connection failed: %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
+ if (r->in.binding == NULL) {
+ s->rpc_conn.in.name = r->in.name;
+ s->rpc_conn.level = LIBNET_RPC_CONNECT_DC;
+ } else {
+ s->rpc_conn.in.binding = r->in.binding;
+ s->rpc_conn.level = LIBNET_RPC_CONNECT_BINDING;
}
- r->out.dcerpc_pipe = final_pipe;
- talloc_steal(r, r->out.realm);
- talloc_steal(r, r->out.domain_sid);
- talloc_steal(r, r->out.domain_name);
- talloc_steal(r, r->out.dcerpc_pipe);
+ s->rpc_conn.in.dcerpc_iface = &dcerpc_table_lsarpc;
+
+ /* request connection to the lsa pipe on the pdc */
+ conn_req = libnet_RpcConnect_send(ctx, c, &s->rpc_conn);
+ if (composite_nomem(c, conn_req)) return c;
+
+ composite_continue(c, conn_req, continue_dci_rpc_connect, c);
- /* This should close the LSA pipe, which we don't need now we have the info */
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
+ return c;
}
+
+NTSTATUS libnet_RpcConnectDCInfo_recv(struct composite_context *c, struct libnet_context *ctx,
+ TALLOC_CTX *mem_ctx, struct libnet_RpcConnect *r)
+{
+ NTSTATUS status;
+ struct rpc_connect_dci_state *s;
+
+ status = composite_wait(c);
+ if (NT_STATUS_IS_OK(status)) {
+ s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
+
+ r->out.realm = talloc_steal(mem_ctx, s->r.out.realm);
+ r->out.domain_sid = talloc_steal(mem_ctx, s->r.out.domain_sid);
+ r->out.domain_name = talloc_steal(mem_ctx, s->r.out.domain_name);
+ r->out.dcerpc_pipe = talloc_steal(mem_ctx, s->r.out.dcerpc_pipe);
+ }
+
+ talloc_free(c);
+ return status;
+}
+
+
+/**
+ * Connects to rpc pipe on remote server or pdc, and returns info on the domain name, domain sid and realm
+ *
+ * @param ctx initialised libnet context
+ * @param r data structure containing necessary parameters and return values. Must be a talloc context
+ * @return nt status of the call
+ **/
+
+NTSTATUS libnet_RpcConnectDCInfo(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
+ struct libnet_RpcConnect *r)
+{
+ struct composite_context *c;
+
+ c = libnet_RpcConnectDCInfo_send(ctx, mem_ctx, r);
+ return libnet_RpcConnectDCInfo_recv(c, ctx, mem_ctx, r);
+}
diff --git a/source4/libnet/libnet_rpc.h b/source4/libnet/libnet_rpc.h
index 333881debd..33eaafc851 100644
--- a/source4/libnet/libnet_rpc.h
+++ b/source4/libnet/libnet_rpc.h
@@ -29,7 +29,9 @@ enum libnet_RpcConnect_level {
name to a pdc address before connecting) */
LIBNET_RPC_CONNECT_DC, /* connect to any DC (resolves domain
name to a DC address before connecting) */
- LIBNET_RPC_CONNECT_BINDING /* specified binding string */
+ LIBNET_RPC_CONNECT_BINDING, /* specified binding string */
+ LIBNET_RPC_CONNECT_DC_INFO /* connect to a DC and provide basic domain
+ information (name, realm, sid, guid) */
};
struct libnet_RpcConnect {
@@ -42,6 +44,15 @@ struct libnet_RpcConnect {
} in;
struct {
struct dcerpc_pipe *dcerpc_pipe;
+
+ /* parameters provided in LIBNET_RPC_CONNECT_DC_INFO level, null otherwise */
+ const char *domain_name;
+ struct dom_sid *domain_sid;
+
+ /* These parameters are only present if the remote server is known to be AD */
+ const char *realm;
+ struct GUID *guid;
+
const char *error_string;
} out;
};
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
index 5c5407df3e..04f9e000f4 100644
--- a/source4/libnet/libnet_vampire.c
+++ b/source4/libnet/libnet_vampire.c
@@ -157,7 +157,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
struct cli_credentials *machine_account;
struct dcerpc_pipe *p;
struct libnet_context *machine_net_ctx;
- struct libnet_RpcConnectDCInfo *c;
+ struct libnet_RpcConnect *c;
struct libnet_SamSync_state *state;
const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
int i;
@@ -193,21 +193,22 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
- c = talloc(samsync_ctx, struct libnet_RpcConnectDCInfo);
+ c = talloc(samsync_ctx, struct libnet_RpcConnect);
if (!c) {
r->out.error_string = NULL;
talloc_free(samsync_ctx);
return NT_STATUS_NO_MEMORY;
}
+ c->level = LIBNET_RPC_CONNECT_DC_INFO;
if (r->in.binding_string) {
- c->level = LIBNET_RPC_CONNECT_BINDING;
c->in.binding = r->in.binding_string;
+
} else {
- /* prepare connect to the NETLOGON pipe of PDC */
- c->level = LIBNET_RPC_CONNECT_PDC;
c->in.name = cli_credentials_get_domain(machine_account);
}
+
+ /* prepare connect to the NETLOGON pipe of PDC */
c->in.dcerpc_iface = &dcerpc_table_netlogon;
/* We must do this as the machine, not as any command-line
@@ -223,7 +224,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
machine_net_ctx->cred = machine_account;
/* connect to the NETLOGON pipe of the PDC */
- nt_status = libnet_RpcConnectDCInfo(machine_net_ctx, c);
+ nt_status = libnet_RpcConnect(machine_net_ctx, samsync_ctx, c);
if (!NT_STATUS_IS_OK(nt_status)) {
if (r->in.binding_string) {
r->out.error_string = talloc_asprintf(mem_ctx,