X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Fauth-krb5.c;h=7b88af31ddd6228f152be2e1813a43c239cd7419;hb=78ba3ee1d71032a1325036d5cefa8d0549d76ccd;hp=62827c6f294184799b2e2a19e4afd6009add6e06;hpb=d3372da97568d5e1f35fa19787c8ec8af93a0435;p=doldaconnect.git diff --git a/daemon/auth-krb5.c b/daemon/auth-krb5.c index 62827c6..7b88af3 100644 --- a/daemon/auth-krb5.c +++ b/daemon/auth-krb5.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -266,7 +266,7 @@ static void setrenew(struct krb5data *data) data->renewtimer = timercallback(good, (void (*)(int, void *))renewcreds, data); } -static int krbauth(struct authhandle *auth, char *passdata) +static int krbauth(struct authhandle *auth, struct socket *sk, char *passdata) { int ret; struct krb5data *data; @@ -305,6 +305,7 @@ static int krbauth(struct authhandle *auth, char *passdata) if(auth->text != NULL) free(auth->text); auth->text = icmbstowcs((char *)error_message(ret), NULL); + free(msg); return(AUTH_DENIED); } free(msg); @@ -348,7 +349,7 @@ static int krbauth(struct authhandle *auth, char *passdata) authorized = 1; if(authorized) { - flog(LOG_INFO, "krb5 principal %s successfully authorized as %s", data->cname, data->username); + flog(LOG_INFO, "krb5 principal %s successfully authorized as %s%s", data->cname, data->username, (data->creds == NULL)?"":" (with fwd creds)"); return(AUTH_SUCCESS); } else { flog(LOG_INFO, "krb5 principal %s not authorized as %s", data->cname, data->username); @@ -369,15 +370,16 @@ static int krbauth(struct authhandle *auth, char *passdata) if((ret = krb5_rd_cred(k5context, data->context, &k5d, &fwdcreds, NULL)) != 0) { flog(LOG_ERR, "krb5_rd_cred returned an error: %s", error_message(ret)); + free(msg); return(AUTH_ERR); } + free(msg); if(*fwdcreds == NULL) { flog(LOG_ERR, "forwarded credentials array was empty (from %s)", data->username); krb5_free_tgt_creds(k5context, fwdcreds); return(AUTH_ERR); } - flog(LOG_INFO, "received forwarded credentials for %s", data->username); /* Copy only the first credential. (Change this if it becomes a problem) */ ret = krb5_copy_creds(k5context, *fwdcreds, &data->creds); krb5_free_tgt_creds(k5context, fwdcreds); @@ -420,43 +422,67 @@ static int opensess(struct authhandle *auth) flog(LOG_ERR, "could not get passwd entry for forwarded tickets (user %s): %s", data->username, strerror(errno)); return(AUTH_ERR); } - buf = sprintf2("/tmp/krb5cc_dc_%i_XXXXXX", pwent->pw_uid); - if((fd = mkstemp(buf)) < 0) - { - free(buf); - flog(LOG_ERR, "could not create temporary file for ccache: %s", strerror(errno)); - return(AUTH_ERR); - } - close(fd); - buf2 = sprintf2("FILE:%s", buf); - if((ret = krb5_cc_resolve(k5context, buf2, &data->ccache)) != 0) + if(!confgetint("auth-krb5", "usedefcc")) { - free(buf); + buf = sprintf2("/tmp/krb5cc_dc_%i_XXXXXX", pwent->pw_uid); + if((fd = mkstemp(buf)) < 0) + { + free(buf); + flog(LOG_ERR, "could not create temporary file for ccache: %s", strerror(errno)); + return(AUTH_ERR); + } + close(fd); + buf2 = sprintf2("FILE:%s", buf); + if((ret = krb5_cc_resolve(k5context, buf2, &data->ccache)) != 0) + { + free(buf); + free(buf2); + flog(LOG_ERR, "could not resolve ccache name \"%s\": %s", buf2, error_message(ret)); + return(AUTH_ERR); + } + setenv("KRB5CCNAME", buf2, 1); free(buf2); - flog(LOG_ERR, "could not resolve ccache name \"%s\": %s", buf2, error_message(ret)); - return(AUTH_ERR); - } - setenv("KRB5CCNAME", buf2, 1); - free(buf2); - if((ret = krb5_cc_initialize(k5context, data->ccache, data->ticket->enc_part2->client)) != 0) - { - free(buf); - flog(LOG_ERR, "could not initialize ccache: %s", error_message(ret)); - return(AUTH_ERR); - } - if((ret = krb5_cc_store_cred(k5context, data->ccache, data->creds)) != 0) - { - free(buf); - flog(LOG_ERR, "could not store forwarded TGT into ccache: %s", error_message(ret)); - return(AUTH_ERR); - } - if(chown(buf, pwent->pw_uid, pwent->pw_gid)) - { + if((ret = krb5_cc_initialize(k5context, data->ccache, data->ticket->enc_part2->client)) != 0) + { + free(buf); + flog(LOG_ERR, "could not initialize ccache: %s", error_message(ret)); + return(AUTH_ERR); + } + if((ret = krb5_cc_store_cred(k5context, data->ccache, data->creds)) != 0) + { + free(buf); + flog(LOG_ERR, "could not store forwarded TGT into ccache: %s", error_message(ret)); + return(AUTH_ERR); + } + if(chown(buf, pwent->pw_uid, pwent->pw_gid)) + { + free(buf); + flog(LOG_ERR, "could not chown new ccache to %i:%i: %s", pwent->pw_uid, pwent->pw_gid, strerror(errno)); + return(AUTH_ERR); + } free(buf); - flog(LOG_ERR, "could not chown new ccache to %i:%i: %s", pwent->pw_uid, pwent->pw_gid, strerror(errno)); - return(AUTH_ERR); + } else { + if((buf = (char *)krb5_cc_default_name(k5context)) == NULL) { + flog(LOG_ERR, "could not get default ccache name"); + return(AUTH_ERR); + } + if((ret = krb5_cc_resolve(k5context, buf, &data->ccache)) != 0) + { + flog(LOG_ERR, "could not resolve ccache name \"%s\": %s", buf, error_message(ret)); + return(AUTH_ERR); + } + setenv("KRB5CCNAME", buf, 1); + if((ret = krb5_cc_initialize(k5context, data->ccache, data->ticket->enc_part2->client)) != 0) + { + flog(LOG_ERR, "could not initialize ccache: %s", error_message(ret)); + return(AUTH_ERR); + } + if((ret = krb5_cc_store_cred(k5context, data->ccache, data->creds)) != 0) + { + flog(LOG_ERR, "could not store forwarded TGT into ccache: %s", error_message(ret)); + return(AUTH_ERR); + } } - free(buf); } return(AUTH_SUCCESS); } @@ -568,9 +594,20 @@ static void terminate(void) static struct configvar myvars[] = { + /** The name of the service principal to use for Kerberos V + * authentication. */ {CONF_VAR_STRING, "service", {.str = L"doldacond"}}, + /** The path to an alternative keytab file. If unspecified, the + * system default keytab will be used. */ {CONF_VAR_STRING, "keytab", {.str = L""}}, + /** Whether to renew renewable credentials automatically before + * they expire. */ {CONF_VAR_BOOL, "renewcreds", {.num = 1}}, + /** If true, the default credentials cache will be used, which is + * useful for e.g. Linux kernel key handling. If false, a file + * credentials cache will be created using mkstemp(3), using the + * pattern /tmp/krb5cc_dc_$UID_XXXXXX. */ + {CONF_VAR_BOOL, "usedefcc", {.num = 0}}, {CONF_VAR_END} };