r6028: A MAJOR update to intergrate the new credentails system fully with
authorAndrew Bartlett <abartlet@samba.org>
Thu, 24 Mar 2005 04:14:06 +0000 (04:14 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:11:15 +0000 (13:11 -0500)
GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'.

GENSEC now no longer has it's own handling of 'set username' etc,
instead it uses cli_credentials calls.

In order to link the credentails code right though Samba, a lot of
interfaces have changed to remove 'username, domain, password'
arguments, and these have been replaced with a single 'struct
cli_credentials'.

In the session setup code, a new parameter 'workgroup' contains the
client/server current workgroup, which seems unrelated to the
authentication exchange (it was being filled in from the auth info).

This allows in particular kerberos to only call back for passwords
when it actually needs to perform the kinit.

The kerberos code has been modified not to use the SPNEGO provided
'principal name' (in the mechListMIC), but to instead use the name the
host was connected to as.  This better matches Microsoft behaviour,
is more secure and allows better use of standard kerberos functions.

To achieve this, I made changes to our socket code so that the
hostname (before name resolution) is now recorded on the socket.

In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now
in libcli/auth/schannel.c, and it looks much more like a standard
GENSEC module.  The actual sign/seal code moved to
libcli/auth/schannel_sign.c in a previous commit.

The schannel credentails structure is now merged with the rest of the
credentails, as many of the values (username, workstation, domain)
where already present there.  This makes handling this in a generic
manner much easier, as there is no longer a custom entry-point.

The auth_domain module continues to be developed, but is now just as
functional as auth_winbind.  The changes here are consequential to the
schannel changes.

The only removed function at this point is the RPC-LOGIN test
(simulating the load of a WinXP login), which needs much more work to
clean it up (it contains copies of too much code from all over the
torture suite, and I havn't been able to penetrate its 'structure').

Andrew Bartlett
(This used to be commit 2301a4b38a21aa60917973451687063d83d18d66)

45 files changed:
source4/auth/auth_domain.c
source4/client/client.c
source4/include/smb_interfaces.h
source4/libcli/auth/config.mk
source4/libcli/auth/credentials.c
source4/libcli/auth/gensec.c
source4/libcli/auth/gensec.h
source4/libcli/auth/gensec.mk
source4/libcli/auth/gensec_krb5.c
source4/libcli/auth/gensec_ntlmssp.c
source4/libcli/auth/kerberos.h
source4/libcli/auth/ntlmssp_sign.c
source4/libcli/auth/schannel.c [new file with mode: 0644]
source4/libcli/auth/schannel_sign.c
source4/libcli/auth/spnego.c
source4/libcli/cliconnect.c
source4/libcli/composite/composite.h
source4/libcli/composite/connect.c
source4/libcli/composite/fetchfile.c
source4/libcli/composite/sesssetup.c
source4/libcli/ldap/ldap.h
source4/libcli/ldap/ldap_client.c
source4/libcli/raw/clisession.c
source4/libcli/raw/clisocket.c
source4/libcli/raw/clitree.c
source4/librpc/config.mk
source4/librpc/rpc/dcerpc_auth.c
source4/librpc/rpc/dcerpc_schannel.c
source4/librpc/rpc/dcerpc_util.c
source4/ntvfs/cifs/vfs_cifs.c
source4/smb_server/reply.c
source4/smb_server/sesssetup.c
source4/torture/basic/secleak.c
source4/torture/gentest.c
source4/torture/ldap/basic.c
source4/torture/ldap/common.c
source4/torture/locktest.c
source4/torture/masktest.c
source4/torture/raw/composite.c
source4/torture/raw/context.c
source4/torture/rpc/netlogon.c
source4/torture/rpc/schannel.c
source4/torture/rpc/xplogin.c
source4/torture/torture.c
source4/utils/ntlm_auth.c

index 6a968592bdc3cb97cfaa2d96581591dd6eeedf94..a6950445cbcf7fb16882c2e3ebbc97ecd5c7fa40 100644 (file)
@@ -51,7 +51,15 @@ static NTSTATUS domain_check_password(struct auth_method_context *ctx,
                binding = bindings[0];
        }
 
+       if (!user_info->account_name) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       if (!user_info->workstation_name) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
        credentials = cli_credentials_init(mem_ctx);
+       cli_credentials_set_conf(credentials);
        status = cli_credentials_set_machine_account(credentials);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -101,7 +109,7 @@ static NTSTATUS domain_check_password(struct auth_method_context *ctx,
        ninfo.lm.data = user_info->lm_resp.data;
 
        r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
-       r.in.workstation = creds->computer_name;
+       r.in.workstation = cli_credentials_get_workstation(credentials);
        r.in.credential = &auth;
        r.in.return_authenticator = &auth2;
        r.in.logon_level = 2;
index 4ce686cdcfd6586c0976d6386837e8dfaa55bdbd..9738292f037978e33eaa24a6ec60bbeed3c6f793 100644 (file)
@@ -3043,7 +3043,7 @@ static struct smbcli_state *do_connect(const char *server, const char *share, st
                smbcli_parse_unc(share, NULL, &server, &share);
        }
        
-       status = smbcli_full_connection(NULL, &c, lp_netbios_name(), server,
+       status = smbcli_full_connection(NULL, &c, server,
                                        share, NULL, cred);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Connection to \\\\%s\\%s failed - %s\n", 
index 1052a6297d590052c8fa8f7cce40032d70e622f4..af9f6efd7a2ceba3a6a124be61b3936e3b1a0d24 100644 (file)
@@ -269,14 +269,14 @@ union smb_sesssetup {
                        DATA_BLOB secblob;
                        const char *os;
                        const char *lanman;
-                       const char *domain;
+                       const char *workgroup;
                } in;
                struct {
                        uint16_t action;
                        DATA_BLOB secblob;
                        char *os;
                        char *lanman;
-                       char *domain;
+                       char *workgroup;
                        uint16_t vuid;
                } out;
        } spnego;
index b37e2143605ed71e2f022cea33ed083a2335a1c3..0c013ce0ef88db9027141c22f0e14bcbb5e694d0 100644 (file)
@@ -1,8 +1,7 @@
 #################################
 # Start SUBSYSTEM GENSEC
 [SUBSYSTEM::LIBCLI_AUTH]
-ADD_OBJ_FILES = libcli/auth/schannel_sign.o \
-               libcli/auth/credentials.o \
+ADD_OBJ_FILES = libcli/auth/credentials.o \
                libcli/auth/session.o \
                libcli/auth/smbencrypt.o 
 REQUIRED_SUBSYSTEMS = \
index 90b8313c9d8558e9153b2d7cc699bca8c5f68faf..bcb462ae9da9e82248bbf435a77c8e8a05f3ac4b 100644 (file)
@@ -192,18 +192,12 @@ 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 69de016156729ca2aaef0f6f11e65c8bf9d7abbd..cc7327187cb02702d0d1dc3abca541962a979014 100644 (file)
@@ -4,7 +4,7 @@
    Generic Authentication Interface
 
    Copyright (C) Andrew Tridgell 2003
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -130,13 +130,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense
 
        (*gensec_security)->ops = NULL;
 
-       ZERO_STRUCT((*gensec_security)->user);
        ZERO_STRUCT((*gensec_security)->target);
-       ZERO_STRUCT((*gensec_security)->default_user);
-
-       (*gensec_security)->default_user.name = "";
-       (*gensec_security)->default_user.domain = talloc_strdup(*gensec_security, lp_workgroup());
-       (*gensec_security)->default_user.realm = talloc_strdup(*gensec_security, lp_realm());
 
        (*gensec_security)->subcontext = False;
        (*gensec_security)->want_features = 0;
@@ -185,8 +179,6 @@ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense
        (*gensec_security)->gensec_role = GENSEC_CLIENT;
        (*gensec_security)->password_callback = NULL;
 
-       ZERO_STRUCT((*gensec_security)->user);
-
        return status;
 }
 
@@ -507,163 +499,24 @@ BOOL gensec_have_feature(struct gensec_security *gensec_security,
 }
 
 /** 
- * Set a username on a GENSEC context - ensures it is talloc()ed 
- *
- */
-
-NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) 
-{
-       gensec_security->user.name = talloc_strdup(gensec_security, user);
-       if (user && !gensec_security->user.name) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-/** 
- * Set a username on a GENSEC context - ensures it is talloc()ed 
- *
- */
-
-const char *gensec_get_username(struct gensec_security *gensec_security) 
-{
-       if (gensec_security->user.name) {
-               return gensec_security->user.name;
-       }
-       return gensec_security->default_user.name;
-}
-
-/** 
- * Set a domain on a GENSEC context - ensures it is talloc()ed 
+ * Associate a credentails structure with a GENSEC context - talloc_reference()s it to the context 
  *
  */
 
-NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain
+NTSTATUS gensec_set_credentials(struct gensec_security *gensec_security, struct cli_credentials *credentials
 {
-       gensec_security->user.domain = talloc_strdup(gensec_security, domain);
-       if (domain && !gensec_security->user.domain) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       gensec_security->credentials = talloc_reference(gensec_security, credentials);
        return NT_STATUS_OK;
 }
 
 /** 
- * Return the NT domain for this GENSEC context
+ * Return the credentails structure associated with a GENSEC context
  *
  */
 
-const char *gensec_get_domain(struct gensec_security *gensec_security) 
+struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security) 
 {
-       if (gensec_security->user.domain) {
-               return gensec_security->user.domain;
-       } else if (gensec_security->user.realm) {
-               return gensec_security->user.realm;
-       }
-       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 (workstation && !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 
- *
- */
-
-NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *realm) 
-{
-       gensec_security->user.realm = talloc_strdup(gensec_security, realm);
-       if (realm && !gensec_security->user.realm) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-/** 
- * Return the Krb5 realm for this context
- *
- */
-
-const char *gensec_get_realm(struct gensec_security *gensec_security) 
-{
-       if (gensec_security->user.realm) {
-               return gensec_security->user.realm;
-       } else if (gensec_security->user.domain) {
-               return gensec_security->user.domain;
-       }
-       return gensec_security->default_user.realm;
-}
-
-/** 
- * Return a kerberos principal for this context, if one has been set 
- *
- */
-
-char *gensec_get_client_principal(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx) 
-{
-       const char *realm = gensec_get_realm(gensec_security);
-       if (realm) {
-               return talloc_asprintf(mem_ctx, "%s@%s", 
-                                      gensec_get_username(gensec_security), 
-                                      gensec_get_realm(gensec_security));
-       } else {
-               return talloc_strdup(mem_ctx, gensec_get_username(gensec_security));
-       }
-}
-
-/** 
- * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will
- * not do a callback
- *
- */
-
-NTSTATUS gensec_set_password(struct gensec_security *gensec_security,
-                            const char *password) 
-{
-       gensec_security->user.password = talloc_strdup(gensec_security, password);
-       if (password && !gensec_security->user.password) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-/** 
- * Set the target principal name (if already known) on a GENSEC context - ensures it is talloc()ed 
- *
- */
-
-NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) 
-{
-       gensec_security->target.principal = talloc_strdup(gensec_security, principal);
-       if (!gensec_security->target.principal) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
+       return gensec_security->credentials;
 }
 
 /** 
@@ -713,54 +566,6 @@ const char *gensec_get_target_service(struct gensec_security *gensec_security)
        return "host";
 }
 
-const char *gensec_get_target_principal(struct gensec_security *gensec_security) 
-{
-       const char *mechListMIC;
-       
-       if (gensec_security->target.principal) {
-               return gensec_security->target.principal;
-       }
-
-       mechListMIC = talloc_asprintf(gensec_security,"%s$@%s",
-                                     lp_netbios_name(),
-                                     lp_realm());
-       return mechListMIC;
-}
-
-/** 
- * Set a password callback, if the gensec module we use demands a password
- */
-
-void gensec_set_password_callback(struct gensec_security *gensec_security, 
-                                 gensec_password_callback callback, void *callback_private_data) 
-{
-       gensec_security->password_callback = callback;
-       gensec_security->password_callback_private = callback_private_data;
-}
-
-/**
- * Get (or call back for) a password.
- */
-
-NTSTATUS gensec_get_password(struct gensec_security *gensec_security,
-                            TALLOC_CTX *mem_ctx, 
-                            char **password) 
-{
-       if (gensec_security->user.password) {
-               *password = talloc_strdup(mem_ctx, gensec_security->user.password);
-               if (!*password) {
-                       return NT_STATUS_NO_MEMORY;
-               } else {
-                       return NT_STATUS_OK;
-               }
-       }
-       if (!gensec_security->password_callback) {
-               *password = NULL;
-               return NT_STATUS_OK;
-       }
-       return gensec_security->password_callback(gensec_security, mem_ctx, password);
-}
-
 /*
   register a GENSEC backend. 
 
@@ -821,6 +626,5 @@ const struct gensec_critical_sizes *gensec_interface_version(void)
 */
 NTSTATUS gensec_init(void)
 {
-       gensec_dcerpc_schannel_init();
        return NT_STATUS_OK;
 }
index a4383d852c52227b171459cb00ef9222c0d2d24c..91c817d48a82897e1870a89da652294d577f7937 100644 (file)
@@ -4,7 +4,7 @@
    Generic Authentication Interface
 
    Copyright (C) Andrew Tridgell 2003
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #define GENSEC_OID_KERBEROS5_USER2USER "1 2 840 113554 1 2 2 3"
 
 struct gensec_security;
-struct gensec_user {
-       const char *workstation;
-       const char *domain;
-       const char *realm;
-       const char *name;
-       const char *password;
-};
 struct gensec_target {
        const char *principal;
        const char *hostname;
@@ -105,8 +98,7 @@ struct gensec_security {
        void *password_callback_private;
        const struct gensec_security_ops *ops;
        void *private_data;
-       struct gensec_user user;
-       struct gensec_user default_user;
+       struct cli_credentials *credentials;
        struct gensec_target target;
        enum gensec_role gensec_role;
        BOOL subcontext;
index 7e2e34081d3a8629f8820a04ec81bd8666a75fd4..b4c612da14ea6d4de9f40466ddf6e7b245a33106 100644 (file)
@@ -68,6 +68,18 @@ REQUIRED_SUBSYSTEMS = AUTH
 # End MODULE gensec_ntlmssp
 ################################################
 
+################################################
+# Start MODULE gensec_schannel
+[MODULE::gensec_schannel]
+SUBSYSTEM = GENSEC
+INIT_FUNCTION = gensec_schannel_init
+INIT_OBJ_FILES = libcli/auth/schannel.o
+ADD_OBJ_FILES = \
+               libcli/auth/schannel_sign.o
+REQUIRED_SUBSYSTEMS = AUTH SCHANNELDB
+# End MODULE gensec_ntlmssp
+################################################
+
 ################################################
 # Start SUBSYSTEM SCHANNELDB
 [SUBSYSTEM::SCHANNELDB]
index 71670632b947a3270eb29488312b25354fce285c..453485d81603fc8872bbfbf17abc1bd32800d269 100644 (file)
@@ -320,7 +320,12 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
        struct gensec_krb5_state *gensec_krb5_state;
        krb5_error_code ret;
        NTSTATUS nt_status;
-
+       const char *hostname = gensec_get_target_hostname(gensec_security);
+       if (!hostname) {
+               DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+                       
        nt_status = gensec_krb5_start(gensec_security);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
@@ -341,22 +346,8 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
        }
        
        while (1) {
-               if (gensec_security->target.principal) {
-                       DEBUG(5, ("Finding ticket for target [%s]\n", gensec_security->target.principal));
-                       ret = ads_krb5_mk_req(gensec_krb5_state->context, 
-                                             &gensec_krb5_state->auth_context,
-                                             AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED,
-                                             gensec_security->target.principal,
-                                             gensec_krb5_state->ccache, 
-                                             &gensec_krb5_state->ticket);
-               } else {
+               {
                        krb5_data in_data;
-                       const char *hostname = gensec_get_target_hostname(gensec_security);
-                       if (!hostname) {
-                               DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
-                               return NT_STATUS_ACCESS_DENIED;
-                       }
-                       
                        in_data.length = 0;
 
                        ret = krb5_mk_req(gensec_krb5_state->context, 
@@ -372,36 +363,40 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
                case 0:
                        return NT_STATUS_OK;
                case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
-                       DEBUG(3, ("Server is not registered with our KDC: %s\n", 
-                                 error_message(ret)));
+                       DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n", 
+                                 hostname, error_message(ret)));
                        return NT_STATUS_ACCESS_DENIED;
                case KRB5KDC_ERR_PREAUTH_FAILED:
                case KRB5KRB_AP_ERR_TKT_EXPIRED:
                case KRB5_CC_END:
+                       /* Too much clock skew - we will need to kinit to re-skew the clock */
+               case KRB5KRB_AP_ERR_SKEW:
+               case KRB5_KDCREP_SKEW:
                {
                        DEBUG(3, ("kerberos (mk_req) failed: %s\n", 
                                  error_message(ret)));
                        /* fall down to remaining code */
                }
+
+
                /* just don't print a message for these really ordinary messages */
                case KRB5_FCC_NOFILE:
                case KRB5_CC_NOTFOUND:
                case ENOENT:
+                       
                {
-                       char *password;
+                       const char *password;
                        char *ccache_string;
                        time_t kdc_time = 0;
-                       nt_status = gensec_get_password(gensec_security, 
-                                                       gensec_security, 
-                                                       &password);
+                       password = cli_credentials_get_password(gensec_security->credentials);
                        if (!NT_STATUS_IS_OK(nt_status)) {
                                return nt_status;
                        }
                        
                        /* this string should be unique */
                        ccache_string = talloc_asprintf(gensec_krb5_state, "MEMORY:%s:%s:%s", 
-                                                       gensec_get_client_principal(gensec_security, gensec_krb5_state), 
-                                                       gensec_get_target_principal(gensec_security),
+                                                       cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), 
+                                                       gensec_get_target_hostname(gensec_security),
                                                        generate_random_str(gensec_krb5_state, 16));
 
                        ret = krb5_cc_resolve(gensec_krb5_state->context, ccache_string, &gensec_krb5_state->ccache);
@@ -413,8 +408,8 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
                        }
 
                        ret = kerberos_kinit_password_cc(gensec_krb5_state->context, gensec_krb5_state->ccache, 
-                                                     gensec_get_client_principal(gensec_security, gensec_krb5_state), 
-                                                     password, NULL, &kdc_time);
+                                                        cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), 
+                                                        password, NULL, &kdc_time);
 
                        /* cope with ticket being in the future due to clock skew */
                        if ((unsigned)kdc_time > time(NULL)) {
@@ -422,10 +417,18 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
                                int time_offset =(unsigned)kdc_time-t;
                                DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset));
                                krb5_set_real_time(gensec_krb5_state->context, t + time_offset + 1, 0);
+                               break;
                        }
        
+                       if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
+                               DEBUG(1,("kinit for %s failed (%s)\n", 
+                                        cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), 
+                                        error_message(ret)));
+                               return NT_STATUS_TIME_DIFFERENCE_AT_DC;
+                       }
                        if (ret) {
-                               DEBUG(1,("kinit failed (%s)\n", 
+                               DEBUG(1,("kinit for %s failed (%s)\n", 
+                                        cli_credentials_get_principal(gensec_security->credentials, gensec_krb5_state), 
                                         error_message(ret)));
                                return NT_STATUS_WRONG_PASSWORD;
                        }
index 51456d9107017b6cb7f4739d1ed7a5a8f8161834..595590488669c66dfb1af7bfafbda58ca87673e0 100644 (file)
@@ -109,7 +109,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
        nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, gensec_ntlmssp_state,
-                                                 user_info, &gensec_ntlmssp_state->server_info);
+                                       user_info, &gensec_ntlmssp_state->server_info);
        talloc_free(user_info);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
@@ -197,7 +197,7 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur
 static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
 {
        struct gensec_ntlmssp_state *gensec_ntlmssp_state;
-       char *password = NULL;
+       const char *password = NULL;
        NTSTATUS nt_status;
 
        nt_status = gensec_ntlmssp_start(gensec_security);
@@ -228,25 +228,20 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur
        }
 
        nt_status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, 
-                                      gensec_security->user.domain);
+                                      cli_credentials_get_domain(gensec_security->credentials));
        NT_STATUS_NOT_OK_RETURN(nt_status);
        
        nt_status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, 
