diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-03-19 08:34:43 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:11:07 -0500 |
commit | df643022136a4b229aca817f5b57f7302a97f852 (patch) | |
tree | e2a2b5b20b5b3c580fd899a4f39a7911ac5ea250 | |
parent | 4037a7e80c3e5d9560b084d9925896d2a5a9518c (diff) | |
download | samba-df643022136a4b229aca817f5b57f7302a97f852.tar.gz samba-df643022136a4b229aca817f5b57f7302a97f852.tar.bz2 samba-df643022136a4b229aca817f5b57f7302a97f852.zip |
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
44 files changed, 714 insertions, 542 deletions
diff --git a/source4/client/client.c b/source4/client/client.c index 59311a35d8..0ebebf747e 100644 --- a/source4/client/client.c +++ b/source4/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/source4/gtk/tools/gepdump.c b/source4/gtk/tools/gepdump.c index d445dd63cb..eeb927e43f 100644 --- a/source4/gtk/tools/gepdump.c +++ b/source4/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/source4/gtk/tools/gwcrontab.c b/source4/gtk/tools/gwcrontab.c index 69ef2d7965..3212821c18 100644 --- a/source4/gtk/tools/gwcrontab.c +++ b/source4/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/source4/gtk/tools/gwsam.c b/source4/gtk/tools/gwsam.c index 69c8dbc361..1a6bc37f2f 100644 --- a/source4/gtk/tools/gwsam.c +++ b/source4/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/source4/lib/com/dcom/main.c b/source4/lib/com/dcom/main.c index 4d9c635be8..d3d44edc71 100644 --- a/source4/lib/com/dcom/main.c +++ b/source4/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/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 2302416554..4a285262c6 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/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/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index bcb462ae9d..90b8313c9d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/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/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h index d1417bf83e..6ce3288b01 100644 --- a/source4/libcli/auth/credentials.h +++ b/source4/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/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index e0fa27359a..d3fa7daae3 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/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/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index a555584840..a4383d852c 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/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/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index 524815382d..51456d9107 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/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/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c index 572ce66bb2..91bc9eadbd 100644 --- a/source4/libcli/auth/ntlmssp.c +++ b/source4/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/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index e8a2356e2c..e17c133c8b 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/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/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c index 92442234bd..a5521d4626 100644 --- a/source4/libcli/auth/schannel.c +++ b/source4/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/source4/libcli/auth/schannel_state.c b/source4/libcli/auth/schannel_state.c index 2a9e0a3ec3..b2d632a1f0 100644 --- a/source4/libcli/auth/schannel_state.c +++ b/source4/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/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c index 48f5e345f4..97660f4eb5 100644 --- a/source4/libnet/libnet_rpc.c +++ b/source4/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/source4/librpc/idl/echo.idl b/source4/librpc/idl/echo.idl index 86e16763c2..d3d0305cb6 100644 --- a/source4/librpc/idl/echo.idl +++ b/source4/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/source4/librpc/idl/schannel.idl b/source4/librpc/idl/schannel.idl index d840d78ef9..f66744fec3 100644 --- a/source4/librpc/idl/schannel.idl +++ b/source4/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/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 1bcf4224c4..ac74788ba6 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -143,6 +143,7 @@ done: */ NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p, const char *uuid, uint_t version, + const char *workstation, const char *domain, const char *username, const char *password, @@ -161,6 +162,13 @@ NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p, return status; } + status = gensec_set_workstation(p->conn->security_state.generic_state, workstation); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client workstation name to %s: %s\n", + workstation, nt_errstr(status))); + return status; + } + status = gensec_set_domain(p->conn->security_state.generic_state, domain); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index d99d43ad58..170ddee1f3 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -33,7 +33,6 @@ struct dcerpc_schannel_state { enum schannel_position state; struct schannel_state *schannel_state; struct creds_CredentialState *creds; - char *account_name; }; /* @@ -104,7 +103,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, NTSTATUS status; struct schannel_bind bind_schannel; struct schannel_bind_ack bind_schannel_ack; - const char *account_name; + const char *workstation; + const char *domain; *out = data_blob(NULL, 0); switch (gensec_security->gensec_role) { @@ -114,7 +114,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, return NT_STATUS_OK; } - status = schannel_start(&dce_schan_state->schannel_state, + status = schannel_start(dce_schan_state, + &dce_schan_state->schannel_state, dce_schan_state->creds->session_key, True); if (!NT_STATUS_IS_OK(status)) { @@ -130,11 +131,11 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, bind_schannel.u.info23.domain = gensec_security->user.domain; bind_schannel.u.info23.account_name = gensec_security->user.name; bind_schannel.u.info23.dnsdomain = str_format_nbt_domain(out_mem_ctx, fulldomainname); - bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, gensec_security->user.name); + bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, gensec_get_workstation(gensec_security)); #else bind_schannel.bind_type = 3; bind_schannel.u.info3.domain = gensec_security->user.domain; - bind_schannel.u.info3.account_name = gensec_security->user.name; + bind_schannel.u.info3.workstation = gensec_get_workstation(gensec_security); #endif status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel, @@ -163,27 +164,29 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, } if (bind_schannel.bind_type == 23) { - account_name = bind_schannel.u.info23.account_name; + workstation = bind_schannel.u.info23.workstation; + domain = bind_schannel.u.info23.domain; } else { - account_name = bind_schannel.u.info3.account_name; + workstation = bind_schannel.u.info3.workstation; + domain = bind_schannel.u.info3.domain; } /* pull the session key for this client */ - status = schannel_fetch_session_key(out_mem_ctx, account_name, &dce_schan_state->creds); + status = schannel_fetch_session_key(out_mem_ctx, workstation, + domain, &dce_schan_state->creds); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not find session key for attempted schannel connection on %s: %s\n", - account_name, nt_errstr(status))); + DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", + workstation, nt_errstr(status))); return status; } - dce_schan_state->account_name = talloc_strdup(dce_schan_state, account_name); - /* start up the schannel server code */ - status = schannel_start(&dce_schan_state->schannel_state, + status = schannel_start(dce_schan_state, + &dce_schan_state->schannel_state, dce_schan_state->creds->session_key, False); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not initialise schannel state for account %s: %s\n", - account_name, nt_errstr(status))); + DEBUG(3, ("Could not initialise schannel state from client %s: %s\n", + workstation, nt_errstr(status))); return status; } talloc_steal(dce_schan_state, dce_schan_state->schannel_state); @@ -195,8 +198,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack, (ndr_push_flags_fn_t)ndr_push_schannel_bind_ack); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not return schannel bind ack for account %s: %s\n", - account_name, nt_errstr(status))); + DEBUG(3, ("Could not return schannel bind ack for client %s: %s\n", + workstation, nt_errstr(status))); return status; } @@ -248,18 +251,6 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, } -/* - end crypto state -*/ -static int dcerpc_schannel_destroy(void *ptr) -{ - struct dcerpc_schannel_state *dce_schan_state = ptr; - - schannel_end(&dce_schan_state->schannel_state); - - return 0; -} - static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security) { struct dcerpc_schannel_state *dce_schan_state; @@ -272,8 +263,6 @@ static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security) dce_schan_state->state = DCERPC_SCHANNEL_STATE_START; gensec_security->private_data = dce_schan_state; - talloc_set_destructor(dce_schan_state, dcerpc_schannel_destroy); - return NT_STATUS_OK; } @@ -306,6 +295,7 @@ static NTSTATUS dcerpc_schannel_client_start(struct gensec_security *gensec_secu get a schannel key using a netlogon challenge on a secondary pipe */ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, + const char *workstation, const char *domain, const char *username, const char *password, @@ -313,13 +303,15 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, struct creds_CredentialState *creds) { NTSTATUS status; + struct dcerpc_binding *b; struct dcerpc_pipe *p2; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate2 a; struct netr_Credential credentials1, credentials2, credentials3; struct samr_Password mach_pwd; - const char *workgroup, *workstation; + const char *workgroup; uint32_t negotiate_flags; + TALLOC_CTX *tmp_ctx; if (p->conn->flags & DCERPC_SCHANNEL_128) { negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; @@ -327,20 +319,45 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; } - workstation = username; workgroup = domain; + tmp_ctx = talloc_new(NULL); + /* step 1 - establish a netlogon connection, with no authentication */ - status = dcerpc_secondary_connection(p, &p2, - DCERPC_NETLOGON_NAME, - DCERPC_NETLOGON_UUID, - DCERPC_NETLOGON_VERSION); + + /* Find the original binding string */ + status = dcerpc_parse_binding(tmp_ctx, p->conn->binding_string, &b); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string)); + talloc_free(tmp_ctx); return status; } + /* Make binding string for netlogon, not the other pipe */ + status = dcerpc_epm_map_binding(tmp_ctx, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n", + DCERPC_NETLOGON_UUID, nt_errstr(status))); + talloc_free(p); + return status; + } + + status = dcerpc_secondary_connection(p, &p2, b); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + talloc_free(tmp_ctx); + + status = dcerpc_bind_auth_none(p2, DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(p2); + return status; + } /* step 2 - request a netlogon challenge @@ -361,11 +378,13 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, step 3 - authenticate on the netlogon pipe */ E_md4hash(password, mach_pwd.hash); - creds_client_init(creds, &credentials1, &credentials2, &mach_pwd, &credentials3, + creds_client_init(creds, &credentials1, &credentials2, + workstation, domain, username, + &mach_pwd, &credentials3, negotiate_flags); a.in.server_name = r.in.server_name; - a.in.account_name = talloc_asprintf(p, "%s$", workstation); + a.in.account_name = username; a.in.secure_channel_type = chan_type; a.in.computer_name = workstation; a.in.negotiate_flags = &negotiate_flags; @@ -398,9 +417,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p, */ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, const char *uuid, uint_t version, - const char *domain, - const char *username, - const char *password, struct creds_CredentialState *creds) { NTSTATUS status; @@ -411,17 +427,28 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, return status; } - status = gensec_set_username(p->conn->security_state.generic_state, username); + status = gensec_set_workstation(p->conn->security_state.generic_state, creds->computer_name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set schannel workstation to %s: %s\n", + creds->computer_name, nt_errstr(status))); + talloc_free(p->conn->security_state.generic_state); + p->conn->security_state.generic_state = NULL; + return status; + } + + status = gensec_set_username(p->conn->security_state.generic_state, creds->account_name); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status))); + DEBUG(1, ("Failed to set schannel username to %s: %s\n", + creds->account_name, nt_errstr(status))); talloc_free(p->conn->security_state.generic_state); p->conn->security_state.generic_state = NULL; return status; } - status = gensec_set_domain(p->conn->security_state.generic_state, domain); + status = gensec_set_domain(p->conn->security_state.generic_state, creds->domain); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set schannel domain to %s: %s\n", domain, nt_errstr(status))); + DEBUG(1, ("Failed to set schannel domain to %s: %s\n", + creds->domain, nt_errstr(status))); talloc_free(p->conn->security_state.generic_state); p->conn->security_state.generic_state = NULL; return status; @@ -456,6 +483,7 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p, NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, const char *uuid, uint_t version, + const char *workstation, const char *domain, const char *username, const char *password) @@ -477,6 +505,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, } status = dcerpc_schannel_key(p, domain, + workstation, username, password, chan_type, @@ -488,9 +517,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p, return status; } - return dcerpc_bind_auth_schannel_withkey(p, uuid, version, domain, - username, password, - creds); + return dcerpc_bind_auth_schannel_withkey(p, uuid, version, creds); } static BOOL dcerpc_schannel_have_feature(struct gensec_security *gensec_security, diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index aa2d0bf20f..1a5a31c330 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -375,7 +375,19 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c, struct smb_private *smb; NTSTATUS status; union smb_open io; + char *pipe_name_talloc; + if (!strncasecmp(pipe_name, "/pipe/", 6) || + !strncasecmp(pipe_name, "\\pipe\\", 6)) { + pipe_name += 6; + } + + if (pipe_name[0] != '\\') { + pipe_name_talloc = talloc_asprintf(NULL, "\\%s", pipe_name); + } else { + pipe_name_talloc = talloc_strdup(NULL, pipe_name); + } + io.ntcreatex.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.flags = 0; io.ntcreatex.in.root_fid = 0; @@ -394,10 +406,12 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c, io.ntcreatex.in.create_options = 0; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; io.ntcreatex.in.security_flags = 0; - io.ntcreatex.in.fname = pipe_name; + io.ntcreatex.in.fname = pipe_name_talloc; status = smb_raw_open(tree, tree, &io); + talloc_free(pipe_name_talloc); + if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 7b753d1b30..91e6ea9397 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -323,12 +323,18 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi /* parse a binding string into a dcerpc_binding structure */ -NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding *b) +NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out) { + struct dcerpc_binding *b; char *options, *type; char *p; int i, j, comma_count; + b = talloc(mem_ctx, struct dcerpc_binding); + if (!b) { + return NT_STATUS_NO_MEMORY; + } + p = strchr(s, '@'); if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ @@ -373,14 +379,14 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ p = strchr(s, '['); if (p) { - b->host = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); + b->host = talloc_strndup(b, s, PTR_DIFF(p, s)); options = talloc_strdup(mem_ctx, p+1); if (options[strlen(options)-1] != ']') { return NT_STATUS_INVALID_PARAMETER; } options[strlen(options)-1] = 0; } else { - b->host = talloc_strdup(mem_ctx, s); + b->host = talloc_strdup(b, s); options = NULL; } @@ -393,18 +399,19 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ b->endpoint = NULL; if (!options) { + *b_out = b; return NT_STATUS_OK; } comma_count = count_chars(options, ','); - b->options = talloc_array(mem_ctx, const char *, comma_count+2); + b->options = talloc_array(b, const char *, comma_count+2); if (!b->options) { return NT_STATUS_NO_MEMORY; } for (i=0; (p = strchr(options, ',')); i++) { - b->options[i] = talloc_strndup(mem_ctx, options, PTR_DIFF(p, options)); + b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options)); if (!b->options[i]) { return NT_STATUS_NO_MEMORY; } @@ -441,6 +448,7 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ if (b->options[0] == NULL) b->options = NULL; + *b_out = b; return NT_STATUS_OK; } @@ -657,9 +665,13 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower) return -1; } -NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding *binding) +NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding **b_out) { NTSTATUS status; + struct dcerpc_binding *binding; + + binding = talloc(mem_ctx, struct dcerpc_binding); + NT_STATUS_HAVE_NO_MEMORY(binding); ZERO_STRUCT(binding->object); binding->options = NULL; @@ -699,6 +711,7 @@ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, if (tower->num_floors >= 5) { binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]); } + *b_out = binding; return NT_STATUS_OK; } @@ -773,7 +786,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding * } NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, - const char *uuid, uint_t version) + const char *uuid, uint_t version) { struct dcerpc_pipe *p; NTSTATUS status; @@ -781,42 +794,51 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind struct policy_handle handle; struct GUID guid; struct epm_twr_t twr, *twr_r; - struct dcerpc_binding epmapper_binding; + struct dcerpc_binding *epmapper_binding; const struct dcerpc_interface_table *table = idl_iface_by_uuid(uuid); int i; /* First, check if there is a default endpoint specified in the IDL */ if (table) { - struct dcerpc_binding default_binding; + struct dcerpc_binding *default_binding; - binding->authservice = talloc_strdup(mem_ctx, table->authservices->names[0]); + binding->authservice = talloc_strdup(binding, table->authservices->names[0]); /* Find one of the default pipes for this interface */ for (i = 0; i < table->endpoints->count; i++) { status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding); - if (NT_STATUS_IS_OK(status) && default_binding.transport == binding->transport && default_binding.endpoint) { - binding->endpoint = talloc_strdup(mem_ctx, default_binding.endpoint); - return NT_STATUS_OK; + if (NT_STATUS_IS_OK(status)) { + if (default_binding->transport == binding->transport && default_binding->endpoint) { + binding->endpoint = talloc_reference(binding, default_binding->endpoint); + talloc_free(default_binding); + return NT_STATUS_OK; + } else { + talloc_free(default_binding); + } } } } + epmapper_binding = talloc_zero(mem_ctx, struct dcerpc_binding); + if (!epmapper_binding) { + return NT_STATUS_NO_MEMORY; + } - ZERO_STRUCT(epmapper_binding); - epmapper_binding.transport = binding->transport; - epmapper_binding.host = binding->host; - epmapper_binding.options = NULL; - epmapper_binding.flags = 0; - epmapper_binding.endpoint = NULL; - epmapper_binding.authservice = NULL; + epmapper_binding->transport = binding->transport; + epmapper_binding->host = talloc_reference(epmapper_binding, + binding->host); + epmapper_binding->options = NULL; + epmapper_binding->flags = 0; + epmapper_binding->endpoint = NULL; + epmapper_binding->authservice = NULL; status = dcerpc_pipe_connect_b(&p, - &epmapper_binding, - DCERPC_EPMAPPER_UUID, - DCERPC_EPMAPPER_VERSION, - NULL, NULL, NULL); + epmapper_binding, + DCERPC_EPMAPPER_UUID, + DCERPC_EPMAPPER_VERSION, + NULL, NULL, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { return status; @@ -866,7 +888,7 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind return NT_STATUS_PORT_UNREACHABLE; } - binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &twr_r->tower.floors[3]); + binding->endpoint = talloc_reference(binding, dcerpc_floor_get_rhs_data(mem_ctx, &twr_r->tower.floors[3])); dcerpc_pipe_close(p); @@ -877,13 +899,14 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind /* perform an authenticated bind if needed */ -static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, - struct dcerpc_binding *binding, - const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) +NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, + struct dcerpc_binding *binding, + const char *pipe_uuid, + uint32_t pipe_version, + const char *workstation, + const char *domain, + const char *username, + const char *password) { NTSTATUS status; p->conn->flags = binding->flags; @@ -893,7 +916,8 @@ static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) { status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, - domain, username, password); + domain, workstation, + username, password); } else if (username && username[0]) { uint8_t auth_type; if (binding->flags & DCERPC_AUTH_SPNEGO) { @@ -905,6 +929,7 @@ static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, } status = dcerpc_bind_auth_password(p, pipe_uuid, pipe_version, + workstation, domain, username, password, auth_type, binding->authservice); @@ -925,6 +950,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, uint32_t pipe_version, + const char *workstation, const char *domain, const char *username, const char *password) @@ -957,23 +983,14 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, pipe_name = binding->endpoint; - if (!strncasecmp(pipe_name, "/pipe/", 6) || - !strncasecmp(pipe_name, "\\pipe\\", 6)) { - pipe_name += 6; - } - - if (pipe_name[0] != '\\') { - pipe_name = talloc_asprintf(tmp_ctx, "\\%s", pipe_name); - } - if (!username || !username[0] || (binding->flags & DCERPC_SCHANNEL_ANY)) { - status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(), + status = smbcli_full_connection(p->conn, &cli, workstation, binding->host, "ipc$", NULL, "", "", NULL); } else { - status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(), + status = smbcli_full_connection(p->conn, &cli, workstation, binding->host, "ipc$", NULL, username, domain, @@ -995,12 +1012,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, if (!(binding->flags & DCERPC_AUTH_OPTIONS)) { username = NULL; } - - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } (*pp) = p; talloc_free(tmp_ctx); @@ -1013,10 +1024,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp, static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) + uint32_t pipe_version) { NTSTATUS status; struct dcerpc_pipe *p; @@ -1050,12 +1058,6 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp, return status; } - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } - (*pp) = p; talloc_free(tmp_ctx); @@ -1069,10 +1071,7 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp, static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) + uint32_t pipe_version) { NTSTATUS status; struct dcerpc_pipe *p; @@ -1097,12 +1096,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp, return status; } - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } - (*pp) = p; return status; @@ -1113,10 +1106,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp, static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, - uint32_t pipe_version, - const char *domain, - const char *username, - const char *password) + uint32_t pipe_version) { NTSTATUS status; uint32_t port = 0; @@ -1153,12 +1143,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp, return status; } - status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); - return status; - } - (*pp) = p; talloc_free(tmp_ctx); @@ -1172,33 +1156,42 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **pp, struct dcerpc_binding *binding, const char *pipe_uuid, uint32_t pipe_version, + const char *workstation, const char *domain, const char *username, const char *password) { NTSTATUS status = NT_STATUS_INVALID_PARAMETER; - + switch (binding->transport) { case NCACN_NP: status = dcerpc_pipe_connect_ncacn_np(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + workstation, domain, username, password); break; case NCACN_IP_TCP: - status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version); break; case NCACN_UNIX_STREAM: - status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version); break; case NCALRPC: - status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version, - domain, username, password); + status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version); break; default: return NT_STATUS_NOT_SUPPORTED; } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = dcerpc_pipe_auth(*pp, binding, pipe_uuid, pipe_version, workstation, domain, username, password); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(*pp); + *pp = NULL; + return status; + } + return status; } @@ -1209,15 +1202,19 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp, const char *binding, const char *pipe_uuid, uint32_t pipe_version, + const char *workstation, const char *domain, const char *username, const char *password) { - struct dcerpc_binding b; + struct dcerpc_binding *b; NTSTATUS status; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return NT_STATUS_NO_MEMORY; + } status = dcerpc_parse_binding(tmp_ctx, binding, &b); if (!NT_STATUS_IS_OK(status)) { @@ -1226,9 +1223,10 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp, return status; } - DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b))); + DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, b))); - status = dcerpc_pipe_connect_b(pp, &b, pipe_uuid, pipe_version, domain, username, password); + status = dcerpc_pipe_connect_b(pp, b, pipe_uuid, pipe_version, workstation, + domain, username, password); talloc_free(tmp_ctx); @@ -1243,13 +1241,12 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp, will be on the same SMB connection, but use a new fnum */ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe **p2, - const char *pipe_name, - const char *pipe_uuid, - uint32_t pipe_version) + struct dcerpc_binding *b) + + { struct smbcli_tree *tree; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; - struct dcerpc_binding b; (*p2) = dcerpc_pipe_init(p); if (*p2 == NULL) { @@ -1262,23 +1259,15 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe * if (!tree) { return NT_STATUS_INVALID_PARAMETER; } - status = dcerpc_pipe_open_smb((*p2)->conn, tree, pipe_name); + status = dcerpc_pipe_open_smb((*p2)->conn, tree, b->endpoint); break; case NCACN_IP_TCP: - status = dcerpc_parse_binding(p, p->conn->binding_string, &b); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = dcerpc_pipe_open_tcp((*p2)->conn, b.host, atoi(b.endpoint)); + status = dcerpc_pipe_open_tcp((*p2)->conn, b->host, atoi(b->endpoint)); break; case NCALRPC: - status = dcerpc_parse_binding(p, p->conn->binding_string, &b); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = dcerpc_pipe_open_pipe((*p2)->conn, b.endpoint); + status = dcerpc_pipe_open_pipe((*p2)->conn, b->endpoint); break; default: @@ -1292,12 +1281,6 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe * (*p2)->conn->flags = p->conn->flags; - status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(*p2); - return status; - } - return NT_STATUS_OK; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index abb4c51f65..68c59b7502 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/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/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c0cd221da6..b050830883 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/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/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index c3a779326e..77fb76448c 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/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/source4/rpc_server/dcerpc_sock.c b/source4/rpc_server/dcerpc_sock.c index d2ebf794b3..56b55a9fbf 100644 --- a/source4/rpc_server/dcerpc_sock.c +++ b/source4/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/source4/rpc_server/epmapper/rpc_epmapper.c b/source4/rpc_server/epmapper/rpc_epmapper.c index 8a61fc6428..d7d447f852 100644 --- a/source4/rpc_server/epmapper/rpc_epmapper.c +++ b/source4/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/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index fd93d495e2..6a29bf7db8 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/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/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index ee526e1978..9ed6b5a1bd 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/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/source4/torture/libnet/userinfo.c b/source4/torture/libnet/userinfo.c index c541474a75..9a775277cb 100644 --- a/source4/torture/libnet/userinfo.c +++ b/source4/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/source4/torture/local/binding_string.c b/source4/torture/local/binding_string.c index 66e8a5350f..79d1e89ed6 100644 --- a/source4/torture/local/binding_string.c +++ b/source4/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/source4/torture/rpc/bind.c b/source4/torture/rpc/bind.c index 10ffa50289..3eb02c31eb 100644 --- a/source4/torture/rpc/bind.c +++ b/source4/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/source4/torture/rpc/epmapper.c b/source4/torture/rpc/epmapper.c index eecfdb3f89..debcd98756 100644 --- a/source4/torture/rpc/epmapper.c +++ b/source4/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/source4/torture/rpc/mgmt.c b/source4/torture/rpc/mgmt.c index 1dea24517d..cb2023b64c 100644 --- a/source4/torture/rpc/mgmt.c +++ b/source4/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/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 7c516da118..2266659c37 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/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/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 4fe7903332..e08eaca22e 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/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/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index cd39b625c3..505e331d19 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/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/source4/torture/rpc/scanner.c b/source4/torture/rpc/scanner.c index a0ebf9d642..3d78d7a888 100644 --- a/source4/torture/rpc/scanner.c +++ b/source4/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/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index 820dfaf4a5..1b10e2a4f2 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/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/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 7a9d8c3635..e5c827afaa 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/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/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 891bbcaf10..2d96116c0d 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/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/source4/torture/rpc/xplogin.c b/source4/torture/rpc/xplogin.c index c64825852c..cf42f938c1 100644 --- a/source4/torture/rpc/xplogin.c +++ b/source4/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/source4/torture/torture.c b/source4/torture/torture.c index 32c258068b..588bf1bcff 100644 --- a/source4/torture/torture.c +++ b/source4/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/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c index b527504046..81c7f90c9b 100644 --- a/source4/utils/ntlm_auth.c +++ b/source4/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; } |