summaryrefslogtreecommitdiff
path: root/source4/auth/credentials/credentials_krb5.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-02-25 16:16:33 +1100
committerAndrew Tridgell <tridge@samba.org>2010-02-26 13:59:16 +1100
commit781ad038c96195031053291414a12225eb818fd9 (patch)
treefaf68b7deb844b69cb7463d6c7f689ecc7248971 /source4/auth/credentials/credentials_krb5.c
parentad7223b9bd31f71b8af2ae83361d7e054a433cc5 (diff)
downloadsamba-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>
Diffstat (limited to 'source4/auth/credentials/credentials_krb5.c')
-rw-r--r--source4/auth/credentials/credentials_krb5.c115
1 files changed, 70 insertions, 45 deletions
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;
}