-                                        gensec_security->user.name);
+                                        cli_credentials_get_username(gensec_security->credentials));
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
-       if (gensec_security->user.name) {
-               nt_status = gensec_get_password(gensec_security, gensec_ntlmssp_state, &password);
-               NT_STATUS_NOT_OK_RETURN(nt_status);
-       }
+       password = cli_credentials_get_password(gensec_security->credentials);
 
-       if (password) {
-               nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password);
-               NT_STATUS_NOT_OK_RETURN(nt_status);
-       }
+       nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password);
+       NT_STATUS_NOT_OK_RETURN(nt_status);
 
        nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state,
-                                           gensec_get_workstation(gensec_security));
+                                           cli_credentials_get_workstation(gensec_security->credentials));
 
        gensec_security->private_data = gensec_ntlmssp_state;
 
index 9bb6d22eb6b485fe9c566e2ef717bd0f865e311b..c9b2eae55cb0e16c361b123bb8f5bf7ef9419648 100644 (file)
@@ -93,5 +93,6 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
 void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype);
 BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2);
 void kerberos_free_data_contents(krb5_context context, krb5_data *pdata);
+krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);
 #endif /* HAVE_KRB5 */
 
index 1b391306bceb6433153f111e53aaf644ed136522..347a85da77a7936851a44d04dd7de7fb3679ba48 100644 (file)
@@ -3,7 +3,7 @@
  *  Version 3.0
  *  NTLMSSP Signing routines
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2001
- *  Copyright (C) Andrew Bartlett 2003
+ *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/source4/libcli/auth/schannel.c b/source4/libcli/auth/schannel.c
new file mode 100644 (file)
index 0000000..3dbf105
--- /dev/null
@@ -0,0 +1,268 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   dcerpc schannel operations
+
+   Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_schannel.h"
+#include "auth/auth.h"
+#include "libcli/auth/schannel.h"
+
+static size_t schannel_sig_size(struct gensec_security *gensec_security)
+{
+       return 32;
+}
+
+static NTSTATUS schannel_session_key(struct gensec_security *gensec_security, 
+                                           DATA_BLOB *session_key)
+{
+       return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 
+                                      const DATA_BLOB in, DATA_BLOB *out) 
+{
+       struct schannel_state *state = gensec_security->private_data;
+       NTSTATUS status;
+       struct schannel_bind bind_schannel;
+       struct schannel_bind_ack bind_schannel_ack;
+       struct creds_CredentialState *creds;
+
+       const char *workstation;
+       const char *domain;
+       *out = data_blob(NULL, 0);
+
+       switch (gensec_security->gensec_role) {
+       case GENSEC_CLIENT:
+               if (state->state != SCHANNEL_STATE_START) {
+                       /* we could parse the bind ack, but we don't know what it is yet */
+                       return NT_STATUS_OK;
+               }
+
+               state->creds = talloc_reference(state, cli_credentials_get_netlogon_creds(gensec_security->credentials));
+
+               bind_schannel.unknown1 = 0;
+#if 0
+               /* to support this we'd need to have access to the full domain name */
+               bind_schannel.bind_type = 23;
+               bind_schannel.u.info23.domain = cli_credentials_get_domain(gensec_security->credentials);
+               bind_schannel.u.info23.account_name = cli_credentials_get_username(gensec_security->credentials);
+               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, cli_credentials_get_workstation(gensec_security->credentials));
+#else
+               bind_schannel.bind_type = 3;
+               bind_schannel.u.info3.domain = cli_credentials_get_domain(gensec_security->credentials);
+               bind_schannel.u.info3.workstation = cli_credentials_get_workstation(gensec_security->credentials);
+#endif
+               
+               status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel,
+                                             (ndr_push_flags_fn_t)ndr_push_schannel_bind);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(3, ("Could not create schannel bind: %s\n",
+                                 nt_errstr(status)));
+                       return status;
+               }
+               
+               state->state = SCHANNEL_STATE_UPDATE_1;
+
+               return NT_STATUS_MORE_PROCESSING_REQUIRED;
+       case GENSEC_SERVER:
+               
+               if (state->state != SCHANNEL_STATE_START) {
+                       /* no third leg on this protocol */
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               
+               /* parse the schannel startup blob */
+               status = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, 
+                                             (ndr_pull_flags_fn_t)ndr_pull_schannel_bind);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               
+               if (bind_schannel.bind_type == 23) {
+                       workstation = bind_schannel.u.info23.workstation;
+                       domain = bind_schannel.u.info23.domain;
+               } else {
+                       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, workstation, 
+                                                   domain, &creds);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n",
+                                 workstation, nt_errstr(status)));
+                       return status;
+               }
+
+               state->creds = talloc_reference(state, creds);
+
+               bind_schannel_ack.unknown1 = 1;
+               bind_schannel_ack.unknown2 = 0;
+               bind_schannel_ack.unknown3 = 0x6c0000;
+               
+               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 client %s: %s\n",
+                                 workstation, nt_errstr(status)));
+                       return status;
+               }
+
+               state->state = SCHANNEL_STATE_UPDATE_1;
+
+               return NT_STATUS_OK;
+       }
+       return NT_STATUS_INVALID_PARAMETER;
+}
+
+/**
+ * Return the struct creds_CredentialState.
+ *
+ * Make sure not to call this unless gensec is using schannel...
+ */
+
+NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security,
+                              TALLOC_CTX *mem_ctx,
+                              struct creds_CredentialState **creds)
+{ 
+       struct schannel_state *state = gensec_security->private_data;
+
+       *creds = talloc_reference(mem_ctx, state->creds);
+       if (!*creds) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+               
+
+/** 
+ * Return the credentials of a logged on user, including session keys
+ * etc.
+ *
+ * Only valid after a successful authentication
+ *
+ * May only be called once per authentication.
+ *
+ */
+
+static NTSTATUS schannel_session_info(struct gensec_security *gensec_security,
+                                     struct auth_session_info **session_info)
+{
+       (*session_info) = talloc(gensec_security, struct auth_session_info);
+       NT_STATUS_HAVE_NO_MEMORY(*session_info);
+
+       ZERO_STRUCTP(*session_info);
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS schannel_start(struct gensec_security *gensec_security)
+{
+       struct schannel_state *state;
+
+       state = talloc(gensec_security, struct schannel_state);
+       if (!state) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       state->state = SCHANNEL_STATE_START;
+       state->seq_num = 0;
+       gensec_security->private_data = state;
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS schannel_server_start(struct gensec_security *gensec_security) 
+{
+       NTSTATUS status;
+       struct schannel_state *state;
+
+       status = schannel_start(gensec_security);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       state = gensec_security->private_data;
+       state->initiator = False;
+               
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS schannel_client_start(struct gensec_security *gensec_security) 
+{
+       NTSTATUS status;
+       struct schannel_state *state;
+
+       status = schannel_start(gensec_security);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       state = gensec_security->private_data;
+       state->initiator = True;
+               
+       return NT_STATUS_OK;
+}
+
+
+static BOOL schannel_have_feature(struct gensec_security *gensec_security,
+                                        uint32_t feature)
+{
+       if (feature & (GENSEC_FEATURE_SIGN | 
+                      GENSEC_FEATURE_SEAL)) {
+               return True;
+       }
+       return False;
+}
+
+
+static const struct gensec_security_ops gensec_schannel_security_ops = {
+       .name           = "schannel",
+       .auth_type      = DCERPC_AUTH_TYPE_SCHANNEL,
+       .client_start   = schannel_client_start,
+       .server_start   = schannel_server_start,
+       .update         = schannel_update,
+       .seal_packet    = schannel_seal_packet,
+       .sign_packet    = schannel_sign_packet,
+       .check_packet   = schannel_check_packet,
+       .unseal_packet  = schannel_unseal_packet,
+       .session_key    = schannel_session_key,
+       .session_info   = schannel_session_info,
+       .sig_size       = schannel_sig_size,
+       .have_feature   = schannel_have_feature,
+       .enabled        = True
+};
+
+NTSTATUS gensec_schannel_init(void)
+{
+       NTSTATUS ret;
+       ret = gensec_register(&gensec_schannel_security_ops);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0,("Failed to register '%s' gensec backend!\n",
+                       gensec_schannel_security_ops.name));
+               return ret;
+       }
+
+       return ret;
+}
index d582ff2dd0ee0b4c8053caa6224af7ce9bfaf33e..3b493bd0d382d99b3fba7869e3a69e8dbc0d6dbf 100644 (file)
@@ -4,6 +4,7 @@
    schannel library code
 
    Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include "includes.h"
 #include "lib/crypto/crypto.h"
-
-struct schannel_state {
-       uint8_t session_key[16];
-       uint32_t seq_num;
-       BOOL initiator;
-};
+#include "libcli/auth/schannel.h"
+#include "libcli/auth/gensec.h"
+#include "libcli/auth/credentials.h"
 
 #define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
 #define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
@@ -43,7 +41,7 @@ static void netsec_deal_with_seq_num(struct schannel_state *state,
        uint8_t sequence_key[16];
        uint8_t digest1[16];
 
-       hmac_md5(state->session_key, zeros, sizeof(zeros), digest1);
+       hmac_md5(state->creds->session_key, zeros, sizeof(zeros), digest1);
        hmac_md5(digest1, packet_digest, 8, sequence_key);
        arcfour_crypt(seq_num, sequence_key, 8);
 
@@ -102,11 +100,14 @@ static void schannel_digest(const uint8_t sess_key[16],
 /*
   unseal a packet
 */
-NTSTATUS schannel_unseal_packet(struct schannel_state *state,
+NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security, 
                                TALLOC_CTX *mem_ctx, 
                                uint8_t *data, size_t length, 
+                               const uint8_t *whole_pdu, size_t pdu_length, 
                                DATA_BLOB *sig)
 {
+       struct schannel_state *state = gensec_security->private_data;
+       
        uint8_t digest_final[16];
        uint8_t confounder[8];
        uint8_t seq_num[8];
@@ -122,11 +123,11 @@ NTSTATUS schannel_unseal_packet(struct schannel_state *state,
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0:0x80);
 
-       netsec_get_sealing_key(state->session_key, seq_num, sealing_key);
+       netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key);
        arcfour_crypt(confounder, sealing_key, 8);
        arcfour_crypt(data, sealing_key, length);
 
-       schannel_digest(state->session_key, 
+       schannel_digest(state->creds->session_key, 
                        netsec_sig, confounder, 
                        data, length, digest_final);
 
@@ -150,10 +151,14 @@ NTSTATUS schannel_unseal_packet(struct schannel_state *state,
 /*
   check the signature on a packet
 */
-NTSTATUS schannel_check_packet(struct schannel_state *state, 
+NTSTATUS schannel_check_packet(struct gensec_security *gensec_security, 
+                              TALLOC_CTX *mem_ctx, 
                               const uint8_t *data, size_t length, 
+                              const uint8_t *whole_pdu, size_t pdu_length, 
                               const DATA_BLOB *sig)
 {
+       struct schannel_state *state = gensec_security->private_data;
+
        uint8_t digest_final[16];
        uint8_t seq_num[8];
        static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE;
@@ -167,9 +172,9 @@ NTSTATUS schannel_check_packet(struct schannel_state *state,
        SIVAL(seq_num, 4, state->initiator?0:0x80);
 
        dump_data_pw("seq_num:\n", seq_num, 8);
-       dump_data_pw("sess_key:\n", state->session_key, 16);
+       dump_data_pw("sess_key:\n", state->creds->session_key, 16);
 
-       schannel_digest(state->session_key, 
+       schannel_digest(state->creds->session_key, 
                        netsec_sig, NULL, 
                        data, length, digest_final);
 
@@ -194,11 +199,14 @@ NTSTATUS schannel_check_packet(struct schannel_state *state,
 /*
   seal a packet
 */
-NTSTATUS schannel_seal_packet(struct schannel_state *state
+NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security
                              TALLOC_CTX *mem_ctx, 
                              uint8_t *data, size_t length, 
+                             const uint8_t *whole_pdu, size_t pdu_length, 
                              DATA_BLOB *sig)
 {
+       struct schannel_state *state = gensec_security->private_data;
+
        uint8_t digest_final[16];
        uint8_t confounder[8];
        uint8_t seq_num[8];
@@ -210,11 +218,11 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state,
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0x80:0);
 
-       schannel_digest(state->session_key, 
+       schannel_digest(state->creds->session_key, 
                        netsec_sig, confounder, 
                        data, length, digest_final);
 
-       netsec_get_sealing_key(state->session_key, seq_num, sealing_key);
+       netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key);
        arcfour_crypt(confounder, sealing_key, 8);
        arcfour_crypt(data, sealing_key, length);
 
@@ -239,11 +247,14 @@ NTSTATUS schannel_seal_packet(struct schannel_state *state,
 /*
   sign a packet
 */
-NTSTATUS schannel_sign_packet(struct schannel_state *state
+NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security
                              TALLOC_CTX *mem_ctx, 
                              const uint8_t *data, size_t length, 
+                             const uint8_t *whole_pdu, size_t pdu_length, 
                              DATA_BLOB *sig)
 {
+       struct schannel_state *state = gensec_security->private_data;
+
        uint8_t digest_final[16];
        uint8_t seq_num[8];
        static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE;
@@ -251,7 +262,7 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state,
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0x80:0);
 
-       schannel_digest(state->session_key, 
+       schannel_digest(state->creds->session_key, 
                        netsec_sig, NULL, 
                        data, length, digest_final);
 
@@ -271,23 +282,3 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state,
 
        return NT_STATUS_OK;
 }
-
-/*
-  create an schannel context state
-*/
-NTSTATUS schannel_start(TALLOC_CTX *mem_ctx, 
-                       struct schannel_state **state,
-                       const uint8_t session_key[16],
-                       BOOL initiator)
-{
-       (*state) = talloc(mem_ctx, struct schannel_state);
-       if (!(*state)) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       memcpy((*state)->session_key, session_key, 16);
-       (*state)->initiator = initiator;
-       (*state)->seq_num = 0;
-
-       return NT_STATUS_OK;
-}
index 39807671656d38c4e97901338b5d2c01537fba4d..f5a091cd784c413bfa1f09885fe0e8145057f6ee 100644 (file)
@@ -610,7 +610,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
                        spnego_out.negTokenInit.mechTypes = mechlist;
                        spnego_out.negTokenInit.reqFlags = 0;
                        spnego_out.negTokenInit.mechListMIC
-                               = data_blob_string_const(gensec_get_target_principal(gensec_security));
+                               = data_blob_string_const(talloc_asprintf(out_mem_ctx, "%s$@%s", lp_netbios_name(), lp_realm()));
                        spnego_out.negTokenInit.mechToken = unwrapped_out;
                        
                        if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {
@@ -657,13 +657,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
                }
 
                if (spnego.negTokenInit.targetPrincipal) {
-                       DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal));
-                       nt_status = gensec_set_target_principal(gensec_security, 
-                                                               spnego.negTokenInit.targetPrincipal);
-                       if (!NT_STATUS_IS_OK(nt_status)) {
-                               spnego_free_data(&spnego);
-                               return nt_status;
-                       }
+                       DEBUG(5, ("Server claims it's principal name is %s (ignored)\n", spnego.negTokenInit.targetPrincipal));
                }
 
                nt_status = gensec_spnego_client_parse_negTokenInit(gensec_security,
index 7459460137af8c894f2121df805114a2fa4188ea..53a97da168e10a7d92b8ee96e84f9451aa4d01bb 100644 (file)
@@ -63,7 +63,7 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli)
 
 /* wrapper around smb_raw_session_setup() */
 NTSTATUS smbcli_session_setup(struct smbcli_state *cli, 
-                                                         struct cli_credentials *credentials)
+                             struct cli_credentials *credentials)
 {
        struct smb_composite_sesssetup setup;
        NTSTATUS status;
@@ -77,15 +77,8 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli,
 
        setup.in.sesskey = cli->transport->negotiate.sesskey;
        setup.in.capabilities = cli->transport->negotiate.capabilities;
-       if (cli_credentials_is_anonymous(credentials)) {
-               if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
-                       setup.in.password = cli_credentials_get_password(credentials);
-               } else {
-                       setup.in.password = NULL;
-               }
-               setup.in.user = cli_credentials_get_username(credentials);
-               setup.in.domain = cli_credentials_get_domain(credentials);
-       }
+       setup.in.credentials = credentials;
+       setup.in.workgroup = lp_workgroup();
 
        status = smb_composite_sesssetup(cli->session, &setup);
 
@@ -144,7 +137,6 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename,
 */
 NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx,
                                struct smbcli_state **ret_cli, 
-                               const char *myname,
                                const char *host,
                                const char *sharename,
                                const char *devtype,
@@ -159,7 +151,7 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx,
        *ret_cli = NULL;
 
        status = smbcli_tree_full_connection(parent_ctx,
-                                            &tree, myname, host, 0, sharename, devtype,
+                                            &tree, host, 0, sharename, devtype,
                                             credentials);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
index bf0fb9ed48a73b7fa63eed8f07996394e4670d89..18922127ee7cf0acc3d898356b0d30e24cb10fb4 100644 (file)
@@ -70,12 +70,10 @@ struct smb_composite_fetchfile {
                const char *dest_host;
                int port;
                const char *called_name;
-               const char *calling_name;
                const char *service;
                const char *service_type;
-               const char *user;
-               const char *domain;
-               const char *password;
+               struct cli_credentials *credentials;
+               const char *workgroup;
                const char *filename;
        } in;
        struct {
@@ -111,12 +109,10 @@ struct smb_composite_connect {
                const char *dest_host;
                int port;
                const char *called_name;
-               const char *calling_name;
                const char *service;
                const char *service_type;
-               const char *user;
-               const char *domain;
-               const char *password;
+               struct cli_credentials *credentials;
+               const char *workgroup;
        } in;
        struct {
                struct smbcli_tree *tree;
@@ -132,9 +128,8 @@ struct smb_composite_sesssetup {
        struct {
                uint32_t sesskey;
                uint32_t capabilities;
-               const char *password;
-               const char *user;
-               const char *domain;
+               struct cli_credentials *credentials;
+               const char *workgroup;
        } in;
        struct {
                uint16_t vuid;
index 5f5275f7e647bb2aac3e7264b5690b1595c69187..0da71df99280d51414c223157ceccc6e339e6399 100644 (file)
@@ -166,9 +166,8 @@ static NTSTATUS connect_negprot(struct composite_context *c,
        /* prepare a session setup to establish a security context */
        state->io_setup->in.sesskey      = state->transport->negotiate.sesskey;
        state->io_setup->in.capabilities = state->transport->negotiate.capabilities;
-       state->io_setup->in.domain       = io->in.domain;
-       state->io_setup->in.user         = io->in.user;
-       state->io_setup->in.password     = io->in.password;
+       state->io_setup->in.credentials  = io->in.credentials;
+       state->io_setup->in.workgroup    = io->in.workgroup;
 
        state->creq = smb_composite_sesssetup_send(state->session, state->io_setup);
        NT_STATUS_HAVE_NO_MEMORY(state->creq);
@@ -214,7 +213,7 @@ static NTSTATUS connect_socket(struct composite_context *c,
        state->transport = smbcli_transport_init(state->sock, state, True);
        NT_STATUS_HAVE_NO_MEMORY(state->transport);
 
-       calling.name = io->in.calling_name;
+       calling.name = cli_credentials_get_workstation(io->in.credentials);
        calling.type = NBT_NAME_CLIENT;
        calling.scope = NULL;
 
@@ -254,7 +253,7 @@ static NTSTATUS connect_resolve(struct composite_context *c,
        status = resolve_name_recv(state->creq, state, &address);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port);
+       state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port, io->in.dest_host);
        NT_STATUS_HAVE_NO_MEMORY(state->creq);
 
        state->stage = CONNECT_SOCKET;
index 2bf6ef902321bc4a241d29d1187230df5f29bab0..fb9226985e9cec4645625a39b1a2acc3506e0432 100644 (file)
@@ -140,12 +140,10 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc
        state->connect->in.dest_host    = io->in.dest_host;
        state->connect->in.port         = io->in.port;
        state->connect->in.called_name  = io->in.called_name;
-       state->connect->in.calling_name = io->in.calling_name;
        state->connect->in.service      = io->in.service;
        state->connect->in.service_type = io->in.service_type;
-       state->connect->in.user         = io->in.user;
-       state->connect->in.domain       = io->in.domain;
-       state->connect->in.password     = io->in.password;
+       state->connect->in.credentials  = io->in.credentials;
+       state->connect->in.workgroup    = io->in.workgroup;
 
        state->req = smb_composite_connect_send(state->connect, event_ctx);
        if (state->req == NULL) goto failed;
index 07c718b05b698f30fcdffb7f70cee7b5ffe16e3e..31ca5caed79986b98d125fc8fbc382187ffde8f5 100644 (file)
@@ -142,7 +142,7 @@ static void request_handler(struct smbcli_request *req)
        }
 
        /* enforce the local signing required flag */
-       if (NT_STATUS_IS_OK(c->status) && state->io->in.user && state->io->in.user[0]) {
+       if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) {
                if (!session->transport->negotiate.sign_info.doing_signing 
                    && session->transport->negotiate.sign_info.mandatory_signing) {
                        DEBUG(0, ("SMB signing required, but server does not support it\n"));
@@ -169,6 +169,7 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c,
                                                struct smb_composite_sesssetup *io) 
 {
        struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state);
+       const char *password = cli_credentials_get_password(io->in.credentials);
 
        state->setup.nt1.level           = RAW_SESSSETUP_NT1;
        state->setup.nt1.in.bufsize      = session->transport->options.max_xmit;
@@ -176,23 +177,23 @@ static struct smbcli_request *session_setup_nt1(struct composite_context *c,
        state->setup.nt1.in.vc_num       = 1;
        state->setup.nt1.in.sesskey      = io->in.sesskey;
        state->setup.nt1.in.capabilities = io->in.capabilities;
-       state->setup.nt1.in.domain       = io->in.domain;
-       state->setup.nt1.in.user         = io->in.user;
        state->setup.nt1.in.os           = "Unix";
        state->setup.nt1.in.lanman       = "Samba";
 
-       if (!io->in.password) {
+       state->setup.old.in.domain  = cli_credentials_get_domain(io->in.credentials);
+       state->setup.old.in.user    = cli_credentials_get_username(io->in.credentials);
+       if (!password) {
                state->setup.nt1.in.password1 = data_blob(NULL, 0);
                state->setup.nt1.in.password2 = data_blob(NULL, 0);
        } else if (session->transport->negotiate.sec_mode & 
                   NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
-               state->setup.nt1.in.password1 = lanman_blob(state, io->in.password, 
+               state->setup.nt1.in.password1 = lanman_blob(state, password, 
                                                            session->transport->negotiate.secblob);
-               state->setup.nt1.in.password2 = nt_blob(state, io->in.password, 
+               state->setup.nt1.in.password2 = nt_blob(state, password, 
                                                        session->transport->negotiate.secblob);
-               use_nt1_session_keys(session, io->in.password, &state->setup.nt1.in.password2);
+               use_nt1_session_keys(session, password, &state->setup.nt1.in.password2);
        } else {
-               state->setup.nt1.in.password1 = data_blob_talloc(state, io->in.password, strlen(io->in.password));
+               state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password));
                state->setup.nt1.in.password2 = data_blob(NULL, 0);
        }
 
@@ -208,26 +209,27 @@ static struct smbcli_request *session_setup_old(struct composite_context *c,
                                                struct smb_composite_sesssetup *io)
 {
        struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state);
+       const char *password = cli_credentials_get_password(io->in.credentials);
 
        state->setup.old.level      = RAW_SESSSETUP_OLD;
        state->setup.old.in.bufsize = session->transport->options.max_xmit;
        state->setup.old.in.mpx_max = session->transport->options.max_mux;
        state->setup.old.in.vc_num  = 1;
        state->setup.old.in.sesskey = io->in.sesskey;
-       state->setup.old.in.domain  = io->in.domain;
-       state->setup.old.in.user    = io->in.user;
+       state->setup.old.in.domain  = cli_credentials_get_domain(io->in.credentials);
+       state->setup.old.in.user    = cli_credentials_get_username(io->in.credentials);
        state->setup.old.in.os      = "Unix";
        state->setup.old.in.lanman  = "Samba";
        
-       if (!io->in.password) {
+       if (!password) {
                state->setup.old.in.password = data_blob(NULL, 0);
        } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
-               state->setup.old.in.password = lanman_blob(state, io->in.password, 
+               state->setup.old.in.password = lanman_blob(state, password, 
                                                           session->transport->negotiate.secblob);
        } else {
                state->setup.old.in.password = data_blob_talloc(state,
-                                                               io->in.password, 
-                                                               strlen(io->in.password));
+                                                               password, 
+                                                               strlen(password));
        }
        
        return smb_raw_session_setup_send(session, &state->setup);
@@ -253,9 +255,10 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c,
        state->setup.spnego.in.vc_num       = 1;
        state->setup.spnego.in.sesskey      = io->in.sesskey;
        state->setup.spnego.in.capabilities = io->in.capabilities;
-       state->setup.spnego.in.domain       = io->in.domain;
        state->setup.spnego.in.os           = "Unix";
        state->setup.spnego.in.lanman       = "Samba";
+       state->setup.spnego.in.workgroup    = io->in.workgroup;
+
        state->setup.spnego.out.vuid        = session->vuid;
 
        smbcli_temp_set_signing(session->transport);
@@ -268,30 +271,23 @@ static struct smbcli_request *session_setup_spnego(struct composite_context *c,
 
        gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
 
-       status = gensec_set_domain(session->gensec, io->in.domain);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", 
-                         io->in.domain, nt_errstr(status)));
-               return NULL;
-       }
-
-       status = gensec_set_username(session->gensec, io->in.user);
+       status = gensec_set_credentials(session->gensec, io->in.credentials);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", 
-                         io->in.user, nt_errstr(status)));
+               DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", 
+                         nt_errstr(status)));
                return NULL;
        }
 
-       status = gensec_set_password(session->gensec, io->in.password);
+       status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client password: %s\n", 
+               DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", 
                          nt_errstr(status)));
                return NULL;
        }
 
-       status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname);
+       status = gensec_set_target_service(session->gensec, "cifs");
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", 
+               DEBUG(1, ("Failed to start set GENSEC target service: %s\n", 
                          nt_errstr(status)));
                return NULL;
        }
index 3e51e4f60f4327053179925d7d1251d63acda655..710c022a3c0960df937a3065bbdb2dbe699934cc 100644 (file)
@@ -337,11 +337,11 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid,
 struct ldap_message *ldap_transaction(struct ldap_connection *conn,
                                      struct ldap_message *request);
 int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password);
-int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password);
+int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds);
 struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, 
                                                const char *userdn, const char *password);
 struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url,
