r5902: A rather large change...
authorAndrew Bartlett <abartlet@samba.org>
Sat, 19 Mar 2005 08:34:43 +0000 (08:34 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:11:07 +0000 (13:11 -0500)
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:
source4/client/client.c
source4/gtk/tools/gepdump.c
source4/gtk/tools/gwcrontab.c
source4/gtk/tools/gwsam.c
source4/lib/com/dcom/main.c
source4/lib/registry/reg_backend_rpc.c
source4/libcli/auth/credentials.c
source4/libcli/auth/credentials.h
source4/libcli/auth/gensec.c
source4/libcli/auth/gensec.h
source4/libcli/auth/gensec_ntlmssp.c
source4/libcli/auth/ntlmssp.c
source4/libcli/auth/ntlmssp.h
source4/libcli/auth/schannel.c
source4/libcli/auth/schannel_state.c
source4/libnet/libnet_rpc.c
source4/librpc/idl/echo.idl
source4/librpc/idl/schannel.idl
source4/librpc/rpc/dcerpc_auth.c
source4/librpc/rpc/dcerpc_schannel.c
source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_util.c
source4/ntvfs/ipc/vfs_ipc.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h
source4/rpc_server/dcerpc_sock.c
source4/rpc_server/epmapper/rpc_epmapper.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/remote/dcesrv_remote.c
source4/torture/libnet/userinfo.c
source4/torture/local/binding_string.c
source4/torture/rpc/bind.c
source4/torture/rpc/epmapper.c
source4/torture/rpc/mgmt.c
source4/torture/rpc/netlogon.c
source4/torture/rpc/samlogon.c
source4/torture/rpc/samsync.c
source4/torture/rpc/scanner.c
source4/torture/rpc/schannel.c
source4/torture/rpc/spoolss.c
source4/torture/rpc/testjoin.c
source4/torture/rpc/xplogin.c
source4/torture/torture.c
source4/utils/ntlm_auth.c

index 59311a35d85293b5de48163a4432947de7629fac..0ebebf747e2f6373c85d31a4545c901fe95bcb52 100644 (file)
@@ -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)) {
index d445dd63cbece5c5449205b63143974b29da4c8c..eeb927e43fceb44a99145af02cb5c8e4c311ebd6 100644 (file)
@@ -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);
index 69ef2d7965b79f2dfc2fa0dc279b4273c70d855c..3212821c18a577dd60645ac8b1a8d0905e133b9b 100644 (file)
@@ -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);
index 69c8dbc36118b0202d5783335ef4da38e626208f..1a6bc37f2f8b51bf5a70bb46a2964730db6f602a 100644 (file)
@@ -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);
index 4d9c635be84840b3c636cf3fdc14261b5caa5298..d3d44edc71cbd8b47f752f16fad0856ddd4a562e 100644 (file)
@@ -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)));
index 230241655455745f618e8b225dfe6ad68a6e1d7b..4a285262c60dd4ad155526025774bc9a8d4da87b 100644 (file)
@@ -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;
index bcb462ae9da9e82248bbf435a77c8e8a05f3ac4b..90b8313c9d8558e9153b2d7cc699bca8c5f68faf 100644 (file)
@@ -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));
index d1417bf83e78e35b1b5bacd9f497f47b143664bc..6ce3288b014d9ee8e3f84c9b882686eacf94b0e8 100644 (file)
@@ -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;
index e0fa27359a2ec7eefa563b6366f2ac00de018256..d3fa7daae3dd02b95f7581a9ead9f9c16dbeadaa 100644 (file)
@@ -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, 
@@ -617,6 +617,34 @@ const char *gensec_get_domain(struct gensec_security *gensec_security)
        return gensec_security->default_user.domain;
 }
 
+/** 
+ * 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 
  *
index a555584840e521543c222f30257c4a429e539b05..a4383d852c52227b171459cb00ef9222c0d2d24c 100644 (file)
@@ -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,
index 524815382d6b5f03a1e1158198c6a52d7fc67e12..51456d9107017b6cb7f4739d1ed7a5a8f8161834 100644 (file)
@@ -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;
index 572ce66bb2e79c670d735430db18c5c2157918c3..91bc9eadbd88c7a19063a9d6dc11ace5b4ee4096 100644 (file)
@@ -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);
index e8a2356e2c89890d6c6cdcf3338b4af519d54d55..e17c133c8ba975dab1974dc342c08ae1183ae366 100644 (file)
@@ -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 */
index 92442234bda90fd2f633b5fb6550dd86c8e59b6a..a5521d46263cbe2dde69365b532c4f87f2b8d865 100644 (file)
@@ -271,25 +271,15 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state,
        return NT_STATUS_OK;
 }
 
