diff options
Diffstat (limited to 'source')
44 files changed, 714 insertions, 542 deletions
diff --git a/source/client/client.c b/source/client/client.c index 59311a35d85..0ebebf747e2 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -2558,6 +2558,7 @@ static BOOL browse_host(const char *query_host) status = dcerpc_pipe_connect(&p, binding, DCERPC_SRVSVC_UUID, DCERPC_SRVSVC_VERSION, + lp_netbios_name(), domain, username, password); if (!NT_STATUS_IS_OK(status)) { diff --git a/source/gtk/tools/gepdump.c b/source/gtk/tools/gepdump.c index d445dd63cbe..eeb927e43fc 100644 --- a/source/gtk/tools/gepdump.c +++ b/source/gtk/tools/gepdump.c @@ -77,7 +77,7 @@ static const char *get_protocol_name(enum epm_protocol protocol) static void add_epm_entry(TALLOC_CTX *mem_ctx, const char *annotation, struct epm_tower *t) { - struct dcerpc_binding bd; + struct dcerpc_binding *bd; int i; NTSTATUS status; GtkTreeIter toweriter; @@ -89,10 +89,10 @@ static void add_epm_entry(TALLOC_CTX *mem_ctx, const char *annotation, struct ep } /* Don't show UUID's */ - ZERO_STRUCT(bd.object); + ZERO_STRUCT(bd->object); gtk_tree_store_append(store_eps, &toweriter, NULL); - gtk_tree_store_set(store_eps, &toweriter, 0, strdup(annotation), 1, strdup(dcerpc_binding_string(mem_ctx, &bd)), 2, t, -1); + gtk_tree_store_set(store_eps, &toweriter, 0, strdup(annotation), 1, strdup(dcerpc_binding_string(mem_ctx, bd)), 2, t, -1); for (i = 0; i < t->num_floors; i++) { const char *data; @@ -187,7 +187,9 @@ static void on_connect_clicked(GtkButton *btn, gpointer user_data) mem_ctx = talloc_init("connect"); bs = gtk_rpc_binding_dialog_get_binding_string (d, mem_ctx); - status = dcerpc_pipe_connect(&epmapper_pipe, bs, DCERPC_EPMAPPER_UUID, DCERPC_EPMAPPER_VERSION, lp_workgroup(), "", ""); + status = dcerpc_pipe_connect(&epmapper_pipe, bs, + DCERPC_EPMAPPER_UUID, DCERPC_EPMAPPER_VERSION, + lp_netbios_name(), lp_workgroup(), "", ""); if (NT_STATUS_IS_ERR(status)) { gtk_show_ntstatus(mainwin, status); diff --git a/source/gtk/tools/gwcrontab.c b/source/gtk/tools/gwcrontab.c index 69ef2d7965b..3212821c18a 100644 --- a/source/gtk/tools/gwcrontab.c +++ b/source/gtk/tools/gwcrontab.c @@ -104,12 +104,13 @@ on_connect_activate (GtkMenuItem *menuitem, /* If connected, get list of jobs */ status = dcerpc_pipe_connect_b(&at_pipe, - gtk_rpc_binding_dialog_get_binding(d, mem_ctx), - DCERPC_ATSVC_UUID, - DCERPC_ATSVC_VERSION, - gtk_rpc_binding_dialog_get_userdomain(d), - gtk_rpc_binding_dialog_get_username(d), - gtk_rpc_binding_dialog_get_password(d)); + gtk_rpc_binding_dialog_get_binding(d, mem_ctx), + DCERPC_ATSVC_UUID, + DCERPC_ATSVC_VERSION, + lp_netbios_name(), + gtk_rpc_binding_dialog_get_userdomain(d), + gtk_rpc_binding_dialog_get_username(d), + gtk_rpc_binding_dialog_get_password(d)); if(!NT_STATUS_IS_OK(status)) { gtk_show_ntstatus(mainwin, status); diff --git a/source/gtk/tools/gwsam.c b/source/gtk/tools/gwsam.c index 69c8dbc3611..1a6bc37f2f8 100644 --- a/source/gtk/tools/gwsam.c +++ b/source/gtk/tools/gwsam.c @@ -129,11 +129,12 @@ static void connect_sam(void) mem_ctx = talloc_init("gwsam_connect"); /* If connected, get list of jobs */ status = dcerpc_pipe_connect_b(&sam_pipe, - gtk_rpc_binding_dialog_get_binding(d, mem_ctx), - DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION, - gtk_rpc_binding_dialog_get_userdomain(d), - gtk_rpc_binding_dialog_get_username(d), - gtk_rpc_binding_dialog_get_password(d)); + gtk_rpc_binding_dialog_get_binding(d, mem_ctx), + DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION, + lp_netbios_name(), + gtk_rpc_binding_dialog_get_userdomain(d), + gtk_rpc_binding_dialog_get_username(d), + gtk_rpc_binding_dialog_get_password(d)); if(!NT_STATUS_IS_OK(status)) { gtk_show_ntstatus(mainwin, status); diff --git a/source/lib/com/dcom/main.c b/source/lib/com/dcom/main.c index 4d9c635be84..d3d44edc71c 100644 --- a/source/lib/com/dcom/main.c +++ b/source/lib/com/dcom/main.c @@ -40,11 +40,15 @@ struct dcom_client_context *dcom_client_init(struct com_context *ctx, const char return ctx->dcom; } -static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dcerpc_binding *b, struct STRINGBINDING *bd) +static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dcerpc_binding **b_out, struct STRINGBINDING *bd) { char *host, *endpoint; + struct dcerpc_binding *b; - ZERO_STRUCTP(b); + b = talloc_zero(mem_ctx, struct dcerpc_binding); + if (!b) { + return NT_STATUS_NO_MEMORY; + } b->transport = dcerpc_transport_by_endpoint_protocol(bd->wTowerId); @@ -53,7 +57,7 @@ static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dc return NT_STATUS_NOT_SUPPORTED; } - host = talloc_strdup(mem_ctx, bd->NetworkAddr); + host = talloc_strdup(b, bd->NetworkAddr); endpoint = strchr(host, '['); if (endpoint) { @@ -64,56 +68,61 @@ static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dc } b->host = host; - b->endpoint = endpoint; + b->endpoint = talloc_strdup(b, endpoint); + *b_out = b; return NT_STATUS_OK; } static NTSTATUS dcom_connect_host(struct com_context *ctx, struct dcerpc_pipe **p, const char *server) { - struct dcerpc_binding bd; - enum dcerpc_transport_t available_transports[] = { NCACN_IP_TCP, NCACN_NP }; + struct dcerpc_binding *bd; + const char * available_transports[] = { "ncacn_ip_tcp", "ncacn_np" }; int i; NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_init("dcom_connect"); if (server == NULL) { - bd.transport = NCALRPC; - return dcerpc_pipe_connect_b(p, &bd, - DCERPC_IREMOTEACTIVATION_UUID, - DCERPC_IREMOTEACTIVATION_VERSION, - ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password); + return dcerpc_pipe_connect(p, "ncalrpc", + DCERPC_IREMOTEACTIVATION_UUID, + DCERPC_IREMOTEACTIVATION_VERSION, + lp_netbios_name(), + ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password); } /* Allow server name to contain a binding string */ if (NT_STATUS_IS_OK(dcerpc_parse_binding(mem_ctx, server, &bd))) { - status = dcerpc_pipe_connect_b(p, &bd, - DCERPC_IREMOTEACTIVATION_UUID, - DCERPC_IREMOTEACTIVATION_VERSION, - ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password); + status = dcerpc_pipe_connect_b(p, bd, + DCERPC_IREMOTEACTIVATION_UUID, + DCERPC_IREMOTEACTIVATION_VERSION, + lp_netbios_name(), + ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password); talloc_free(mem_ctx); return status; } - talloc_free(mem_ctx); - ZERO_STRUCT(bd); - bd.host = server; - for (i = 0; i < ARRAY_SIZE(available_transports); i++) { - bd.transport = available_transports[i]; + char *binding = talloc_asprintf(mem_ctx, "%s:%s", available_transports[i], server); + if (!binding) { + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } - status = dcerpc_pipe_connect_b(p, &bd, - DCERPC_IREMOTEACTIVATION_UUID, - DCERPC_IREMOTEACTIVATION_VERSION, - ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password); + status = dcerpc_pipe_connect(p, binding, + DCERPC_IREMOTEACTIVATION_UUID, + DCERPC_IREMOTEACTIVATION_VERSION, + lp_netbios_name(), + ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password); if (NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); return status; } } + talloc_free(mem_ctx); return status; } @@ -254,7 +263,7 @@ WERROR dcom_get_class_object(struct com_context *ctx, struct GUID *clsid, const NTSTATUS dcom_get_pipe (struct IUnknown *iface, struct dcerpc_pipe **pp) { - struct dcerpc_binding binding; + struct dcerpc_binding *binding; struct GUID iid; uint64_t oxid; NTSTATUS status; @@ -297,14 +306,16 @@ NTSTATUS dcom_get_pipe (struct IUnknown *iface, struct dcerpc_pipe **pp) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Error parsing string binding")); } else { - status = dcerpc_pipe_connect_b(&p, &binding, + status = dcerpc_pipe_connect_b(&p, binding, uuid, 0.0, - iface->ctx->dcom->domain, iface->ctx->dcom->user, + lp_netbios_name(), + iface->ctx->dcom->domain, + iface->ctx->dcom->user, iface->ctx->dcom->password); } - + talloc_free(binding); i++; - } while (NT_STATUS_IS_ERR(status) && ox->bindings.stringbindings[i]); + } while (!NT_STATUS_IS_OK(status) && ox->bindings.stringbindings[i]); if (NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Unable to connect to remote host - %s\n", nt_errstr(status))); diff --git a/source/lib/registry/reg_backend_rpc.c b/source/lib/registry/reg_backend_rpc.c index 23024165545..4a285262c60 100644 --- a/source/lib/registry/reg_backend_rpc.c +++ b/source/lib/registry/reg_backend_rpc.c @@ -384,6 +384,7 @@ WERROR reg_open_remote (struct registry_context **ctx, const char *user, const c status = dcerpc_pipe_connect(&p, location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, + lp_netbios_name(), lp_workgroup(), user, pass); (*ctx)->backend_data = p; diff --git a/source/libcli/auth/credentials.c b/source/libcli/auth/credentials.c index bcb462ae9da..90b8313c9d8 100644 --- a/source/libcli/auth/credentials.c +++ b/source/libcli/auth/credentials.c @@ -192,12 +192,18 @@ next comes the client specific functions void creds_client_init(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, + const char *computer_name, + const char *domain, + const char *account_name, const struct samr_Password *machine_password, struct netr_Credential *initial_credential, uint32_t negotiate_flags) { creds->sequence = time(NULL); creds->negotiate_flags = negotiate_flags; + creds->computer_name = talloc_strdup(creds, computer_name); + creds->domain = talloc_strdup(creds, domain); + creds->account_name = talloc_strdup(creds, account_name); dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); diff --git a/source/libcli/auth/credentials.h b/source/libcli/auth/credentials.h index d1417bf83e7..6ce3288b014 100644 --- a/source/libcli/auth/credentials.h +++ b/source/libcli/auth/credentials.h @@ -30,6 +30,7 @@ struct creds_CredentialState { struct netr_Credential client; struct netr_Credential server; uint16_t secure_channel_type; + const char *domain; const char *computer_name; const char *account_name; uint32_t rid; diff --git a/source/libcli/auth/gensec.c b/source/libcli/auth/gensec.c index e0fa27359a2..d3fa7daae3d 100644 --- a/source/libcli/auth/gensec.c +++ b/source/libcli/auth/gensec.c @@ -148,7 +148,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense * @param mem_ctx The parent TALLOC memory context. * @param parent The parent GENSEC context * @param gensec_security Returned GENSEC context pointer. - * @note Used by SPENGO in particular, for the actual implementation mechanism + * @note Used by SPNEGO in particular, for the actual implementation mechanism */ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, @@ -618,6 +618,34 @@ const char *gensec_get_domain(struct gensec_security *gensec_security) } /** + * Set the client workstation on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_workstation(struct gensec_security *gensec_security, const char *workstation) +{ + gensec_security->user.workstation = talloc_strdup(gensec_security, workstation); + if (!gensec_security->user.workstation) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Return the client workstation on a GENSEC context - ensures it is talloc()ed + * + */ + +const char *gensec_get_workstation(struct gensec_security *gensec_security) +{ + if (gensec_security->user.workstation) { + return gensec_security->user.workstation; + } else { + return lp_netbios_name(); + } +} + +/** * Set a kerberos realm on a GENSEC context - ensures it is talloc()ed * */ diff --git a/source/libcli/auth/gensec.h b/source/libcli/auth/gensec.h index a555584840e..a4383d852c5 100644 --- a/source/libcli/auth/gensec.h +++ b/source/libcli/auth/gensec.h @@ -29,6 +29,7 @@ struct gensec_security; struct gensec_user { + const char *workstation; const char *domain; const char *realm; const char *name; @@ -59,7 +60,7 @@ struct gensec_security_ops { const char *name; const char *sasl_name; uint8_t auth_type; /* 0 if not offered on DCE-RPC */ - const char *oid; /* NULL if not offered by SPENGO */ + const char *oid; /* NULL if not offered by SPNEGO */ NTSTATUS (*client_start)(struct gensec_security *gensec_security); NTSTATUS (*server_start)(struct gensec_security *gensec_security); NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, diff --git a/source/libcli/auth/gensec_ntlmssp.c b/source/libcli/auth/gensec_ntlmssp.c index 524815382d6..51456d91070 100644 --- a/source/libcli/auth/gensec_ntlmssp.c +++ b/source/libcli/auth/gensec_ntlmssp.c @@ -245,6 +245,9 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur NT_STATUS_NOT_OK_RETURN(nt_status); } + nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state, + gensec_get_workstation(gensec_security)); + gensec_security->private_data = gensec_ntlmssp_state; return NT_STATUS_OK; diff --git a/source/libcli/auth/ntlmssp.c b/source/libcli/auth/ntlmssp.c index 572ce66bb2e..91bc9eadbd8 100644 --- a/source/libcli/auth/ntlmssp.c +++ b/source/libcli/auth/ntlmssp.c @@ -194,7 +194,7 @@ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *dom NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) { ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation); - if (!ntlmssp_state->domain) { + if (!ntlmssp_state->workstation) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; @@ -346,7 +346,7 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, *chal_flags |= NTLMSSP_REQUEST_TARGET; if (ntlmssp_state->server_role == ROLE_STANDALONE) { *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; - return ntlmssp_state->get_global_myname(); + return ntlmssp_state->server_name; } else { *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; return ntlmssp_state->get_domain(); @@ -531,7 +531,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, msrpc_gen(out_mem_ctx, &struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, - NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name, NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, 0, ""); @@ -923,7 +923,9 @@ NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmss (*ntlmssp_state)->set_challenge = set_challenge; (*ntlmssp_state)->may_set_challenge = may_set_challenge; - (*ntlmssp_state)->get_global_myname = lp_netbios_name; + (*ntlmssp_state)->workstation = NULL; + (*ntlmssp_state)->server_name = lp_netbios_name(); + (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ @@ -990,7 +992,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, ntlmssp_state->get_domain(), - ntlmssp_state->get_global_myname()); + ntlmssp_state->workstation); ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; @@ -1240,7 +1242,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, nt_response.data, nt_response.length, ntlmssp_state->domain, ntlmssp_state->user, - ntlmssp_state->get_global_myname(), + ntlmssp_state->workstation, encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { @@ -1279,7 +1281,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmss (*ntlmssp_state)->role = NTLMSSP_CLIENT; - (*ntlmssp_state)->get_global_myname = lp_netbios_name; + (*ntlmssp_state)->workstation = lp_netbios_name(); (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True); diff --git a/source/libcli/auth/ntlmssp.h b/source/libcli/auth/ntlmssp.h index e8a2356e2c8..e17c133c8ba 100644 --- a/source/libcli/auth/ntlmssp.h +++ b/source/libcli/auth/ntlmssp.h @@ -95,7 +95,7 @@ struct ntlmssp_state char *user; char *domain; - char *workstation; + const char *workstation; char *password; char *server_domain; @@ -161,7 +161,7 @@ struct ntlmssp_state */ NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); - const char *(*get_global_myname)(void); + const char *server_name; const char *(*get_domain)(void); /* SMB Signing */ diff --git a/source/libcli/auth/schannel.c b/source/libcli/auth/schannel.c index 92442234bda..a5521d46263 100644 --- a/source/libcli/auth/schannel.c +++ b/source/libcli/auth/schannel.c @@ -272,24 +272,14 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state, } /* - destroy an schannel context - */ -void schannel_end(struct schannel_state **state) -{ - if (*state) { - talloc_free(*state); - (*state) = NULL; - } -} - -/* create an schannel context state */ -NTSTATUS schannel_start(struct schannel_state **state, +NTSTATUS schannel_start(TALLOC_CTX *mem_ctx, + struct schannel_state **state, const uint8_t session_key[16], BOOL initiator) { - (*state) = talloc(NULL, struct schannel_state); + (*state) = talloc(mem_ctx, struct schannel_state); if (!(*state)) { return NT_STATUS_NO_MEMORY; } diff --git a/source/libcli/auth/schannel_state.c b/source/libcli/auth/schannel_state.c index 2a9e0a3ec39..b2d632a1f0e 100644 --- a/source/libcli/auth/schannel_state.c +++ b/source/libcli/auth/schannel_state.c @@ -127,6 +127,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, ldb_msg_add_string(ldb, msg, "secureChannelType", sct); ldb_msg_add_string(ldb, msg, "accountName", creds->account_name); ldb_msg_add_string(ldb, msg, "computerName", creds->computer_name); + ldb_msg_add_string(ldb, msg, "flatname", creds->domain); ldb_msg_add_string(ldb, msg, "rid", rid); ldb_delete(ldb, msg->dn); @@ -155,6 +156,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, */ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, const char *computer_name, + const char *domain, struct creds_CredentialState **creds) { struct ldb_context *ldb; @@ -174,7 +176,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - expr = talloc_asprintf(mem_ctx, "(dn=computerName=%s)", computer_name); + expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", computer_name, domain); if (expr == NULL) { talloc_free(ldb); return NT_STATUS_NO_MEMORY; @@ -217,6 +219,8 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL)); + (*creds)->domain = talloc_reference(*creds, ldb_msg_find_string(res[0], "flatname", NULL)); + (*creds)->rid = ldb_msg_find_uint(res[0], "rid", 0); talloc_free(ldb); diff --git a/source/libnet/libnet_rpc.c b/source/libnet/libnet_rpc.c index 48f5e345f46..97660f4eb5e 100644 --- a/source/libnet/libnet_rpc.c +++ b/source/libnet/libnet_rpc.c @@ -98,12 +98,13 @@ static NTSTATUS libnet_rpc_connect_standard(struct libnet_context *ctx, TALLOC_C r->standard.in.server_name); status = dcerpc_pipe_connect(&r->standard.out.dcerpc_pipe, - binding, - r->standard.in.dcerpc_iface_uuid, - r->standard.in.dcerpc_iface_version, - ctx->user.domain_name, - ctx->user.account_name, - ctx->user.password); + binding, + r->standard.in.dcerpc_iface_uuid, + r->standard.in.dcerpc_iface_version, + lp_netbios_name(), + ctx->user.domain_name, + ctx->user.account_name, + ctx->user.password); if (!NT_STATUS_IS_OK(status)) { r->standard.out.error_string = talloc_asprintf(mem_ctx, "dcerpc_pipe_connect to pipe %s failed with %s\n", diff --git a/source/librpc/idl/echo.idl b/source/librpc/idl/echo.idl index 86e16763c2b..d3d0305cb6d 100644 --- a/source/librpc/idl/echo.idl +++ b/source/librpc/idl/echo.idl @@ -23,12 +23,12 @@ interface rpcecho /* Sink data to the server */ void echo_SinkData( [in] uint32 len, - [in,size_is(len)] uint8 data[] + [in,ref,size_is(len)] uint8 *data[] ); /* Source data from server */ void echo_SourceData( [in] uint32 len, - [out,size_is(len)] uint8 data[] + [out,ref,size_is(len)] uint8 *data[] ); diff --git a/source/librpc/idl/schannel.idl b/source/librpc/idl/schannel.idl index d840d78ef99..f66744fec3a 100644 --- a/source/librpc/idl/schannel.idl +++ b/source/librpc/idl/schannel.idl @@ -15,7 +15,7 @@ interface schannel */ typedef struct { astring domain; - astring account_name; + astring workstation; } schannel_bind_3; typedef struct { diff --git a/source/librpc/rpc/dcerpc_auth.c b/source/librpc/rpc/dcerpc_auth.c index 1bcf4224c46..ac74788ba6c 100644 --- a/source/librpc/rpc/dcerpc_auth.c +++ b/source/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/source/librpc/rpc/dcerpc_schannel.c b/source/librpc/rpc/dcerpc_schannel.c index d99d43ad587..170ddee1f30 100644 --- a/source/librpc/rpc/dcerpc_schannel.c +++ b/source/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/source/librpc/rpc/dcerpc_smb.c b/source/librpc/rpc/dcerpc_smb.c index aa2d0bf20f0..1a5a31c330f 100644 --- a/source/librpc/rpc/dcerpc_smb.c +++ b/source/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/source/librpc/rpc/dcerpc_util.c b/source/librpc/rpc/dcerpc_util.c index 7b753d1b307..91e6ea93973 100644 --- a/source/librpc/rpc/dcerpc_util.c +++ b/source/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; } diff --git a/source/ntvfs/ipc/vfs_ipc.c b/source/ntvfs/ipc/vfs_ipc.c index abb4c51f65f..68c59b75027 100644 --- a/source/ntvfs/ipc/vfs_ipc.c +++ b/source/ntvfs/ipc/vfs_ipc.c @@ -180,7 +180,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, { struct pipe_state *p; NTSTATUS status; - struct dcerpc_binding ep_description; + struct dcerpc_binding *ep_description; struct ipc_private *private = ntvfs->private_data; int fnum; struct stream_connection *srv_conn = req->smb_conn->connection; @@ -192,6 +192,9 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p = talloc(req, struct pipe_state); NT_STATUS_HAVE_NO_MEMORY(p); + ep_description = talloc(req, struct dcerpc_binding); + NT_STATUS_HAVE_NO_MEMORY(ep_description); + while (fname[0] == '\\') fname++; p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); @@ -211,15 +214,15 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, know what interface the user actually wants, just that they want one of the interfaces attached to this pipe endpoint. */ - ep_description.transport = NCACN_NP; - ep_description.endpoint = p->pipe_name; + ep_description->transport = NCACN_NP; + ep_description->endpoint = talloc_reference(ep_description, p->pipe_name); /* The session info is refcount-increased in the * dcesrv_endpoint_search_connect() function */ status = dcesrv_endpoint_search_connect(private->dcesrv, p, - &ep_description, + ep_description, req->session->session_info, srv_conn, &p->dce_conn); diff --git a/source/rpc_server/dcerpc_server.c b/source/rpc_server/dcerpc_server.c index c0cd221da6a..b050830883d 100644 --- a/source/rpc_server/dcerpc_server.c +++ b/source/rpc_server/dcerpc_server.c @@ -58,7 +58,7 @@ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, { struct dcesrv_endpoint *ep; for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) { - if (endpoints_match(&ep->ep_description, ep_description)) { + if (endpoints_match(ep->ep_description, ep_description)) { return ep; } } @@ -166,7 +166,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, { struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; - struct dcerpc_binding binding; + struct dcerpc_binding *binding; BOOL add_ep = False; NTSTATUS status; @@ -179,13 +179,13 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* check if this endpoint exists */ - if ((ep=find_endpoint(dce_ctx, &binding))==NULL) { + if ((ep=find_endpoint(dce_ctx, binding))==NULL) { ep = talloc(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(ep); - ep->ep_description = binding; + ep->ep_description = talloc_reference(ep, binding); add_ep = True; } diff --git a/source/rpc_server/dcerpc_server.h b/source/rpc_server/dcerpc_server.h index c3a779326e6..77fb76448c3 100644 --- a/source/rpc_server/dcerpc_server.h +++ b/source/rpc_server/dcerpc_server.h @@ -212,7 +212,7 @@ struct dcesrv_context { struct dcesrv_endpoint { struct dcesrv_endpoint *next, *prev; /* the type and location of the endpoint */ - struct dcerpc_binding ep_description; + struct dcerpc_binding *ep_description; /* the security descriptor for smb named pipes */ struct security_descriptor *sd; /* the list of interfaces available on this endpoint */ diff --git a/source/rpc_server/dcerpc_sock.c b/source/rpc_server/dcerpc_sock.c index d2ebf794b36..56b55a9fbf9 100644 --- a/source/rpc_server/dcerpc_sock.c +++ b/source/rpc_server/dcerpc_sock.c @@ -159,11 +159,11 @@ static NTSTATUS add_socket_rpc_unix(struct dcesrv_context *dce_ctx, struct dcesr dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, - "unix", e->ep_description.endpoint, &port, + "unix", e->ep_description->endpoint, &port, dcesrv_sock); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", - e->ep_description.endpoint, nt_errstr(status))); + e->ep_description->endpoint, nt_errstr(status))); } return status; @@ -177,14 +177,14 @@ static NTSTATUS add_socket_rpc_ncalrpc(struct dcesrv_context *dce_ctx, struct dc char *full_path; NTSTATUS status; - if (!e->ep_description.endpoint) { + if (!e->ep_description->endpoint) { /* No identifier specified: use DEFAULT. * DO NOT hardcode this value anywhere else. Rather, specify * no endpoint and let the epmapper worry about it. */ - e->ep_description.endpoint = talloc_strdup(dce_ctx, "DEFAULT"); + e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT"); } - full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description.endpoint); + full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description->endpoint); dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); @@ -197,7 +197,7 @@ static NTSTATUS add_socket_rpc_ncalrpc(struct dcesrv_context *dce_ctx, struct dc "unix", full_path, &port, dcesrv_sock); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n", - e->ep_description.endpoint, full_path, nt_errstr(status))); + e->ep_description->endpoint, full_path, nt_errstr(status))); } return status; } @@ -213,8 +213,8 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct uint16_t port = 0; NTSTATUS status; - if (e->ep_description.endpoint) { - port = atoi(e->ep_description.endpoint); + if (e->ep_description->endpoint) { + port = atoi(e->ep_description->endpoint); } dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context); @@ -231,8 +231,8 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct address, port, nt_errstr(status))); } - if (e->ep_description.endpoint == NULL) { - e->ep_description.endpoint = talloc_asprintf(dce_ctx, "%d", port); + if (e->ep_description->endpoint == NULL) { + e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port); } return status; @@ -275,7 +275,7 @@ NTSTATUS dcesrv_sock_init(struct dcesrv_context *dce_ctx, } for (e=dce_ctx->endpoint_list;e;e=e->next) { - switch (e->ep_description.transport) { + switch (e->ep_description->transport) { case NCACN_UNIX_STREAM: status = add_socket_rpc_unix(dce_ctx, e, event_ctx, model_ops); NT_STATUS_NOT_OK_RETURN(status); diff --git a/source/rpc_server/epmapper/rpc_epmapper.c b/source/rpc_server/epmapper/rpc_epmapper.c index 8a61fc64281..d7d447f852f 100644 --- a/source/rpc_server/epmapper/rpc_epmapper.c +++ b/source/rpc_server/epmapper/rpc_epmapper.c @@ -64,7 +64,7 @@ static uint32_t build_ep_list(TALLOC_CTX *mem_ctx, for (d=endpoint_list; d; d=d->next) { struct dcesrv_if_list *iface; - struct dcerpc_binding description; + struct dcerpc_binding *description; for (iface=d->interface_list;iface;iface=iface->next) { (*eps) = talloc_realloc(mem_ctx, @@ -77,10 +77,10 @@ static uint32_t build_ep_list(TALLOC_CTX *mem_ctx, (*eps)[total].name = iface->iface.name; description = d->ep_description; - GUID_from_string(iface->iface.uuid, &description.object); - description.object_version = iface->iface.if_version; + GUID_from_string(iface->iface.uuid, &description->object); + description->object_version = iface->iface.if_version; - status = dcerpc_binding_build_tower(mem_ctx, &description, &(*eps)[total].ep); + status = dcerpc_binding_build_tower(mem_ctx, description, &(*eps)[total].ep); if (NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to build tower for %s\n", iface->iface.name)); continue; diff --git a/source/rpc_server/netlogon/dcerpc_netlogon.c b/source/rpc_server/netlogon/dcerpc_netlogon.c index fd93d495e2a..6a29bf7db84 100644 --- a/source/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source/rpc_server/netlogon/dcerpc_netlogon.c @@ -230,6 +230,9 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL pipe_state->creds->secure_channel_type = r->in.secure_channel_type; pipe_state->creds->rid = *r->out.rid; + + pipe_state->creds->domain = talloc_strdup(pipe_state->creds, lp_workgroup()); + /* remember this session key state */ nt_status = schannel_store_session_key(mem_ctx, pipe_state->creds); diff --git a/source/rpc_server/remote/dcesrv_remote.c b/source/rpc_server/remote/dcesrv_remote.c index ee526e1978f..9ed6b5a1bdf 100644 --- a/source/rpc_server/remote/dcesrv_remote.c +++ b/source/rpc_server/remote/dcesrv_remote.c @@ -43,6 +43,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } status = dcerpc_pipe_connect(&(private->c_pipe), binding, iface->uuid, iface->if_version, + lp_netbios_name(), lp_workgroup(), lp_parm_string(-1, "dcerpc_remote", "username"), lp_parm_string(-1, "dcerpc_remote", "password")); diff --git a/source/torture/libnet/userinfo.c b/source/torture/libnet/userinfo.c index c541474a751..9a775277cb8 100644 --- a/source/torture/libnet/userinfo.c +++ b/source/torture/libnet/userinfo.c @@ -209,7 +209,7 @@ BOOL torture_userinfo(void) NTSTATUS status; const char *binding; struct dcerpc_pipe *p; - struct dcerpc_binding b; + struct dcerpc_binding *b; TALLOC_CTX *mem_ctx; BOOL ret = True; struct policy_handle h; @@ -236,7 +236,7 @@ BOOL torture_userinfo(void) ret = False; goto done; } - name.string = b.host; + name.string = b->host; if (!test_opendomain(p, mem_ctx, &h, &name, &sid)) { ret = False; diff --git a/source/torture/local/binding_string.c b/source/torture/local/binding_string.c index 66e8a5350f7..79d1e89ed6f 100644 --- a/source/torture/local/binding_string.c +++ b/source/torture/local/binding_string.c @@ -25,7 +25,7 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding) { - struct dcerpc_binding b, b2; + struct dcerpc_binding *b, *b2; const char *s, *s2; struct epm_tower tower; NTSTATUS status; @@ -37,7 +37,7 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding) return False; } - s = dcerpc_binding_string(mem_ctx, &b); + s = dcerpc_binding_string(mem_ctx, b); if (!s) { DEBUG(0, ("Error converting binding back to string for '%s'\n", binding)); return False; @@ -49,7 +49,7 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding) } /* Generate protocol towers */ - status = dcerpc_binding_build_tower(mem_ctx, &b, &tower); + status = dcerpc_binding_build_tower(mem_ctx, b, &tower); if (NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Error generating protocol tower from '%s': %s\n", binding, nt_errstr(status))); return False; @@ -65,18 +65,18 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding) /* Compare to a stripped down version of the binding string because * the protocol tower doesn't contain the extra option data */ - b.options = NULL; + b->options = NULL; - b.flags = 0; + b->flags = 0; - s = dcerpc_binding_string(mem_ctx, &b); + s = dcerpc_binding_string(mem_ctx, b); if (!s) { DEBUG(0, ("Error converting binding back to string for (stripped down) '%s'\n", binding)); return False; } - s2 = dcerpc_binding_string(mem_ctx, &b2); + s2 = dcerpc_binding_string(mem_ctx, b2); if (!s) { DEBUG(0, ("Error converting binding back to string for '%s'\n", binding)); return False; diff --git a/source/torture/rpc/bind.c b/source/torture/rpc/bind.c index 10ffa502899..3eb02c31eb5 100644 --- a/source/torture/rpc/bind.c +++ b/source/torture/rpc/bind.c @@ -37,12 +37,12 @@ BOOL torture_multi_bind(void) { struct dcerpc_pipe *p; + const char *workstation = lp_netbios_name(); const char *domain = lp_parm_string(-1, "torture", "userdomain"); const char *username = lp_parm_string(-1, "torture", "username"); const char *password = lp_parm_string(-1, "torture", "password"); const char *pipe_uuid = DCERPC_LSARPC_UUID; uint32_t pipe_version = DCERPC_LSARPC_VERSION; - struct dcerpc_binding b; struct dcerpc_binding *binding; const char *binding_string = lp_parm_string(-1, "torture", "binding"); TALLOC_CTX *mem_ctx; @@ -51,15 +51,13 @@ BOOL torture_multi_bind(void) mem_ctx = talloc_init("torture_multi_bind"); - status = dcerpc_parse_binding(mem_ctx, binding_string, &b); + status = dcerpc_parse_binding(mem_ctx, binding_string, &binding); if (!NT_STATUS_IS_OK(status)) { printf("Failed to parse dcerpc binding '%s'\n", binding_string); talloc_free(mem_ctx); return False; } - binding = &b; - status = torture_rpc_connection(&p, NULL, pipe_uuid, @@ -69,24 +67,8 @@ BOOL torture_multi_bind(void) return False; } - if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) { - status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, - domain, username, password); - } else if (username && username[0]) { - uint8_t auth_type; - if (binding->flags & DCERPC_AUTH_SPNEGO) { - auth_type = DCERPC_AUTH_TYPE_SPNEGO; - } else { - auth_type = DCERPC_AUTH_TYPE_NTLMSSP; - } - - status = dcerpc_bind_auth_password(p, pipe_uuid, pipe_version, - domain, username, password, - auth_type, - binding->authservice); - } else { - status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version); - } + status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, + workstation, domain, username, password); if (NT_STATUS_IS_OK(status)) { printf("(incorrectly) allowed re-bind to uuid %s - %s\n", diff --git a/source/torture/rpc/epmapper.c b/source/torture/rpc/epmapper.c index eecfdb3f898..debcd987566 100644 --- a/source/torture/rpc/epmapper.c +++ b/source/torture/rpc/epmapper.c @@ -213,7 +213,7 @@ static BOOL test_Insert(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct epm_Insert r; - struct dcerpc_binding bd; + struct dcerpc_binding *bd; r.in.num_ents = 1; @@ -228,7 +228,7 @@ static BOOL test_Insert(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) r.in.entries[0].tower = talloc(mem_ctx, struct epm_twr_t); - status = dcerpc_binding_build_tower(mem_ctx, &bd, &r.in.entries[0].tower->tower); + status = dcerpc_binding_build_tower(mem_ctx, bd, &r.in.entries[0].tower->tower); if (NT_STATUS_IS_ERR(status)) { printf("Unable to build tower from binding struct\n"); return False; diff --git a/source/torture/rpc/mgmt.c b/source/torture/rpc/mgmt.c index 1dea24517dc..cb2023b64c6 100644 --- a/source/torture/rpc/mgmt.c +++ b/source/torture/rpc/mgmt.c @@ -181,7 +181,7 @@ BOOL torture_rpc_mgmt(void) BOOL ret = True; const char *binding = lp_parm_string(-1, "torture", "binding"); const struct dcerpc_interface_list *l; - struct dcerpc_binding b; + struct dcerpc_binding *b; mem_ctx = talloc_init("torture_rpc_mgmt"); @@ -205,8 +205,8 @@ BOOL torture_rpc_mgmt(void) printf("\nTesting pipe '%s'\n", l->table->name); - if (b.transport == NCACN_IP_TCP) { - status = dcerpc_epm_map_binding(mem_ctx, &b, + if (b->transport == NCACN_IP_TCP) { + status = dcerpc_epm_map_binding(mem_ctx, b, l->table->uuid, l->table->if_version); if (!NT_STATUS_IS_OK(status)) { @@ -214,10 +214,10 @@ BOOL torture_rpc_mgmt(void) continue; } } else { - b.endpoint = l->table->name; + b->endpoint = talloc_strdup(b, l->table->name); } - lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b)); + lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, b)); status = torture_rpc_connection(&p, l->table->name, diff --git a/source/torture/rpc/netlogon.c b/source/torture/rpc/netlogon.c index 7c516da1180..2266659c379 100644 --- a/source/torture/rpc/netlogon.c +++ b/source/torture/rpc/netlogon.c @@ -76,16 +76,22 @@ static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *machine_name, const char *plain_pass, - struct creds_CredentialState *creds) + struct creds_CredentialState **creds_out) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate a; struct netr_Credential credentials1, credentials2, credentials3; + struct creds_CredentialState *creds; struct samr_Password mach_password; printf("Testing ServerReqChallenge\n"); + creds = talloc(mem_ctx, struct creds_CredentialState); + if (!creds) { + return False; + } + r.in.server_name = NULL; r.in.computer_name = machine_name; r.in.credentials = &credentials1; @@ -108,7 +114,11 @@ BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, a.in.credentials = &credentials3; a.out.credentials = &credentials3; - creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3, + creds_client_init(creds, &credentials1, &credentials2, + machine_name, + lp_workgroup(), + a.in.account_name, + &mach_password, &credentials3, 0); printf("Testing ServerAuthenticate\n"); @@ -124,6 +134,7 @@ BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return False; } + *creds_out = creds; return True; } @@ -132,16 +143,22 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *machine_name, const char *plain_pass, int sec_chan_type, - struct creds_CredentialState *creds) + struct creds_CredentialState **creds_out) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate2 a; struct netr_Credential credentials1, credentials2, credentials3; + struct creds_CredentialState *creds; struct samr_Password mach_password; printf("Testing ServerReqChallenge\n"); + creds = talloc(mem_ctx, struct creds_CredentialState); + if (!creds) { + return False; + } + r.in.server_name = NULL; r.in.computer_name = machine_name; r.in.credentials = &credentials1; @@ -166,7 +183,11 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, a.in.credentials = &credentials3; a.out.credentials = &credentials3; - creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3, + creds_client_init(creds, &credentials1, &credentials2, + machine_name, + lp_workgroup(), + a.in.account_name, + &mach_password, &credentials3, negotiate_flags); printf("Testing ServerAuthenticate2\n"); @@ -184,6 +205,7 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("negotiate_flags=0x%08x\n", negotiate_flags); + *creds_out = creds; return True; } @@ -192,17 +214,23 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, uint32_t negotiate_flags, const char *machine_name, const char *plain_pass, - struct creds_CredentialState *creds) + struct creds_CredentialState **creds_out) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate3 a; struct netr_Credential credentials1, credentials2, credentials3; + struct creds_CredentialState *creds; struct samr_Password mach_password; uint32_t rid; printf("Testing ServerReqChallenge\n"); + creds = talloc(mem_ctx, struct creds_CredentialState); + if (!creds) { + return False; + } + r.in.server_name = NULL; r.in.computer_name = machine_name; r.in.credentials = &credentials1; @@ -228,7 +256,11 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, a.out.negotiate_flags = &negotiate_flags; a.out.rid = &rid; - creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3, + creds_client_init(creds, &credentials1, &credentials2, + machine_name, + lp_workgroup(), + a.in.account_name, + &mach_password, &credentials3, negotiate_flags); printf("Testing ServerAuthenticate3\n"); @@ -246,6 +278,7 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("negotiate_flags=0x%08x\n", negotiate_flags); + *creds_out = creds; return True; } @@ -257,7 +290,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) NTSTATUS status; struct netr_ServerPasswordSet r; const char *password; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) { @@ -272,7 +305,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) password = ""; E_md4hash(password, r.in.new_password.hash); - creds_des_encrypt(&creds, &r.in.new_password); + creds_des_encrypt(creds, &r.in.new_password); /* by changing the machine password to "" * we check if the server uses password restrictions * for ServerPasswordSet2 @@ -281,7 +314,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Testing a second ServerPasswordSet on machine account\n"); printf("Changing machine account password to '%s'\n", password); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -289,7 +322,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -303,12 +336,12 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) password = generate_random_str(mem_ctx, 8); E_md4hash(password, r.in.new_password.hash); - creds_des_encrypt(&creds, &r.in.new_password); + creds_des_encrypt(creds, &r.in.new_password); printf("Testing ServerPasswordSet on machine account\n"); printf("Changing machine account password to '%s'\n", password); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -316,7 +349,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -327,7 +360,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Testing a second ServerPasswordSet on machine account\n"); printf("Changing machine account password to '%s' (same as previous run)\n", password); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -335,7 +368,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -357,7 +390,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) NTSTATUS status; struct netr_ServerPasswordSet2 r; const char *password; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) { @@ -371,7 +404,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) password = ""; encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE); - creds_arcfour_crypt(&creds, r.in.new_password.data, 516); + creds_arcfour_crypt(creds, r.in.new_password.data, 516); /* by changing the machine password to "" * we check if the server uses password restrictions @@ -381,7 +414,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Testing a second ServerPasswordSet2 on machine account\n"); printf("Changing machine account password to '%s'\n", password); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -389,7 +422,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -403,12 +436,12 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) /* now try a random password */ password = generate_random_str(mem_ctx, 8); encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE); - creds_arcfour_crypt(&creds, r.in.new_password.data, 516); + creds_arcfour_crypt(creds, r.in.new_password.data, 516); printf("Testing ServerPasswordSet2 on machine account\n"); printf("Changing machine account password to '%s'\n", password); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -416,7 +449,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -427,7 +460,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Testing a second ServerPasswordSet2 on machine account\n"); printf("Changing machine account password to '%s' (same as previous run)\n", password); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -435,7 +468,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -460,7 +493,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) struct netr_NetworkInfo ninfo; const char *username = lp_parm_string(-1, "torture", "username"); const char *password = lp_parm_string(-1, "torture", "password"); - struct creds_CredentialState creds; + struct creds_CredentialState *creds; int i; BOOL ret = True; @@ -494,7 +527,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) for (i=2;i<=3;i++) { ZERO_STRUCT(auth2); - creds_client_authenticator(&creds, &auth); + creds_client_authenticator(creds, &auth); r.in.validation_level = i; @@ -506,7 +539,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) ret = False; } - if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } } @@ -540,7 +573,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct netr_DatabaseSync r; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i; BOOL ret = True; @@ -561,7 +594,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Testing DatabaseSync of id %d\n", r.in.database_id); do { - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status) && @@ -571,7 +604,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) break; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -601,7 +634,7 @@ static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct netr_DatabaseDeltas r; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; const uint32_t database_ids[] = {0, 1, 2}; int i; BOOL ret = True; @@ -628,7 +661,7 @@ static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) r.in.database_id, r.in.sequence_num); do { - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status) && @@ -638,7 +671,7 @@ static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) break; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -657,7 +690,7 @@ static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct netr_AccountDeltas r; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; BOOL ret = True; if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) { @@ -667,7 +700,7 @@ static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.computername = TEST_MACHINE_NAME; ZERO_STRUCT(r.in.return_authenticator); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); ZERO_STRUCT(r.in.uas); r.in.count=10; r.in.level=0; @@ -692,7 +725,7 @@ static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct netr_AccountSync r; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; BOOL ret = True; if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) { @@ -702,7 +735,7 @@ static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.computername = TEST_MACHINE_NAME; ZERO_STRUCT(r.in.return_authenticator); - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); ZERO_STRUCT(r.in.recordid); r.in.reference=0; r.in.level=0; @@ -886,7 +919,7 @@ static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct netr_DatabaseSync2 r; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; const uint32_t database_ids[] = {0, 1, 2}; int i; BOOL ret = True; @@ -910,7 +943,7 @@ static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Testing DatabaseSync2 of id %d\n", r.in.database_id); do { - creds_client_authenticator(&creds, &r.in.credential); + creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status) && @@ -920,7 +953,7 @@ static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) break; } - if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) { + if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -1082,7 +1115,7 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) struct netr_LogonGetDomainInfo r; struct netr_DomainQuery1 q1; struct netr_Authenticator a; - struct creds_CredentialState creds; + struct creds_CredentialState *creds; if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, TEST_MACHINE_NAME, machine_password, &creds)) { @@ -1091,7 +1124,7 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) ZERO_STRUCT(r); - creds_client_authenticator(&creds, &a); + creds_client_authenticator(creds, &a); r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.computer_name = TEST_MACHINE_NAME; @@ -1119,7 +1152,7 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!creds_client_check(&creds, &a.cred)) { + if (!creds_client_check(creds, &a.cred)) { printf("Credential chaining failed\n"); return False; } @@ -1143,8 +1176,8 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) struct netr_DomainQuery1 q1; struct netr_Authenticator a; #define ASYNC_COUNT 100 - struct creds_CredentialState creds; - struct creds_CredentialState creds_async[ASYNC_COUNT]; + struct creds_CredentialState *creds; + struct creds_CredentialState *creds_async[ASYNC_COUNT]; struct rpc_request *req[ASYNC_COUNT]; int i; int *async_counter = talloc(mem_ctx, int); @@ -1183,9 +1216,9 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) *async_counter = 0; for (i=0;i<ASYNC_COUNT;i++) { - creds_client_authenticator(&creds, &a); + creds_client_authenticator(creds, &a); - creds_async[i] = creds; + creds_async[i] = talloc_memdup(creds, creds, sizeof(*creds)); req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r); req[i]->async.callback = async_callback; @@ -1206,7 +1239,7 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) break; } - if (!creds_client_check(&creds_async[i], &a.cred)) { + if (!creds_client_check(creds_async[i], &a.cred)) { printf("Credential chaining failed at async %d\n", i); break; } @@ -1220,6 +1253,7 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; + struct dcerpc_binding *b; struct dcerpc_pipe *p2; struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; @@ -1240,15 +1274,25 @@ static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Torturing GetDCName\n"); - status = dcerpc_secondary_connection(p, &p2, - DCERPC_LSARPC_NAME, - DCERPC_LSARPC_UUID, - DCERPC_LSARPC_VERSION); + status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string); + return False; + } + + status = dcerpc_secondary_connection(p, &p2, b); if (!NT_STATUS_IS_OK(status)) { printf("Failed to create secondary connection\n"); return False; } + status = dcerpc_bind_auth_none(p2, DCERPC_LSARPC_UUID, + DCERPC_LSARPC_VERSION); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to create bind on secondary connection\n"); + return False; + } + qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; diff --git a/source/torture/rpc/samlogon.c b/source/torture/rpc/samlogon.c index 4fe79033325..e08eaca22ea 100644 --- a/source/torture/rpc/samlogon.c +++ b/source/torture/rpc/samlogon.c @@ -28,6 +28,7 @@ #include "lib/crypto/crypto.h" #define TEST_MACHINE_NAME "samlogontest" +#define TEST_USER_NAME "samlogontestuser" enum ntlm_break { BREAK_BOTH, @@ -1067,6 +1068,7 @@ static const struct ntlm_tests { static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, const char *account_domain, const char *account_name, + const char *plain_pass, int n_subtests) { int i, v, l, f; @@ -1084,7 +1086,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, samlogon_state.mem_ctx = mem_ctx; samlogon_state.account_name = account_name; samlogon_state.account_domain = account_domain; - samlogon_state.password = lp_parm_string(-1, "torture", "password"); + samlogon_state.password = plain_pass; samlogon_state.p = p; samlogon_state.creds = creds; @@ -1149,13 +1151,13 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, */ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, - const char *account_domain, const char *account_name) + const char *account_domain, const char *account_name, + const char *plain_pass) { NTSTATUS status; struct netr_LogonSamLogonWithFlags r; struct netr_Authenticator a, ra; struct netr_PasswordInfo pinfo; - const char *plain_pass; ZERO_STRUCT(a); ZERO_STRUCT(r); @@ -1179,8 +1181,6 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, pinfo.identity_info.account_name.string = account_name; pinfo.identity_info.workstation.string = TEST_MACHINE_NAME; - plain_pass = lp_parm_string(-1, "torture", "password"); - E_deshash(plain_pass, pinfo.lmpassword.hash); E_md4hash(plain_pass, pinfo.ntpassword.hash); @@ -1195,13 +1195,13 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("Testing netr_LogonSamLogonWithFlags (Interactive Logon)\n"); status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r); - if (!NT_STATUS_IS_OK(status)) { - printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status)); + if (!r.out.return_authenticator || !creds_client_check(creds, &r.out.return_authenticator->cred)) { + printf("Credential chaining failed\n"); return False; } - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { - printf("Credential chaining failed\n"); + if (!NT_STATUS_IS_OK(status)) { + printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status)); return False; } @@ -1214,14 +1214,20 @@ BOOL torture_rpc_samlogon(void) { NTSTATUS status; struct dcerpc_pipe *p; - struct dcerpc_binding b; - TALLOC_CTX *mem_ctx; + struct dcerpc_binding *b; + TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_netlogon"); BOOL ret = True; - void *join_ctx; + struct test_join *join_ctx; +#if 0 + struct test_join *user_ctx; + const char *user_password; +#endif + char *test_machine_account; const char *machine_password; const char *binding = lp_parm_string(-1, "torture", "binding"); int i; - + int ci; + unsigned int credential_flags[] = { NETLOGON_NEG_AUTH2_FLAGS, NETLOGON_NEG_ARCFOUR, @@ -1232,17 +1238,88 @@ BOOL torture_rpc_samlogon(void) struct creds_CredentialState *creds; - mem_ctx = talloc_init("torture_rpc_netlogon"); - + struct { + const char *domain; + const char *username; + const char *password; + BOOL network_login; + } usercreds[] = { + { + lp_parm_string(-1, "torture", "userdomain"), + lp_parm_string(-1, "torture", "username"), + lp_parm_string(-1, "torture", "password"), + True + }, + { + NULL, + talloc_asprintf(mem_ctx, + "%s@%s", + lp_parm_string(-1, "torture", "username"), + lp_parm_string(-1, "torture", "userdomain")), + lp_parm_string(-1, "torture", "password"), + False + }, + { + NULL, + talloc_asprintf(mem_ctx, + "%s@%s", + lp_parm_string(-1, "torture", "username"), + lp_realm()), + lp_parm_string(-1, "torture", "password"), + True + }, +#if 0 + { + lp_parm_string(-1, "torture", "userdomain"), + TEST_USER_NAME, + NULL, + True + }, + { + NULL, + talloc_asprintf(mem_ctx, + "%s@%s", + TEST_USER_NAME, + lp_realm()), + NULL, + True + }, + { + NULL, + talloc_asprintf(mem_ctx, + "%s@%s", + TEST_USER_NAME, + lp_parm_string(-1, "torture", "userdomain")), + NULL, + False + } +#endif + }; + + test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME); /* We only need to join as a workstation here, and in future, * if we wish to test against trusted domains, we must be a * workstation here */ - join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_WSTRUST, - &machine_password); + join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), ACB_WSTRUST, + &machine_password); if (!join_ctx) { printf("Failed to join as Workstation\n"); return False; } +#if 0 + user_ctx = torture_create_testuser(TEST_USER_NAME, + lp_parm_string(-1, "torture", "userdomain"), + ACB_NORMAL, + &user_password); + if (!user_ctx) { + printf("Failed to join as Workstation\n"); + return False; + } + + usercreds[3].password = user_password; + usercreds[4].password = user_password; + usercreds[5].password = user_password; +#endif status = dcerpc_parse_binding(mem_ctx, binding, &b); if (!NT_STATUS_IS_OK(status)) { @@ -1254,14 +1331,15 @@ BOOL torture_rpc_samlogon(void) /* We have to use schannel, otherwise the SamLogonEx fails * with INTERNAL_ERROR */ - b.flags &= ~DCERPC_AUTH_OPTIONS; - b.flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128; + b->flags &= ~DCERPC_AUTH_OPTIONS; + b->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128; - status = dcerpc_pipe_connect_b(&p, &b, + status = dcerpc_pipe_connect_b(&p, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, - lp_workgroup(), TEST_MACHINE_NAME, + lp_workgroup(), + test_machine_account, machine_password); if (!NT_STATUS_IS_OK(status)) { @@ -1275,91 +1353,46 @@ BOOL torture_rpc_samlogon(void) goto failed; } - if (!test_InteractiveLogon(p, mem_ctx, creds, - lp_parm_string(-1, "torture", "userdomain"), - lp_parm_string(-1, "torture", "username"))) { - ret = False; - } - - if (!test_SamLogon(p, mem_ctx, creds, - lp_parm_string(-1, "torture", "userdomain"), - lp_parm_string(-1, "torture", "username"), - 0)) { - ret = False; - } - - if (!test_InteractiveLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_parm_string(-1, "torture", "userdomain")))) { - ret = False; - } - - if (!test_InteractiveLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_realm()))) { - ret = False; - } - - if (!test_SamLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_realm()), - 0)) { - ret = False; - } - - if (!test_SamLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_realm()), - 0)) { - ret = False; - } - - for (i=0; i < ARRAY_SIZE(credential_flags); i++) { - - if (!test_SetupCredentials2(p, mem_ctx, credential_flags[i], - TEST_MACHINE_NAME, machine_password, - SEC_CHAN_WKSTA, creds)) { - return False; - } + for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) { if (!test_InteractiveLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_parm_string(-1, "torture", "userdomain")))) { + usercreds[ci].domain, + usercreds[ci].username, + usercreds[ci].password)) { ret = False; } - if (!test_InteractiveLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_realm()))) { - ret = False; + if (usercreds[ci].network_login) { + if (!test_SamLogon(p, mem_ctx, creds, + usercreds[ci].domain, + usercreds[ci].username, + usercreds[ci].password, + 0)) { + ret = False; + } } + } + + for (i=0; i < ARRAY_SIZE(credential_flags); i++) { - if (!test_SamLogon(p, mem_ctx, creds, - NULL, - talloc_asprintf(mem_ctx, - "%s@%s", - lp_parm_string(-1, "torture", "username"), - lp_realm()), - 1)) { - ret = False; + for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) { + + if (!test_InteractiveLogon(p, mem_ctx, creds, + usercreds[ci].domain, + usercreds[ci].username, + usercreds[ci].password)) { + ret = False; + } + + if (usercreds[ci].network_login) { + if (!test_SamLogon(p, mem_ctx, creds, + usercreds[ci].domain, + usercreds[ci].username, + usercreds[ci].password, + 1)) { + ret = False; + } + } } } @@ -1369,6 +1402,8 @@ failed: torture_rpc_close(p); torture_leave_domain(join_ctx); - +#if 0 + torture_leave_domain(user_ctx); +#endif return ret; } diff --git a/source/torture/rpc/samsync.c b/source/torture/rpc/samsync.c index cd39b625c36..505e331d19a 100644 --- a/source/torture/rpc/samsync.c +++ b/source/torture/rpc/samsync.c @@ -1284,10 +1284,10 @@ BOOL torture_rpc_samsync(void) struct test_join *join_ctx2; struct test_join *user_ctx; const char *machine_password; - const char *machine_password2; + const char *wksta_machine_password; const char *binding = lp_parm_string(-1, "torture", "binding"); - struct dcerpc_binding b; - struct dcerpc_binding b_netlogon_wksta; + struct dcerpc_binding *b; + struct dcerpc_binding *b_netlogon_wksta; struct samr_Connect c; struct samr_SetDomainInfo s; struct policy_handle *domain_policy; @@ -1298,17 +1298,23 @@ BOOL torture_rpc_samsync(void) struct samsync_state *samsync_state; + char *test_machine_account; + + char *test_wksta_machine_account; + mem_ctx = talloc_init("torture_rpc_netlogon"); - join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST, - &machine_password); + test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME); + join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), ACB_SVRTRUST, + &machine_password); if (!join_ctx) { printf("Failed to join as BDC\n"); return False; } - join_ctx2 = torture_join_domain(TEST_WKSTA_MACHINE_NAME, lp_workgroup(), ACB_WSTRUST, - &machine_password2); + test_wksta_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_WKSTA_MACHINE_NAME); + join_ctx2 = torture_create_testuser(test_wksta_machine_account, lp_workgroup(), ACB_WSTRUST, + &wksta_machine_password); if (!join_ctx2) { printf("Failed to join as member\n"); return False; @@ -1409,17 +1415,19 @@ BOOL torture_rpc_samsync(void) goto failed; } - b.flags &= ~DCERPC_AUTH_OPTIONS; - b.flags |= DCERPC_SCHANNEL_BDC | DCERPC_SIGN; + b->flags &= ~DCERPC_AUTH_OPTIONS; + b->flags |= DCERPC_SCHANNEL_BDC | DCERPC_SIGN; - status = dcerpc_pipe_connect_b(&samsync_state->p, &b, + status = dcerpc_pipe_connect_b(&samsync_state->p, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, - lp_workgroup(), TEST_MACHINE_NAME, + lp_workgroup(), + test_machine_account, machine_password); if (!NT_STATUS_IS_OK(status)) { + printf("Failed to connect to server as a BDC: %s\n", nt_errstr(status)); ret = False; goto failed; } @@ -1438,17 +1446,20 @@ BOOL torture_rpc_samsync(void) goto failed; } - b_netlogon_wksta.flags &= ~DCERPC_AUTH_OPTIONS; - b_netlogon_wksta.flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN; + b_netlogon_wksta->flags &= ~DCERPC_AUTH_OPTIONS; + b_netlogon_wksta->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN; - status = dcerpc_pipe_connect_b(&samsync_state->p_netlogon_wksta, &b_netlogon_wksta, + status = dcerpc_pipe_connect_b(&samsync_state->p_netlogon_wksta, + b_netlogon_wksta, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, - lp_workgroup(), TEST_WKSTA_MACHINE_NAME, - machine_password2); + lp_workgroup(), + test_wksta_machine_account, + wksta_machine_password); if (!NT_STATUS_IS_OK(status)) { + printf("Failed to connect to server as a Workstation: %s\n", nt_errstr(status)); ret = False; goto failed; } diff --git a/source/torture/rpc/scanner.c b/source/torture/rpc/scanner.c index a0ebf9d6425..3d78d7a8882 100644 --- a/source/torture/rpc/scanner.c +++ b/source/torture/rpc/scanner.c @@ -136,7 +136,7 @@ BOOL torture_rpc_scanner(void) BOOL ret = True; const struct dcerpc_interface_list *l; const char *binding = lp_parm_string(-1, "torture", "binding"); - struct dcerpc_binding b; + struct dcerpc_binding *b; mem_ctx = talloc_init("torture_rpc_scanner"); @@ -160,8 +160,8 @@ BOOL torture_rpc_scanner(void) printf("\nTesting pipe '%s'\n", l->table->name); - if (b.transport == NCACN_IP_TCP) { - status = dcerpc_epm_map_binding(mem_ctx, &b, + if (b->transport == NCACN_IP_TCP) { + status = dcerpc_epm_map_binding(mem_ctx, b, l->table->uuid, l->table->if_version); if (!NT_STATUS_IS_OK(status)) { @@ -169,10 +169,10 @@ BOOL torture_rpc_scanner(void) continue; } } else { - b.endpoint = l->table->name; + b->endpoint = talloc_strdup(b, l->table->name); } - lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b)); + lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, b)); status = torture_rpc_connection(&p, l->table->name, diff --git a/source/torture/rpc/schannel.c b/source/torture/rpc/schannel.c index 820dfaf4a5d..1b10e2a4f27 100644 --- a/source/torture/rpc/schannel.c +++ b/source/torture/rpc/schannel.c @@ -93,6 +93,8 @@ static BOOL test_netlogon_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.logon_level = 2; r.in.logon.network = &ninfo; + printf("Testing LogonSamLogon with name %s\n", username); + for (i=2;i<3;i++) { ZERO_STRUCT(auth2); creds_client_authenticator(creds, &auth); @@ -121,13 +123,14 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, const char *machine_password; NTSTATUS status; const char *binding = lp_parm_string(-1, "torture", "binding"); - struct dcerpc_binding b; + struct dcerpc_binding *b; struct dcerpc_pipe *p = NULL; struct dcerpc_pipe *p_netlogon = NULL; struct creds_CredentialState *creds; + char *test_machine_account = talloc_asprintf(NULL, "%s$", TEST_MACHINE_NAME); - join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), acct_flags, - &machine_password); + join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), + acct_flags, &machine_password); if (!join_ctx) { printf("Failed to join domain with acct_flags=0x%x\n", acct_flags); return False; @@ -139,17 +142,18 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, goto failed; } - b.flags &= ~DCERPC_AUTH_OPTIONS; - b.flags |= dcerpc_flags; + b->flags &= ~DCERPC_AUTH_OPTIONS; + b->flags |= dcerpc_flags; - status = dcerpc_pipe_connect_b(&p, &b, + status = dcerpc_pipe_connect_b(&p, b, DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION, - lp_workgroup(), TEST_MACHINE_NAME, + lp_workgroup(), + test_machine_account, machine_password); if (!NT_STATUS_IS_OK(status)) { - printf("Failed to connect with schannel\n"); + printf("Failed to connect with schannel: %s\n", nt_errstr(status)); goto failed; } @@ -158,27 +162,33 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, goto failed; } - - status = dcerpc_parse_binding(mem_ctx, binding, &b); + status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds); if (!NT_STATUS_IS_OK(status)) { - printf("Bad binding string %s\n", binding); goto failed; } - /* Also test that when we connect to the netlogon pipe, that * the credentials we setup on the first pipe are valid for * the second */ - b.flags &= ~DCERPC_AUTH_OPTIONS; - b.flags |= dcerpc_flags; + /* Swap the binding details from SAMR to NETLOGON */ + status = dcerpc_epm_map_binding(mem_ctx, b, DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + status = dcerpc_secondary_connection(p, &p_netlogon, + b); - status = dcerpc_pipe_connect_b(&p_netlogon, &b, - DCERPC_NETLOGON_UUID, - DCERPC_NETLOGON_VERSION, - lp_workgroup(), - TEST_MACHINE_NAME, - machine_password); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + status = dcerpc_bind_auth_schannel_withkey(p_netlogon, + DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION, + creds); if (!NT_STATUS_IS_OK(status)) { goto failed; diff --git a/source/torture/rpc/spoolss.c b/source/torture/rpc/spoolss.c index 7a9d8c3635c..e5c827afaab 100644 --- a/source/torture/rpc/spoolss.c +++ b/source/torture/rpc/spoolss.c @@ -705,6 +705,7 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct struct policy_handle *handle) { NTSTATUS status; + struct dcerpc_binding *b; struct dcerpc_pipe *p2; BOOL ret = True; @@ -715,15 +716,27 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct printf("testing close on secondary pipe\n"); - status = dcerpc_secondary_connection(p, &p2, - DCERPC_SPOOLSS_NAME, - DCERPC_SPOOLSS_UUID, - DCERPC_SPOOLSS_VERSION); + status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string); + return False; + } + + status = dcerpc_secondary_connection(p, &p2, b); if (!NT_STATUS_IS_OK(status)) { printf("Failed to create secondary connection\n"); return False; } + status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID, + DCERPC_SPOOLSS_VERSION); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to create bind on secondary connection\n"); + dcerpc_pipe_close(p2); + + return False; + } + if (test_ClosePrinter(p2, mem_ctx, handle)) { printf("ERROR: Allowed close on secondary connection!\n"); ret = False; diff --git a/source/torture/rpc/testjoin.c b/source/torture/rpc/testjoin.c index 891bbcaf10f..2d96116c0da 100644 --- a/source/torture/rpc/testjoin.c +++ b/source/torture/rpc/testjoin.c @@ -232,7 +232,7 @@ again: s.in.level = 21; u.info21.acct_flags = acct_type; - u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME; + u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME; comment.string = talloc_asprintf(join, "Tortured by Samba4: %s", timestring(join, time(NULL))); @@ -242,6 +242,10 @@ again: timestring(join, time(NULL))); u.info21.full_name = full_name; + u.info21.description.string = talloc_asprintf(join, + "Samba4 torture account created by host %s: %s", + lp_netbios_name(), timestring(join, time(NULL))); + printf("Resetting ACB flags, force pw change time\n"); status = dcerpc_samr_SetUserInfo(join->p, join, &s); diff --git a/source/torture/rpc/xplogin.c b/source/torture/rpc/xplogin.c index c64825852cf..cf42f938c1d 100644 --- a/source/torture/rpc/xplogin.c +++ b/source/torture/rpc/xplogin.c @@ -180,7 +180,7 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp, uint32_t pipe_version) { const char *binding = lp_parm_string(-1, "torture", "binding"); - struct dcerpc_binding b; + struct dcerpc_binding *b; NTSTATUS status; struct dcerpc_pipe *p; TALLOC_CTX *tmp_ctx; @@ -205,46 +205,23 @@ static NTSTATUS connect_to_pipe(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))); - if (b.endpoint == NULL) { - const struct dcerpc_interface_table *table = - idl_iface_by_uuid(pipe_uuid); - struct dcerpc_binding default_binding; - int i; - - if (!table) { - DEBUG(0,("Unknown interface endpoint '%s'\n", - pipe_uuid)); - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_PARAMETER; - } - - /* Find one of the default pipes for this interface */ - for (i = 0; i < table->endpoints->count; i++) { - const char * const *names = table->endpoints->names; - status = dcerpc_parse_binding(tmp_ctx, names[i], - &default_binding); - - if (NT_STATUS_IS_OK(status) && - default_binding.transport == NCACN_NP) { - pipe_name = default_binding.endpoint; - break; - } + /* Look up identifier using the epmapper */ + if (!b->endpoint) { + status = dcerpc_epm_map_binding(tmp_ctx, b, pipe_uuid, pipe_version); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n", + pipe_uuid, nt_errstr(status))); + talloc_free(p); + return status; } - } else { - pipe_name = b.endpoint; + DEBUG(1,("Mapped to DCERPC/NP pipe %s\n", b->endpoint)); } - if (!strncasecmp(pipe_name, "/pipe/", 6) || - !strncasecmp(pipe_name, "\\pipe\\", 6)) { - pipe_name += 6; - } + pipe_name = b->endpoint; + - if (pipe_name[0] != '\\') { - pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name); - } - status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name); if (!NT_STATUS_IS_OK(status)) { @@ -502,6 +479,9 @@ static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport, a.out.credentials = &credentials3; creds_client_init(creds, &credentials1, &credentials2, + machine_name, + domain, + a.in.account_name, &mach_password, &credentials3, negotiate_flags); @@ -1056,7 +1036,6 @@ static BOOL xp_login(const char *dcname, const char *wksname, status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, - "", "", "", netlogon_creds); if (!NT_STATUS_IS_OK(status)) diff --git a/source/torture/torture.c b/source/torture/torture.c index 32c258068bb..588bf1bcffd 100644 --- a/source/torture/torture.c +++ b/source/torture/torture.c @@ -138,6 +138,7 @@ NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p, } status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version, + lp_netbios_name(), lp_parm_string(-1, "torture", "userdomain"), lp_parm_string(-1, "torture", "username"), lp_parm_string(-1, "torture", "password")); @@ -154,7 +155,7 @@ NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p, { NTSTATUS status; const char *binding = lp_parm_string(-1, "torture", "binding"); - struct dcerpc_binding b; + struct dcerpc_binding *b; TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_connection_smb"); if (!binding) { @@ -169,9 +170,10 @@ NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p, return status; } - b.transport = transport; + b->transport = transport; - status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version, + status = dcerpc_pipe_connect_b(p, b, pipe_uuid, pipe_version, + lp_netbios_name(), lp_parm_string(-1, "torture", "userdomain"), lp_parm_string(-1, "torture", "username"), lp_parm_string(-1, "torture", "password")); @@ -2597,7 +2599,7 @@ static void usage(poptContext pc) static BOOL is_binding_string(const char *binding_string) { TALLOC_CTX *mem_ctx = talloc_init("is_binding_string"); - struct dcerpc_binding binding_struct; + struct dcerpc_binding *binding_struct; NTSTATUS status; status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct); diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c index b527504046d..81c7f90c9b9 100644 --- a/source/utils/ntlm_auth.c +++ b/source/utils/ntlm_auth.c @@ -395,7 +395,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, } if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(1, ("SPENGO login failed to initialise: %s\n", nt_errstr(nt_status))); + DEBUG(1, ("SPNEGO login failed to initialise: %s\n", nt_errstr(nt_status))); mux_printf(mux_id, "BH\n"); return; } |