-                                                       const char *username, const char *domain, const char *password);
+                                                       struct cli_credentials *creds);
 BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid,
                                 const struct timeval *endtime);
 BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg,
index e3904c7a6b4d907308f35fe41b304451cad22db9..71b57e116e6359f389a6b36ccdc58c6b84e02a92 100644 (file)
@@ -605,7 +605,7 @@ int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const cha
        return result;
 }
 
-int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password)
+int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds)
 {
        NTSTATUS status;
        TALLOC_CTX *mem_ctx = NULL;
@@ -626,23 +626,9 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha
 
        gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
 
-       status = gensec_set_domain(conn->gensec, domain);
+       status = gensec_set_credentials(conn->gensec, creds);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", 
-                         domain, nt_errstr(status)));
-               goto done;
-       }
-
-       status = gensec_set_username(conn->gensec, username);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", 
-                         username, nt_errstr(status)));
-               goto done;
-       }
-
-       status = gensec_set_password(conn->gensec, password);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client password: %s\n", 
+               DEBUG(1, ("Failed to start set GENSEC creds: %s\n", 
                          nt_errstr(status)));
                goto done;
        }
@@ -739,8 +725,9 @@ struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *u
        return conn;
 }
 
-struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url,
-                                                       const char *username, const char *domain, const char *password)
+struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, 
+                                                       const char *url,
+                                                       struct cli_credentials *creds)
 {
        struct ldap_connection *conn;
        int result;
@@ -750,7 +737,7 @@ struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, con
                return NULL;
        }
 