-/*
-  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;
        }
index 2a9e0a3ec397459d951300f6dc82f99103296cb9..b2d632a1f0e5fb56ae012cae94dda08905217994 100644 (file)
@@ -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);
index 48f5e345f469429bf745343e429f0381d8c4dd12..97660f4eb5ef9ce5e61ab8f6bb193dca56c950e3 100644 (file)
@@ -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",
index 86e16763c2bea7d2e97b657426a50db314026d7e..d3d0305cb6dd001f4ed2aee82d96dfa9a2029009 100644 (file)
@@ -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[]
        );
 
 
index d840d78ef9993fd51cca0638870a4786872cd346..f66744fec3aa2dad4f26bd73d3b170b28e51ed3d 100644 (file)
@@ -15,7 +15,7 @@ interface schannel
        */
        typedef struct {
                astring domain;
-               astring account_name;
+               astring workstation;
        } schannel_bind_3;
 
        typedef struct {
index 1bcf4224c46a5905499f6bd846014e82befb81c4..ac74788ba6c2c6ce1b10917452055cc286b9a789 100644 (file)
@@ -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", 
index d99d43ad5875a276c2c15a3f72e5bc5d6a97bf80..170ddee1f300545135d53e802c73ff561c243288 100644 (file)
@@ -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,
index aa2d0bf20f023cf17c6ea289d4075dabdddf0ef0..1a5a31c330fb69f1a6aab02a55d3b553579f6638 100644 (file)
@@ -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;
         }
index 7b753d1b3070a9dfaf9b762d5bbdf5e8d793115b..91e6ea9397304cc64c5dca66842f9dbeeb485eb2 100644 (file)
@@ -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;
 }
 
index abb4c51f65f7964c085e9c219c287b37152e6ae1..68c59b75027a6cf08af8d4e299b0c06030f4036d 100644 (file)
@@ -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);
index c0cd221da6ad00dcc09178bb6a0e50001ac5bfef..b050830883dd8c002e55443d71d73c85d8a2ec6c 100644 (file)
@@ -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;
        }
 
index c3a779326e62fe271d8da3231882f9f2e4ff867c..77fb76448c370edf491fe4a16c838d4e3d65d611 100644 (file)
@@ -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 */
index d2ebf794b36e6c851c2e9721f94cba64174e39f1..56b55a9fbf919274d36b2cff936f07e7755b44bb 100644 (file)
@@ -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);
index 8a61fc642814306af35a121408d4bb1219e88382..d7d447f852f5978d930435810d2328ac5d07b457 100644 (file)
@@ -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;
index fd93d495e2a242201f7a67cccb814b0e8b721fed..6a29bf7db84b7eaf947ac9524a7d5a0e229d4871 100644 (file)
@@ -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);
 
index ee526e1978f0ab692d29d332e32301944ce1646c..9ed6b5a1bdf8bb7fbf99165751f9aefe27c5abd5 100644 (file)
@@ -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"));
index c541474a751892d6f082eb5adf9808c196ede1f1..9a775277cb8aa547a201a41ba84aaaa9765445a9 100644 (file)
@@ -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;
index 66e8a5350f739619fe7f60a25cb4d3f482e1da54..79d1e89ed6f94a9cb543526c7eb7744b2da4c1ab 100644 (file)
@@ -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;
index 10ffa5028998004d146c1c7e5e5a1c1746b8d05b..3eb02c31eb5feed499b88f76491ac9f58e947d3c 100644 (file)
 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", 
index eecfdb3f89892695d81f8fc642610094f17791dc..debcd987566193d93a3fb4ec8bf1fdfbadbe58d6 100644 (file)
@@ -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;
index 1dea24517dc22e0ebb3cc743397bd23ccffa043a..cb2023b64c6c2ec0d2d49633837ddad4ecf42e05 100644 (file)
@@ -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,
index 7c516da11804a9beb0e218147a243905d7e35303..2266659c3795e5cc940ad66de67e3bbefab3af8e 100644 (file)
@@ -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;
index 4fe79033325aca48dd633b83a8b0376ae23860ae..e08eaca22eaf66e0f6826d4444f0fbaf55c42db2 100644 (file)
@@ -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;
 }
index cd39b625c363e136d528e95183d5f581ab3f19af..505e331d19ad81296910f62202aa07f386f2be48 100644 (file)
@@ -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;
        }
index a0ebf9d6425dade1e76f84ead5953503478213b6..3d78d7a888247252fab463546433bf860668ce68 100644 (file)
@@ -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,
index 820dfaf4a5d9a72ecc3abdde9587b4196839d59f..1b10e2a4f275160a910a3797e1ec105a70a36906 100644 (file)
@@ -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;
index 7a9d8c3635ce3e042415a6b624fb417ae670186f..e5c827afaab238722da0500532b04241fa4749ec 100644 (file)
@@ -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;
index 891bbcaf10fed158cbc155b1e0daa7ff9d4be653..2d96116c0da08e4d646544a7287ace84e03b75ef 100644 (file)
@@ -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);
index c64825852cf1e48057ee4ead7cd8a9a82878656e..cf42f938c1d90b4a9c2ec14ab8f34f8772a88208 100644 (file)
@@ -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))
index 32c258068bbde15aa0f9ca054714b33617c6b245..588bf1bcffdaa426f22d696682d2f791157348c5 100644 (file)
@@ -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);
index b527504046d53eb0c51677a741395f84d64070e1..81c7f90c9b9961c3af918a1766240493d9747f25 100644 (file)
@@ -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;
                }