--- libpam-krb5-1.2.0.orig/Makefile +++ libpam-krb5-1.2.0/Makefile @@ -13,7 +13,7 @@ CC = gcc CFLAGS = -O2 -fPIC -Wall -LDFLAGS = -shared -Xlinker -x +LDFLAGS = -shared -Wl,-x -Wl,-z,defs OSLIBS = -lpam -lresolv --- libpam-krb5-1.2.0.orig/context.c +++ libpam-krb5-1.2.0/context.c @@ -42,7 +42,6 @@ goto done; } - retval = valid_context(c); done: if (c && retval != PAM_SUCCESS) { free_context(c); @@ -58,47 +57,18 @@ if ((pamret = pam_get_data(pamh, "ctx", (void *) ctx)) != PAM_SUCCESS) goto done; - pamret = valid_context(*ctx); + done: if (pamret != PAM_SUCCESS) *ctx = NULL; return pamret; } -int -valid_context(struct context *c) -{ - int retval = PAM_SERVICE_ERR; - - if (!c) - goto done; - if (!c->name) - goto done; - if (pam_args.ignore_root && strcmp("root", c->name) == 0) - goto done; - - if (!c->princ) { - /* fetch the principal */ - if ((retval = krb5_parse_name(c->context, c->name, - &c->princ)) != 0) { - dlog(c, "krb5_parse_name(): %s", error_message(retval)); - retval = PAM_SERVICE_ERR; - goto done; - } - } - - if (!krb5_kuserok(c->context, c->princ, c->name)) { - retval = PAM_SERVICE_ERR; - goto done; - } - retval = PAM_SUCCESS; -done: - return retval; -} - void free_context(struct context *ctx) { + if (ctx == NULL) + return; if (ctx->context) { if (ctx->princ) krb5_free_principal(ctx->context, ctx->princ); @@ -111,3 +81,11 @@ } free(ctx); } + +void +destroy_context(pam_handle_t *pamh, void *data, int pam_end_status) +{ + struct context *ctx = (struct context *) data; + if (ctx) + free_context(ctx); +} --- libpam-krb5-1.2.0.orig/context.h +++ libpam-krb5-1.2.0/context.h @@ -20,11 +20,13 @@ krb5_ccache cache; krb5_principal princ; int dont_destroy_cache; + int initialized; }; int new_context(pam_handle_t *pamh, struct context **ctx); int fetch_context(pam_handle_t *pamh, struct context **ctx); int valid_context(struct context *ctx); void free_context(struct context *ctx); +void destroy_context(pam_handle_t *pamh, void *data, int pam_end_status); #endif /* CONTEXT_H_ */ --- libpam-krb5-1.2.0.orig/pam_krb5.5 +++ libpam-krb5-1.2.0/pam_krb5.5 @@ -1,28 +1,28 @@ -.\" -.\" $Id: pam_krb5.5,v 1.4 2001/05/12 22:42:14 hartmans Exp $ -.TH pam_krb5 5 "15 Jan 1999" +.TH pam_krb5 5 "2005-11-07" "1.2.0" .SH NAME pam_krb5 \- Kerberos 5 PAM module .SH SYNOPSIS .LP -.Blib/security/pam_krb5.so.1 +.nf +auth sufficient pam_krb5.so ignore_root +account required pam_krb5.so ignore_root +password optional pam_krb5.so ignore_root +session optional pam_krb5.so ignore_root +.fi .LP .SH DESCRIPTION .IX "pam_krb5" "" "\fLpam_krb5\fP \(em Kerberos 5 PAM module" .PP The Kerberos 5 service module for PAM, typically -.BR /usr/lib/security/pam_krb5.so.1 , +.BR /lib/security/pam_krb5.so , provides functionality for three PAM categories: authentication, account management, +session management, and password management. -It also provides functions for session management to write out credentials. Normally, -these functions should not be needed as the authentication functions do this, but -if credentials are needed in the session phase, -then these functions can be used. - +.LP The -.B pam_krb5.so.1 +.B pam_krb5.so module is a shared object that can be dynamically loaded to provide the necessary functionality upon demand. @@ -39,25 +39,42 @@ converts the supplied username into a Kerberos principal, by appending the default local realm name. It also supports usernames with explicit realm names. -If a realm name is supplied, then upon a sucessful return, it -changes the username by mapping the principal name into a local username -(calling \f3krb5_aname_to_localname()\f1). This typically just means -the realm name is stripped. .LP It prompts the user for a password and obtains a new Kerberos TGT for the principal. The TGT is verified by obtaining a service ticket for the local host. .LP -When prompting for the current password, the authentication -module will use the prompt "Password for : ". -.LP The .B pam_sm_setcred(\|) function stores the newly acquired credentials in a credentials cache, and sets the environment variable .B KRB5CCNAME -appropriately. -This module destroys the credentials cache when the PAM data is cleaned up. Thus, you should set close_sessions to yes in /etc/login.defs. +appropriately. This module destroys the credentials cache when the PAM +data is cleaned up. Thus, you should set close_sessions to yes in +/etc/login.defs. +.LP +If the authentication is done as root and a local keytab is available, +.B pam_krb5.so +will do a proper Kerberos authentication by using the Kerberos TGT +acquired to obtain a service ticket and then validate the service ticket +against a local keytab. If there is no local keytab or if the keytab file +.RI ( /etc/krb5.keytab ) +is not readable, this step will be skipped. Without performing this step, +authentication is vulnerable to KDC spoofing. If a keytab is available, +the module first looks for a principal named +.RI host/ machine +where +.I machine +is the fully qualified local hostname. If that principal isn't available, +it looks for +.IR service / machine +where +.I service +is the PAM service used (the first argument to +.BR pam_start(\|) ) +and +.I machine +is the same as above. .LP The following options may be passed to the authentication module: .TP 15 @@ -68,13 +85,12 @@ level. .TP .B use_first_pass -If the authentication module is not the first in the stack, -and a previous module obtained the user's password, that password is -used to authenticate the user. If this fails, the authentication -module returns failure without prompting the user for a password. -This option has no effect if the authentication module is -the first in the stack, or if no previous modules obtained the -user's password. +If the authentication module is not the first in the stack, and a previous +module obtained the user's password, that password is used to authenticate +the user. If this fails, the authentication module returns failure +without prompting the user for a password. This option has no effect if +the authentication module is the first in the stack, or if no previous +modules obtained the user's password. .TP .B try_first_pass This option is similar to the @@ -91,42 +107,89 @@ as ftp or pop, where the user would not be able to destroy them. [This is not a recommendation to use the module for those services.] .TP +.B ignore_root +Never attempt to authenticate the user "root". Always fail immediately if +that user is being authenticated; presumably the PAM stack will fall back +to some other mechanism. +.TP +.B search_k5login +Normally, the authentication module attempts to authenticate as a Kerberos +principal derived from the username by appending the default realm. +Verification of the presence of that Kerberos principal in the user's +\&.k5login file can then be done via the account management module. When +this option is given and a \&.k5login file is present, the provided +password is instead used to attempt to authenticate as each Kerberos +principal listed in the \&.k5login file in turn. If there is no +\&.k5login file, the behavior is the same as normal. This may be useful +when there is no simple mapping from local username to Kerberos principal +name, but requires the \&.k5login file be readable at the time of +authentication (and therefore may not work with schemes such as sshd's +privilege separation). +.SH Kerberos 5 Session Management Module +The Kerberos 5 session management component +provides functions to initiate +(\f3pam_sm_open_session(\|)\f1) +and terminate +(\f3pam_sm_close_session(\|)\f1) +sessions. This module takes all of the same options as the authentication +module and will authenticate the user if authentication has not already +been established. In addition, it takes the following options specific to +this module: +.TP .B ccache= -Use as the credentials cache. must be in the form -.IR type:residual . -The special tokens +Use as the credentials cache. must be in the form +.I type:residual +(where +.I type +is optional if a file cache is used). The special tokens .BR %u , -to designate the decimal uid of the user; -and +to designate the decimal uid of the user, and .BR %p , -to designate the current process id; can be used in . +to designate the current process id, can be used in . If +ends with the literal string XXXXXX (six X's), that string will be +replaced by randomly generated characters and the ticket cache opened via +mkstemp. This is strongly recommended if points to a +world-writable directory. +.TP +.B ccache_dir= +Put the ticket cache in instead of the default of /tmp. Ignored if +.B ccache +is also set. .SH Kerberos 5 Account Management Module The Kerberos 5 account management component provides a function to perform account management, .BR pam_sm_acct_mgmt(\|) . The function verifies that the authenticated principal is allowed to login to the local user account by calling -.B krb5_kuserok() -(which checks the user's \&.k5login file). +.B krb5_kuserok(\|) +(which checks the user's \&.k5login file). Note that this is also done by +pam_sm_authenticate(\|) and pam_sm_setcred(\|). +.LP +If the user didn't log on using krb5, this function silently succeeds. +.LP +The following options may be passed to the account module: +.TP 15 +.B ignore_root +Skip any attempt to validate the root account and just succeed quietly. +Presumably whatever validation is necessary will be handled by another +module in the PAM stack. .SH Kerberos 5 Password Management Module The Kerberos 5 password management component provides a function to change passwords (\f3pam_sm_chauthtok(\|)\f1). The username supplied (the user running the .BR passwd (1) -command, or the username given as an argument) is mapped into -a Kerberos principal name, using the same technique as in -the authentication module. Note that if a realm name was -explicitly supplied during authentication, but not during -a password change, the mapping -done by the password management module may not result in the -same principal as was used for authentication. -.LP -Unlike when -changing a unix password, the password management module will -allow any user to change any principal's password (if the user knows -the principal's old password, of course). Also unlike unix, root -is always prompted for the principal's old password. +command, or the username given as an argument) is mapped into a Kerberos +principal name, using the same technique as in the authentication module. +Note that if a realm name was explicitly supplied during authentication, +but not during a password change, the mapping done by the password +management module may not result in the same principal as was used for +authentication. +.LP +Unlike when changing a unix password, the password management module will +allow any user to change any principal's password (if the user knows the +principal's old password, of course). Also unlike unix, root is always +prompted for the principal's old password. .LP The password management module uses the same heuristics as .BR kpasswd (1) @@ -142,30 +205,23 @@ level. .TP .B use_first_pass -If the password management module is not the first in the stack, -and a previous module obtained the user's old password, that password is -used to authenticate the user. If this fails, the password -management -module returns failure without prompting the user for the old password. -If successful, the new password entered to the previous module is also -used as the new Kerberos password. If the new password fails, -the password management module returns failure without -prompting the user for a new password. +If the password management module is not the first in the stack, and a +previous module obtained the user's old password, that password is used to +authenticate the user. If this fails, the password management module +returns failure without prompting the user for the old password. If +successful, the new password entered to the previous module is also used +as the new Kerberos password. If the new password fails, the password +management module returns failure without prompting the user for a new +password. .TP .B try_first_pass This option is similar to the .B use_first_pass option, except that if the previously obtained old or new passwords fail, the user is prompted for them. -.SH Kerberos 5 Session Management Module -The Kerberos 5 session management component -provides functions to initiate -(\f3pam_sm_open_session(\|)\f1) -and terminate -(\f3pam_sm_close_session(\|)\f1) -sessions. Since session management is not defined under Kerberos 5, -both of these functions simply return success. They are provided -only because of the naming conventions for PAM modules. +.TP +.B ignore_root +Do not try to change passwords for the root user, just fail immediately. .SH ENVIRONMENT .TP "\w'.SM KRB5CCNAME\ \ 'u" .SM KRB5CCNAME @@ -174,7 +230,10 @@ .TP /tmp/krb5cc_[uid]_[rand] default credentials cache ([uid] is the decimal UID of the user and [rand] -is a random string). +is a random string). The directory in which it is stored may be changed +with the +.B ccache_dir +option. .TP ~/\&.k5login file containing Kerberos principals that are allowed access. --- libpam-krb5-1.2.0.orig/pam_krb5.h +++ libpam-krb5-1.2.0/pam_krb5.h @@ -25,6 +25,8 @@ int no_ccache; int ignore_root; char *ccache_dir; + char *ccache; + int search_k5login; int quiet; /* not really an arg, but it may as well be */ }; extern struct pam_args pam_args; @@ -37,7 +39,7 @@ struct credlist **); int get_user_info(pam_handle_t *, const char *, int, char **); -int verify_krb_v5_tgt(krb5_context, krb5_ccache, const char *); +int validate_auth(struct context *); krb5_prompter_fct pam_prompter; --- libpam-krb5-1.2.0.orig/pam_krb5_acct.c +++ libpam-krb5-1.2.0/pam_krb5_acct.c @@ -26,14 +26,21 @@ parse_args(flags, argc, argv); dlog(ctx, "%s: entry", __FUNCTION__); - if (fetch_context(pamh, &ctx) != PAM_SUCCESS) { - /* User did not use krb5 to login */ - /* pamret = PAM_SUCCESS; // I don't think we want to do this. - * // This policy should be in pam.conf, - * // not here. Fail, instead. Admin can - * // override w/ 'sufficient' */ - goto done; + /* Succeed if the user did not use krb5 to login. Yes, ideally we should + probably fail and require that the user set up policy properly in their + PAM configuration, but it's not common for the user to do so and that's + not how other krb5 PAM modules work. If we don't do this, root logins + with the system root password fail, which is a bad failure mode. */ + pamret = pam_get_data(pamh, "ctx", (void *) &ctx); + if (pamret != PAM_SUCCESS || ctx == NULL) { + pamret = PAM_SUCCESS; + ctx = NULL; + dlog(ctx, "%s: skipping non-Kerberos login", __FUNCTION__); + goto done; } + pamret = fetch_context(pamh, &ctx); + if (pamret == PAM_SUCCESS) + pamret = validate_auth(ctx); /* XXX: we could be a bit more thorough here; see what krb5_kuserok * *doesn't* check for, and check that here. */ --- libpam-krb5-1.2.0.orig/pam_krb5_auth.c +++ libpam-krb5-1.2.0/pam_krb5_auth.c @@ -8,6 +8,7 @@ #define PAM_SM_AUTH #include +#include #include #include #include @@ -60,15 +61,56 @@ } #endif -static void -destroy_context(pam_handle_t *pamh, void *data, int pam_end_status) +static const char * +get_krb5ccname(struct context *ctx, const char *key) +{ + const char *name; + + /* TODO: figure out why pam_getenv() returns NULL */ + name = pam_getenv(ctx->pamh, key); + if (!name) + name = getenv(key); + if (!name && ctx && ctx->context && ctx->cache) + name = krb5_cc_get_name(ctx->context, ctx->cache); + + return name; +} + +static int +set_krb5ccname(struct context *ctx, const char *name, const char *key) { - struct context *ctx = (struct context *) data; - if (ctx) - free_context(ctx); + char *env_name = NULL; + int pamret; + + env_name = malloc(strlen(key) + 1 + strlen(name) + 1); + if (!env_name) { + dlog(ctx, "malloc() failure"); + pamret = PAM_BUF_ERR; + goto done; + } + + sprintf(env_name, "%s=%s", key, name); + if ((pamret = pam_putenv(ctx->pamh, env_name)) != PAM_SUCCESS) { + dlog(ctx, "pam_putenv(): %s", pam_strerror(ctx->pamh, pamret)); + pamret = PAM_SERVICE_ERR; + goto done; + } + + pamret = PAM_SUCCESS; +done: + if (env_name) + free(env_name); + return pamret; } -/* Authenticate a user via krb5 */ +/* Authenticate a user via krb5. + + It would be nice to be able to save the ticket cache temporarily as a + memory cache and then only write it out to disk during the session + initialization. Unfortunately, OpenSSH 4.2 does PAM authentication in a + subprocess and therefore has no saved module-specific data available once + it opens a session, so we have to save the ticket cache to disk and store + in the environment where it is. */ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) @@ -76,7 +118,8 @@ struct context *ctx = NULL; struct credlist *clist = NULL; int pamret = PAM_SERVICE_ERR; - char cache_name[L_tmpnam + 8]; + char cache_name[] = "/tmp/krb5cc_pam_XXXXXX"; + int ccfd; parse_args(flags, argc, argv); dlog(ctx, "%s: entry", __FUNCTION__); @@ -92,59 +135,145 @@ goto done; } - /* Generate a unique cache_name */ - strcpy(cache_name, "MEMORY:"); - tmpnam(&cache_name[7]); - if ((pamret = password_auth(ctx, NULL, &clist)) != PAM_SUCCESS) goto done; + ccfd = mkstemp(cache_name); + if (ccfd < 0) { + dlog(ctx, "mkstemp(\"%s\") failed: %s", cache_name, strerror(errno)); + pamret = PAM_SERVICE_ERR; + goto done; + } + close(ccfd); if ((pamret = init_ccache(ctx, cache_name, clist, &ctx->cache)) != PAM_SUCCESS) goto done; + if ((pamret = validate_auth(ctx)) != PAM_SUCCESS) + goto done; + if ((pamret = set_krb5ccname(ctx, cache_name, "PAM_KRB5CCNAME")) != PAM_SUCCESS) + goto done; done: free_credlist(ctx, clist); dlog(ctx, "%s: exit (%s)", __FUNCTION__, pamret ? "failure" : "success"); + + /* Clear the context on failure so that the account management module + knows that we didn't authenticate with Kerberos. */ + if (pamret != PAM_SUCCESS) + pam_set_data(pamh, "ctx", NULL, NULL); return pamret; } -static const char * -get_krb5ccname(struct context *ctx) +/* Determine the name of the ticket cache. Handles ccache and ccache_dir PAM + options and returns newly allocated memory. */ +static char * +build_ccache_name(struct context *ctx, uid_t uid) { - const char *name; + char *cache_name; - /* TODO: figure out why pam_getenv() returns NULL */ - name = getenv("KRB5CCNAME"); - if (!name && ctx && ctx->context && ctx->cache) - name = krb5_cc_get_name(ctx->context, ctx->cache); + if (pam_args.ccache == NULL) { + size_t ccache_size = 1 + strlen(pam_args.ccache_dir) + + strlen("/krb5cc_4294967295_XXXXXX"); - return name; + cache_name = malloc(ccache_size); + if (!cache_name) { + dlog(ctx, "malloc() failure"); + return NULL; + } + snprintf(cache_name, ccache_size, "%s/krb5cc_%d_XXXXXX", + pam_args.ccache_dir, uid); + } else { + size_t len = 0, delta; + char *p, *q; + + for (p = pam_args.ccache; *p != '\0'; p++) { + if (p[0] == '%' && p[1] == 'u') { + len += snprintf(NULL, 0, "%d", uid); + p++; + } else if (p[0] == '%' && p[1] == 'p') { + len += snprintf(NULL, 0, "%d", getpid()); + p++; + } else { + len++; + } + } + len++; + cache_name = malloc(len); + if (cache_name == NULL) { + dlog(ctx, "malloc() failure"); + return NULL; + } + for (p = pam_args.ccache, q = cache_name; *p != '\0'; p++) { + if (p[0] == '%' && p[1] == 'u') { + delta = snprintf(q, len, "%d", uid); + q += delta; + len -= delta; + p++; + } else if (p[0] == '%' && p[1] == 'p') { + delta = snprintf(q, len, "%d", getpid()); + q += delta; + len -= delta; + p++; + } else { + *q = *p; + q++; + len--; + } + } + *q = '\0'; + } + return cache_name; } +/* Create a new context for a session if we've lost the context created during + authentication (such as when running under OpenSSH. */ static int -set_krb5ccname(struct context *ctx, const char *name) +create_session_context(pam_handle_t *pamh, struct context **newctx) { - char *env_name = NULL; - int pamret; - - env_name = malloc(sizeof("KRB5CCNAME=") + strlen(name)); - if (!env_name) { - dlog(ctx, "malloc() failure"); - pamret = PAM_BUF_ERR; - goto done; - } - - sprintf(env_name, "KRB5CCNAME=%s", name); - if ((pamret = pam_putenv(ctx->pamh, env_name)) != PAM_SUCCESS) { - dlog(ctx, "pam_putenv(): %s", pam_strerror(ctx->pamh, pamret)); - pamret = PAM_SERVICE_ERR; - goto done; - } + struct context *ctx = NULL; + const char *tmpname; + int pamret; + if (pam_args.ignore_root) { + pamret = pam_get_user(pamh, &tmpname, NULL); + if (pamret == PAM_SUCCESS && strcmp("root", tmpname) == 0) { + dlog(ctx, "ignoring root login"); + pamret = PAM_SUCCESS; + goto fail; + } + } + pamret = new_context(pamh, &ctx); + if (pamret != PAM_SUCCESS) { + dlog(ctx, "creating session context failed"); + goto fail; + } + tmpname = get_krb5ccname(ctx, "PAM_KRB5CCNAME"); + if (tmpname == NULL) { + dlog(ctx, "unable to get PAM_KRB5CCNAME, assuming non-Kerberos login"); pamret = PAM_SUCCESS; -done: - if (env_name) - free(env_name); - return pamret; + goto fail; + } + dlog(ctx, "found initial ticket cache at %s", tmpname); + if (krb5_cc_resolve(ctx->context, tmpname, &ctx->cache) != 0) { + dlog(ctx, "cannot resolve cache %s", tmpname); + pamret = PAM_SERVICE_ERR; + goto fail; + } + if (krb5_cc_get_principal(ctx->context, ctx->cache, &ctx->princ) != 0) { + dlog(ctx, "cannot retrieve principal"); + pamret = PAM_SERVICE_ERR; + goto fail; + } + if ((pamret = pam_set_data(pamh, "ctx", ctx, + destroy_context)) != PAM_SUCCESS) { + dlog(ctx, "cannot set context data"); + goto fail; + } + *newctx = ctx; + return PAM_SUCCESS; + +fail: + if (ctx != NULL) + free_context(ctx); + return pamret; } /* Called after a successful authentication. Set user credentials. */ @@ -158,16 +287,15 @@ char *cache_name = NULL; int reinit = 0; int pamret; - struct passwd *pw = NULL; - uid_t euid = geteuid(); /* Usually 0 */ - gid_t egid = getegid(); + uid_t uid; + gid_t gid; parse_args(flags, argc, argv); dlog(ctx, "%s: entry (0x%x)", __FUNCTION__, flags); if (flags & PAM_DELETE_CRED) - return pam_set_data(pamh, "ctx", NULL, destroy_context); + return pam_set_data(pamh, "ctx", NULL, destroy_context); if (flags & (PAM_REINITIALIZE_CRED | PAM_REFRESH_CRED)) reinit = 1; @@ -178,8 +306,22 @@ return PAM_SERVICE_ERR; pamret = fetch_context(pamh, &ctx); + if (pamret != PAM_SUCCESS) { + dlog(ctx, "%s: no context found, creating one", __FUNCTION__); + pamret = create_session_context(pamh, &ctx); + if (ctx == NULL) + goto done; + } + + /* Revalidate the user. */ + pamret = validate_auth(ctx); if (pamret != PAM_SUCCESS) - goto done; + goto done; + + /* Some programs (xdm, for instance) appear to call setcred over and + * over again, so avoid doing useless work. */ + if (ctx->initialized) + return PAM_SUCCESS; if (pam_args.no_ccache) goto done; @@ -191,28 +333,31 @@ pamret = PAM_USER_UNKNOWN; goto done; } - - /* Avoid following a symlink as root */ - if (setegid(pw->pw_gid)) { - dlog(ctx, "setegid(): %s", ctx->name); - pamret = PAM_SERVICE_ERR; - goto done; - } - if (seteuid(pw->pw_uid)) { - dlog(ctx, "seteuid(): %s", ctx->name); - pamret = PAM_SERVICE_ERR; - goto done; - } + uid = pw->pw_uid; + gid = pw->pw_gid; /* Get the cache name */ if (reinit) { - const char *name = get_krb5ccname(ctx); + const char *name, *k5name; + + name = get_krb5ccname(ctx, "KRB5CCNAME"); if (!name) { - dlog(ctx, "Unable to get KRBCCNAME!"); + dlog(ctx, "Unable to get KRB5CCNAME!"); pamret = PAM_SERVICE_ERR; goto done; } + /* If the cache we have in the context and the cache we're + * reinitializing are the same cache, don't do anything; otherwise, + * we'll end up destroying the cache. */ + if (ctx->cache != NULL) { + k5name = krb5_cc_get_name(ctx->context, ctx->cache); + if (k5name != NULL && strcmp(name, k5name) == 0) { + pamret = PAM_SUCCESS; + goto done; + } + } + cache_name = strdup(name); if (!cache_name) { dlog(ctx, "malloc() failure"); @@ -220,32 +365,31 @@ goto done; } dlog(ctx, "%s: attempting to refresh cred cache %s", __FUNCTION__, cache_name); + /* If we're refreshing the cache, we didn't really create it; * some other application (probably login?) is still using it. * Thus, don't remove it! */ ctx->dont_destroy_cache = 1; } else { - int ccache_fd; - size_t ccache_size = 1 + strlen(pam_args.ccache_dir) + - strlen("/krb5cc_4294967295_XXXXXX"); + int ccache_fd; + size_t len; - cache_name = malloc(ccache_size); - if (!cache_name) { - dlog(ctx, "malloc() failure"); + cache_name = build_ccache_name(ctx, uid); + if (cache_name == NULL) { pamret = PAM_BUF_ERR; goto done; } - snprintf(cache_name, ccache_size, "%s/krb5cc_%d_XXXXXX", - pam_args.ccache_dir, pw->pw_uid); - ccache_fd = mkstemp(cache_name); - if (ccache_fd == -1) { - dlog(ctx, "mkstemp() failure"); - pamret = PAM_BUF_ERR; - goto done; + len = strlen(cache_name); + if (len > 6 && strncmp("XXXXXX", cache_name + len - 6, 6) == 0) { + ccache_fd = mkstemp(cache_name); + if (ccache_fd == -1) { + dlog(ctx, "mkstemp() failure"); + pamret = PAM_SERVICE_ERR; + goto done; + } + close(ccache_fd); } - close(ccache_fd); - } /* Initialize the new ccache */ @@ -255,16 +399,19 @@ if ((pamret = init_ccache(ctx, cache_name, clist, &cache)) != PAM_SUCCESS) goto done; - if (chown(cache_name, pw->pw_uid, pw->pw_gid) == -1) { + if (chown(cache_name, uid, gid) == -1) { dlog(ctx, "chown(): %s", strerror(errno)); pamret = PAM_SERVICE_ERR; goto done; } - if ((pamret = set_krb5ccname(ctx, cache_name)) != PAM_SUCCESS) + if ((pamret = set_krb5ccname(ctx, cache_name, "KRB5CCNAME")) != PAM_SUCCESS) goto done; + if (pam_getenv(pamh, "PAM_KRB5CCNAME") != NULL) + if ((pamret = pam_putenv(pamh, "PAM_KRB5CCNAME")) != PAM_SUCCESS) + goto done; + ctx->initialized = 1; - if (!reinit) - krb5_cc_destroy(ctx->context, ctx->cache); + krb5_cc_destroy(ctx->context, ctx->cache); ctx->cache = cache; cache = NULL; @@ -274,8 +421,6 @@ if (cache_name) free(cache_name); free_credlist(ctx, clist); - seteuid(euid); - setegid(egid); dlog(ctx, "%s: exit (%s)", __FUNCTION__, pamret ? "failure" : "success"); return pamret; } --- libpam-krb5-1.2.0.orig/pam_krb5_pass.c +++ libpam-krb5-1.2.0/pam_krb5_pass.c @@ -18,6 +18,7 @@ #include #include "pam_krb5.h" #include "credlist.h" +#include "context.h" /* Utter a message to the user */ static void @@ -57,7 +58,7 @@ if (pam_args.try_first_pass || pam_args.use_first_pass) pam_get_item(ctx->pamh, PAM_AUTHTOK, (const void **) pass); - if (!pass) { + if (!*pass) { if ((pamret = get_user_info(ctx->pamh, "Enter new password: ", PAM_PROMPT_ECHO_OFF, pass) != PAM_SUCCESS)) { dlog(ctx, "get_user_info(): %s", pam_strerror(ctx->pamh, pamret)); pamret = PAM_SERVICE_ERR; @@ -135,24 +136,51 @@ struct context *ctx = NULL; struct credlist *clist = NULL; - int pamret; + int pamret = PAM_SUCCESS; + const char *tmpname; char *pass = NULL; parse_args(flags, argc, argv); - dlog(ctx, "%s: entry", __FUNCTION__); + dlog(ctx, "%s: entry (flags %d)", __FUNCTION__, flags); - if (flags & PAM_PRELIM_CHECK) /* not sure if this a right way to do it */ - return PAM_SUCCESS; - if (!(flags & PAM_UPDATE_AUTHTOK)) - return PAM_AUTHTOK_ERR; + if (flags & PAM_PRELIM_CHECK) + goto done; + if (!(flags & PAM_UPDATE_AUTHTOK)) { + pamret = PAM_AUTHTOK_ERR; + goto done; + } + + if (pam_args.ignore_root) { + pamret = pam_get_user(pamh, &tmpname, NULL); + if (pamret == PAM_SUCCESS && strcmp("root", tmpname) == 0) { + dlog(ctx, "ignoring root password change"); + pamret = PAM_SUCCESS; + goto done; + } + } pamret = fetch_context(pamh, &ctx); - if (pamret != PAM_SUCCESS) - goto done; + if (pamret != PAM_SUCCESS) { + pamret = new_context(pamh, &ctx); + if (pamret != PAM_SUCCESS) { + dlog(ctx, "creating context failed (%d)", pamret); + pamret = PAM_AUTHTOK_ERR; + goto done; + } + pamret = pam_set_data(pamh, "ctx", ctx, destroy_context); + if (pamret != PAM_SUCCESS) { + dlog(ctx, "cannot set context data"); + pamret = PAM_AUTHTOK_ERR; + goto done; + } + } /* Auth using old password */ - if ((pamret = password_auth(ctx, "kadmin/changepw", &clist)) != PAM_SUCCESS) + pamret = password_auth(ctx, "kadmin/changepw", &clist); + if (pamret != PAM_SUCCESS) { + pamret = PAM_AUTHTOK_ERR; goto done; + } /* Now get the new password */ if ((pamret = get_new_password(ctx, &pass)) != PAM_SUCCESS) --- libpam-krb5-1.2.0.orig/support.c +++ libpam-krb5-1.2.0/support.c @@ -5,10 +5,13 @@ */ #include +#include #include #include #include +#include #include +#include #include #include #include @@ -39,8 +42,12 @@ pam_args.no_ccache = 1; else if (strcmp(argv[i], "ignore_root") == 0) pam_args.ignore_root = 1; - else if (strcmp(argv[i], "ccache_dir=") == 0) - pam_args.ccache_dir = (char *) &argv[i][7]; + else if (strncmp(argv[i], "ccache=", 7) == 0) + pam_args.ccache = (char *) &argv[i][7]; + else if (strncmp(argv[i], "ccache_dir=", 11) == 0) + pam_args.ccache_dir = (char *) &argv[i][11]; + else if (strcmp(argv[i], "search_k5login") == 0) + pam_args.search_k5login = 1; } if (flags & PAM_SILENT) @@ -49,6 +56,111 @@ pam_args.ccache_dir = "/tmp"; } + + +/* + * Used to support trying each principal in the .k5login file. Read through + * each line that parses correctly as a principal and use the provided + * password to try to authenticate as that user. If at any point we succeed, + * fill out creds, set princ to the successful principal in the context, and + * return PAM_SUCCESS. Otherwise, return PAM_AUTH_ERR for a general + * authentication error or PAM_SERVICE_ERR for a system error. If + * PAM_AUTH_ERR is returned, retval will be filled in with the Kerberos + * error if available, 0 otherwise. + */ +static int +k5login_password_auth(struct context *ctx, krb5_creds *creds, + krb5_get_init_creds_opt *opts, char *in_tkt_service, + char *pass, int *retval) +{ + char *filename; + char line[BUFSIZ]; + size_t len; + FILE *k5login; + struct passwd *pwd; + struct stat st; + int k5_errno; + krb5_principal princ; + + /* Assume no Kerberos error. */ + *retval = 0; + + /* C sucks at string manipulation. Generate the filename for the user's + .k5login file. */ + pwd = getpwnam(ctx->name); + if (pwd == NULL) + return PAM_AUTH_ERR; + len = strlen(pwd->pw_dir) + strlen("/.k5login"); + filename = malloc(len + 1); + if (filename == NULL) + return PAM_SERVICE_ERR; + strncpy(filename, pwd->pw_dir, len); + filename[len] = '\0'; + strncat(filename, "/.k5login", len - strlen(pwd->pw_dir)); + + /* If there is no file, do this the easy way. */ + if (access(filename, R_OK) != 0) { + k5_errno = krb5_parse_name(ctx->context, ctx->name, &ctx->princ); + if (k5_errno != 0) { + dlog(ctx, "krb5_parse_name(): %s", error_message(k5_errno)); + return PAM_SERVICE_ERR; + } + *retval = krb5_get_init_creds_password(ctx->context, creds, + ctx->princ, pass, pam_prompter, ctx->pamh, 0, + in_tkt_service, opts); + return (*retval == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; + } + + /* Make sure the ownership on .k5login is okay. The user must own their + own .k5login or it must be owned by root. */ + k5login = fopen(filename, "r"); + free(filename); + if (k5login == NULL) + return PAM_AUTH_ERR; + if (fstat(fileno(k5login), &st) != 0) + goto fail; + if (st.st_uid != 0 && (st.st_uid != pwd->pw_uid)) + goto fail; + + /* Parse the .k5login file. Ignore any lines that are too long or that + don't parse into a Kerberos principal. */ + while (fgets(line, BUFSIZ, k5login) != NULL) { + len = strlen(line); + if (line[len - 1] != '\n') { + while (fgets(line, BUFSIZ, k5login) != NULL) { + len = strlen(line); + if (line[len - 1] == '\n') + break; + } + continue; + } + line[len - 1] = '\0'; + k5_errno = krb5_parse_name(ctx->context, line, &princ); + if (k5_errno != 0) + continue; + + /* Now, attempt to authenticate as that user. */ + *retval = krb5_get_init_creds_password(ctx->context, creds, + princ, pass, pam_prompter, ctx->pamh, 0, + in_tkt_service, opts); + + /* If that worked, update ctx->princ and return success. Otherwise, + continue on to the next line. */ + if (*retval == 0) { + if (ctx->princ) + krb5_free_principal(ctx->context, ctx->princ); + ctx->princ = princ; + fclose(k5login); + return PAM_SUCCESS; + } + krb5_free_principal(ctx->context, princ); + } + +fail: + fclose(k5login); + return PAM_AUTH_ERR; +} + /* * Prompt the user for a password; authenticate the password with the KDC. * If correct, fill in creds with TGT magic. */ @@ -61,6 +173,7 @@ int retval; char *pass = NULL; int retry; + int success; new_credlist(ctx, credlist); memset(&creds, 0, sizeof(krb5_creds)); @@ -74,6 +187,14 @@ goto done; } + /* Fill in the principal to authenticate as. */ + retval = krb5_parse_name(ctx->context, ctx->name, &ctx->princ); + if (retval != 0) { + dlog(ctx, "krb5_parse_name(): %s", error_message(retval)); + retval = PAM_SERVICE_ERR; + goto done; + } + retry = pam_args.try_first_pass ? 1 : 0; if (pam_args.try_first_pass || pam_args.use_first_pass) pam_get_item(ctx->pamh, PAM_AUTHTOK, (void *) &pass); @@ -102,15 +223,23 @@ } /* Get a TGT */ - retval = krb5_get_init_creds_password(ctx->context, &creds, ctx->princ, pass, pam_prompter, ctx->pamh, 0, in_tkt_service, &opts); - if (retval == 0 || (!retry && retval != KRB5KRB_AP_ERR_BAD_INTEGRITY)) { - if ((retval = append_to_credlist(ctx, credlist, creds)) != PAM_SUCCESS) + if (pam_args.search_k5login) { + success = k5login_password_auth(ctx, &creds, &opts, + in_tkt_service, pass, &retval); + } else { + retval = krb5_get_init_creds_password(ctx->context, + &creds, ctx->princ, pass, pam_prompter, + ctx->pamh, 0, in_tkt_service, &opts); + success = (retval == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; + } + if (success == PAM_SUCCESS) { + retval = append_to_credlist(ctx, credlist, creds); + if (retval != PAM_SUCCESS) goto done; - break; } pass = NULL; - } while (retry); + } while (retry && retval == KRB5KRB_AP_ERR_BAD_INTEGRITY); if (retval == 0 && pass) { /* success; set this in case we're changing the passwd */ @@ -186,11 +315,6 @@ c = c->next; } - if (verify_krb_v5_tgt(ctx->context, *cache, ctx->service) == -1) { - retval = PAM_AUTH_ERR; - goto done; - } - done: if (retval != PAM_SUCCESS && *cache) krb5_cc_destroy(ctx->context, *cache); @@ -250,7 +374,7 @@ * * Returns 1 for confirmation, -1 for failure, 0 for uncertainty. */ -int +static int verify_krb_v5_tgt(krb5_context context, krb5_ccache ccache, const char *pam_service) { @@ -349,3 +473,37 @@ return retval; } + + +/* Verify the user authentication. First, obtain and verify a service ticket + using their TGT, and then call krb5_kuserok if this is a local account. We + don't need to check krb5_aname_to_localname since we derived the principal + name for the authentication from PAM_USER and it therefore either started + as an unqualified name or already has the domain that we want. */ +int +validate_auth(struct context *ctx) +{ + struct passwd *pwd; + + /* Sanity checks. */ + if (ctx == NULL) + return PAM_SERVICE_ERR; + if (ctx->name == NULL) + return PAM_SERVICE_ERR; + + /* Try to obtain and check a service ticket. */ + if (verify_krb_v5_tgt(ctx->context, ctx->cache, ctx->service) == -1) + return PAM_AUTH_ERR; + + /* If the account is a local account, call krb5_kuserok. It's the + responsibility of the calling application to deal with authorization + issues for non-local accounts. */ + if (strchr(ctx->name, '@') == NULL) { + pwd = getpwnam(ctx->name); + if (pwd != NULL && !krb5_kuserok(ctx->context, ctx->princ, ctx->name)) + return PAM_AUTH_ERR; + } + + /* Everything looks fine. */ + return PAM_SUCCESS; +} --- libpam-krb5-1.2.0.orig/debian/control +++ libpam-krb5-1.2.0/debian/control @@ -0,0 +1,19 @@ +Source: libpam-krb5 +Section: net +Priority: optional +Maintainer: Sam Hartman +Uploaders: Russ Allbery +Standards-Version: 3.6.2 +Build-Depends: debhelper (>= 4.0.0), libkrb5-dev, comerr-dev, libpam0g-dev + +Package: libpam-krb5 +Architecture: any +Depends: ${shlibs:Depends}, krb5-config +Conflicts: libpam-heimdal +Description: PAM module for MIT Kerberos + A Kerberos v5 PAM module for use with MIT Kerberos. It supports + authenticating against a Kerberos v5 KDC, obtaining tickets and + populating an initial ticket cache, authorizing users via a ~/.k5login + file, and changing Kerberos v5 passwords. This module should only be + used for local logins unless you really know what you are doing. + --- libpam-krb5-1.2.0.orig/debian/dirs +++ libpam-krb5-1.2.0/debian/dirs @@ -0,0 +1 @@ +lib/security --- libpam-krb5-1.2.0.orig/debian/compat +++ libpam-krb5-1.2.0/debian/compat @@ -0,0 +1 @@ +4 --- libpam-krb5-1.2.0.orig/debian/changelog +++ libpam-krb5-1.2.0/debian/changelog @@ -0,0 +1,198 @@ +libpam-krb5 (1.2.0-3) unstable; urgency=low + + * Only call krb5_kuserok when the account to which we're authenticating + is a local account to allow use of pam_krb5 for application + authentication of users without local accounts. (Closes: #354133) + * Restructure the code to do user validation after obtaining their + initial tickets. This eliminates a lot of confusing special cases and + deferred checking and makes it easier to audit the code. + * Don't create the ticket cache until after successful authentication. + Otherwise, we leave files behind in /tmp. + * Document what principals libpam_krb5.so looks for in the system keytab + to do ticket validation. (Closes: #350556) + + -- Russ Allbery Wed, 8 Mar 2006 16:58:13 -0800 + +libpam-krb5 (1.2.0-2) unstable; urgency=low + + * Always use a disk cache for temporary storage of credentials and cope + with not having module-specific data during pam_sm_setcred by passing + the cache path in an environment variable. This is required to cope + with OpenSSH's technique (when using ChallengeResponseAuthentication) + of doing PAM authentication in a child process and then opening the + session in the parent. (Closes: #339734) + * Only initialize the ticket cache once no matter how many times setcred + is called. Saves duplicate work and works around a bug in xdm, which + calls setcred repeatedly and discards the environment set by the final + call. + * Don't assume we already have a context when changing passwords; passwd + doesn't work that way. (Closes: #344003) + * Fix the test for the new password. I don't think this would have + worked at all before. + * Improve debugging output for password changes. + * If search_k5login is specified but no .k5login is found, still check + the user with krb5_kuserok in case there are custom principal mappings + defined. + * Handle ignore_root in a cleaner fashion and add support for + ignore_root on password changes. + * Depend on krb5-config. (Closes: #342271) + * Document that ccache and ccache_dir must be specified as options to + the session module. (Closes: #341926) + * Document that pam_sm_authenticate and pam_sm_setcred also call + krb5_kuserok. + * Properly override the upstream CFLAGS so that debugging builds work. + * Don't ignore errors from make clean. + * Providing binary-indep in debian/rules is required by Policy even if + there are no arch-independent packages. Whoops. + + -- Russ Allbery Mon, 16 Jan 2006 18:11:57 -0800 + +libpam-krb5 (1.2.0-1) unstable; urgency=low + + * New upstream maintainer and version. + - Now supports reinitialization of credentials properly, allowing + programs such as xlock to refresh credentials. (Closes: #309345) + This currently only works with versions of xlock that try to refresh + credentials (xlockmore does not). + - Do not include the principal name in the prompt. This breaks some + SSH clients and isn't necessary. (Closes: #321319) + - New ignore_root option to skip this module for root authentication, + ameliorating pam_krb5 problems when the network is down. Partially + addresses #315622. + * Bug fixes to upstream version (all sent back to the maintainer): + - Succeed silently in account management if Kerberos wasn't used. + - Parse ccache_dir correctly. + - Bring the man page up to date. + - Link with -z defs to ensure all symbols were found. + * Readd the ccache option with a better implementation and allow for + randomization of the filename using mkstemp even if ccache is used. + * Add search_k5login option to allow authentication based on the + principals listed in ~/.k5login when the local account name doesn't + easily map to the Kerberos principal. + * Add specific configuration recommendations to README.Debian. + * Install upstream changelog now that there is one. + * Add a watch file. + * Update standards version to 3.6.2 (no changes required). + * Remove maintainer from uploaders; dak can handle this properly. + * Update uploader address. + * Remove unnecessary code from debian/rules. + + -- Russ Allbery Fri, 18 Nov 2005 14:48:57 -0800 + +libpam-krb5 (1.0-12) unstable; urgency=low + + * Revert the PAM_REINITIALIZE_CREDS change as it breaks sshd with + UsePAM. Add a source comment explaining the confusion about the + meaning of this flag. + + -- Russ Allbery Wed, 13 Apr 2005 16:01:45 -0700 + +libpam-krb5 (1.0-11) unstable; urgency=low + + * Return PAM_CRED_UNAVAIL to PAM_REINITIALIZE_CREDS as the apparently + most appropriate error message. (Closes: #191001) + * Remove reference to non-existant man page pam.conf(8) and change + pam(8) to pam(7). Thanks, Nik A. Melchior. (Closes: #271066) + * Include the user UID in the default ticket cache name so that rpc.gssd + and similar programs can find the ticket cache. Document the random + string in the default ticket cache name in the man page. Thanks, + Steinar H. Gunderson. (Closes: #295027) + * Really remove stray ex.doc-base.package file. + + -- Russ Allbery Wed, 13 Apr 2005 13:54:47 -0700 + +libpam-krb5 (1.0-10) unstable; urgency=low + + * Free authentication context used to prevent KDC spoofing, fixing a + file descriptor leak. Thanks, Martin Kögler. (Closes: #194542) + * Fix use_first_pass and try_first_pass for password changes and report + password change errors via the PAM conversation. Thanks, Martin Mares. + (Closes: #133461) + * Return PAM_USER_UNKNOWN and PAM_AUTHINFO_UNAVAIL where appropriate + when authenticating. Thanks, Roland Bauerschmidt. (Closes: #239399) + * Add missing includes to eliminate warnings. + * Update standards version to 3.6.1. + - Build with -g -O2 by default and support requesting no optimization. + * Simplified the build system. The copy of source files into a + subdirectory isn't needed since we don't apply patches at build time, + so the package can be built normally with a regular make invocation. + * Be sure not to pass -I/usr/include to the compiler. + * Updated the build system to debhelper 4. + - Removed unneeded call to dh_suidregister. + - Use dh_installman rather than dh_installmanpages. + * Flesh out the package description. + * Removed stray ex.doc-base.package file. + * Refer to /usr/share/common-licenses in debian/copyright for the GPL + and remove dh_make boilerplate language. + + -- Russ Allbery Mon, 6 Sep 2004 16:39:13 -0400 + +libpam-krb5 (1.0-9) unstable; urgency=high + + * Upload with no code changes in order to pick up symbol versions, + Closes: #260372 + * High urgency because we want this to make it into sarge. + * Don't build-depend on libdb2-dev, Closes: #248517 + + -- Sam Hartman Wed, 18 Aug 2004 13:47:38 -0400 + +libpam-krb5 (1.0-8) unstable; urgency=low + + * Don't require user to exist in NSS, Closes: #141288 + * Conflict with libpam-heimdal, Closes: #146279 + * Fix pam_silent handling thanks to nocturne@permabit.com, Closes: #114475 + + -- Sam Hartman Sun, 4 Aug 2002 17:57:28 -0400 + +libpam-krb5 (1.0-7) unstable; urgency=low + + * Move fron non-us to main--second to last package of mine + + -- Sam Hartman Sat, 6 Apr 2002 20:55:14 -0500 + +libpam-krb5 (1.0-6) unstable; urgency=low + + * New version that supports sessions management. You may want to use + this to write out credentials at session managemment time, for example + so they can be used by openafs. + + -- Sam Hartman Sat, 12 May 2001 18:41:49 -0400 + +libpam-krb5 (1.0-5) unstable; urgency=low + + * Fix build-depends, closes: #80555 + + -- Sam Hartman Wed, 27 Dec 2000 17:02:18 -0500 + +libpam-krb5 (1.0-4) unstable; urgency=medium + + * Wildcard enctype matching so that you don't have to have a des-cbc-md5 + key. Previously, if you did not have a des-cbc-md5 key, it looks like + the code might not verify the ticket against the key, treating it as + if you had no local key and blindly trusted the KDC. In practice this + is not an issue with most Kerberos setups. + * Test against pam service keys like imap rather than just the host + service key. We still prefer host to service keys. + + -- Sam Hartman Tue, 19 Dec 2000 17:49:12 -0500 + +libpam-krb5 (1.0-3) unstable; urgency=low + + * Add code to destroy ccache on logout. + * Upload to Debian (Closes: BUG#79001) + + -- Sam Hartman Fri, 8 Dec 2000 13:46:06 -0500 + +libpam-krb5 (1.0-2) unstable; urgency=low + + * Release MIT Kerberos5 version of PAM module. + + -- Sam Hartman Thu, 30 Nov 2000 17:49:41 -0500 + +libpam-heimdal (1.0-1) unstable; urgency=low + + * Initial Release. + + -- Brian May Fri, 17 Nov 2000 10:32:40 +1100 + + --- libpam-krb5-1.2.0.orig/debian/copyright +++ libpam-krb5-1.2.0/debian/copyright @@ -0,0 +1,162 @@ +Original package by Brian May 2000-11-09 +Built for MIT Kerberos by Sam Hartman 2000-11-30 + +It was downloaded from: + + + +Upstream Authors: + + Andres Salomon + Frank Cusack + +Copyright: + + Copyright (c) 2005 Andres Salomon + Copyright (c) Frank Cusack, 1999-2000. + fcusack@fcusack.com + All rights reserved + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, and the entire permission notice in its entirety, + including the disclaimer of warranties. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + ALTERNATIVELY, this product may be distributed under the terms of the + GNU Public License, in which case the provisions of the GPL are + required INSTEAD OF the above restrictions. (This clause is necessary + due to a potential bad interaction between the GPL and the + restrictions contained in a BSD-style copyright.) + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +The GPL is available on Debian systems in /usr/share/common-licenses/GPL. +This software may contain code from Naomaru Itoi: + + PAM-kerberos5 module Copyright notice. + Naomaru Itoi , June 24, 1997. + + COPYRIGHT (c) 1997 + THE REGENTS OF THE UNIVERSITY OF MICHIGAN + ALL RIGHTS RESERVED + + PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS AND + REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS FOR ANY PURPOSE, + SO LONG AS THE NAME OF THE UNIVERSITY OF MICHIGAN IS NOT USED IN ANY + ADVERTISING OR PUBLICITY PERTAINING TO THE USE OR DISTRIBUTION OF THIS + SOFTWARE WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE ABOVE + COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE UNIVERSITY OF + MICHIGAN IS INCLUDED IN ANY COPY OF ANY PORTION OF THIS SOFTWARE, THEN + THE DISCLAIMER BELOW MUST ALSO BE INCLUDED. + + THE SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE + UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT + WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR + IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + MERCHANTABITILY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF + THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, + INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, + WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION WITH THE USE + OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + + PAM-kerberos5 module is written based on PAM-kerberos4 module by + Derrick J. Brashear and kerberos5-1.0pl1 by M.I.T. kerberos team. + Permission to use, copy, modify, distribute this software is hereby + granted, as long as it is granted by Derrick J. Brashear and + M.I.T. kerberos team. Followings are their copyright information. + +This software may contain code from Derrick J. Brashear: + + Copyright (c) Derrick J. Brashear, 1996. All rights reserved + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, and the entire permission notice in its entirety, + including the disclaimer of warranties. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + ALTERNATIVELY, this product may be distributed under the terms of the + GNU Public License, in which case the provisions of the GPL are + required INSTEAD OF the above restrictions. (This clause is necessary + due to a potential bad interaction between the GPL and the + restrictions contained in a BSD-style copyright.) + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +This software may contain code from MIT Kerberos 5: + + Copyright Notice and Legal Administrivia + ---------------------------------------- + + Copyright (C) 1996 by the Massachusetts Institute of Technology. + + All rights reserved. + + Export of this software from the United States of America may require + a specific license from the United States Government. It is the + responsibility of any person or organization contemplating export to + obtain such a license before exporting. + + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of M.I.T. not be used in advertising or publicity pertaining + to distribution of the software without specific, written prior + permission. M.I.T. makes no representations about the suitability of + this software for any purpose. It is provided "as is" without express + or implied warranty. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + Individual source code files are copyright MIT, Cygnus Support, + OpenVision, Oracle, Sun Soft, and others. + + Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + and Zephyr are trademarks of the Massachusetts Institute of Technology + (MIT). No commercial use of these trademarks may be made without + prior written permission of MIT. + + "Commercial use" means use of a name in a product or other for-profit + manner. It does NOT prevent a commercial firm from referring to the + MIT trademarks in order to convey information (although in doing so, + recognition of their trademark status should be given). --- libpam-krb5-1.2.0.orig/debian/docs +++ libpam-krb5-1.2.0/debian/docs @@ -0,0 +1,3 @@ +README +README.patched +TODO --- libpam-krb5-1.2.0.orig/debian/rules +++ libpam-krb5-1.2.0/debian/rules @@ -0,0 +1,54 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS = -Wall -g -fPIC +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +build: build-stamp +build-stamp: + dh_testdir + $(MAKE) CFLAGS="$(CFLAGS)" + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + $(MAKE) clean + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean + dh_installdirs + install -m 644 pam_krb5.so $(CURDIR)/debian/libpam-krb5/lib/security + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs ChangeLog + dh_installdocs + dh_installman pam_krb5.5 + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary-indep: +binary: binary-arch binary-indep +.PHONY: build clean binary-arch binary-indep binary install --- libpam-krb5-1.2.0.orig/debian/README.Debian +++ libpam-krb5-1.2.0/debian/README.Debian @@ -0,0 +1,56 @@ +libpam-krb5 for Debian +---------------------- + +After installing this package, you must modify your PAM configuration +before you will be able to use Kerberos to authenticate. For a system +where user account authentication should be handled primarily through +Kerberos and password changes should be made against Kerberos, with +fallback to local authentication, the following basic configuration should +work. In /etc/pam.d/common-auth, put: + + auth sufficient pam_krb5.so ignore_root + auth required pam_unix.so try_first_pass nullok_secure + +In /etc/pam.d/common-session: + + session optional pam_krb5.so ignore_root + session required pam_unix.so + +In /etc/pam.d/common-account: + + account required pam_krb5.so ignore_root + account required pam_unix.so + +(Note that the account function of pam_krb5.so will always succeed if the +user didn't log in via Kerberos, so this is will still allow access via a +local password. It will ensure that, if the user did log in via Kerberos, +their Kerberos authentication is checked against ~/.k5login if present.) + +Finally, in /etc/pam.d/common-password: + + password sufficient pam_krb5.so ignore_root + password required pam_unix.so nullok obscure min=4 max=8 md5 + +Note the ignore_root on all of these lines. This is optional, but +normally sites do not create a single root@example.com Kerberos principal +and use it for authentication to root accounts. In addition, trying to do +Kerberos authentication when the network is down may cause delays or +timeouts, and this way such authentication is never attempted for a root +login. + +If you regularly use ticket forwarding (such as with Kerberos rlogin or +ssh with GSSAPI support), you may wish to add the "forwardable" option to +the pam_krb5.so line in /etc/pam.d/common-auth. + +This configuration assumes that one can generate a person's Kerberos +credential by appending the default realm to the local username. If this +is not the case for your system, make sure that every account for which +this is not the case has a .k5login file in their home directory listing +the Kerberos principals that should have access (or which is empty if none +should). Otherwise, someone will be able to access that account if they +know the password of the Kerberos principal in the default realm with the +same name. In this situation, you will probably also want to add the +"search_k5login" option to the pam_krb5.so line in /etc/pam.d/common-auth; +see the pam_krb5(5) man page for more information. + + -- Russ Allbery , Fri Nov 18 13:18:48 2005 --- libpam-krb5-1.2.0.orig/debian/watch +++ libpam-krb5-1.2.0/debian/watch @@ -0,0 +1,4 @@ +# watch -- Rules for uscan to find new upstream versions. + +version=3 +http://www.squishy.cc/software/pam-krb5/pam-krb5-(.*)\.tar\.gz --- libpam-krb5-1.2.0.orig/debian/NEWS.Debian +++ libpam-krb5-1.2.0/debian/NEWS.Debian @@ -0,0 +1,10 @@ +libpam-krb5 (1.2.0-2) unstable; urgency=low + + The user's credential cache is now created by the session stage of the + PAM module rather than the authentication stage. This means that if you + were setting the ccache option in the PAM configuration, be sure to set + that option in the configuration line for the session stage as well for + it to take effect. + + -- Russ Allbery Wed, 7 Dec 2005 17:48:50 -0800 +