-       result = ldap_bind_sasl(conn, username, domain, password);
+       result = ldap_bind_sasl(conn, creds);
        if (result != LDAP_SUCCESS) {
                talloc_free(conn);
                return NULL;
index 5f75701871392d7c7abb69fcac09e7a3aa24bcae..31566245896b9b83cc2bf369212bf19d36dbafce 100644 (file)
@@ -134,7 +134,7 @@ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session
                smbcli_req_append_blob(req, &parms->spnego.in.secblob);
                smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
                smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
-               smbcli_req_append_string(req, parms->spnego.in.domain, STR_TERMINATE);
+               smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE);
                break;
        }
 
@@ -210,7 +210,7 @@ NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req,
                p += parms->spnego.out.secblob.length;
                p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
                p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
-               p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.domain, p, -1, STR_TERMINATE);
+               p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
                break;
        }
 
index cbb479ca1a1388e8fb645663088be2ab4f553c1b..7cb7040131071249c9218aa100b650b038ec9ae4 100644 (file)
@@ -34,7 +34,8 @@ struct clisocket_connect {
        int port_num;
        int *iports;
        struct smbcli_socket *sock;
-       const char *dest_host;
+       const char *dest_host_addr;
+       const char *dest_hostname;
 };
 
 
@@ -83,7 +84,7 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even
        c->status = socket_connect_complete(conn->sock->sock, 0);
        if (NT_STATUS_IS_OK(c->status)) {
                socket_set_option(conn->sock->sock, lp_socket_options(), NULL);
-               conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_host);
+               conn->sock->hostname = talloc_strdup(conn->sock, conn->dest_hostname);
                c->state = SMBCLI_REQUEST_DONE;
                if (c->async.fn) {
                        c->async.fn(c);
@@ -95,7 +96,7 @@ static void smbcli_sock_connect_handler(struct event_context *ev, struct fd_even
        for (i=conn->port_num+1;conn->iports[i];i++) {
                conn->port_num = i;
                c->status = smbcli_sock_connect_one(conn->sock, 
-                                                   conn->dest_host, 
+                                                   conn->dest_host_addr
                                                    conn->iports[i], c);
                if (NT_STATUS_IS_OK(c->status) ||
                    NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -151,7 +152,8 @@ static NTSTATUS smbcli_sock_connect_one(struct smbcli_socket *sock,
   this is the async send side of the interface
 */
 struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock, 
-                                                 const char *host_addr, int port)
+                                                  const char *host_addr, int port,
+                                                  const char *host_name)
 {
        struct composite_context *c;
        struct clisocket_connect *conn;
@@ -184,8 +186,11 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock,
                conn->iports[1] = 0;
        }
 
-       conn->dest_host = talloc_strdup(c, host_addr);
-       if (conn->dest_host == NULL) goto failed;
+       conn->dest_host_addr = talloc_strdup(c, host_addr);
+       if (conn->dest_host_addr == NULL) goto failed;
+
+       conn->dest_hostname = talloc_strdup(c, host_name);
+       if (conn->dest_hostname == NULL) goto failed;
 
        c->private = conn;
        c->state = SMBCLI_REQUEST_SEND;
@@ -196,7 +201,7 @@ struct composite_context *smbcli_sock_connect_send(struct smbcli_socket *sock,
                conn->port_num = i;
                conn->sock->port = conn->iports[i];
                c->status = smbcli_sock_connect_one(sock, 
-                                                   conn->dest_host, 
+                                                   conn->dest_host_addr
                                                    conn->iports[i], c);
                if (NT_STATUS_IS_OK(c->status) ||
                    NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -229,11 +234,12 @@ NTSTATUS smbcli_sock_connect_recv(struct composite_context *c)
 
   sync version of the function
 */
-NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port)
+NTSTATUS smbcli_sock_connect(struct smbcli_socket *sock, const char *host_addr, int port,
+                            const char *host_name)
 {
        struct composite_context *c;
 
-       c = smbcli_sock_connect_send(sock, host_addr, port);
+       c = smbcli_sock_connect_send(sock, host_addr, port, host_name);
        if (c == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -337,9 +343,7 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in
                return False;
        }
 
-       sock->hostname = name;
-
-       status = smbcli_sock_connect(sock, address, port);
+       status = smbcli_sock_connect(sock, address, port, name);
 
        return NT_STATUS_IS_OK(status);
 }
index f333cf7a98d3a46236ed33ffef586a86d963cfb7..87c2dbba7c03f1838caee1b4493b9a5d7f089a84 100644 (file)
@@ -164,7 +164,6 @@ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree)
 */
 NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
                                     struct smbcli_tree **ret_tree, 
-                                    const char *my_name, 
                                     const char *dest_host, int port,
                                     const char *service, const char *service_type,
                                     struct cli_credentials *credentials)
@@ -175,12 +174,10 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
        io.in.dest_host = dest_host;
        io.in.port = port;
        io.in.called_name = strupper_talloc(parent_ctx, dest_host);
-       io.in.calling_name = strupper_talloc(parent_ctx, my_name);
        io.in.service = service;
        io.in.service_type = service_type;
-       io.in.domain = cli_credentials_get_domain(credentials);
-       io.in.user = cli_credentials_get_username(credentials);
-       io.in.password = cli_credentials_get_password(credentials);
+       io.in.credentials = credentials;
+       io.in.workgroup = lp_workgroup();
        
        status = smb_composite_connect(&io, parent_ctx);
        if (NT_STATUS_IS_OK(status)) {
index 70fafdaf3bee8192750f24d2f7438962ebcb2770..f6b05a41b51b18563eb9d78c9541dbd5a7cab7ba 100644 (file)
@@ -20,9 +20,9 @@ INIT_OBJ_FILES = \
                librpc/rpc/dcerpc.o
 ADD_OBJ_FILES = \
                librpc/rpc/dcerpc_auth.o \
+               librpc/rpc/dcerpc_schannel.o \
                librpc/rpc/dcerpc_util.o \
                librpc/rpc/dcerpc_error.o \
-               librpc/rpc/dcerpc_schannel.o \
                librpc/rpc/dcerpc_smb.o \
                librpc/rpc/dcerpc_sock.o
 REQUIRED_SUBSYSTEMS = SOCKET
index c5bfe150bd207c49483080cc8e30738d501f16a0..ae0a89910ea3ac595fe25a5f531d5d5c4825065e 100644 (file)
@@ -4,7 +4,7 @@
    Generic Authentication Interface
 
    Copyright (C) Andrew Tridgell 2003
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
    Copyright (C) Stefan Metzmacher 2004
    
    This program is free software; you can redistribute it and/or modify
@@ -159,34 +159,10 @@ NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p,
                return status;
        }
 
-       status = gensec_set_workstation(p->conn->security_state.generic_state, 
-                                                               cli_credentials_get_workstation(credentials));
+       status = gensec_set_credentials(p->conn->security_state.generic_state, 
+                                       credentials);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client workstation name to %s: %s\n", 
-                         cli_credentials_get_workstation(credentials), nt_errstr(status)));
-               return status;
-       }
-
-       status = gensec_set_domain(p->conn->security_state.generic_state, 
-                                                          cli_credentials_get_domain(credentials));
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", 
-                         cli_credentials_get_domain(credentials), nt_errstr(status)));
-               return status;
-       }
-
-       status = gensec_set_username(p->conn->security_state.generic_state, 
-                                                                cli_credentials_get_username(credentials));
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", 
-                         cli_credentials_get_username(credentials), nt_errstr(status)));
-               return status;
-       }
-
-       status = gensec_set_password(p->conn->security_state.generic_state, 
-                                                                cli_credentials_get_password(credentials));
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start set GENSEC client password: %s\n", 
+               DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", 
                          nt_errstr(status)));
                return status;
        }
