diff options
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r-- | source4/librpc/rpc/dcerpc_auth.c | 8 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_schannel.c | 125 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_smb.c | 16 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 207 |
4 files changed, 194 insertions, 162 deletions
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 1bcf4224c4..ac74788ba6 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -143,6 +143,7 @@ done: */ NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p, const char *uuid, uint_t version, + const char *workstation, const char *domain, const char *username, const char *password, @@ -161,6 +162,13 @@ NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p, return status; } + status = gensec_set_workstation(p->conn->security_state.generic_state, workstation); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client workstation name to %s: %s\n", + workstation, nt_errstr(status))); + return status; + } + status = gensec_set_domain(p->conn->security_state.generic_state, domain); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index d99d43ad58..170ddee1f3 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -33,7 +33,6 @@ struct dcerpc_schannel_state { enum schannel_position state; struct schannel_state *schannel_state; struct creds_CredentialState *creds; - char *account_name; }; /* @@ -104,7 +103,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, NTSTATUS status; struct schannel_bind bind_schannel; struct schannel_bind_ack bind_schannel_ack; - const char *account_name; + const char *workstation; + const char *domain; *out = data_blob(NULL, 0); switch (gensec_security->gensec_role) { @@ -114,7 +114,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, return NT_STATUS_OK; } - status = schannel_start(&dce_schan_state->schannel_state, + status = schannel_start(dce_schan_state, + &dce_schan_state->schannel_state, dce_schan_state->creds->session_key, True); if (!NT_STATUS_IS_OK(status)) { @@ -130,11 +131,11 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, bind_schannel.u.info23.domain = gensec_security->user.domain; bind_schannel.u.info23.account_name = gensec_security->user.name; bind_schannel.u.info23.dnsdomain = str_format_nbt_domain(out_mem_ctx, fulldomainname); - bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, gensec_security->user.name); + bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, gensec_get_workstation(gensec_security)); #else bind_schannel.bind_type = 3; bind_schannel.u.info3.domain = gensec_security->user.domain; - bind_schannel.u.info3.account_name = gensec_security->user.name; + bind_schannel.u.info3.workstation = gensec_get_workstation(gensec_security); #endif status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel, @@ -163,27 +164,29 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, } if (bind_schannel.bind_type == 23) { - account_name = bind_schannel.u.info23.account_name; + workstation = bind_schannel.u.info23.workstation; + domain = bind_schannel.u.info23.domain; } else { - account_name = bind_schannel.u.info3.account_name; + workstation = bind_schannel.u.info3.workstation; + domain = bind_schannel.u.info3.domain; } /* pull the session key for this client */ - status = schannel_fetch_session_key(out_mem_ctx, account_name, &dce_schan_state->creds); + status = schannel_fetch_session_key(out_mem_ctx, workstation, + domain, &dce_schan_state->creds); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not find session key for attempted schannel connection on %s: %s\n", - account_name, nt_errstr(status))); + DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", + workstation, nt_errstr(status))); return status; } - dce_schan_state->account_name = talloc_strdup(dce_schan_state, account_name); - /* start up the schannel server code */ - status = schannel_start(&dce_schan_state->schannel_state, + status = schannel_start(dce_schan_state, + &dce_schan_state->schannel_state, dce_schan_state->creds->session_key, False); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not initialise schannel state for account %s: %s\n", - account_name, nt_errstr(status))); + DEBUG(3, ("Could not initialise schannel state from client %s: %s\n", + workstation, nt_errstr(status))); return status; } talloc_steal(dce_schan_state, dce_schan_state->schannel_state); @@ -195,8 +198,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack, (ndr_push_flags_fn_t)ndr_push_schannel_bind_ack); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not return schannel bind ack for account %s: %s\n", - account_name, nt_errstr(status))); + DEBUG(3, ("Could not return schannel bind ack for client %s: %s\n", + workstation, nt_errstr(status))); return status; } @@ -248,18 +251,6 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, } -/* - end crypto state -*/ -static int dcerpc_schannel_destroy(void *ptr) -{ - struct dcerpc_schannel_state *dce_schan_state = ptr; - - schannel_end(&dce_schan_state->schannel_state); - - return 0; -} - static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security) { struct dcerpc_schannel_state *dce_schan_state; @@ -272,8 +263,6 @@ static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security) dce_schan_state->state = DCERPC_SCHANNEL_STATE_START; gensec_security->private_data = dce_schan_state; - talloc_set_destructor(dce_schan_state, dcerpc_schannel_destroy); - return NT_STATUS_OK; } @@ -306,6 +295,7 @@ static NTSTATUS dcerpc_schannel_client_start(struct gensec_security *gensec_secu get a schannel key using a netlogon challenge on a secondary pipe */ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, + const char *workstation, const char *domain, const char *username, const char *password, @@ -313,13 +303,15 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, struct creds_CredentialState *creds) { NTSTATUS status; + struct dcerpc_binding *b; struct dcerpc_pipe *p2; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate2 a; struct netr_Credential credentials1, credentials2, credentials3; struct samr_Password mach_pwd; - const char *workgroup, *workstation; + const char *workgroup; uint32_t negotiate_flags; + TALLOC_CTX *tmp_ctx; if (p->conn->flags & DCERPC_SCHANNEL_128) { negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; @@ -327,20 +319,45 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; } - workstation = username; workgroup = domain; + tmp_ctx = talloc_new(NULL); + /* step 1 - establish a netlogon connection, with no authentication */ - status = dcerpc_secondary_connection(p, &p2, - DCERPC_NETLOGON_NAME, - DCERPC_NETLOGON_UUID, - DCERPC_NETLOGON_VERSION); + + /* Find the original binding string */ + status = dcerpc_parse_binding(tmp_ctx, p->conn->binding_string, &b); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string)); + talloc_free(tmp_ctx); return status; } + /* Make binding string for netlogon, not the other pipe */ + status = dcerpc_epm_map_binding(tmp_ctx, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n", + DCERPC_NETLOGON_UUID, nt_errstr(status))); + talloc_free(p); + return status; + } + + status = dcerpc_secondary_connection(p, &p2, b); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + talloc_free(tmp_ctx); + + status = dcerpc_bind_auth_none(p2, DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(p2); + return status; + } /* step 2 - request a netlogon challenge @@ -361,11 +378,13 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, step 3 - authenticate on the netlogon pipe */ E_md4hash(password, mach_pwd.hash); - creds_client_init(creds, &credentials1, &credentials2, &mach_pwd, &credentials3, + creds_client_init(creds, &credentials1, &credentials2, + workstation, domain, username, + &mach_pwd, &credentials3, negotiate_flags); a.in.server_name = r.in.server_name; - a.in.account_name = talloc_asprintf(p, "%s$", workstation); + a.in.account_name = username; a.in.secure_channel_type = chan_type; a.in.computer_name = workstation; a.in.negotiate_flags = &negotiate_flags; @@ -398,9 +417,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, */ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, const char *uuid, uint_t version, - const char *domain, - const char *username, - const char *password, struct creds_CredentialState *creds) { NTSTATUS status; @@ -411,17 +427,28 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, return status; } - status = gensec_set_username(p->conn->security_state.generic_state, username); + status = gensec_set_workstation(p->conn->security_state.generic_state, creds->computer_name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set schannel workstation to %s: %s\n", + creds->computer_name, nt_errstr(status))); + talloc_free(p->conn->security_state.generic_state); + p->conn->security_state.generic_state = NULL; + return status; + } + + status = gensec_set_username(p->conn->security_state.generic_state, creds->account_name); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status))); + DEBUG(1, ("Failed to set schannel username to %s: %s\n", + creds->account_name, nt_errstr(status))); talloc_free(p->conn->security_state.generic_state); p->conn->security_state.generic_state = NULL; return status; } - status = gensec_set_domain(p->conn->security_state.generic_state, domain); + status = gensec_set_domain(p->conn->security_state.generic_state, creds->domain); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set schannel domain to %s: %s\n", domain, nt_errstr(status))); + DEBUG(1, ("Failed to set schannel domain to %s: %s\n", + creds->domain, nt_errstr(status))); talloc_free(p->conn->security_state.generic_state); p->conn->security_state.generic_state = NULL; return status; @@ -456,6 +483,7 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, const char *uuid, uint_t version, + const char *workstation, const char *domain, const char *username, const char *password) @@ -477,6 +505,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, } status = dcerpc_schannel_key(p, domain, + workstation, username, password, chan_type, @@ -488,9 +517,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, return status; } - return dcerpc_bind_auth_schannel_withkey(p, uuid, version, domain, - username, password, - creds); + return dcerpc_bind_auth_schannel_withkey(p, uuid, version, creds); } static BOOL dcerpc_schannel_have_feature(struct gensec_security *gensec_security, diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index aa2d0bf20f..1a5a31c330 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -375,7 +375,19 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c, struct smb_private *smb; NTSTATUS status; union smb_open io; + char *pipe_name_talloc; + if (!strncasecmp(pipe_name, "/pipe/", 6) || + !strncasecmp(pipe_name, "\\pipe\\", 6)) { + pipe_name += 6; + } + + if (pipe_name[0] != '\\') { + pipe_name_talloc = talloc_asprintf(NULL, "\\%s", pipe_name); + } else { + pipe_name_talloc = talloc_strdup(NULL, pipe_name); + } + io.ntcreatex.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.flags = 0; io.ntcreatex.in.root_fid = 0; @@ -394,10 +406,12 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c, io.ntcreatex.in.create_options = 0; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; io.ntcreatex.in.security_flags = 0; - io.ntcreatex.in.fname = pipe_name; + io.ntcreatex.in.fname = pipe_name_talloc; status = smb_raw_open(tree, tree, &io); + talloc_free(pipe_name_talloc); + if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 7b753d1b30..91e6ea9397 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -323,12 +323,18 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi /* parse a binding string into a dcerpc_binding structure */ -NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding *b) +NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out) { + struct dcerpc_binding *b; char *options, *type; char *p; int i, j, comma_count; + b = talloc(mem_ctx, struct dcerpc_binding); + if (!b) { + return NT_STATUS_NO_MEMORY; + } + p = strchr(s, '@'); if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ @@ -373,14 +379,14 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ p = strchr(s, '['); if (p) { - b->host = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); + b->host = talloc_strndup(b, s, PTR_DIFF(p, s)); options = talloc_strdup(mem_ctx, p+1); if (options[strlen(options)-1] != ']') { return NT_STATUS_INVALID_PARAMETER; } options[strlen(options)-1] = 0; } else { - b->host = talloc_strdup(mem_ctx, s); + b->host = talloc_strdup(b, s); options = NULL; } @@ -393,18 +399,19 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ b->endpoint = NULL; if (!options) { + *b_out = b; return NT_STATUS_OK; } comma_count = count_chars(options, ','); - b->options = talloc_array(mem_ctx, const char *, comma_count+2); + b->options = talloc_array(b, const char *, comma_count+2); if (!b->options) { return NT_STATUS_NO_MEMORY; } for (i=0; (p = strchr(options, ',')); i++) { - b->options[i] = talloc_strndup(mem_ctx, options, PTR_DIFF(p, options)); + b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options)); if (!b->options[i]) { return NT_STATUS_NO_MEMORY; } @@ -441,6 +448,7 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ if (b->options[0] == NULL) b->options = NULL; + *b_out = b; return NT_STATUS_OK; } @@ -657,9 +665,13 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower) return -1; } -NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding *binding) +NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding **b_out) { NTSTATUS status; + struct dcerpc_binding *binding; + + binding = talloc(mem_ctx, struct dcerpc_binding); + NT_STATUS_HAVE_NO_MEMORY(binding); ZERO_STRUCT(binding->object); binding->options = NULL; @@ -699,6 +711,7 @@ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, if (tower->num_floors >= 5) { binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]); } + *b_out = binding; return NT_STATUS_OK; } @@ -773,7 +786,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding * } NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, - const char *uuid, uint_t version) + const char *uuid, uint_t version) { struct dcerpc_pipe *p; NTSTATUS status; @@ -781,42 +794,51 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind struct policy_handle handle; struct GUID guid; struct epm_twr_t twr, *twr_r; - struct dcerpc_binding epmapper_binding; + struct dcerpc_binding *epmapper_binding; const struct dcerpc_interface_table *table = idl_iface_by_uuid(uuid); int i; /* First, check if there is a default endpoint specified in the IDL */ if (table) { - struct dcerpc_binding default_binding; + struct dcerpc_binding *default_binding; - binding->authservice = talloc_strdup(mem_ctx, table->authservices->names[0]); + binding->authservice = talloc_strdup(binding, table->authservices->names[0]); /* Find one of the default pipes for this interface */ for (i = 0; i < table->endpoints->count; i++) { status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding); - if (NT_STATUS_IS_OK(status) && default_binding.transport == binding->transport && default_binding.endpoint) { - binding->endpoint = talloc_strdup(mem_ctx, default_binding.endpoint); - return NT_STATUS_OK; + if (NT_STATUS_IS_OK(status)) { + if (default_binding->transport == binding->transport && default_binding->endpoint) { + binding->endpoint = talloc_reference(binding, default_binding->endpoint); + talloc_free(default_binding); + return NT_STATUS_OK; + } else { + talloc_free(default_binding); + } } } } + epmapper_binding = talloc_zero(mem_ctx, struct dcerpc_binding); + if (!epmapper_binding) { + return NT_STATUS_NO_MEMORY; + } - ZERO_STRUCT(epmapper_binding); - epmapper_binding.transport = binding->transport; - epmapper_binding.host = binding->host; - epmapper_binding.options = NULL; - epmapper_binding.flags = 0; - epmapper_binding.endpoint = NULL; - epmapper_binding.authservice = NULL; + epmapper_binding->transport = binding->transport; + epmapper_binding->host = talloc_reference(epmapper_binding, + binding->host); + epmapper_binding->options = NULL; + epmapper_binding->flags = 0; + epmapper_binding->endpoint = NULL; + epmapper_binding->authservice = NULL; status = dcerpc_pipe_connect_b(&p, - &epmapper_binding, - DCERPC_EPMAPPER_UUID, - DCERPC_EPMAPPER_VERSION, - NULL, NULL, NULL); + epmapper_binding, + DCERPC_EPMAPPER_UUID, + DCERPC_EPMAPPER_VERSION, + NULL, NULL, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { return status; @@ -866,7 +888,7 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind return NT_STATUS_PORT_UNREACHABLE; } - binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &twr_r->tower.floors[3]); + binding->endpoint = talloc_reference(binding, dcerpc_floor_get_rhs_data(mem_ctx, &twr_r->tower.floors[3])); dcerpc_pipe_close(p); @@ -877,13 +899,14 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind /* perform an authenticated bind if needed */ -static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, - struct dcerpc_binding *binding, - const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) +NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, + struct dcerpc_binding *binding, + const char *pipe_uuid, + uint32_t pipe_version, + const char *workstation, + const char *domain, + const char *username, + const char *password) { NTSTATUS status; p->conn->flags = binding->flags; @@ -893,7 +916,8 @@ static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) { status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, - domain, username, password); + domain, workstation, + username, password); } else if (username && username[0]) { uint8_t auth_type; if (binding->flags & DCERPC_AUTH_SPNEGO) { @@ -905,6 +929,7 @@ static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, } status = dcerpc_bind_auth_password(p, pipe_uuid, pipe_version, + workstation, domain, username, password, auth_type, binding->authservice); @@ -925,6 +950,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, uint32_t pipe_version, + const char *workstation, const char *domain, const char *username, const char *password) @@ -957,23 +983,14 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, pipe_name = binding->endpoint; - if (!strncasecmp(pipe_name, "/pipe/", 6) || - !strncasecmp(pipe_name, "\\pipe\\", 6)) { - pipe_name += 6; - } - - if (pipe_name[0] != '\\') { - pipe_name = talloc_asprintf(tmp_ctx, "\\%s", pipe_name); - } - if (!username || !username[0] || (binding->flags & DCERPC_SCHANNEL_ANY)) { - status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(), + status = smbcli_full_connection(p->conn, &cli, workstation, binding->host, "ipc$", NULL, "", "", NULL); } else { - status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(), + status = smbcli_full_connection(p->conn, &cli, workstation, binding->host, "ipc$", NULL, username, domain, @@ -995,12 +1012,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, if (!(binding->flags & DCERPC_AUTH_OPTIONS)) { username = NULL; } - - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } (*pp) = p; talloc_free(tmp_ctx); @@ -1013,10 +1024,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) + uint32_t pipe_version) { NTSTATUS status; struct dcerpc_pipe *p; @@ -1050,12 +1058,6 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp, return status; } - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } - (*pp) = p; talloc_free(tmp_ctx); @@ -1069,10 +1071,7 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp, static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) + uint32_t pipe_version) { NTSTATUS status; struct dcerpc_pipe *p; @@ -1097,12 +1096,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp, return status; } - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } - (*pp) = p; return status; @@ -1113,10 +1106,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp, static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) + uint32_t pipe_version) { NTSTATUS status; uint32_t port = 0; @@ -1153,12 +1143,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp, return status; } - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } - (*pp) = p; talloc_free(tmp_ctx); @@ -1172,33 +1156,42 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, uint32_t pipe_version, + const char *workstation, const char *domain, const char *username, const char *password) { NTSTATUS status = NT_STATUS_INVALID_PARAMETER; - + switch (binding->transport) { case NCACN_NP: status = dcerpc_pipe_connect_ncacn_np(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + workstation, domain, username, password); break; case NCACN_IP_TCP: - status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version); break; case NCACN_UNIX_STREAM: - status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version); break; case NCALRPC: - status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version); break; default: return NT_STATUS_NOT_SUPPORTED; } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = dcerpc_pipe_auth(*pp, binding, pipe_uuid, pipe_version, workstation, domain, username, password); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(*pp); + *pp = NULL; + return status; + } + return status; } @@ -1209,15 +1202,19 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp, const char *binding, const char *pipe_uuid, uint32_t pipe_version, + const char *workstation, const char *domain, const char *username, const char *password) { - struct dcerpc_binding b; + struct dcerpc_binding *b; NTSTATUS status; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return NT_STATUS_NO_MEMORY; + } status = dcerpc_parse_binding(tmp_ctx, binding, &b); if (!NT_STATUS_IS_OK(status)) { @@ -1226,9 +1223,10 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp, return status; } - DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b))); + DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, b))); - status = dcerpc_pipe_connect_b(pp, &b, pipe_uuid, pipe_version, domain, username, password); + status = dcerpc_pipe_connect_b(pp, b, pipe_uuid, pipe_version, workstation, + domain, username, password); talloc_free(tmp_ctx); @@ -1243,13 +1241,12 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp, will be on the same SMB connection, but use a new fnum */ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe **p2, - const char *pipe_name, - const char *pipe_uuid, - uint32_t pipe_version) + struct dcerpc_binding *b) + + { struct smbcli_tree *tree; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; - struct dcerpc_binding b; (*p2) = dcerpc_pipe_init(p); if (*p2 == NULL) { @@ -1262,23 +1259,15 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe * if (!tree) { return NT_STATUS_INVALID_PARAMETER; } - status = dcerpc_pipe_open_smb((*p2)->conn, tree, pipe_name); + status = dcerpc_pipe_open_smb((*p2)->conn, tree, b->endpoint); break; case NCACN_IP_TCP: - status = dcerpc_parse_binding(p, p->conn->binding_string, &b); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = dcerpc_pipe_open_tcp((*p2)->conn, b.host, atoi(b.endpoint)); + status = dcerpc_pipe_open_tcp((*p2)->conn, b->host, atoi(b->endpoint)); break; case NCALRPC: - status = dcerpc_parse_binding(p, p->conn->binding_string, &b); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = dcerpc_pipe_open_pipe((*p2)->conn, b.endpoint); + status = dcerpc_pipe_open_pipe((*p2)->conn, b->endpoint); break; default: @@ -1292,12 +1281,6 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe * (*p2)->conn->flags = p->conn->flags; - status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(*p2); - return status; - } - return NT_STATUS_OK; } |