diff options
author | Andrew Bartlett <abartlet@samba.org> | 2006-10-13 13:01:48 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:21:00 -0500 |
commit | 57b8c5cd227d33b2eec34ed503b0b14c04344a87 (patch) | |
tree | ce7f660463f5273f3ff89eee4670216b1fc153ce /source4/libnet | |
parent | 541339fbd2d0d4154644c7a843adf56ec382afc4 (diff) | |
download | samba-57b8c5cd227d33b2eec34ed503b0b14c04344a87.tar.gz samba-57b8c5cd227d33b2eec34ed503b0b14c04344a87.tar.bz2 samba-57b8c5cd227d33b2eec34ed503b0b14c04344a87.zip |
r19266: Add a target_hostname element to the binding struct. This allows us
to perform a lookup once, resolve the name to an IP, while still
communicating the full name to the lower layers, for kerberos etc.
This fixes 'net samdump', which was failing due to the schannel target
name being *smbserver.
Andrew Bartlett
(This used to be commit 0546f487f4cc99b5549dc1e457ea243d4bd66333)
Diffstat (limited to 'source4/libnet')
-rw-r--r-- | source4/libnet/libnet_join.c | 2 | ||||
-rw-r--r-- | source4/libnet/libnet_rpc.c | 60 | ||||
-rw-r--r-- | source4/libnet/libnet_rpc.h | 19 |
3 files changed, 49 insertions, 32 deletions
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 5781bc19c2..57ecddd9da 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -229,7 +229,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J /* Now we know the user's DN, open with LDAP, read and modify a few things */ remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", - drsuapi_binding->host); + drsuapi_binding->target_hostname); if (!remote_ldb_url) { r->out.error_string = NULL; talloc_free(tmp_ctx); diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c index 53c8ba86a1..cedd0d07c0 100644 --- a/source4/libnet/libnet_rpc.c +++ b/source4/libnet/libnet_rpc.c @@ -53,6 +53,7 @@ static struct composite_context* libnet_RpcConnectSrv_send(struct libnet_context { struct composite_context *c; struct rpc_connect_srv_state *s; + struct dcerpc_binding *b; struct composite_context *pipe_connect_req; /* composite context allocation and setup */ @@ -72,16 +73,21 @@ static struct composite_context* libnet_RpcConnectSrv_send(struct libnet_context /* prepare binding string */ switch (r->level) { - case LIBNET_RPC_CONNECT_DC: - case LIBNET_RPC_CONNECT_PDC: case LIBNET_RPC_CONNECT_SERVER: s->binding = talloc_asprintf(s, "ncacn_np:%s", r->in.name); break; + case LIBNET_RPC_CONNECT_SERVER_ADDRESS: + s->binding = talloc_asprintf(s, "ncacn_np:%s", r->in.address); + break; case LIBNET_RPC_CONNECT_BINDING: s->binding = talloc_strdup(s, r->in.binding); break; + case LIBNET_RPC_CONNECT_DC: + case LIBNET_RPC_CONNECT_PDC: + /* this should never happen - DC and PDC level has a separate + composite function */ case LIBNET_RPC_CONNECT_DC_INFO: /* this should never happen - DC_INFO level has a separate composite function */ @@ -89,9 +95,23 @@ static struct composite_context* libnet_RpcConnectSrv_send(struct libnet_context return c; } + /* parse binding string to the structure */ + c->status = dcerpc_parse_binding(c, s->binding, &b); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", s->binding)); + composite_error(c, c->status); + return c; + } + + if (r->level == LIBNET_RPC_CONNECT_SERVER_ADDRESS) { + b->target_hostname = talloc_reference(b, r->in.name); + if (composite_nomem(b->target_hostname, c)) { + return c; + } + } + /* connect to remote dcerpc pipe */ - pipe_connect_req = dcerpc_pipe_connect_send(c, &s->r.out.dcerpc_pipe, - s->binding, r->in.dcerpc_iface, + pipe_connect_req = dcerpc_pipe_connect_b_send(c, b, r->in.dcerpc_iface, ctx->cred, c->event_ctx); if (composite_nomem(pipe_connect_req, c)) return c; @@ -112,7 +132,7 @@ static void continue_pipe_connect(struct composite_context *ctx) s = talloc_get_type(c->private_data, struct rpc_connect_srv_state); /* receive result of rpc pipe connection */ - c->status = dcerpc_pipe_connect_recv(ctx, c, &s->r.out.dcerpc_pipe); + c->status = dcerpc_pipe_connect_b_recv(ctx, c, &s->r.out.dcerpc_pipe); s->r.out.error_string = NULL; composite_done(c); @@ -237,7 +257,7 @@ static struct composite_context* libnet_RpcConnectDC_send(struct libnet_context /* - Step 2 of RpcConnectDC: get domain controller name/address and + Step 2 of RpcConnectDC: get domain controller name and initiate RpcConnect to it */ static void continue_lookup_dc(struct composite_context *ctx) @@ -256,19 +276,7 @@ static void continue_lookup_dc(struct composite_context *ctx) if (!composite_is_ok(c)) return; /* decide on preferred address type depending on DC type */ - switch (s->r.level) { - case LIBNET_RPC_CONNECT_PDC: - s->connect_name = s->f.out.dcs[0].name; - break; - - case LIBNET_RPC_CONNECT_DC: - s->connect_name = s->f.out.dcs[0].address; - break; - - default: - /* we shouldn't absolutely get here */ - composite_error(c, NT_STATUS_INVALID_LEVEL); - } + s->connect_name = s->f.out.dcs[0].name; /* prepare a monitor message and post it */ msg.type = net_lookup_dc; @@ -282,11 +290,12 @@ static void continue_lookup_dc(struct composite_context *ctx) if (s->monitor_fn) s->monitor_fn(&msg); /* ok, pdc has been found so do attempt to rpc connect */ - s->r2.level = s->r.level; + s->r2.level = LIBNET_RPC_CONNECT_SERVER_ADDRESS; /* this will cause yet another name resolution, but at least * we pass the right name down the stack now */ - s->r2.in.name = talloc_strdup(c, s->connect_name); + s->r2.in.name = talloc_strdup(s, s->connect_name); + s->r2.in.address = talloc_steal(s, s->f.out.dcs[0].address); s->r2.in.dcerpc_iface = s->r.in.dcerpc_iface; /* send rpc connect request to the server */ @@ -630,7 +639,7 @@ static void continue_lsa_query_info(struct rpc_request *req) *s->final_binding = *s->lsa_pipe->binding; /* Ensure we keep hold of the member elements */ - talloc_reference(s->final_binding, s->lsa_pipe->binding); + if (composite_nomem(talloc_reference(s->final_binding, s->lsa_pipe->binding), c)) return; epm_map_req = dcerpc_epm_map_binding_send(c, s->final_binding, s->r.in.dcerpc_iface, s->lsa_pipe->conn->event_ctx); @@ -735,7 +744,11 @@ static NTSTATUS libnet_RpcConnectDCInfo_recv(struct composite_context *c, struct } } else { - r->out.error_string = talloc_steal(mem_ctx, s->r.out.error_string); + if (s->r.out.error_string) { + r->out.error_string = talloc_steal(mem_ctx, s->r.out.error_string); + } else { + r->out.error_string = talloc_asprintf(mem_ctx, "Connection to DC failed: %s", nt_errstr(status)); + } } talloc_free(c); @@ -761,6 +774,7 @@ struct composite_context* libnet_RpcConnect_send(struct libnet_context *ctx, switch (r->level) { case LIBNET_RPC_CONNECT_SERVER: + case LIBNET_RPC_CONNECT_SERVER_ADDRESS: case LIBNET_RPC_CONNECT_BINDING: c = libnet_RpcConnectSrv_send(ctx, mem_ctx, r); break; diff --git a/source4/libnet/libnet_rpc.h b/source4/libnet/libnet_rpc.h index 178e1cc269..2663cec869 100644 --- a/source4/libnet/libnet_rpc.h +++ b/source4/libnet/libnet_rpc.h @@ -26,14 +26,16 @@ */ enum libnet_RpcConnect_level { - LIBNET_RPC_CONNECT_SERVER, /* connect to a standalone rpc server */ - LIBNET_RPC_CONNECT_PDC, /* connect to a domain pdc (resolves domain - 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_DC_INFO /* connect to a DC and provide basic domain - information (name, realm, sid, guid) */ + LIBNET_RPC_CONNECT_SERVER, /* connect to a standalone rpc server */ + LIBNET_RPC_CONNECT_SERVER_ADDRESS, /* connect to a standalone rpc server, + knowing both name and address */ + LIBNET_RPC_CONNECT_PDC, /* connect to a domain pdc (resolves domain + 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_DC_INFO /* connect to a DC and provide basic domain + information (name, realm, sid, guid) */ }; struct libnet_RpcConnect { @@ -41,6 +43,7 @@ struct libnet_RpcConnect { struct { const char *name; + const char *address; const char *binding; const struct dcerpc_interface_table *dcerpc_iface; } in; |