index 77453cf4768887041a8861d2acfe7aa55de53b1f..3ae2624ff9df208b407b138cc76b027c1406f1a5 100644 (file)
@@ -4,7 +4,8 @@
    dcerpc schannel operations
 
    Copyright (C) Andrew Tridgell 2004
-   
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
 #include "librpc/gen_ndr/ndr_schannel.h"
 #include "auth/auth.h"
 
-enum schannel_position {
-       DCERPC_SCHANNEL_STATE_START = 0,
-       DCERPC_SCHANNEL_STATE_UPDATE_1
-};
-
-struct dcerpc_schannel_state {
-       enum schannel_position state;
-       struct schannel_state *schannel_state;
-       struct creds_CredentialState *creds;
-};
-
-/*
-  wrappers for the schannel_*() functions
-
-  These will become static again, when we get dynamic registration, and
-  decrpc_schannel_security_ops come back here.
-*/
-static NTSTATUS dcerpc_schannel_unseal_packet(struct gensec_security *gensec_security, 
-                                             TALLOC_CTX *mem_ctx, 
-                                             uint8_t *data, size_t length, 
-                                             const uint8_t *whole_pdu, size_t pdu_length, 
-                                             DATA_BLOB *sig)
-{
-       struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
-       
-       return schannel_unseal_packet(dce_schan_state->schannel_state, mem_ctx, data, length, sig);
-}
-
-static NTSTATUS dcerpc_schannel_check_packet(struct gensec_security *gensec_security, 
-                                            TALLOC_CTX *mem_ctx, 
-                                            const uint8_t *data, size_t length, 
-                                            const uint8_t *whole_pdu, size_t pdu_length, 
-                                            const DATA_BLOB *sig)
-{
-       struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
-
-       return schannel_check_packet(dce_schan_state->schannel_state, data, length, sig);
-}
-
-static NTSTATUS dcerpc_schannel_seal_packet(struct gensec_security *gensec_security, 
-                                           TALLOC_CTX *mem_ctx, 
-                                           uint8_t *data, size_t length, 
-                                           const uint8_t *whole_pdu, size_t pdu_length, 
-                                           DATA_BLOB *sig)
-{
-       struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
-
-       return schannel_seal_packet(dce_schan_state->schannel_state, mem_ctx, data, length, sig);
-}
-
-static NTSTATUS dcerpc_schannel_sign_packet(struct gensec_security *gensec_security, 
-                                           TALLOC_CTX *mem_ctx, 
-                                           const uint8_t *data, size_t length, 
-                                           const uint8_t *whole_pdu, size_t pdu_length, 
-                                           DATA_BLOB *sig)
-{
-       struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
-
-       return schannel_sign_packet(dce_schan_state->schannel_state, mem_ctx, data, length, sig);
-}
-
-static size_t dcerpc_schannel_sig_size(struct gensec_security *gensec_security)
-{
-       return 32;
-}
-
-static NTSTATUS dcerpc_schannel_session_key(struct gensec_security *gensec_security, 
-                                           DATA_BLOB *session_key)
-{
-       return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 
-                                      const DATA_BLOB in, DATA_BLOB *out) 
-{
-       struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
-       NTSTATUS status;
-       struct schannel_bind bind_schannel;
-       struct schannel_bind_ack bind_schannel_ack;
-       const char *workstation;
-       const char *domain;
-       *out = data_blob(NULL, 0);
-
-       switch (gensec_security->gensec_role) {
-       case GENSEC_CLIENT:
-               if (dce_schan_state->state != DCERPC_SCHANNEL_STATE_START) {
-                       /* we could parse the bind ack, but we don't know what it is yet */
-                       return NT_STATUS_OK;
-               }
-               
-               status = schannel_start(dce_schan_state,
-                                       &dce_schan_state->schannel_state, 
-                                       dce_schan_state->creds->session_key,
-                                       True);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(1, ("Failed to start schannel client\n"));
-                       return status;
-               }
-               talloc_steal(dce_schan_state, dce_schan_state->schannel_state);
-       
-               bind_schannel.unknown1 = 0;
-#if 0
-               /* to support this we'd need to have access to the full domain name */
-               bind_schannel.bind_type = 23;
-               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_get_workstation(gensec_security));
-#else
-               bind_schannel.bind_type = 3;
-               bind_schannel.u.info3.domain = gensec_security->user.domain;
-               bind_schannel.u.info3.workstation = gensec_get_workstation(gensec_security);
-#endif
-               
-               status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel,
-                                             (ndr_push_flags_fn_t)ndr_push_schannel_bind);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3, ("Could not create schannel bind: %s\n",
-                                 nt_errstr(status)));
-                       return status;
-               }
-               
-               dce_schan_state->state = DCERPC_SCHANNEL_STATE_UPDATE_1;
-
-               return NT_STATUS_MORE_PROCESSING_REQUIRED;
-       case GENSEC_SERVER:
-               
-               if (dce_schan_state->state != DCERPC_SCHANNEL_STATE_START) {
-                       /* no third leg on this protocol */
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-               
-               /* parse the schannel startup blob */
-               status = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, 
-                                             (ndr_pull_flags_fn_t)ndr_pull_schannel_bind);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-               
-               if (bind_schannel.bind_type == 23) {
-                       workstation = bind_schannel.u.info23.workstation;
-                       domain = bind_schannel.u.info23.domain;
-               } else {
-                       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, workstation, 
-                                                   domain, &dce_schan_state->creds);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n",
-                                 workstation, nt_errstr(status)));
-                       return status;
-               }
-
-               /* start up the schannel server code */
-               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 from client %s: %s\n",
-                                 workstation, nt_errstr(status)));
-                       return status;
-               }
-               talloc_steal(dce_schan_state, dce_schan_state->schannel_state);
-               
-               bind_schannel_ack.unknown1 = 1;
-               bind_schannel_ack.unknown2 = 0;
-               bind_schannel_ack.unknown3 = 0x6c0000;
-               
-               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 client %s: %s\n",
-                                 workstation, nt_errstr(status)));
-                       return status;
-               }
-
-               dce_schan_state->state = DCERPC_SCHANNEL_STATE_UPDATE_1;
-
-               return NT_STATUS_OK;
-       }
-       return NT_STATUS_INVALID_PARAMETER;
-}
-
-/** 
- * Return the credentials of a logged on user, including session keys
- * etc.
- *
- * Only valid after a successful authentication
- *
- * May only be called once per authentication.
- *
- */
-
-NTSTATUS dcerpc_schannel_session_info(struct gensec_security *gensec_security,
-                                     struct auth_session_info **session_info)
-{
-       (*session_info) = talloc(gensec_security, struct auth_session_info);
-       NT_STATUS_HAVE_NO_MEMORY(*session_info);
-
-       ZERO_STRUCTP(*session_info);
-
-       return NT_STATUS_OK;
-}
-
-/**
- * Return the struct creds_CredentialState.
- *
- * Make sure not to call this unless gensec is using schannel...
- */
-
-NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security,
-                              TALLOC_CTX *mem_ctx,
-                              struct creds_CredentialState **creds)
-{ 
-       struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
-
-       *creds = talloc_reference(mem_ctx, dce_schan_state->creds);
-       if (!*creds) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-               
-
-static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security)
-{
-       struct dcerpc_schannel_state *dce_schan_state;
-
-       dce_schan_state = talloc(gensec_security, struct dcerpc_schannel_state);
-       if (!dce_schan_state) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       dce_schan_state->state = DCERPC_SCHANNEL_STATE_START;
-       gensec_security->private_data = dce_schan_state;
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS dcerpc_schannel_server_start(struct gensec_security *gensec_security) 
-{
-       NTSTATUS status;
-
-       status = dcerpc_schannel_start(gensec_security);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS dcerpc_schannel_client_start(struct gensec_security *gensec_security) 
-{
-       NTSTATUS status;
-
-       status = dcerpc_schannel_start(gensec_security);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
-
 /*
   get a schannel key using a netlogon challenge on a secondary pipe
 */
 static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx, 
                                    struct dcerpc_pipe *p,
                                    struct cli_credentials *credentials,
-                                   int chan_type,
-                                   struct creds_CredentialState *creds)
+                                   int chan_type)
 {
        NTSTATUS status;
        struct dcerpc_binding *b;
@@ -307,8 +40,12 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
        struct netr_ServerAuthenticate2 a;
        struct netr_Credential credentials1, credentials2, credentials3;
        struct samr_Password mach_pwd;
-       const char *workgroup;
        uint32_t negotiate_flags;
+       struct creds_CredentialState *creds;
+       creds = talloc(tmp_ctx, struct creds_CredentialState);
+       if (!creds) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        if (p->conn->flags & DCERPC_SCHANNEL_128) {
                negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
@@ -316,8 +53,6 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
                negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
        }
 
-       workgroup = cli_credentials_get_domain(credentials);
-
        /*
          step 1 - establish a netlogon connection, with no authentication
        */
@@ -369,9 +104,6 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
        */
        E_md4hash(cli_credentials_get_password(credentials), mach_pwd.hash);
        creds_client_init(creds, &credentials1, &credentials2, 
-                         cli_credentials_get_workstation(credentials), 
-                         cli_credentials_get_domain(credentials), 
-                         cli_credentials_get_username(credentials), 
                          &mach_pwd, &credentials3,
                          negotiate_flags);
 
@@ -393,6 +125,8 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
+       cli_credentials_set_netlogon_creds(credentials, creds);
+
        /*
          the schannel session key is now in creds.session_key
 
@@ -403,76 +137,6 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
        return NT_STATUS_OK;
 }
 
-/*
-  do a schannel style bind on a dcerpc pipe. The username is usually
-  of the form HOSTNAME$ and the password is the domain trust password
-*/
-NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
-                                          const char *uuid, uint_t version,
-                                          struct creds_CredentialState *creds)
-{
-       NTSTATUS status;
-       struct dcerpc_schannel_state *dce_schan_state;
-
-       status = gensec_client_start(p, &p->conn->security_state.generic_state);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       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", 
-                         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, creds->domain);
-       if (!NT_STATUS_IS_OK(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;
-       }
-       
-       status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, 
-                                              DCERPC_AUTH_TYPE_SCHANNEL, 
-                                              dcerpc_auth_level(p->conn));
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to start SCHANNEL GENSEC backend: %s\n", nt_errstr(status)));
-               talloc_free(p->conn->security_state.generic_state);
-               p->conn->security_state.generic_state = NULL;
-               return status;
-       }
-
-       dce_schan_state = p->conn->security_state.generic_state->private_data;
-       dce_schan_state->creds = talloc_reference(dce_schan_state, creds);
-
-       status = dcerpc_bind_auth(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p->conn),
-                                 uuid, version);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to bind to pipe with SCHANNEL: %s\n", nt_errstr(status)));
-               talloc_free(p->conn->security_state.generic_state);
-               p->conn->security_state.generic_state = NULL;
-               return status;
-       }
-
-       return NT_STATUS_OK;
-}
-
 NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx, 
                                   struct dcerpc_pipe *p,
                                   const char *uuid, uint_t version,
