diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-02-25 16:16:33 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-02-26 13:59:16 +1100 |
commit | 781ad038c96195031053291414a12225eb818fd9 (patch) | |
tree | faf68b7deb844b69cb7463d6c7f689ecc7248971 | |
parent | ad7223b9bd31f71b8af2ae83361d7e054a433cc5 (diff) | |
download | samba-781ad038c96195031053291414a12225eb818fd9.tar.gz samba-781ad038c96195031053291414a12225eb818fd9.tar.bz2 samba-781ad038c96195031053291414a12225eb818fd9.zip |
s4-krb5: propogate errors from a lot more kerberos functions
We need to be able to give sensible error messages when a kerberos
calls fails. This propogates the kerberos error up the stack to the
caller.
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
-rw-r--r-- | source4/auth/credentials/credentials.c | 4 | ||||
-rw-r--r-- | source4/auth/credentials/credentials.h | 11 | ||||
-rw-r--r-- | source4/auth/credentials/credentials_krb5.c | 115 | ||||
-rw-r--r-- | source4/auth/credentials/credentials_krb5.h | 6 | ||||
-rw-r--r-- | source4/auth/credentials/pycredentials.c | 11 | ||||
-rw-r--r-- | source4/auth/gensec/gensec_gssapi.c | 12 | ||||
-rw-r--r-- | source4/auth/gensec/gensec_krb5.c | 12 | ||||
-rw-r--r-- | source4/auth/kerberos/kerberos.c | 4 | ||||
-rw-r--r-- | source4/auth/kerberos/kerberos.h | 10 | ||||
-rw-r--r-- | source4/auth/kerberos/kerberos_util.c | 62 | ||||
-rw-r--r-- | source4/libcli/util/pyerrors.h | 5 | ||||
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 3 | ||||
-rw-r--r-- | source4/smbd/service_named_pipe.c | 4 |
13 files changed, 158 insertions, 101 deletions
diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 959068c24d..2515c4ce75 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -661,6 +661,7 @@ _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred, struct loadparm_context *lp_ctx) { char *p; + const char *error_string; if (lp_ctx != NULL) { cli_credentials_set_conf(cred, lp_ctx); @@ -692,7 +693,8 @@ _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred, } if (cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) { - cli_credentials_set_ccache(cred, event_context_find(cred), lp_ctx, NULL, CRED_GUESS_FILE); + cli_credentials_set_ccache(cred, event_context_find(cred), lp_ctx, NULL, CRED_GUESS_FILE, + &error_string); } } diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h index 21a9c61b9a..6c077c9bec 100644 --- a/source4/auth/credentials/credentials.h +++ b/source4/auth/credentials/credentials.h @@ -161,12 +161,13 @@ int cli_credentials_get_krb5_context(struct cli_credentials *cred, int cli_credentials_get_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, - struct ccache_container **ccc); + struct ccache_container **ccc, + const char **error_string); int cli_credentials_get_named_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, char *ccache_name, - struct ccache_container **ccc); + struct ccache_container **ccc, const char **error_string); int cli_credentials_get_keytab(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, @@ -185,7 +186,8 @@ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, - struct gssapi_creds_container **_gcc); + struct gssapi_creds_container **_gcc, + const char **error_string); void cli_credentials_set_kerberos_state(struct cli_credentials *creds, enum credentials_use_kerberos use_kerberos); bool cli_credentials_set_domain(struct cli_credentials *cred, @@ -258,7 +260,8 @@ int cli_credentials_set_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, const char *name, - enum credentials_obtained obtained); + enum credentials_obtained obtained, + const char **error_string); bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained); bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, int fd, enum credentials_obtained obtained); diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index b722901968..e04b7f5926 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -65,8 +65,9 @@ _PUBLIC_ NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred, } static int cli_credentials_set_from_ccache(struct cli_credentials *cred, - struct ccache_container *ccache, - enum credentials_obtained obtained) + struct ccache_container *ccache, + enum credentials_obtained obtained, + const char **error_string) { krb5_principal princ; @@ -81,20 +82,17 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred, ccache->ccache, &princ); if (ret) { - char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, - ret, cred); - DEBUG(1,("failed to get principal from ccache: %s\n", - err_mess)); - talloc_free(err_mess); + (*error_string) = talloc_asprintf(cred, "failed to get principal from ccache: %s\n", + smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, + ret, cred)); return ret; } ret = krb5_unparse_name(ccache->smb_krb5_context->krb5_context, princ, &name); if (ret) { - char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, ret, cred); - DEBUG(1,("failed to unparse principal from ccache: %s\n", - err_mess)); - talloc_free(err_mess); + (*error_string) = talloc_asprintf(cred, "failed to unparse principal from ccache: %s\n", + smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, + ret, cred)); return ret; } @@ -127,9 +125,10 @@ static int free_dccache(struct ccache_container *ccc) { _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, - struct loadparm_context *lp_ctx, - const char *name, - enum credentials_obtained obtained) + struct loadparm_context *lp_ctx, + const char *name, + enum credentials_obtained obtained, + const char **error_string) { krb5_error_code ret; krb5_principal princ; @@ -140,34 +139,39 @@ _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, ccc = talloc(cred, struct ccache_container); if (!ccc) { + (*error_string) = error_message(ENOMEM); return ENOMEM; } ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &ccc->smb_krb5_context); if (ret) { + (*error_string) = error_message(ret); talloc_free(ccc); return ret; } if (!talloc_reference(ccc, ccc->smb_krb5_context)) { talloc_free(ccc); + (*error_string) = error_message(ENOMEM); return ENOMEM; } if (name) { ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache); if (ret) { - DEBUG(1,("failed to read krb5 ccache: %s: %s\n", - name, - smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); + (*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n", + name, + smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, + ret, ccc)); talloc_free(ccc); return ret; } } else { ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache); if (ret) { - DEBUG(3,("failed to read default krb5 ccache: %s\n", - smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); + (*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n", + smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, + ret, ccc)); talloc_free(ccc); return ret; } @@ -178,17 +182,19 @@ _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ); if (ret) { - DEBUG(3,("failed to get principal from default ccache: %s\n", - smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); - talloc_free(ccc); + (*error_string) = talloc_asprintf(cred, "failed to get principal from default ccache: %s\n", + smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, + ret, ccc)); + talloc_free(ccc); return ret; } krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ); - ret = cli_credentials_set_from_ccache(cred, ccc, obtained); + ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); if (ret) { + (*error_string) = error_message(ret); return ret; } @@ -205,7 +211,8 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, char *ccache_name, - struct ccache_container **_ccc) + struct ccache_container **_ccc, + const char **error_string) { bool must_free_cc_name = false; krb5_error_code ret; @@ -218,10 +225,13 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, &ccc->smb_krb5_context); if (ret) { talloc_free(ccc); + (*error_string) = talloc_asprintf(cred, "Failed to get krb5_context: %s", + error_message(ret)); return ret; } if (!talloc_reference(ccc, ccc->smb_krb5_context)) { talloc_free(ccc); + (*error_string) = strerror(ENOMEM); return ENOMEM; } @@ -232,6 +242,7 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, if (!ccache_name) { talloc_free(ccc); + (*error_string) = strerror(ENOMEM); return ENOMEM; } } @@ -239,9 +250,10 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name, &ccc->ccache); if (ret) { - DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n", - ccache_name, - smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); + (*error_string) = talloc_asprintf(cred, "failed to resolve a krb5 ccache (%s): %s\n", + ccache_name, + smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, + ret, ccc)); talloc_free(ccache_name); talloc_free(ccc); return ret; @@ -259,14 +271,15 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, *_ccc = ccc; - return ret; + return 0; } _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, char *ccache_name, - struct ccache_container **ccc) + struct ccache_container **ccc, + const char **error_string) { krb5_error_code ret; @@ -280,15 +293,16 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, return 0; } if (cli_credentials_is_anonymous(cred)) { + (*error_string) = "Cannot get anonymous kerberos credentials"; return EINVAL; } - ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccache_name, ccc); + ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccache_name, ccc, error_string); if (ret) { return ret; } - ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache); + ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache, error_string); if (ret) { return ret; } @@ -296,7 +310,7 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, ret = cli_credentials_set_from_ccache(cred, *ccc, (MAX(MAX(cred->principal_obtained, cred->username_obtained), - cred->password_obtained))); + cred->password_obtained)), error_string); cred->ccache = *ccc; cred->ccache_obtained = cred->principal_obtained; @@ -304,15 +318,16 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, return ret; } cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained); - return ret; + return 0; } _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, - struct ccache_container **ccc) + struct ccache_container **ccc, + const char **error_string) { - return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc); + return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc, error_string); } void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, @@ -368,9 +383,10 @@ static int free_gssapi_creds(struct gssapi_creds_container *gcc) } _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, - struct tevent_context *event_ctx, - struct loadparm_context *lp_ctx, - struct gssapi_creds_container **_gcc) + struct tevent_context *event_ctx, + struct loadparm_context *lp_ctx, + struct gssapi_creds_container **_gcc, + const char **error_string) { int ret = 0; OM_uint32 maj_stat, min_stat; @@ -386,7 +402,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, } ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, - &ccache); + &ccache, error_string); if (ret) { DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); return ret; @@ -394,6 +410,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { + (*error_string) = error_message(ENOMEM); return ENOMEM; } @@ -406,6 +423,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, } else { ret = EINVAL; } + (*error_string) = error_message(ENOMEM); return ret; } @@ -437,6 +455,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, } else { ret = EINVAL; } + (*error_string) = error_message(ENOMEM); return ret; } } @@ -452,6 +471,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, } else { ret = EINVAL; } + (*error_string) = error_message(ENOMEM); return ret; } @@ -477,7 +497,8 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, gss_cred_id_t gssapi_cred, - enum credentials_obtained obtained) + enum credentials_obtained obtained, + const char **error_string) { int ret; OM_uint32 maj_stat, min_stat; @@ -489,10 +510,11 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { + (*error_string) = error_message(ENOMEM); return ENOMEM; } - ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, NULL, &ccc); + ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, NULL, &ccc, error_string); if (ret != 0) { return ret; } @@ -505,10 +527,13 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, } else { ret = EINVAL; } + if (ret) { + (*error_string) = error_message(ENOMEM); + } } if (ret == 0) { - ret = cli_credentials_set_from_ccache(cred, ccc, obtained); + ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); } cred->ccache = ccc; cred->ccache_obtained = obtained; @@ -672,6 +697,7 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, struct smb_krb5_context *smb_krb5_context; TALLOC_CTX *mem_ctx; krb5_principal princ; + const char *error_string; if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, MAX(cred->principal_obtained, @@ -696,11 +722,10 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, return ENOMEM; } - ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ); + ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &error_string); if (ret) { DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n", - smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); + error_string)); talloc_free(mem_ctx); return ret; } diff --git a/source4/auth/credentials/credentials_krb5.h b/source4/auth/credentials/credentials_krb5.h index 5e56752eb4..72a4373609 100644 --- a/source4/auth/credentials/credentials_krb5.h +++ b/source4/auth/credentials/credentials_krb5.h @@ -36,12 +36,14 @@ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, gss_cred_id_t gssapi_cred, - enum credentials_obtained obtained); + enum credentials_obtained obtained, + const char **error_string); /* Manually prototyped here to avoid needing krb5 headers in most callers */ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct smb_krb5_context *smb_krb5_context, - krb5_principal *princ); + krb5_principal *princ, + const char **error_string); #endif /* __CREDENTIALS_KRB5_H__ */ diff --git a/source4/auth/credentials/pycredentials.c b/source4/auth/credentials/pycredentials.c index 002ecbcd08..8602be8060 100644 --- a/source4/auth/credentials/pycredentials.c +++ b/source4/auth/credentials/pycredentials.c @@ -254,6 +254,7 @@ static PyObject *py_creds_get_named_ccache(py_talloc_Object *self, PyObject *arg struct ccache_container *ccc; struct tevent_context *event_ctx; int ret; + const char *error_string; if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name)) return NULL; @@ -264,15 +265,17 @@ static PyObject *py_creds_get_named_ccache(py_talloc_Object *self, PyObject *arg event_ctx = tevent_context_init(NULL); - ret = cli_credentials_get_named_ccache(PyCredentials_AsCliCredentials(self), event_ctx, lp_ctx, ccache_name, &ccc); + ret = cli_credentials_get_named_ccache(PyCredentials_AsCliCredentials(self), event_ctx, lp_ctx, + ccache_name, &ccc, &error_string); if (ret == 0) { talloc_steal(ccc, event_ctx); return PyCredentialCacheContainer_from_ccache_container(ccc); - } else { - talloc_free(event_ctx); - return NULL; } + PyErr_SetStringError(error_string); + + talloc_free(event_ctx); + return NULL; } static PyMethodDef py_creds_methods[] = { diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 2759ab41c3..a50190f04c 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -320,6 +320,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi const char *hostname = gensec_get_target_hostname(gensec_security); const char *principal; struct gssapi_creds_container *gcc; + const char *error_string; if (!hostname) { DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); @@ -368,17 +369,17 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi ret = cli_credentials_get_client_gss_creds(creds, gensec_security->event_ctx, - gensec_security->settings->lp_ctx, &gcc); + gensec_security->settings->lp_ctx, &gcc, &error_string); switch (ret) { case 0: break; case KRB5KDC_ERR_PREAUTH_FAILED: return NT_STATUS_LOGON_FAILURE; case KRB5_KDC_UNREACH: - DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); + DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", principal, error_string)); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ default: - DEBUG(1, ("Aquiring initiator credentials failed\n")); + DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string)); return NT_STATUS_UNSUCCESSFUL; } @@ -1335,6 +1336,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); } else { krb5_error_code ret; + const char *error_string; + DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); session_info->credentials = cli_credentials_init(session_info); if (!session_info->credentials) { @@ -1350,9 +1353,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_gssapi_state->delegated_cred_handle, - CRED_SPECIFIED); + CRED_SPECIFIED, &error_string); if (ret) { talloc_free(mem_ctx); + DEBUG(2,("Failed to get gss creds: %s\n", error_string)); return NT_STATUS_NO_MEMORY; } diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 46b8181de7..3d744770df 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -234,7 +234,7 @@ static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_s NTSTATUS nt_status; struct ccache_container *ccache_container; const char *hostname; - + const char *error_string; const char *principal; krb5_data in_data; @@ -277,17 +277,17 @@ static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_s ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security), gensec_security->event_ctx, - gensec_security->settings->lp_ctx, &ccache_container); + gensec_security->settings->lp_ctx, &ccache_container, &error_string); switch (ret) { case 0: break; case KRB5KDC_ERR_PREAUTH_FAILED: return NT_STATUS_LOGON_FAILURE; case KRB5_KDC_UNREACH: - DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); + DEBUG(3, ("Cannot reach a KDC we require to contact %s: %s\n", principal, error_string)); return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ default: - DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_message(ret))); + DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_string)); return NT_STATUS_UNSUCCESSFUL; } in_data.length = 0; @@ -472,6 +472,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, uint8_t tok_id[2]; struct keytab_container *keytab; krb5_principal server_in_keytab; + const char *error_string; if (!in.data) { return NT_STATUS_INVALID_PARAMETER; @@ -488,9 +489,10 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, /* This ensures we lookup the correct entry in that keytab */ ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security), gensec_krb5_state->smb_krb5_context, - &server_in_keytab); + &server_in_keytab, error_string); if (ret) { + DEBUG(2,("Failed to make credentials from principal: %s\n", error_string)); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index a0b21c891a..8df54cc8b4 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -84,8 +84,8 @@ Orignally by remus@snapserver.com */ krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - krb5_principal principal, const char *password, - time_t *expire_time, time_t *kdc_time) + krb5_principal principal, const char *password, + time_t *expire_time, time_t *kdc_time) { krb5_error_code code = 0; krb5_creds my_creds; diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h index 8585aa321b..498da0f9c2 100644 --- a/source4/auth/kerberos/kerberos.h +++ b/source4/auth/kerberos/kerberos.h @@ -103,13 +103,15 @@ 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); char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx); krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx, - struct cli_credentials *credentials, - struct smb_krb5_context *smb_krb5_context, - krb5_ccache ccache); + struct cli_credentials *credentials, + struct smb_krb5_context *smb_krb5_context, + krb5_ccache ccache, + const char **error_string); krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct smb_krb5_context *smb_krb5_context, - krb5_principal *princ); + krb5_principal *princ, + const char **error_string); NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, struct PAC_DATA **pac_data_out, diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 3f8b593e75..494f36dec7 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -105,12 +105,14 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct smb_krb5_context *smb_krb5_context, - krb5_principal *princ) + krb5_principal *princ, + const char **error_string) { krb5_error_code ret; const char *princ_string; struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container); if (!mem_ctx) { + (*error_string) = error_message(ENOMEM); return ENOMEM; } @@ -127,14 +129,17 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, ret = krb5_parse_name(smb_krb5_context->krb5_context, princ_string, princ); - if (ret == 0) { - /* This song-and-dance effectivly puts the principal - * into talloc, so we can't loose it. */ - mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); - mem_ctx->principal = *princ; - talloc_set_destructor(mem_ctx, free_principal); + if (ret) { + (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); + return ret; } - return ret; + + /* This song-and-dance effectivly puts the principal + * into talloc, so we can't loose it. */ + mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); + mem_ctx->principal = *princ; + talloc_set_destructor(mem_ctx, free_principal); + return 0; } /** @@ -145,7 +150,8 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct smb_krb5_context *smb_krb5_context, - krb5_ccache ccache) + krb5_ccache ccache, + const char **error_string) { krb5_error_code ret; const char *password; @@ -155,10 +161,11 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); if (!mem_ctx) { + (*error_string) = strerror(ENOMEM); return ENOMEM; } - ret = principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &princ); + ret = principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &princ, error_string); if (ret) { talloc_free(mem_ctx); return ret; @@ -180,7 +187,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, mach_pwd = cli_credentials_get_nt_hash(credentials, mem_ctx); if (!mach_pwd) { talloc_free(mem_ctx); - DEBUG(1, ("kinit_to_ccache: No password available for kinit\n")); + (*error_string) = "kinit_to_ccache: No password available for kinit\n"; return EINVAL; } ret = krb5_keyblock_init(smb_krb5_context->krb5_context, @@ -207,10 +214,10 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, } if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) { - DEBUG(1,("kinit for %s failed (%s)\n", - cli_credentials_get_principal(credentials, mem_ctx), - smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); + (*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n", + cli_credentials_get_principal(credentials, mem_ctx), + smb_get_krb5_error_message(smb_krb5_context->krb5_context, + ret, mem_ctx)); talloc_free(mem_ctx); return ret; } @@ -227,13 +234,13 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, ret = kinit_to_ccache(parent_ctx, credentials, smb_krb5_context, - ccache); + ccache, error_string); } if (ret) { - DEBUG(1,("kinit for %s failed (%s)\n", - cli_credentials_get_principal(credentials, mem_ctx), - smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); + (*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n", + cli_credentials_get_principal(credentials, mem_ctx), + smb_get_krb5_error_message(smb_krb5_context->krb5_context, + ret, mem_ctx)); talloc_free(mem_ctx); return ret; } @@ -351,6 +358,7 @@ static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx, krb5_principal salt_princ; krb5_principal princ; const char *princ_string; + const char *error_string; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); if (!mem_ctx) { @@ -359,11 +367,9 @@ static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx, princ_string = cli_credentials_get_principal(machine_account, mem_ctx); /* Get the principal we will store the new keytab entries under */ - ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ); + ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ, &error_string); if (ret) { - DEBUG(1,("create_keytab: makeing krb5 principal failed (%s)\n", - smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); + DEBUG(1,("create_keytab: makeing krb5 principal failed (%s)\n", error_string)); talloc_free(mem_ctx); return ret; } @@ -491,6 +497,8 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, int kvno; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); const char *princ_string; + const char *error_string; + if (!mem_ctx) { return ENOMEM; } @@ -499,11 +507,9 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, princ_string = cli_credentials_get_principal(machine_account, mem_ctx); /* Get the principal we will store the new keytab entries under */ - ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ); + ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ, &error_string); if (ret) { - DEBUG(1,("update_keytab: makeing krb5 principal failed (%s)\n", - smb_get_krb5_error_message(smb_krb5_context->krb5_context, - ret, mem_ctx))); + DEBUG(1,("update_keytab: makeing krb5 principal failed (%s)\n", error_string)); talloc_free(mem_ctx); return ret; } diff --git a/source4/libcli/util/pyerrors.h b/source4/libcli/util/pyerrors.h index 66823f4a41..3fd2a7c9fa 100644 --- a/source4/libcli/util/pyerrors.h +++ b/source4/libcli/util/pyerrors.h @@ -24,6 +24,11 @@ #define PyErr_FromNTSTATUS(status) Py_BuildValue("(i,s)", NT_STATUS_V(status), discard_const_p(char, get_friendly_nt_error_msg(status))) +#define PyErr_FromString(str) Py_BuildValue("(s)", discard_const_p(char, str)) + +#define PyErr_SetStringError(str) \ + PyErr_SetObject(PyExc_RuntimeError, PyErr_FromString(str)) + #define PyErr_SetWERROR(err) \ PyErr_SetObject(PyExc_RuntimeError, PyErr_FromWERROR(err)) diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index aefa93a8ef..5d5c3c6eb9 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -349,11 +349,12 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs, OM_uint32 gret; OM_uint32 minor_status; gss_buffer_desc cred_token; + const char *error_string; ret = cli_credentials_get_client_gss_creds(req->session_info->credentials, ipriv->ntvfs->ctx->event_ctx, ipriv->ntvfs->ctx->lp_ctx, - &gcc); + &gcc, &error_string); if (ret) { goto skip; } diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c index c10f43273c..712742be1f 100644 --- a/source4/smbd/service_named_pipe.c +++ b/source4/smbd/service_named_pipe.c @@ -263,6 +263,7 @@ static NTSTATUS named_pipe_recv_auth_request(void *private_data, gss_buffer_desc cred_token; gss_cred_id_t cred_handle; int ret; + const char *error_string; DEBUG(10, ("named_pipe_auth: delegated credentials supplied by client\n")); @@ -292,9 +293,10 @@ static NTSTATUS named_pipe_recv_auth_request(void *private_data, conn->event.ctx, conn->lp_ctx, cred_handle, - CRED_SPECIFIED); + CRED_SPECIFIED, &error_string); if (ret) { rep.status = NT_STATUS_INTERNAL_ERROR; + DEBUG(2, ("Failed to set pipe forwarded creds: %s\n", error_string)); goto reply; } |