s4-krb5: propogate errors from a lot more kerberos functions
authorAndrew Tridgell <tridge@samba.org>
Thu, 25 Feb 2010 05:16:33 +0000 (16:16 +1100)
committerAndrew Tridgell <tridge@samba.org>
Fri, 26 Feb 2010 02:59:16 +0000 (13:59 +1100)
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>

13 files changed:
source4/auth/credentials/credentials.c
source4/auth/credentials/credentials.h
source4/auth/credentials/credentials_krb5.c
source4/auth/credentials/credentials_krb5.h
source4/auth/credentials/pycredentials.c
source4/auth/gensec/gensec_gssapi.c
source4/auth/gensec/gensec_krb5.c
source4/auth/kerberos/kerberos.c
source4/auth/kerberos/kerberos.h
source4/auth/kerberos/kerberos_util.c
source4/libcli/util/pyerrors.h
source4/ntvfs/ipc/vfs_ipc.c
source4/smbd/service_named_pipe.c

index 959068c24d9e4749c9a64a30c5ef8cee0094c7fb..2515c4ce7518684aa3bb9566e0a4625de498c228 100644 (file)
@@ -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);
        }
 }
 
index 21a9c61b9a56c5361b6430efee8f2c911a2ed812..6c077c9beccaa64ab3d9529ff7f0f9933c075a4a 100644 (file)
@@ -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);
index b72290196826ba5b89bb6a889d926821480fd9ae..e04b7f5926c9db1e5febb6b5b38abe078039e37d 100644 (file)
@@ -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;
        }
index 5e56752eb4ac40c0b5c1e246b4c0374bd7ff2477..72a437360995c06c1c338e0c32ec6e20cf9a06a4 100644 (file)
@@ -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__ */
index 002ecbcd08f99687f20ddd3bf7adab4d555a2540..8602be8060b5eccbb4321572479df7da281b8e57 100644 (file)
@@ -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[] = {
index 2759ab41c3062c07b0d14cdbb86590af169a16b6..a50190f04c827303201243bf338d6daf6a6d3124 100644 (file)
@@ -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;
                }
                
index 46b8181de7a4de749c7c933d8a1073d22069407e..3d744770dfe2b27c66c0c9d383bf69a5814500ec 100644 (file)
@@ -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;
                }
 
index a0b21c891a1cc992aa541ebe37ee5bcecd697d76..8df54cc8b460c98d10e7334413bcc7ff99c5cc98 100644 (file)
@@ -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;
index 8585aa321b59d3f594077e21f864e9690a45e3f1..498da0f9c2aec28c0fac7b7fce52ef86cdd37a20 100644 (file)
@@ -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,
index 3f8b593e752cd4bfc521a1824c3b17f585a0bd1c..494f36dec7aad0b864e0756ba03d6e67f578e125 100644 (file)
@@ -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;
        }
index 66823f4a41cba9a6f7637828ecddefe94a92c80c..3fd2a7c9fabb44fadab94a2040928bc5d058b1c2 100644 (file)
 
 #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))
 
index aefa93a8eff5617632cfb0aba0b4017b0fa072fb..5d5c3c6eb97e75a2e5a5028e070122c6895c95db 100644 (file)
@@ -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;
                }
index c10f43273c6f282aa37f15cc0c3f0fc4971cf5da..712742be1f57f569ff1b355b07a26493b94714a2 100644 (file)
@@ -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;
                        }