@@ -480,11 +144,6 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx,
 {
        NTSTATUS status;
        int chan_type = 0;
-       struct creds_CredentialState *creds;
-       creds = talloc(tmp_ctx, struct creds_CredentialState);
-       if (!creds) {
-               return NT_STATUS_NO_MEMORY;
-       }
 
        if (p->conn->flags & DCERPC_SCHANNEL_BDC) {
                chan_type = SEC_CHAN_BDC;
@@ -494,58 +153,20 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx,
                chan_type = SEC_CHAN_DOMAIN;
        }
 
+       /* Fills in NETLOGON credentials */
        status = dcerpc_schannel_key(tmp_ctx, 
                                     p, credentials,
-                                    chan_type,
-                                    creds);
+                                    chan_type);
 
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to fetch schannel session key: %s\n",
+               DEBUG(1, ("Failed to setup credentials for account %s: %s\n",
+                         cli_credentials_get_username(credentials), 
                          nt_errstr(status)));
                return status;
        }
 
-       return dcerpc_bind_auth_schannel_withkey(p, uuid, version, creds);
+       return dcerpc_bind_auth_password(p, uuid, version, 
+                                        credentials, DCERPC_AUTH_TYPE_SCHANNEL,
+                                        NULL);
 }
 
-static BOOL dcerpc_schannel_have_feature(struct gensec_security *gensec_security,
-                                        uint32_t feature)
-{
-       if (feature & (GENSEC_FEATURE_SESSION_KEY | 
-                      GENSEC_FEATURE_SIGN | 
-                      GENSEC_FEATURE_SEAL)) {
-               return True;
-       }
-       return False;
-}
-
-
-static const struct gensec_security_ops gensec_dcerpc_schannel_security_ops = {
-       .name           = "dcerpc_schannel",
-       .auth_type      = DCERPC_AUTH_TYPE_SCHANNEL,
-       .client_start   = dcerpc_schannel_client_start,
-       .server_start   = dcerpc_schannel_server_start,
-       .update         = dcerpc_schannel_update,
-       .seal_packet    = dcerpc_schannel_seal_packet,
-       .sign_packet    = dcerpc_schannel_sign_packet,
-       .check_packet   = dcerpc_schannel_check_packet,
-       .unseal_packet  = dcerpc_schannel_unseal_packet,
-       .session_key    = dcerpc_schannel_session_key,
-       .session_info   = dcerpc_schannel_session_info,
-       .sig_size       = dcerpc_schannel_sig_size,
-       .have_feature   = dcerpc_schannel_have_feature,
-       .enabled        = True
-};
-
-NTSTATUS gensec_dcerpc_schannel_init(void)
-{
-       NTSTATUS ret;
-       ret = gensec_register(&gensec_dcerpc_schannel_security_ops);
-       if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(0,("Failed to register '%s' gensec backend!\n",
-                       gensec_dcerpc_schannel_security_ops.name));
-               return ret;
-       }
-
-       return ret;
-}
index 88b1c54cefd803f72de72330ca0299cd027ce7bb..ffefd5111cacfec99524d4f7fdf609182b5508bb 100644 (file)
@@ -5,6 +5,7 @@
 
    Copyright (C) Andrew Tridgell 2003
    Copyright (C) Jelmer Vernooij 2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -926,7 +927,12 @@ NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
        p->conn->binding_string = dcerpc_binding_string(p, binding);
 
        if (!cli_credentials_is_anonymous(credentials) &&
-               (binding->flags & DCERPC_SCHANNEL_ANY)) {
+               (binding->flags & DCERPC_SCHANNEL_ANY) && 
+               !cli_credentials_get_netlogon_creds(credentials)) {
+               
+               /* If we don't already have netlogon credentials for
+                * the schannel bind, then we have to get these
+                * first */
                status = dcerpc_bind_auth_schannel(tmp_ctx, 
                                                   p, pipe_uuid, pipe_version, 
                                                   credentials);
@@ -936,6 +942,8 @@ NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
                        auth_type = DCERPC_AUTH_TYPE_SPNEGO;
                } else if (binding->flags & DCERPC_AUTH_KRB5) {
                        auth_type = DCERPC_AUTH_TYPE_KRB5;
+               } else if (binding->flags & DCERPC_SCHANNEL_ANY) {
+                       auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
                } else {
                        auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
                }
@@ -974,13 +982,11 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(TALLOC_CTX *tmp_ctx,
                cli_credentials_set_anonymous(anon_creds);
                cli_credentials_guess(anon_creds);
                status = smbcli_full_connection(p->conn, &cli, 
-                                               cli_credentials_get_workstation(credentials),
                                                binding->host, 
                                                "IPC$", NULL, 
                                                anon_creds);
        } else {
                status = smbcli_full_connection(p->conn, &cli, 
-                                               cli_credentials_get_workstation(credentials),
                                                binding->host, 
                                                "IPC$", NULL,
                                                credentials);
index 0bb47bab2aa68ba2723d0852c0e22b688f000fa8..e283e12f247881b5514b213cf9d73b1f61e5c8b9 100644 (file)
@@ -90,6 +90,8 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
        struct composite_context *creq;
        struct fd_event *fde;
 
+       struct cli_credentials *credentials;
+
        /* Here we need to determine which server to connect to.
         * For now we use parametric options, type cifs.
         * Later we will use security=server and auth_server.c.
@@ -116,16 +118,20 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
 
        ntvfs->private_data = private;
 
+       credentials = cli_credentials_init(private);
+       cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
+       cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
+       cli_credentials_set_password(credentials, pass, CRED_SPECIFIED);
+       cli_credentials_set_workstation(credentials, "vfs_cifs", CRED_SPECIFIED);
+
        /* connect to the server, using the smbd event context */
        io.in.dest_host = host;
        io.in.port = 0;
        io.in.called_name = host;
-       io.in.calling_name = "vfs_cifs";
+       io.in.credentials = credentials;
+       io.in.workgroup = lp_workgroup();
        io.in.service = remote_share;
        io.in.service_type = "?????";
-       io.in.domain = domain;
-       io.in.user = user;
-       io.in.password = pass;
        
        creq = smb_composite_connect_send(&io, tcon->smb_conn->connection->event.ctx);
        status = smb_composite_connect_recv(creq, private);
index 17dcb8623a921b0cb0d947c64830460ba386f4e2..9c8478d6d3127d2e2ae8faf460be6d112f852655 100644 (file)
@@ -2106,9 +2106,9 @@ static void reply_sesssetup_spnego(struct smbsrv_request *req)
        }
        p += blob_len;
        
