summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-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
22 files changed, 431 insertions, 410 deletions
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)) {