summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/auth_domain.c10
-rw-r--r--source4/client/client.c2
-rw-r--r--source4/include/smb_interfaces.h4
-rw-r--r--source4/libcli/auth/config.mk3
-rw-r--r--source4/libcli/auth/credentials.c6
-rw-r--r--source4/libcli/auth/gensec.c210
-rw-r--r--source4/libcli/auth/gensec.h12
-rw-r--r--source4/libcli/auth/gensec.mk12
-rw-r--r--source4/libcli/auth/gensec_krb5.c57
-rw-r--r--source4/libcli/auth/gensec_ntlmssp.c21
-rw-r--r--source4/libcli/auth/kerberos.h1
-rw-r--r--source4/libcli/auth/ntlmssp_sign.c2
-rw-r--r--source4/libcli/auth/schannel.c268
-rw-r--r--source4/libcli/auth/schannel_sign.c67
-rw-r--r--source4/libcli/auth/spnego.c10
-rw-r--r--source4/libcli/cliconnect.c16
-rw-r--r--source4/libcli/composite/composite.h17
-rw-r--r--source4/libcli/composite/connect.c9
-rw-r--r--source4/libcli/composite/fetchfile.c6
-rw-r--r--source4/libcli/composite/sesssetup.c54
-rw-r--r--source4/libcli/ldap/ldap.h4
-rw-r--r--source4/libcli/ldap/ldap_client.c27
-rw-r--r--source4/libcli/raw/clisession.c4
-rw-r--r--source4/libcli/raw/clisocket.c28
-rw-r--r--source4/libcli/raw/clitree.c7
-rw-r--r--source4/librpc/config.mk2
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c32
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c413
-rw-r--r--source4/librpc/rpc/dcerpc_util.c12
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c14
-rw-r--r--source4/smb_server/reply.c12
-rw-r--r--source4/smb_server/sesssetup.c2
-rw-r--r--source4/torture/basic/secleak.c10
-rw-r--r--source4/torture/gentest.c4
-rw-r--r--source4/torture/ldap/basic.c9
-rw-r--r--source4/torture/ldap/common.c5
-rw-r--r--source4/torture/locktest.c3
-rw-r--r--source4/torture/masktest.c4
-rw-r--r--source4/torture/raw/composite.c6
-rw-r--r--source4/torture/raw/context.c20
-rw-r--r--source4/torture/rpc/netlogon.c9
-rw-r--r--source4/torture/rpc/schannel.c9
-rw-r--r--source4/torture/rpc/xplogin.c23
-rw-r--r--source4/torture/torture.c6
-rw-r--r--source4/utils/ntlm_auth.c108
45 files changed, 597 insertions, 963 deletions
diff --git a/source4/auth/auth_domain.c b/source4/auth/auth_domain.c
index 6a968592bd..a6950445cb 100644
--- a/source4/auth/auth_domain.c
+++ b/source4/auth/auth_domain.c
@@ -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;
diff --git a/source4/client/client.c b/source4/client/client.c
index 4ce686cdcf..9738292f03 100644
--- a/source4/client/client.c
+++ b/source4/client/client.c
@@ -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",
diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h
index 1052a6297d..af9f6efd7a 100644
--- a/source4/include/smb_interfaces.h
+++ b/source4/include/smb_interfaces.h
@@ -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;
diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk
index b37e214360..0c013ce0ef 100644
--- a/source4/libcli/auth/config.mk
+++ b/source4/libcli/auth/config.mk
@@ -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 = \
diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c
index 90b8313c9d..bcb462ae9d 100644
--- a/source4/libcli/auth/credentials.c
+++ b/source4/libcli/auth/credentials.c
@@ -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));
diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c
index 69de016156..cc7327187c 100644
--- a/source4/libcli/auth/gensec.c
+++ b/source4/libcli/auth/gensec.c
@@ -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;
}
diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h
index a4383d852c..91c817d48a 100644
--- a/source4/libcli/auth/gensec.h
+++ b/source4/libcli/auth/gensec.h
@@ -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
@@ -28,13 +28,6 @@
#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;
diff --git a/source4/libcli/auth/gensec.mk b/source4/libcli/auth/gensec.mk
index 7e2e34081d..b4c612da14 100644
--- a/source4/libcli/auth/gensec.mk
+++ b/source4/libcli/auth/gensec.mk
@@ -69,6 +69,18 @@ REQUIRED_SUBSYSTEMS = AUTH
################################################
################################################
+# 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]
INIT_OBJ_FILES = \
diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c
index 71670632b9..453485d816 100644
--- a/source4/libcli/auth/gensec_krb5.c
+++ b/source4/libcli/auth/gensec_krb5.c
@@ -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;
}
diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c
index 51456d9107..5955904886 100644
--- a/source4/libcli/auth/gensec_ntlmssp.c
+++ b/source4/libcli/auth/gensec_ntlmssp.c
@@ -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;
diff --git a/source4/libcli/auth/kerberos.h b/source4/libcli/auth/kerberos.h
index 9bb6d22eb6..c9b2eae55c 100644
--- a/source4/libcli/auth/kerberos.h
+++ b/source4/libcli/auth/kerberos.h
@@ -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 */
diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c
index 1b391306bc..347a85da77 100644
--- a/source4/libcli/auth/ntlmssp_sign.c
+++ b/source4/libcli/auth/ntlmssp_sign.c
@@ -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
index 0000000000..3dbf10580b
--- /dev/null
+++ b/source4/libcli/auth/schannel.c
@@ -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;
+}
diff --git a/source4/libcli/auth/schannel_sign.c b/source4/libcli/auth/schannel_sign.c
index d582ff2dd0..3b493bd0d3 100644
--- a/source4/libcli/auth/schannel_sign.c
+++ b/source4/libcli/auth/schannel_sign.c
@@ -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
@@ -22,12 +23,9 @@
#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;
-}
diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c
index 3980767165..f5a091cd78 100644
--- a/source4/libcli/auth/spnego.c
+++ b/source4/libcli/auth/spnego.c
@@ -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,
diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c
index 7459460137..53a97da168 100644
--- a/source4/libcli/cliconnect.c
+++ b/source4/libcli/cliconnect.c
@@ -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;
diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h
index bf0fb9ed48..18922127ee 100644
--- a/source4/libcli/composite/composite.h
+++ b/source4/libcli/composite/composite.h
@@ -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;
diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c
index 5f5275f7e6..0da71df992 100644
--- a/source4/libcli/composite/connect.c
+++ b/source4/libcli/composite/connect.c
@@ -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;
diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c
index 2bf6ef9023..fb9226985e 100644
--- a/source4/libcli/composite/fetchfile.c
+++ b/source4/libcli/composite/fetchfile.c
@@ -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;
diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c
index 07c718b05b..31ca5caed7 100644
--- a/source4/libcli/composite/sesssetup.c
+++ b/source4/libcli/composite/sesssetup.c
@@ -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;
}
diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h
index 3e51e4f60f..710c022a3c 100644
--- a/source4/libcli/ldap/ldap.h
+++ b/source4/libcli/ldap/ldap.h
@@ -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,
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index e3904c7a6b..71b57e116e 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -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;
diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c
index 5f75701871..3156624589 100644
--- a/source4/libcli/raw/clisession.c
+++ b/source4/libcli/raw/clisession.c
@@ -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;
}
diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c
index cbb479ca1a..7cb7040131 100644
--- a/source4/libcli/raw/clisocket.c
+++ b/source4/libcli/raw/clisocket.c
@@ -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);
}
diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c
index f333cf7a98..87c2dbba7c 100644
--- a/source4/libcli/raw/clitree.c
+++ b/source4/libcli/raw/clitree.c
@@ -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)) {
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 70fafdaf3b..f6b05a41b5 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -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
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index c5bfe150bd..ae0a89910e 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -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;
}
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index 77453cf476..3ae2624ff9 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -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
@@ -24,281 +25,13 @@
#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;
-}
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 88b1c54cef..ffefd5111c 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -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);
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index 0bb47bab2a..e283e12f24 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -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);
diff --git a/source4/smb_server/reply.c b/source4/smb_server/reply.c
index 17dcb8623a..9c8478d6d3 100644
--- a/source4/smb_server/reply.c
+++ b/source4/smb_server/reply.c
@@ -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);
}
diff --git a/source4/smb_server/sesssetup.c b/source4/smb_server/sesssetup.c
index dc3a60874a..0f0dcb837e 100644
--- a/source4/smb_server/sesssetup.c
+++ b/source4/smb_server/sesssetup.c
@@ -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;
}
diff --git a/source4/torture/basic/secleak.c b/source4/torture/basic/secleak.c
index 31c23ff5f7..50d5c40d07 100644
--- a/source4/torture/basic/secleak.c
+++ b/source4/torture/basic/secleak.c
@@ -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);
diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c
index 5f036910b6..3e13bf12c0 100644
--- a/source4/torture/gentest.c
+++ b/source4/torture/gentest.c
@@ -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);
diff --git a/source4/torture/ldap/basic.c b/source4/torture/ldap/basic.c
index d0255abe01..b53515fdbc 100644
--- a/source4/torture/ldap/basic.c
+++ b/source4/torture/ldap/basic.c
@@ -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;
}
diff --git a/source4/torture/ldap/common.c b/source4/torture/ldap/common.c
index f421565cbd..9dbe2557eb 100644
--- a/source4/torture/ldap/common.c
+++ b/source4/torture/ldap/common.c
@@ -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 ?
diff --git a/source4/torture/locktest.c b/source4/torture/locktest.c
index 4051f9c411..fe5dfe5178 100644
--- a/source4/torture/locktest.c
+++ b/source4/torture/locktest.c
@@ -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]);
diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c
index d760934334..21e22e91d8 100644
--- a/source4/torture/masktest.c
+++ b/source4/torture/masktest.c
@@ -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);
diff --git a/source4/torture/raw/composite.c b/source4/torture/raw/composite.c
index b9c7609b5f..f836e1eb4b 100644
--- a/source4/torture/raw/composite.c
+++ b/source4/torture/raw/composite.c
@@ -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);
diff --git a/source4/torture/raw/context.c b/source4/torture/raw/context.c
index 3eb848eebd..a610eaa79e 100644
--- a/source4/torture/raw/context.c
+++ b/source4/torture/raw/context.c
@@ -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);
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index d9ce350428..c12560ad53 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -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);
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index d60a8bb60b..7bc184f42e 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -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;
diff --git a/source4/torture/rpc/xplogin.c b/source4/torture/rpc/xplogin.c
index cf42f938c1..f55f6684bc 100644
--- a/source4/torture/rpc/xplogin.c
+++ b/source4/torture/rpc/xplogin.c
@@ -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;
}
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index 4fca36a9ae..eb4dd0b84a 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -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);
diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c
index 81c7f90c9b..3bc479e061 100644
--- a/source4/utils/ntlm_auth.c
+++ b/source4/utils/ntlm_auth.c
@@ -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);
}
}