-       p += req_pull_string(req, &sess.spnego.in.os,     p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.spnego.in.lanman, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.spnego.in.domain, p, -1, STR_TERMINATE);
+       p += req_pull_string(req, &sess.spnego.in.os,        p, -1, STR_TERMINATE);
+       p += req_pull_string(req, &sess.spnego.in.lanman,    p, -1, STR_TERMINATE);
+       p += req_pull_string(req, &sess.spnego.in.workgroup, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
        status = sesssetup_backend(req, &sess);
@@ -2134,9 +2134,9 @@ static void reply_sesssetup_spnego(struct smbsrv_request *req)
        SSVAL(req->out.hdr, HDR_UID, sess.spnego.out.vuid);
 
        memcpy(req->out.data, sess.spnego.out.secblob.data, sess.spnego.out.secblob.length);
-       req_push_str(req, NULL, sess.spnego.out.os, -1, STR_TERMINATE);
-       req_push_str(req, NULL, sess.spnego.out.lanman, -1, STR_TERMINATE);
-       req_push_str(req, NULL, sess.spnego.out.domain, -1, STR_TERMINATE);
+       req_push_str(req, NULL, sess.spnego.out.os,        -1, STR_TERMINATE);
+       req_push_str(req, NULL, sess.spnego.out.lanman,    -1, STR_TERMINATE);
+       req_push_str(req, NULL, sess.spnego.out.workgroup, -1, STR_TERMINATE);
 
        chain_reply(req);
 }
index dc3a60874a0817d6b831016934be9ccea9795a3b..0f0dcb837e5dbc27f62db7248c406a23e62887e6 100644 (file)
@@ -296,7 +296,7 @@ static NTSTATUS sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup
        sesssetup_common_strings(req, 
                                 &sess->spnego.out.os,
                                 &sess->spnego.out.lanman,
-                                &sess->spnego.out.domain);
+                                &sess->spnego.out.workgroup);
 
        return status;
 }
index 31c23ff5f7d424212ba49e984a92e15d9b70d940..50d5c40d07803aa773378a1fdb135c375a4168aa 100644 (file)
@@ -34,9 +34,13 @@ static BOOL try_failed_login(struct smbcli_state *cli)
        session = smbcli_session_init(cli->transport, cli, False);
        setup.in.sesskey = cli->transport->negotiate.sesskey;
        setup.in.capabilities = cli->transport->negotiate.capabilities;
-       setup.in.password = "INVALID-PASSWORD";
-       setup.in.user = "INVALID-USERNAME";
-       setup.in.domain = "INVALID-DOMAIN";
+       setup.in.workgroup = lp_workgroup();
+
+       setup.in.credentials = cli_credentials_init(NULL);
+       cli_credentials_set_conf(setup.in.credentials);
+       cli_credentials_set_domain(setup.in.credentials, "INVALID-DOMAIN", CRED_SPECIFIED);
+       cli_credentials_set_username(setup.in.credentials, "INVALID-USERNAME", CRED_SPECIFIED);
+       cli_credentials_set_password(setup.in.credentials, "INVALID-PASSWORD", CRED_SPECIFIED);
 
        status = smb_composite_sesssetup(session, &setup);
        talloc_free(session);
index 5f036910b60b477e7abbbd39746393be15b5c102..3e13bf12c05194dd1d19cfcfcef97f97449c1181 100644 (file)
@@ -177,8 +177,10 @@ static BOOL connect_servers(void)
                               servers[i].server_name, servers[i].share_name, 
                               servers[i].credentials->username, j);
 
+                       cli_credentials_set_workstation(servers[i].credentials, 
+                                                       "gentest", CRED_SPECIFIED);
+
                        status = smbcli_full_connection(NULL, &servers[i].cli[j],
-                                                       "gentest",
                                                        servers[i].server_name, 
                                                        servers[i].share_name, NULL, 
                                                        servers[i].credentials);
index d0255abe01dd013016c4107cf2ac197b8daf7020..b53515fdbc6285292f8293ed6501145d44ca14fc 100644 (file)
@@ -38,14 +38,14 @@ BOOL test_bind_simple(struct ldap_connection *conn, const char *userdn, const ch
        return ret;
 }
 
-BOOL test_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password)
+BOOL test_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds)
 {
        NTSTATUS status;
        BOOL ret = True;
 
        printf("Testing sasl bind as user\n");
 
-       status = torture_ldap_bind_sasl(conn, username, domain, password);
+       status = torture_ldap_bind_sasl(conn, creds);
        if (!NT_STATUS_IS_OK(status)) {
                ret = False;
        }
@@ -189,9 +189,6 @@ BOOL torture_ldap_basic(void)
        TALLOC_CTX *mem_ctx;
        BOOL ret = True;
        const char *host = lp_parm_string(-1, "torture", "host");
-       const char *username = cli_credentials_get_username(cmdline_credentials);
-       const char *domain = cli_credentials_get_domain(cmdline_credentials);
-       const char *password = cli_credentials_get_password(cmdline_credentials);
        const char *userdn = lp_parm_string(-1, "torture", "ldap_userdn");
        /*const char *basedn = lp_parm_string(-1, "torture", "ldap_basedn");*/
        const char *secret = lp_parm_string(-1, "torture", "ldap_secret");
@@ -217,7 +214,7 @@ BOOL torture_ldap_basic(void)
                ret = False;
        }
 
-       if (!test_bind_sasl(conn, username, domain, password)) {
+       if (!test_bind_sasl(conn, cmdline_credentials)) {
                ret = False;
        }
 
index f421565cbd929dc34d852648b1ec32f59e7da872..9dbe2557eba270f442acce1f727b22676b17c200 100644 (file)
@@ -46,7 +46,8 @@ NTSTATUS torture_ldap_bind(struct ldap_connection *conn, const char *userdn, con
        return NT_STATUS_OK;
 }
 
-NTSTATUS torture_ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password)
+NTSTATUS torture_ldap_bind_sasl(struct ldap_connection *conn, 
+                               struct cli_credentials *creds)
 {
         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        int result;
@@ -56,7 +57,7 @@ NTSTATUS torture_ldap_bind_sasl(struct ldap_connection *conn, const char *userna
                return status;
        }
 
-       result = ldap_bind_sasl(conn, username, domain, password);
+       result = ldap_bind_sasl(conn, creds);
        if (result != LDAP_SUCCESS) {
                printf("Failed to bind with provided credentials and SASL mechanism\n");
                /* FIXME: what abut actually implementing an ldap_connection_free() function ?
index 4051f9c41148e15f3b6792611def24b94131ce5a..fe5dfe517875e9dd969844c23e9c2e116f83be72 100644 (file)
@@ -116,9 +116,10 @@ static struct smbcli_state *connect_one(char *share, int snum)
        share++;
 
        slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), snum);
+       cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED);
 
        do {
-               status = smbcli_full_connection(NULL, &c, myname,
+               status = smbcli_full_connection(NULL, &c, 
                                                server, 
                                                share, NULL,
                                                servers[snum]);
index d760934334bf24f272273afd8f59ea81f3732477..21e22e91d8bf9c6b1d6be8a45f6054601f38c5bd 100644 (file)
@@ -77,7 +77,9 @@ static struct smbcli_state *connect_one(char *share)
        *share = 0;
        share++;
 
-       status = smbcli_full_connection(NULL, &c, "masktest",
+       cli_credentials_set_workstation(credentials, "masktest", CRED_SPECIFIED);
+
+       status = smbcli_full_connection(NULL, &c,
                                        server, 
                                        share, NULL,
                                        credentials);
index b9c7609b5fd4216e5ec90cd0dff8ec90fa90dba7..f836e1eb4b8f5c74d3599586b58d8402544d18a0 100644 (file)
@@ -147,13 +147,11 @@ static BOOL test_fetchfile(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io2.in.dest_host = lp_parm_string(-1, "torture", "host");
        io2.in.port = 0;
        io2.in.called_name = lp_parm_string(-1, "torture", "host");
-       io2.in.calling_name = lp_netbios_name();
        io2.in.service = lp_parm_string(-1, "torture", "share");
        io2.in.service_type = "A:";
 
-       io2.in.user = cli_credentials_get_username(cmdline_credentials);
-       io2.in.domain = cli_credentials_get_domain(cmdline_credentials);
-       io2.in.password = cli_credentials_get_password(cmdline_credentials);
+       io2.in.credentials = cmdline_credentials;
+       io2.in.workgroup  = lp_workgroup();
        io2.in.filename = fname;
 
        printf("testing parallel fetchfile with %d ops\n", torture_numops);
index 3eb848eebd896e501e4ea4ed2a85fbaa0c3cf989..a610eaa79ea170f9be61b3dd3f7f455b7f16e60c 100644 (file)
@@ -81,9 +81,9 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        setup.in.sesskey = cli->transport->negotiate.sesskey;
        setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
-       setup.in.password = cli_credentials_get_password(cmdline_credentials);
-       setup.in.user = cli_credentials_get_username(cmdline_credentials);
-       setup.in.domain = cli_credentials_get_domain(cmdline_credentials);
+       setup.in.workgroup = lp_workgroup();
+
+       setup.in.credentials = cmdline_credentials;
 
        status = smb_composite_sesssetup(session, &setup);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -96,10 +96,9 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        session2->vuid = session->vuid;
        setup.in.sesskey = cli->transport->negotiate.sesskey;
        setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
+       setup.in.workgroup = lp_workgroup();
 
-       setup.in.password = cli_credentials_get_password(cmdline_credentials);
-       setup.in.user = cli_credentials_get_username(cmdline_credentials);
-       setup.in.domain = cli_credentials_get_domain(cmdline_credentials);
+       setup.in.credentials = cmdline_credentials;
 
        status = smb_composite_sesssetup(session2, &setup);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -117,11 +116,10 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                session3->vuid = session->vuid;
                setup.in.sesskey = cli->transport->negotiate.sesskey;
                setup.in.capabilities = 0; /* force a non extended security login (should fail) */
-
-
-               setup.in.password = cli_credentials_get_password(cmdline_credentials);
-               setup.in.user = cli_credentials_get_username(cmdline_credentials);
-               setup.in.domain = cli_credentials_get_domain(cmdline_credentials);
+               setup.in.workgroup = lp_workgroup();
+       
+               setup.in.credentials = cmdline_credentials;
+       
 
                status = smb_composite_sesssetup(session3, &setup);
                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
index d9ce350428ba0c5a91b26115381c1b739c69d13f..c12560ad5314a9af913f2b31bef078ed94a803d4 100644 (file)
@@ -116,9 +116,6 @@ BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        a.out.credentials = &credentials3;
 
        creds_client_init(creds, &credentials1, &credentials2, 
-                         machine_name, 
-                         lp_workgroup(),
-                         a.in.account_name,
                          &mach_password, &credentials3, 
                          0);
 
@@ -185,9 +182,6 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        a.out.credentials = &credentials3;
 
        creds_client_init(creds, &credentials1, &credentials2, 
-                         machine_name, 
-                         lp_workgroup(),
-                         a.in.account_name,
                          &mach_password, &credentials3, 
                          negotiate_flags);
 
@@ -258,9 +252,6 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        a.out.rid = &rid;
 
        creds_client_init(creds, &credentials1, &credentials2, 
-                         machine_name, 
-                         lp_workgroup(),
-                         a.in.account_name,
                          &mach_password, &credentials3,
                          negotiate_flags);
 
index d60a8bb60b7a6e01986b54eee7b2842956b5d2fc..7bc184f42eba8cb0e2078e77c9babf4ac2f652da 100644 (file)
@@ -194,10 +194,11 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       status = dcerpc_bind_auth_schannel_withkey(p_netlogon, 
-                                                  DCERPC_NETLOGON_UUID,
-                                                  DCERPC_NETLOGON_VERSION, 
-                                                  creds);
+       status = dcerpc_bind_auth_password(p_netlogon, 
+                                          DCERPC_NETLOGON_UUID,
+                                          DCERPC_NETLOGON_VERSION, 
+                                          credentials, DCERPC_AUTH_TYPE_SCHANNEL,
+                                          NULL);
 
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
index cf42f938c1d90b4a9c2ec14ab8f34f8772a88208..f55f6684bc032b69421b81d40b8d7cdeac2183de 100644 (file)
@@ -118,11 +118,11 @@ static NTSTATUS anon_ipc(struct smbcli_transport *transport,
        /* prepare a session setup to establish a security context */
        setup.in.sesskey = transport->negotiate.sesskey;
        setup.in.capabilities = transport->negotiate.capabilities;
-       setup.in.password = NULL;
-       setup.in.user = "";
-       setup.in.domain = "";
        setup.in.capabilities &= ~CAP_EXTENDED_SECURITY;
 
+       setup.in.credentials = cli_credentials_init(mem_ctx);
+       cli_credentials_set_anonymous(setup.in.credentials);
+
        status = smb_composite_sesssetup(session, &setup);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(session);
@@ -479,9 +479,6 @@ 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);
 
@@ -978,6 +975,7 @@ static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
        return status;
 }
 
+#if 0
 static BOOL xp_login(const char *dcname, const char *wksname,
                     const char *domain, const char *wkspwd,
                     const char *user1name, const char *user1pw,
@@ -1033,10 +1031,10 @@ static BOOL xp_login(const char *dcname, const char *wksname,
 
        netlogon_schannel_pipe->conn->flags |= DCERPC_SEAL;
 
-       status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
-                                                  DCERPC_NETLOGON_UUID,
-                                                  DCERPC_NETLOGON_VERSION,
-                                                  netlogon_creds);
+       status = dcerpc_bind_auth_password(netlogon_schannel_pipe,
+                                          DCERPC_NETLOGON_UUID,
+                                          DCERPC_NETLOGON_VERSION,
+                                          creds, NULL);
 
        if (!NT_STATUS_IS_OK(status))
                 return False;
@@ -1096,6 +1094,8 @@ static BOOL xp_login(const char *dcname, const char *wksname,
        return True;
 }
 
+#endif
+
 struct user_pw {
        const char *username;
        const char *password;
@@ -1124,10 +1124,13 @@ BOOL torture_rpc_login(void)
               users[useridx1].username,
               users[useridx2].username);
 
+#if 0
        return xp_login(pdcname, machines[machidx].username,
                        domainname, machines[machidx].password,
                        users[useridx1].username,
                        users[useridx1].password,
                        users[useridx2].username,
                        users[useridx2].password);
+#endif
+       return False;
 }
index 4fca36a9aee58c9d31bd44d30fedfb3b115cf520..eb4dd0b84ad4ee98e3dd60ccac66e35d8f3c7d7e 100644 (file)
@@ -82,8 +82,7 @@ BOOL torture_open_connection_share(struct smbcli_state **c,
        NTSTATUS status;
 
        status = smbcli_full_connection(NULL,
-                                       c, lp_netbios_name(),
-                                       hostname, 
+                                       c, hostname, 
                                        sharename, NULL,
                                        cmdline_credentials);
        if (!NT_STATUS_IS_OK(status)) {
@@ -725,8 +724,7 @@ static BOOL run_tcon_devtype_test(void)
        const char *share = lp_parm_string(-1, "torture", "share");
        
        status = smbcli_full_connection(NULL,
-                                       &cli1, lp_netbios_name(),
-                                       host, 
+                                       &cli1, host, 
                                        share, NULL,
                                        cmdline_credentials);
 
index 81c7f90c9b9961c3af918a1766240493d9747f25..3bc479e0613615c67b387af144aadd2e52479e04 100644 (file)
@@ -52,22 +52,22 @@ enum stdio_helper_mode {
 
 typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, 
                                      char *buf, int length, void **private,
-                                     unsigned int mux_id);
+                                     unsigned int mux_id, void **private2);
 
 static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, 
                                        char *buf, int length, void **private,
-                                       unsigned int mux_id);
+                                       unsigned int mux_id, void **private2);
 
 static void manage_gensec_request (enum stdio_helper_mode stdio_helper_mode, 
                                   char *buf, int length, void **private,
-                                  unsigned int mux_id);
+                                  unsigned int mux_id, void **private2);
 
 static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode, 
                                          char *buf, int length, void **private,
