summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/auth.h1
-rw-r--r--source4/auth/auth_util.c2
-rw-r--r--source4/auth/credentials/credentials.c1
-rw-r--r--source4/auth/credentials/credentials.h2
-rw-r--r--source4/auth/credentials/credentials_krb5.c113
-rw-r--r--source4/auth/gensec/gensec_gssapi.c101
-rw-r--r--source4/auth/kerberos/kerberos.h10
-rw-r--r--source4/heimdal/lib/gssapi/accept_sec_context.c38
-rw-r--r--source4/heimdal/lib/gssapi/acquire_cred.c132
-rw-r--r--source4/heimdal/lib/gssapi/copy_ccache.c90
-rw-r--r--source4/heimdal/lib/gssapi/delete_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/gssapi.h8
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_locl.h12
-rw-r--r--source4/heimdal/lib/gssapi/init_sec_context.c46
-rw-r--r--source4/heimdal/lib/gssapi/release_cred.c6
-rw-r--r--source4/heimdal/lib/krb5/ticket.c6
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c28
17 files changed, 427 insertions, 171 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 9f2e0b6a07..58f72aa8af 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -118,6 +118,7 @@ struct auth_session_info {
struct security_token *security_token;
struct auth_serversupplied_info *server_info;
DATA_BLOB session_key;
+ struct cli_credentials *credentials;
};
struct auth_method_context;
diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c
index 753f680fb1..df4e510c2f 100644
--- a/source4/auth/auth_util.c
+++ b/source4/auth/auth_util.c
@@ -526,6 +526,8 @@ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
&session_info->security_token);
NT_STATUS_NOT_OK_RETURN(nt_status);
+ session_info->credentials = NULL;
+
*_session_info = session_info;
return NT_STATUS_OK;
}
diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c
index 5d2c5c553e..86a3df0077 100644
--- a/source4/auth/credentials/credentials.c
+++ b/source4/auth/credentials/credentials.c
@@ -46,6 +46,7 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
cred->domain_obtained = CRED_UNINITIALISED;
cred->realm_obtained = CRED_UNINITIALISED;
cred->ccache_obtained = CRED_UNINITIALISED;
+ cred->gss_creds_obtained = CRED_UNINITIALISED;
cred->keytab_obtained = CRED_UNINITIALISED;
cred->principal_obtained = CRED_UNINITIALISED;
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index b85337bd18..3e84db52a5 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -47,6 +47,7 @@ struct cli_credentials {
enum credentials_obtained domain_obtained;
enum credentials_obtained realm_obtained;
enum credentials_obtained ccache_obtained;
+ enum credentials_obtained gss_creds_obtained;
enum credentials_obtained principal_obtained;
enum credentials_obtained keytab_obtained;
@@ -62,6 +63,7 @@ struct cli_credentials {
struct samr_Password *nt_hash;
struct ccache_container *ccache;
+ struct gssapi_creds_container *gssapi_creds;
struct keytab_container *keytab;
const char *(*workstation_cb) (struct cli_credentials *);
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index abb8418748..a3761e8359 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -85,7 +85,7 @@ int cli_credentials_set_from_ccache(struct cli_credentials *cred,
return 0;
}
-
+/* Free a memory ccache */
static int free_mccache(void *ptr) {
struct ccache_container *ccc = ptr;
krb5_cc_destroy(ccc->smb_krb5_context->krb5_context, ccc->ccache);
@@ -93,6 +93,7 @@ static int free_mccache(void *ptr) {
return 0;
}
+/* Free a disk-based ccache */
static int free_dccache(void *ptr) {
struct ccache_container *ccc = ptr;
krb5_cc_close(ccc->smb_krb5_context->krb5_context, ccc->ccache);
@@ -163,7 +164,7 @@ int cli_credentials_set_ccache(struct cli_credentials *cred,
}
-int cli_credentials_new_ccache(struct cli_credentials *cred)
+int cli_credentials_new_ccache(struct cli_credentials *cred, struct ccache_container **_ccc)
{
krb5_error_code ret;
char *rand_string;
@@ -211,6 +212,10 @@ int cli_credentials_new_ccache(struct cli_credentials *cred)
talloc_steal(cred, ccc);
talloc_free(ccache_name);
+ if (_ccc) {
+ *_ccc = ccc;
+ }
+
return ret;
}
@@ -228,7 +233,7 @@ int cli_credentials_get_ccache(struct cli_credentials *cred,
return EINVAL;
}
- ret = cli_credentials_new_ccache(cred);
+ ret = cli_credentials_new_ccache(cred, NULL);
if (ret) {
return ret;
}
@@ -245,6 +250,108 @@ int cli_credentials_get_ccache(struct cli_credentials *cred,
return ret;
}
+static int free_gssapi_creds(void *ptr) {
+ OM_uint32 min_stat, maj_stat;
+ struct gssapi_creds_container *gcc = ptr;
+ maj_stat = gss_release_cred(&min_stat,
+ &gcc->creds);
+ return 0;
+}
+
+int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
+ struct gssapi_creds_container **_gcc)
+{
+ int ret = 0;
+ OM_uint32 maj_stat, min_stat;
+ struct gssapi_creds_container *gcc;
+ struct ccache_container *ccache;
+ if (cred->gss_creds_obtained >= (MAX(cred->ccache_obtained,
+ MAX(cred->principal_obtained,
+ cred->username_obtained)))) {
+ *_gcc = cred->gssapi_creds;
+ return 0;
+ }
+ ret = cli_credentials_get_ccache(cred,
+ &ccache);
+ if (ret) {
+ DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret)));
+ return ret;
+ }
+
+ gcc = talloc(cred, struct gssapi_creds_container);
+ if (!gcc) {
+ return ENOMEM;
+ }
+
+ maj_stat = gss_krb5_import_ccache(&min_stat, ccache->ccache,
+ &gcc->creds);
+ if (maj_stat) {
+ if (min_stat) {
+ ret = min_stat;
+ } else {
+ ret = EINVAL;
+ }
+ }
+ if (ret == 0) {
+ cred->gss_creds_obtained = cred->ccache_obtained;
+ talloc_set_destructor(gcc, free_gssapi_creds);
+ cred->gssapi_creds = gcc;
+ *_gcc = gcc;
+ }
+ return ret;
+}
+
+/**
+ Set a gssapi cred_id_t into the credentails system.
+
+ This grabs the credentials both 'intact' and getting the krb5
+ ccache out of it. This routine can be generalised in future for
+ the case where we deal with GSSAPI mechs other than krb5.
+
+ On sucess, the caller must not free gssapi_cred, as it now belongs
+ to the credentials system.
+*/
+
+ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
+ gss_cred_id_t gssapi_cred,
+ enum credentials_obtained obtained)
+{
+ int ret;
+ OM_uint32 maj_stat, min_stat;
+ struct ccache_container *ccc;
+ struct gssapi_creds_container *gcc = talloc(cred, struct gssapi_creds_container);
+ if (!gcc) {
+ return ENOMEM;
+ }
+
+ ret = cli_credentials_new_ccache(cred, &ccc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ maj_stat = gss_krb5_copy_ccache(&min_stat,
+ gssapi_cred, ccc->ccache);
+ if (maj_stat) {
+ if (min_stat) {
+ ret = min_stat;
+ } else {
+ ret = EINVAL;
+ }
+ }
+
+ if (ret == 0) {
+ ret = cli_credentials_set_from_ccache(cred, obtained);
+ }
+ if (ret == 0) {
+ gcc->creds = gssapi_cred;
+ talloc_set_destructor(gcc, free_gssapi_creds);
+
+ cred->gss_creds_obtained = obtained;
+ cred->gssapi_creds = gcc;
+ }
+ return ret;
+}
+
int cli_credentials_get_keytab(struct cli_credentials *cred,
struct keytab_container **_ktc)
{
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index d59d19c636..4608b62db5 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -44,8 +44,10 @@ struct gensec_gssapi_state {
krb5_ccache ccache;
const char *ccache_name;
struct keytab_container *keytab;
+ struct gssapi_creds_container *client_cred;
gss_cred_id_t cred;
+ gss_cred_id_t delegated_cred_handle;
};
static char *gssapi_error_string(TALLOC_CTX *mem_ctx,
@@ -83,6 +85,10 @@ static int gensec_gssapi_destory(void *ptr)
maj_stat = gss_release_cred(&min_stat,
&gensec_gssapi_state->cred);
}
+ if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
+ maj_stat = gss_release_cred(&min_stat,
+ &gensec_gssapi_state->delegated_cred_handle);
+ }
if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) {
maj_stat = gss_delete_sec_context (&min_stat,
@@ -118,13 +124,14 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
/* TODO: Fill in channel bindings */
gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
- gensec_gssapi_state->want_flags = GSS_C_MUTUAL_FLAG;
+ gensec_gssapi_state->want_flags = GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG;
gensec_gssapi_state->got_flags = 0;
gensec_gssapi_state->session_key = data_blob(NULL, 0);
gensec_gssapi_state->pac = data_blob(NULL, 0);
gensec_gssapi_state->cred = GSS_C_NO_CREDENTIAL;
+ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory);
@@ -205,7 +212,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi
}
maj_stat = gsskrb5_acquire_cred(&min_stat,
- gensec_gssapi_state->keytab->keytab, NULL,
+ gensec_gssapi_state->keytab->keytab,
gensec_gssapi_state->server_name,
GSS_C_INDEFINITE,
GSS_C_NULL_OID_SET,
@@ -227,7 +234,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
{
struct gensec_gssapi_state *gensec_gssapi_state;
struct cli_credentials *creds = gensec_get_credentials(gensec_security);
- struct ccache_container *ccache;
krb5_error_code ret;
NTSTATUS nt_status;
gss_buffer_desc name_token;
@@ -235,6 +241,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
OM_uint32 maj_stat, min_stat;
const char *hostname = gensec_get_target_hostname(gensec_security);
const char *principal;
+ struct gssapi_creds_container *gcc;
if (!hostname) {
DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
@@ -256,29 +263,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
gensec_gssapi_state = gensec_security->private_data;
- ret = cli_credentials_get_ccache(creds,
- &ccache);
- if (ret) {
- DEBUG(1, ("Failed to get CCACHE for gensec_gssapi: %s\n", error_message(ret)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- principal = cli_credentials_get_principal(creds,
- gensec_gssapi_state);
- name_token.value = discard_const_p(uint8_t, principal);
- name_token.length = strlen(principal);
-
- maj_stat = gss_import_name (&min_stat,
- &name_token,
- GSS_C_NT_USER_NAME,
- &gensec_gssapi_state->client_name);
- if (maj_stat) {
- DEBUG(2, ("GSS Import name of %s failed: %s\n",
- (char *)name_token.value,
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
principal = gensec_get_target_principal(gensec_security);
if (principal && lp_client_use_spnego_principal()) {
name_token.value = discard_const_p(uint8_t, principal);
@@ -307,28 +291,20 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
return NT_STATUS_INVALID_PARAMETER;
}
- maj_stat = gsskrb5_acquire_cred(&min_stat,
- NULL, ccache->ccache,
- gensec_gssapi_state->client_name,
- GSS_C_INDEFINITE,
- GSS_C_NULL_OID_SET,
- GSS_C_INITIATE,
- &gensec_gssapi_state->cred,
- NULL,
- NULL);
- if (maj_stat) {
- switch (min_stat) {
- case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
- DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n",
- hostname, gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
- return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
- default:
- DEBUG(1, ("Aquiring initiator credentails failed: %s\n",
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
- return NT_STATUS_UNSUCCESSFUL;
- }
+ ret = cli_credentials_get_client_gss_creds(creds, &gcc);
+ switch (ret) {
+ case 0:
+ break;
+ case KRB5_KDC_UNREACH:
+ DEBUG(3, ("Cannot reach a KDC we require\n"));
+ return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
+ default:
+ DEBUG(1, ("Aquiring initiator credentails failed\n"));
+ return NT_STATUS_UNSUCCESSFUL;
}
+ gensec_gssapi_state->client_cred = gcc;
+
return NT_STATUS_OK;
}
@@ -369,7 +345,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
const DATA_BLOB in, DATA_BLOB *out)
{
struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
OM_uint32 maj_stat, min_stat;
OM_uint32 min_stat2;
gss_buffer_desc input_token, output_token;
@@ -381,7 +357,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
case GENSEC_CLIENT:
{
maj_stat = gss_init_sec_context(&min_stat,
- gensec_gssapi_state->cred,
+ gensec_gssapi_state->client_cred->creds,
&gensec_gssapi_state->gssapi_context,
gensec_gssapi_state->server_name,
discard_const_p(gss_OID_desc, gensec_gssapi_state->gss_oid),
@@ -407,7 +383,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
&output_token,
&gensec_gssapi_state->got_flags,
NULL,
- NULL);
+ &gensec_gssapi_state->delegated_cred_handle);
gensec_gssapi_state->gss_oid = gss_oid_p;
break;
}
@@ -420,6 +396,12 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
*out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);
gss_release_buffer(&min_stat2, &output_token);
+ if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) {
+ DEBUG(5, ("gensec_gssapi: credentials were delegated\n"));
+ } else {
+ DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n"));
+ }
+
return NT_STATUS_OK;
} else if (maj_stat == GSS_S_CONTINUE_NEEDED) {
*out = data_blob_talloc(out_mem_ctx, output_token.value, output_token.length);
@@ -941,6 +923,27 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key);
NT_STATUS_NOT_OK_RETURN(nt_status);
+ if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) {
+ DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client"));
+ } else {
+ krb5_error_code ret;
+ DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n"));
+ session_info->credentials = cli_credentials_init(session_info);
+ if (!session_info->credentials) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ cli_credentials_set_conf(session_info->credentials);
+
+ ret = cli_credentials_set_client_gss_creds(session_info->credentials,
+ gensec_gssapi_state->delegated_cred_handle,
+ CRED_SPECIFIED);
+ if (ret) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ /* It has been taken from this place... */
+ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+ }
*_session_info = session_info;
return NT_STATUS_OK;
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index 070293df68..9813290650 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -29,6 +29,11 @@ struct ccache_container {
};
+struct gssapi_creds_container {
+ gss_cred_id_t creds;
+};
+
+
struct keytab_container {
struct smb_krb5_context *smb_krb5_context;
krb5_keytab keytab;
@@ -155,5 +160,10 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
krb5_principal client_principal,
time_t tgs_authtime,
DATA_BLOB *pac);
+
+ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
+ gss_cred_id_t gssapi_cred,
+ enum credentials_obtained obtained);
+
#endif /* HAVE_KRB5 */
diff --git a/source4/heimdal/lib/gssapi/accept_sec_context.c b/source4/heimdal/lib/gssapi/accept_sec_context.c
index 8e354c3136..5d43cdcb43 100644
--- a/source4/heimdal/lib/gssapi/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/accept_sec_context.c
@@ -239,7 +239,7 @@ gsskrb5_acceptor_ready(
OM_uint32 ret;
int32_t seq_number;
int is_cfx = 0;
- u_int32_t flags = (*context_handle)->flags;
+ u_int32_t *flags = &(*context_handle)->flags;
krb5_auth_getremoteseqnumber (gssapi_krb5_context,
(*context_handle)->auth_context,
@@ -249,11 +249,11 @@ gsskrb5_acceptor_ready(
ret = _gssapi_msg_order_create(minor_status,
&(*context_handle)->order,
- _gssapi_msg_order_f(flags),
+ _gssapi_msg_order_f(*flags),
seq_number, 0, is_cfx);
if (ret) return ret;
- if (!(flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(flags)) {
+ if (!(*flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(*flags)) {
krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
(*context_handle)->auth_context,
seq_number);
@@ -262,11 +262,14 @@ gsskrb5_acceptor_ready(
/*
* We should handle the delegation ticket, in case it's there
*/
- if ((*context_handle)->fwd_data.length > 0 && (flags & GSS_C_DELEG_FLAG)) {
+ if ((*context_handle)->fwd_data.length > 0 && (*flags & GSS_C_DELEG_FLAG)) {
ret = gsskrb5_accept_delegated_token(minor_status,
context_handle,
delegated_cred_handle);
if (ret) return ret;
+ } else {
+ /* Well, looks like it wasn't there after all */
+ *flags &= ~GSS_C_DELEG_FLAG;
}
(*context_handle)->state = ACCEPTOR_READY;
@@ -297,10 +300,9 @@ gsskrb5_acceptor_start
krb5_ticket *ticket = NULL;
krb5_keytab keytab = NULL;
krb5_keyblock *keyblock = NULL;
- krb5_data fwd_data;
int is_cfx = 0;
- krb5_data_zero (&fwd_data);
+ krb5_data_zero (&(*context_handle)->fwd_data);
/*
* We may, or may not, have an escapsulation.
@@ -415,7 +417,7 @@ gsskrb5_acceptor_start
input_chan_bindings,
authenticator->cksum,
&flags,
- &fwd_data);
+ &(*context_handle)->fwd_data);
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
if (ret) {
return ret;
@@ -461,15 +463,9 @@ gsskrb5_acceptor_start
}
}
- /*
- * We need to send the flags back to the caller
- */
flags |= GSS_C_TRANS_FLAG;
- if (ret_flags)
- *ret_flags = flags;
-
- /* And remember them for later */
+ /* Remember the flags */
(*context_handle)->lifetime = ticket->ticket.endtime;
(*context_handle)->flags = flags;
@@ -491,11 +487,23 @@ gsskrb5_acceptor_start
* When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from the client
*/
if (flags & GSS_C_DCE_STYLE) {
+ if (ret_flags) {
+ /* Return flags to caller, but we haven't processed delgations yet */
+ *ret_flags = flags & ~GSS_C_DELEG_FLAG;
+ }
+
(*context_handle)->state = ACCEPTOR_WAIT_FOR_DCESTYLE;
return GSS_S_CONTINUE_NEEDED;
}
- return gsskrb5_acceptor_ready(minor_status, context_handle, delegated_cred_handle);
+ ret = gsskrb5_acceptor_ready(minor_status, context_handle, delegated_cred_handle);
+
+ /*
+ * We need to send the flags back to the caller
+ */
+
+ *ret_flags = (*context_handle)->flags;
+ return ret;
}
static OM_uint32
diff --git a/source4/heimdal/lib/gssapi/acquire_cred.c b/source4/heimdal/lib/gssapi/acquire_cred.c
index 23c2603352..d67b400920 100644
--- a/source4/heimdal/lib/gssapi/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/acquire_cred.c
@@ -33,7 +33,53 @@
#include "gssapi_locl.h"
-RCSID("$Id: acquire_cred.c,v 1.23 2005/10/21 12:44:08 lha Exp $");
+RCSID("$Id: acquire_cred.c,v 1.24 2005/10/26 11:25:16 lha Exp $");
+
+OM_uint32
+_gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
+ krb5_ccache id,
+ krb5_principal principal,
+ OM_uint32 *lifetime)
+{
+ krb5_creds in_cred, *out_cred;
+ krb5_const_realm realm;
+ krb5_error_code kret;
+
+ memset(&in_cred, 0, sizeof(in_cred));
+ in_cred.client = principal;
+
+ realm = krb5_principal_get_realm(gssapi_krb5_context, principal);
+ if (realm == NULL) {
+ gssapi_krb5_clear_status ();
+ *minor_status = KRB5_PRINC_NOMATCH; /* XXX */
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_make_principal(gssapi_krb5_context, &in_cred.server,
+ realm, KRB5_TGS_NAME, realm, NULL);
+ if (kret) {
+ gssapi_krb5_set_error_string();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_get_credentials(gssapi_krb5_context, 0,
+ id, &in_cred, &out_cred);
+ krb5_free_principal(gssapi_krb5_context, in_cred.server);
+ if (kret) {
+ gssapi_krb5_set_error_string();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ *lifetime = out_cred->times.endtime;
+ krb5_free_creds(gssapi_krb5_context, out_cred);
+
+ return GSS_S_COMPLETE;
+}
+
+
+
static krb5_error_code
get_keytab(krb5_context context, krb5_keytab *keytab)
@@ -61,7 +107,6 @@ static OM_uint32 acquire_initiator_cred
(OM_uint32 * minor_status,
krb5_context context,
krb5_keytab keytab,
- krb5_ccache ccache,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -75,10 +120,11 @@ static OM_uint32 acquire_initiator_cred
krb5_creds cred;
krb5_principal def_princ;
krb5_get_init_creds_opt *opt;
+ krb5_ccache ccache;
krb5_error_code kret;
- krb5_boolean made_ccache = FALSE;
krb5_boolean made_keytab = FALSE;
+ ccache = NULL;
def_princ = NULL;
ret = GSS_S_FAILURE;
memset(&cred, 0, sizeof(cred));
@@ -86,29 +132,22 @@ static OM_uint32 acquire_initiator_cred
/* If we have a preferred principal, lets try to find it in all
* caches, otherwise, fall back to default cache. Ignore
* errors. */
- if (ccache == NULL && handle->principal) {
+ if (handle->principal)
kret = krb5_cc_cache_match (gssapi_krb5_context,
handle->principal,
NULL,
&ccache);
- if (kret) {
- ccache = NULL;
- } else {
- made_ccache = TRUE;
- }
- }
+
if (ccache == NULL) {
kret = krb5_cc_default(gssapi_krb5_context, &ccache);
if (kret)
goto end;
- made_ccache = TRUE;
}
kret = krb5_cc_get_principal(context, ccache,
&def_princ);
if (kret != 0) {
/* we'll try to use a keytab below */
krb5_cc_destroy(context, ccache);
- made_ccache = FALSE;
ccache = NULL;
kret = 0;
} else if (handle->principal == NULL) {
@@ -133,65 +172,41 @@ static OM_uint32 acquire_initiator_cred
if (kret)
goto end;
}
- if (keytab != NULL) {
- kret = get_keytab(context, &keytab);
- if (kret)
- goto end;
- made_keytab = TRUE;
- }
- kret = krb5_get_init_creds_opt_alloc(context, &opt);
+ kret = get_keytab(context, &keytab);
+ if (kret)
+ goto end;
+ kret = krb5_get_init_creds_opt_alloc(gssapi_krb5_context, &opt);
if (kret)
goto end;
- kret = krb5_get_init_creds_keytab(context, &cred,
+ kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred,
handle->principal, keytab, 0, NULL, opt);
krb5_get_init_creds_opt_free(opt);
if (kret)
goto end;
- if (ccache == NULL) {
- kret = krb5_cc_gen_new(context, &krb5_mcc_ops,
- &ccache);
- if (kret)
- goto end;
- made_ccache = TRUE;
- }
- kret = krb5_cc_initialize(context, ccache, cred.client);
+ kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops,
+ &ccache);
if (kret)
goto end;
- kret = krb5_cc_store_cred(context, ccache, &cred);
+ kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client);
if (kret)
goto end;
- handle->lifetime = cred.times.endtime;
- } else {
- krb5_creds in_cred, *out_cred;
- krb5_const_realm realm;
-
- memset(&in_cred, 0, sizeof(in_cred));
- in_cred.client = handle->principal;
-
- realm = krb5_principal_get_realm(context,
- handle->principal);
- if (realm == NULL) {
- kret = KRB5_PRINC_NOMATCH; /* XXX */
- goto end;
- }
-
- kret = krb5_make_principal(context, &in_cred.server,
- realm, KRB5_TGS_NAME, realm, NULL);
+ kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred);
if (kret)
goto end;
+ handle->lifetime = cred.times.endtime;
+ handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ } else {
- kret = krb5_get_credentials(context, 0,
- ccache, &in_cred, &out_cred);
- krb5_free_principal(context, in_cred.server);
- if (kret)
+ ret = _gssapi_krb5_ccache_lifetime(minor_status,
+ ccache,
+ handle->principal,
+ &handle->lifetime);
+ if (ret != GSS_S_COMPLETE)
goto end;
-
- handle->lifetime = out_cred->times.endtime;
- krb5_free_creds(context, out_cred);
+ kret = 0;
}
handle->ccache = ccache;
- handle->made_ccache = made_ccache;
ret = GSS_S_COMPLETE;
end:
@@ -202,8 +217,8 @@ end:
if (made_keytab)
krb5_kt_close(context, keytab);
if (ret != GSS_S_COMPLETE) {
- if (made_ccache)
- krb5_cc_close(context, ccache);
+ if (ccache != NULL)
+ krb5_cc_close(gssapi_krb5_context, ccache);
if (kret != 0) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
@@ -255,7 +270,6 @@ end:
OM_uint32 gsskrb5_acquire_cred
(OM_uint32 * minor_status,
struct krb5_keytab_data *keytab,
- struct krb5_ccache_data *ccache,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -314,7 +328,7 @@ OM_uint32 gsskrb5_acquire_cred
}
if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
ret = acquire_initiator_cred(minor_status, gssapi_krb5_context,
- keytab, ccache,
+ keytab,
desired_name, time_req,
desired_mechs, cred_usage,
handle, actual_mechs, time_rec);
@@ -379,7 +393,7 @@ OM_uint32 gss_acquire_cred
)
{
return gsskrb5_acquire_cred(minor_status,
- NULL, NULL,
+ NULL,
desired_name,
time_req,
desired_mechs,
diff --git a/source4/heimdal/lib/gssapi/copy_ccache.c b/source4/heimdal/lib/gssapi/copy_ccache.c
index 828ca64156..0f2f155870 100644
--- a/source4/heimdal/lib/gssapi/copy_ccache.c
+++ b/source4/heimdal/lib/gssapi/copy_ccache.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: copy_ccache.c,v 1.7 2003/09/01 15:11:09 lha Exp $");
+RCSID("$Id: copy_ccache.c,v 1.9 2005/10/31 16:02:08 lha Exp $");
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
@@ -61,6 +61,94 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
return GSS_S_COMPLETE;
}
+
+OM_uint32
+gss_krb5_import_ccache(OM_uint32 *minor_status,
+ krb5_ccache in,
+ gss_cred_id_t *cred)
+{
+ krb5_error_code kret;
+ gss_cred_id_t handle;
+ OM_uint32 ret;
+
+ *cred = NULL;
+
+ GSSAPI_KRB5_INIT ();
+
+ handle = (gss_cred_id_t)calloc(1, sizeof(*handle));
+ if (handle == GSS_C_NO_CREDENTIAL) {
+ gssapi_krb5_clear_status ();
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
+
+ handle->usage = GSS_C_INITIATE;
+
+ kret = krb5_cc_get_principal(gssapi_krb5_context, in, &handle->principal);
+ if (kret) {
+ free(handle);
+ gssapi_krb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = _gssapi_krb5_ccache_lifetime(minor_status,
+ in,
+ handle->principal,
+ &handle->lifetime);
+ if (ret != GSS_S_COMPLETE) {
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ free(handle);
+ return ret;
+ }
+
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret == GSS_S_COMPLETE)
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret != GSS_S_COMPLETE) {
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ free(handle);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ const char *type, *name;
+ char *str;
+
+ type = krb5_cc_get_type(gssapi_krb5_context, in);
+ name = krb5_cc_get_name(gssapi_krb5_context, in);
+
+ if (asprintf(&str, "%s:%s", type, name) == -1) {
+ krb5_set_error_string(gssapi_krb5_context,
+ "malloc - out of memory");
+ kret = ENOMEM;
+ goto out;
+ }
+
+ kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
+ free(str);
+ if (kret)
+ goto out;
+ }
+
+ *minor_status = 0;
+ *cred = handle;
+ return GSS_S_COMPLETE;
+
+out:
+ gssapi_krb5_set_error_string ();
+ if (handle->principal)
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ free(handle);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+}
+
+
OM_uint32
gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
diff --git a/source4/heimdal/lib/gssapi/delete_sec_context.c b/source4/heimdal/lib/gssapi/delete_sec_context.c
index 83658fa76c..301197aa4c 100644
--- a/source4/heimdal/lib/gssapi/delete_sec_context.c
+++ b/source4/heimdal/lib/gssapi/delete_sec_context.c
@@ -66,6 +66,8 @@ OM_uint32 gss_delete_sec_context
(*context_handle)->service_keyblock);
if((*context_handle)->order)
_gssapi_msg_order_destroy(&(*context_handle)->order);
+ if ((*context_handle)->fwd_data.length > 0)
+ free((*context_handle)->fwd_data.data);
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
diff --git a/source4/heimdal/lib/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi.h
index 4bf6780daa..64a31d1eee 100644
--- a/source4/heimdal/lib/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: gssapi.h,v 1.37 2005/02/21 08:48:15 lukeh Exp $ */
+/* $Id: gssapi.h,v 1.38 2005/10/26 11:22:13 lha Exp $ */
#ifndef GSSAPI_H_
#define GSSAPI_H_
@@ -778,7 +778,6 @@ OM_uint32 gss_unseal
OM_uint32 gsskrb5_acquire_cred
(OM_uint32 * minor_status,
struct krb5_keytab_data *keytab,
- struct krb5_ccache_data *ccache,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -806,6 +805,11 @@ OM_uint32 gss_krb5_copy_service_keyblock
gss_ctx_id_t context_handle,
struct EncryptionKey **out);
+OM_uint32
+gss_krb5_import_ccache(OM_uint32 */*minor*/,
+ struct krb5_ccache_data * /*in*/,
+ gss_cred_id_t */*out*/);
+
OM_uint32 gss_krb5_get_tkt_flags
(OM_uint32 */*minor*/,
gss_ctx_id_t /*context_handle*/,
diff --git a/source4/heimdal/lib/gssapi/gssapi_locl.h b/source4/heimdal/lib/gssapi/gssapi_locl.h
index 1d22099877..aa663e87a6 100644
--- a/source4/heimdal/lib/gssapi/gssapi_locl.h
+++ b/source4/heimdal/lib/gssapi/gssapi_locl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: gssapi_locl.h,v 1.41 2005/10/12 15:20:37 lha Exp $ */
+/* $Id: gssapi_locl.h,v 1.42 2005/10/26 11:23:48 lha Exp $ */
#ifndef GSSAPI_LOCL_H
#define GSSAPI_LOCL_H
@@ -79,12 +79,13 @@ typedef struct gss_ctx_id_t_desc_struct {
typedef struct gss_cred_id_t_desc_struct {
gss_name_t principal;
+ int cred_flags;
+#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
krb5_boolean made_keytab;
struct krb5_keytab_data *keytab;
OM_uint32 lifetime;
gss_cred_usage_t usage;
gss_OID_set mechanisms;
- krb5_boolean made_ccache;
struct krb5_ccache_data *ccache;
HEIMDAL_MUTEX cred_id_mutex;
} gss_cred_id_t_desc;
@@ -108,7 +109,6 @@ struct gssapi_thr_context {
*/
krb5_error_code gssapi_krb5_init (void);
-krb5_error_code gssapi_krb5_init_ev (void *event_context);
#define GSSAPI_KRB5_INIT() do { \
krb5_error_code kret_gss_init; \
@@ -271,6 +271,10 @@ _gss_check_compat(OM_uint32 *, gss_name_t, const char *,
OM_uint32
gssapi_lifetime_left(OM_uint32 *, OM_uint32, OM_uint32 *);
+OM_uint32
+_gssapi_krb5_ccache_lifetime(OM_uint32 *, krb5_ccache,
+ krb5_principal, OM_uint32 *);
+
/* sequence */
OM_uint32
diff --git a/source4/heimdal/lib/gssapi/init_sec_context.c b/source4/heimdal/lib/gssapi/init_sec_context.c
index 93e8d44c86..b8eb748bf5 100644
--- a/source4/heimdal/lib/gssapi/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/init_sec_context.c
@@ -162,7 +162,7 @@ _gsskrb5_create_ctx(
static OM_uint32
gsskrb5_get_creds(
OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
+ krb5_ccache ccache,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
OM_uint32 time_req,
@@ -172,22 +172,10 @@ gsskrb5_get_creds(
OM_uint32 ret;
krb5_error_code kret;
krb5_creds this_cred;
- krb5_ccache ccache = NULL;
OM_uint32 lifetime_rec;
*cred = NULL;
- if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) {
- kret = krb5_cc_default (gssapi_krb5_context, &ccache);
- if (kret) {
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
- } else {
- ccache = initiator_cred_handle->ccache;
- }
-
kret = krb5_cc_get_principal(gssapi_krb5_context,
ccache,
&(*context_handle)->source);
@@ -246,10 +234,6 @@ gsskrb5_get_creds(
if (time_rec) *time_rec = lifetime_rec;
- if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) {
- krb5_cc_close(gssapi_krb5_context, ccache);
- }
-
return GSS_S_COMPLETE;
}
@@ -351,7 +335,7 @@ do_delegation (krb5_auth_context ac,
static OM_uint32
gsskrb5_initiator_start
(OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
+ krb5_ccache ccache,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
@@ -369,7 +353,6 @@ gsskrb5_initiator_start
krb5_flags ap_options;
krb5_creds *cred = NULL;
krb5_data outbuf;
- krb5_ccache ccache = NULL;
u_int32_t flags;
krb5_data authenticator;
Checksum cksum;
@@ -383,7 +366,7 @@ gsskrb5_initiator_start
/* We need to get the credentials for the requested target */
ret = gsskrb5_get_creds(minor_status,
- initiator_cred_handle,
+ ccache,
context_handle,
target_name,
time_req,
@@ -543,7 +526,7 @@ gsskrb5_initiator_start
static OM_uint32
gsskrb5_initiator_wait_for_mutual(
OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
+ krb5_ccache ccache,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
@@ -697,6 +680,8 @@ gsskrb5_init_sec_context
)
{
OM_uint32 ret;
+ krb5_error_code kret;
+ krb5_ccache ccache = NULL;
if (*context_handle == GSS_C_NO_CONTEXT) {
ret = _gsskrb5_create_ctx(minor_status,
@@ -708,12 +693,23 @@ gsskrb5_init_sec_context
if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM;
+ if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) {
+ kret = krb5_cc_default (gssapi_krb5_context, &ccache);
+ if (kret) {
+ gssapi_krb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ ccache = initiator_cred_handle->ccache;
+ }
+
HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex);
switch ((*context_handle)->state) {
case INITIATOR_START:
ret = gsskrb5_initiator_start(minor_status,
- initiator_cred_handle,
+ ccache,
context_handle,
target_name,
mech_type,
@@ -727,7 +723,7 @@ gsskrb5_init_sec_context
break;
case INITIATOR_WAIT_FOR_MUTAL:
ret = gsskrb5_initiator_wait_for_mutual(minor_status,
- initiator_cred_handle,
+ ccache,
context_handle,
target_name,
mech_type,
@@ -771,6 +767,10 @@ gsskrb5_init_sec_context
break;
}
+ if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) {
+ krb5_cc_close(gssapi_krb5_context, ccache);
+ }
+
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
return ret;
diff --git a/source4/heimdal/lib/gssapi/release_cred.c b/source4/heimdal/lib/gssapi/release_cred.c
index 8ae65dd528..ddd80c144b 100644
--- a/source4/heimdal/lib/gssapi/release_cred.c
+++ b/source4/heimdal/lib/gssapi/release_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -54,10 +54,10 @@ OM_uint32 gss_release_cred
krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal);
if ((*cred_handle)->made_keytab)
krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab);
- if ((*cred_handle)->made_ccache) {
+ if ((*cred_handle)->ccache != NULL) {
const krb5_cc_ops *ops;
ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache);
- if (ops == &krb5_mcc_ops)
+ if ((*cred_handle)->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache);
else
krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache);
diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c
index 8f4f8fb152..7dae26acf2 100644
--- a/source4/heimdal/lib/krb5/ticket.c
+++ b/source4/heimdal/lib/krb5/ticket.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: ticket.c,v 1.12 2004/05/25 21:44:47 lha Exp $");
+RCSID("$Id: ticket.c,v 1.14 2005/10/27 13:21:42 lha Exp $");
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_ticket(krb5_context context,
@@ -151,6 +151,7 @@ find_type_in_ad(krb5_context context,
goto out;
break;
}
+#if 0 /* XXX test */
case KRB5_AUTHDATA_KDC_ISSUED: {
AD_KDCIssued child;
@@ -199,6 +200,7 @@ find_type_in_ad(krb5_context context,
goto out;
break;
}
+#endif
case KRB5_AUTHDATA_AND_OR:
if (!failp)
break;
@@ -229,7 +231,7 @@ out:
/*
* Extract the authorization data type of `type' from the
* 'ticket'. Store the field in `data'. This function is to use for
- * kerberos applications
+ * kerberos applications.
*/
krb5_error_code KRB5_LIB_FUNCTION
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index cb6fbb3880..5d0576e8f9 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -32,6 +32,7 @@
#include "libcli/smb_composite/smb_composite.h"
#include "smb_server/smb_server.h"
#include "smbd/service_stream.h"
+#include "auth/auth.h"
/* this is stored in ntvfs_private */
struct cvfs_private {
@@ -106,11 +107,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
remote_share = sharename;
}
- if (!host || !user || !pass || !domain) {
- DEBUG(1,("CIFS backend: You must supply server, user, password and domain\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
private = talloc(req->tcon, struct cvfs_private);
if (!private) {
return NT_STATUS_NO_MEMORY;
@@ -119,11 +115,23 @@ 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);
+ if (!host) {
+ DEBUG(1,("CIFS backend: You must supply server\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (user && pass && domain) {
+ 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);
+ } else if (req->session->session_info->credentials) {
+ credentials = req->session->session_info->credentials;
+ } else {
+ DEBUG(1,("CIFS backend: You must supply server, user, password and domain or have delegated credentials\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
/* connect to the server, using the smbd event context */
io.in.dest_host = host;