-                                         unsigned int mux_id);
+                                         unsigned int mux_id, void **private2);
 
 static void manage_squid_request(enum stdio_helper_mode helper_mode, 
-                                stdio_helper_function fn);
+                                stdio_helper_function fn, void **private2);
 
 static const struct {
        enum stdio_helper_mode mode;
@@ -203,7 +203,7 @@ static NTSTATUS local_pw_check_specified(const char *username,
 
 static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, 
                                       char *buf, int length, void **private,
-                                      unsigned int mux_id) 
+                                      unsigned int mux_id, void **private2
 {
        char *user, *pass;      
        user=buf;
@@ -234,10 +234,9 @@ static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode,
 
 static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mode, 
                                         char *buf, int length, void **private,
-                                        unsigned int mux_id)  
+                                        unsigned int mux_id, void **password)  
 {
        DATA_BLOB in;
-       struct gensec_security **gensec_state = (struct gensec_security **)private;
        if (strlen(buf) < 2) {
                DEBUG(1, ("query [%s] invalid", buf));
                mux_printf(mux_id, "BH\n");
@@ -252,10 +251,10 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod
 
        if (strncmp(buf, "PW ", 3) == 0) {
 
-               (*gensec_state)->password_callback_private = talloc_strndup((*gensec_state), 
-                                                                           (const char *)in.data, in.length);
+               *password = talloc_strndup(*private /* hopefully the right gensec context, useful to use for talloc */,
+                                          (const char *)in.data, in.length);
                
-               if ((*gensec_state)->password_callback_private == NULL) {
+               if (*password == NULL) {
                        DEBUG(1, ("Out of memory\n"));
                        mux_printf(mux_id, "BH\n");
                        data_blob_free(&in);
@@ -271,33 +270,27 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod
        data_blob_free(&in);
 }
 
-/* 
- * Callback for gensec, to ask the calling application for a password.  Uses the above function
- * for the stdio part of this.
+/** 
+ * Callback for password credentails.  This is not async, and when
+ * GENSEC and the credentails code is made async, it will look rather
+ * different.
  */
 
-static NTSTATUS get_password(struct gensec_security *gensec_security, 
-                            TALLOC_CTX *mem_ctx, 
-                            char **password) 
+static const char *get_password(struct cli_credentials *credentials) 
 {
-       *password = NULL;
+       char *password = NULL;
        
        /* Ask for a password */
-       mux_printf((unsigned int)gensec_security->password_callback_private, "PW\n");
-       gensec_security->password_callback_private = NULL;
+       mux_printf((unsigned int)credentials->priv_data, "PW\n");
+       credentials->priv_data = NULL;
 
-       manage_squid_request(NUM_HELPER_MODES /* bogus */, manage_gensec_get_pw_request);
-       *password = (char *)gensec_security->password_callback_private;
-       if (*password) {
-               return NT_STATUS_OK;
-       } else {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
+       manage_squid_request(NUM_HELPER_MODES /* bogus */, manage_gensec_get_pw_request, (void **)&password);
+       return password;
 }
 
 static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, 
                                  char *buf, int length, void **private,
-                                 unsigned int mux_id) 
+                                 unsigned int mux_id, void **private2
 {
        DATA_BLOB in;
        DATA_BLOB out = data_blob(NULL, 0);
@@ -307,6 +300,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
        NTSTATUS nt_status;
        BOOL first = False;
        const char *reply_code;
+       struct cli_credentials *creds;
        
        if (strlen(buf) < 2) {
                DEBUG(1, ("query [%s] invalid", buf));
@@ -351,19 +345,25 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
                        if (!NT_STATUS_IS_OK(gensec_client_start(NULL, gensec_state))) {
                                exit(1);
                        }
-                       gensec_set_username(*gensec_state, opt_username);
-                       gensec_set_domain(*gensec_state, opt_domain);           
+
+                       creds = cli_credentials_init(*gensec_state);
+                       cli_credentials_set_conf(creds);
+                       if (opt_username) {
+                               cli_credentials_set_username(creds, opt_username, CRED_SPECIFIED);
+                       } 
+                       if (opt_domain) {
+                               cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED);
+                       }
                        if (opt_password) {
-                               if (!NT_STATUS_IS_OK(gensec_set_password(*gensec_state, opt_password))) {
-                                       DEBUG(1, ("Out of memory\n"));
-                                       mux_printf(mux_id, "BH\n");
-                                       data_blob_free(&in);
-                                       return;
-                               }
+                               cli_credentials_set_password(creds, opt_password, CRED_SPECIFIED);
                        } else {
-                               gensec_set_password_callback(*gensec_state, get_password, (void*)mux_id);
+                               creds->password_obtained = CRED_CALLBACK;
+                               creds->password_cb = get_password;
+                               creds->priv_data = (void*)mux_id;
                        }
-                       
+
+                       gensec_set_credentials(*gensec_state, creds);
+
                        break;
                case GSS_SPNEGO_SERVER:
                case SQUID_2_5_NTLMSSP:
@@ -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, ("SPNEGO login failed to initialise: %s\n", nt_errstr(nt_status)));
+                       DEBUG(1, ("GENSEC mech failed to start: %s\n", nt_errstr(nt_status)));
                        mux_printf(mux_id, "BH\n");
                        return;
                }
@@ -403,16 +403,11 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
        
        if (strncmp(buf, "PW ", 3) == 0) {
 
-               if (!NT_STATUS_IS_OK(gensec_set_password(*gensec_state, 
-                                                        talloc_strndup((*gensec_state), 
-                                                                       (const char *)in.data, 
-                                                                       in.length)))) {
-                       DEBUG(1, ("gensec_set_password failed: %s\n", nt_errstr(nt_status)));
-                       mux_printf(mux_id, "BH %s\n", nt_errstr(nt_status));
-                       data_blob_free(&in);
-                       return;
-               }
-
+               cli_credentials_set_password((*gensec_state)->credentials, 
+                                            talloc_strndup((*gensec_state), 
+                                                           (const char *)in.data, 
+                                                           in.length),
+                                            CRED_SPECIFIED);
                mux_printf(mux_id, "OK\n");
                data_blob_free(&in);
                return;
@@ -528,7 +523,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
 
 static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, 
                                         char *buf, int length, void **private,
-                                        unsigned int mux_id) 
+                                        unsigned int mux_id, void **private2
 {
        char *request, *parameter;      
        static DATA_BLOB challenge;
@@ -723,7 +718,7 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
 }
 
 static void manage_squid_request(enum stdio_helper_mode helper_mode, 
-                                stdio_helper_function fn) 
+                                stdio_helper_function fn, void **private2
 {
        char buf[SQUID_BUFFER_SIZE+1];
        unsigned int mux_id;
@@ -785,7 +780,12 @@ static void manage_squid_request(enum stdio_helper_mode helper_mode,
                        mux_private->private_pointers = NULL;
                }
                
-               c=memchr(buf,' ',sizeof(buf)-1);
+               c=strchr(buf,' ');
+               if (!c) {
+                       DEBUG(0, ("Invalid Request - no data after multiplex id\n"));
+                       x_fprintf(x_stdout, "ERR\n");
+                       return;
+               }
                c++;
                if (mux_id >= mux_private->max_mux) {
                        unsigned int prev_max = mux_private->max_mux;
@@ -804,7 +804,7 @@ static void manage_squid_request(enum stdio_helper_mode helper_mode,
                private = &normal_private;
        }
        
-       fn(helper_mode, c, length, private, mux_id);
+       fn(helper_mode, c, length, private, mux_id, private2);
 }
 
 static void squid_stream(enum stdio_helper_mode stdio_mode, 
@@ -813,7 +813,7 @@ static void squid_stream(enum stdio_helper_mode stdio_mode,
        x_setbuf(x_stdout, NULL);
        x_setbuf(x_stderr, NULL);
        while(1) {
-               manage_squid_request(stdio_mode, fn);
+               manage_squid_request(stdio_mode, fn, NULL);
        }
 }