diff --git a/lib/krb5/acache.c b/lib/krb5/acache.c index 19eeecda4..13333bc7f 100644 --- a/lib/krb5/acache.c +++ b/lib/krb5/acache.c @@ -125,7 +125,7 @@ init_ccapi(krb5_context context) #ifdef KRB5_USE_PATH_TOKENS { char * explib = NULL; - if (_krb5_expand_path_tokens(context, lib, &explib) == 0) { + if (_krb5_expand_path_tokens(context, lib, NULL, &explib) == 0) { cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL); free(explib); } diff --git a/lib/krb5/aname_to_localname.c b/lib/krb5/aname_to_localname.c index e4af81084..5598dda71 100644 --- a/lib/krb5/aname_to_localname.c +++ b/lib/krb5/aname_to_localname.c @@ -330,7 +330,7 @@ an2ln_default(krb5_context context, if (ret) return ret; - userok = krb5_kuserok(context, rootprinc, res); + userok = _krb5_kuserok(context, rootprinc, res, FALSE); krb5_free_principal(context, rootprinc); if (!userok) return KRB5_NO_LOCALNAME; diff --git a/lib/krb5/cache.c b/lib/krb5/cache.c index 88040cbc6..69d076a16 100644 --- a/lib/krb5/cache.c +++ b/lib/krb5/cache.c @@ -189,7 +189,7 @@ allocate_ccache (krb5_context context, #ifdef KRB5_USE_PATH_TOKENS char * exp_residual = NULL; - ret = _krb5_expand_path_tokens(context, residual, &exp_residual); + ret = _krb5_expand_path_tokens(context, residual, NULL, &exp_residual); if (ret) return ret; @@ -410,7 +410,7 @@ krb5_cc_get_ops(krb5_context context, krb5_ccache id) krb5_error_code _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) { - return _krb5_expand_path_tokens(context, str, res); + return _krb5_expand_path_tokens(context, str, NULL, res); } /* @@ -559,7 +559,7 @@ krb5_cc_set_default_name(krb5_context context, const char *name) return ENOMEM; } - ret = _krb5_expand_path_tokens(context, p, &exp_p); + ret = _krb5_expand_path_tokens(context, p, NULL, &exp_p); free(p); if (ret) return ret; diff --git a/lib/krb5/config_file.c b/lib/krb5/config_file.c index 4ac25ae28..10f1600af 100644 --- a/lib/krb5/config_file.c +++ b/lib/krb5/config_file.c @@ -483,7 +483,7 @@ krb5_config_parse_file_multi (krb5_context context, #ifdef KRB5_USE_PATH_TOKENS char * exp_fname = NULL; - ret = _krb5_expand_path_tokens(context, fname, &exp_fname); + ret = _krb5_expand_path_tokens(context, fname, NULL, &exp_fname); if (ret) { if (newfname) free(newfname); diff --git a/lib/krb5/expand_path.c b/lib/krb5/expand_path.c index 4c4898a79..e7ffe289e 100644 --- a/lib/krb5/expand_path.c +++ b/lib/krb5/expand_path.c @@ -309,6 +309,22 @@ _expand_userid(krb5_context context, PTYPE param, const char *postfix, char **st #endif /* _WIN32 */ +/** + * Expand a %{luser} token + */ + +static int +_expand_luser(krb5_context context, const char *luser, char **ret) +{ + *ret = strdup(luser); + if (*ret == NULL) { + if (context) + krb5_set_error_message(context, ENOMEM, "Out of memory"); + return ENOMEM; + } + return 0; +} + /** * Expand a %{null} token * @@ -374,6 +390,7 @@ static int _expand_token(krb5_context context, const char *token, const char *token_end, + const char *luser, char **ret) { size_t i; @@ -387,6 +404,9 @@ _expand_token(krb5_context context, return EINVAL; } + if (strncmp(token+2, "luser", (token_end - token) - 2) == 0) + return _expand_luser(context, luser, ret); + for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) { if (!strncmp(token+2, tokens[i].tok, (token_end - token) - 2)) return tokens[i].exp_func(context, tokens[i].param, @@ -398,9 +418,23 @@ _expand_token(krb5_context context, return EINVAL; } +/** + * Internal function to expand tokens in paths. + * + * Inputs: + * + * @context A krb5_context + * @path_in The path to expand tokens from + * @luser A local username (optional, for krb5_kuserok()) + * + * Outputs: + * + * @ppath_out Path with expanded tokens (caller must free() this) + */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL _krb5_expand_path_tokens(krb5_context context, const char *path_in, + const char *luser, char **ppath_out) { char *tok_begin, *tok_end, *append; @@ -439,7 +473,7 @@ _krb5_expand_path_tokens(krb5_context context, return EINVAL; } - if (_expand_token(context, tok_begin, tok_end, &append)) { + if (_expand_token(context, tok_begin, tok_end, luser, &append)) { if (*ppath_out) free(*ppath_out); *ppath_out = NULL; diff --git a/lib/krb5/fcache.c b/lib/krb5/fcache.c index 731f29341..acc5956cc 100644 --- a/lib/krb5/fcache.c +++ b/lib/krb5/fcache.c @@ -328,7 +328,7 @@ fcc_gen_new(krb5_context context, krb5_ccache *id) N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } - ret = _krb5_expand_path_tokens(context, file, &exp_file); + ret = _krb5_expand_path_tokens(context, file, NULL, &exp_file); free(file); if (ret) return ret; diff --git a/lib/krb5/kuserok.c b/lib/krb5/kuserok.c index b21ab9b3a..fad554417 100644 --- a/lib/krb5/kuserok.c +++ b/lib/krb5/kuserok.c @@ -32,9 +32,141 @@ */ #include "krb5_locl.h" +#include "kuserok_plugin.h" #include -#ifndef _WIN32 +#ifndef SYSTEM_K5LOGIN_DIR +/* + * System k5login location. File namess in this directory are expected + * to be usernames and to contain a list of principals allowed to login + * as the user named the same as the file. + */ +#define SYSTEM_K5LOGIN_DIR SYSCONFDIR "/k5login.d" +#endif + +/* Plugin framework bits */ + +struct plctx { + const char *rule; + const char *k5login_dir; + const char *luser; + krb5_const_principal principal; + unsigned int flags; + krb5_boolean result; +}; + +static krb5_error_code +plcallback(krb5_context context, const void *plug, void *plugctx, void *userctx) +{ + const krb5plugin_kuserok_ftable *locate = plug; + struct plctx *plctx = userctx; + + return locate->kuserok(plugctx, context, plctx->rule, plctx->flags, + plctx->k5login_dir, plctx->luser, plctx->principal, + &plctx->result); +} + +static krb5_error_code plugin_reg_ret; +static krb5plugin_kuserok_ftable kuserok_simple_plug; +static krb5plugin_kuserok_ftable kuserok_sys_k5login_plug; +static krb5plugin_kuserok_ftable kuserok_user_k5login_plug; + +static void +reg_def_plugins_once(void *ctx) +{ + krb5_error_code ret; + krb5_context context = ctx; + + plugin_reg_ret = krb5_plugin_register(context, PLUGIN_TYPE_DATA, + KRB5_PLUGIN_KUSEROK, + &kuserok_simple_plug); + ret = krb5_plugin_register(context, PLUGIN_TYPE_DATA, + KRB5_PLUGIN_KUSEROK, &kuserok_sys_k5login_plug); + if (!plugin_reg_ret) + plugin_reg_ret = ret; + ret = krb5_plugin_register(context, PLUGIN_TYPE_DATA, + KRB5_PLUGIN_KUSEROK, &kuserok_user_k5login_plug); + if (!plugin_reg_ret) + plugin_reg_ret = ret; +} + +/** + * This function is designed to be portable for Win32 and POSIX. The + * design does lead to multiple getpwnam_r() calls, but this is probably + * not a big deal. + * + * Inputs: + * + * @context A krb5_context + * @is_system_location TRUE if the dir/file are system locations or + * FALSE if they are user home directory locations + * @dir Directory (optional) + * @dirlstat A pointer to struct stat for the directory (optional) + * @file File (optional) + * @owner Name of user that is expected to own the file + */ +static krb5_error_code +check_owner(krb5_context context, krb5_boolean is_system_location, + DIR *dir, struct stat *dirlstat, FILE *file, const char *owner) +{ +#ifdef _WIN32 + /* + * XXX Implement this! + * + * The thing to do is to call _get_osfhandle() on fileno(file) and + * dirfd(dir) to get HANDLEs to the same, then call + * GetSecurityInfo() on those HANDLEs to get the security descriptor + * (SD), then check the owner and DACL. Checking the DACL sounds + * like a lot of work (what, derive a mode from the ACL the way + * NFSv4 servers do?). Checking the owner means doing an LSARPC + * lookup at least (to get the user's SID). + */ + if (is_system_location || owner == NULL) + return 0; + return EACCES; +#else + struct stat st; + struct passwd *pwd = NULL; +#ifdef POSIX_GETPWNAM_R + char pwbuf[2048]; + struct passwd pw; +#endif +#endif + +#ifdef POSIX_GETPWNAM_R + if (owner != NULL && getpwnam_r(owner, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) + return EACCES; +#else + pwd = getpwnam(luser); + if (owner != NULL && pwd == NULL) + return EACCES; +#endif + if (dir) { + if (fstat(dirfd(dir), &st) == -1) + return errno; + if (!S_ISDIR(st.st_mode)) + return ENOTDIR; + if (st.st_dev != dirlstat->st_dev || st.st_ino != dirlstat->st_ino) + return EACCES; + if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) + return EACCES; /* XXX We should have a better code */ + if (pwd != NULL && pwd->pw_uid != st.st_uid && st.st_uid != 0) + return EACCES; + if (file == NULL) + return 0; + } + if (file) { + if (fstat(fileno(file), &st) == -1) + return errno; + if (S_ISDIR(st.st_mode)) + return EISDIR; + if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) + return EACCES; /* XXX We should have a better code */ + if (pwd == NULL || pwd->pw_uid == st.st_uid || st.st_uid == 0) + return 0; + } + return EACCES; +} /* see if principal is mentioned in the filename access file, return TRUE (in result) if so, FALSE otherwise */ @@ -42,74 +174,63 @@ static krb5_error_code check_one_file(krb5_context context, const char *filename, - struct passwd *pwd, - krb5_principal principal, + const char *owner, + krb5_boolean is_system_location, + krb5_const_principal principal, krb5_boolean *result) { FILE *f; char buf[BUFSIZ]; krb5_error_code ret; - struct stat st; *result = FALSE; - f = fopen (filename, "r"); + f = fopen(filename, "r"); if (f == NULL) return errno; rk_cloexec_file(f); - /* check type and mode of file */ - if (fstat(fileno(f), &st) != 0) { - fclose (f); - return errno; - } - if (S_ISDIR(st.st_mode)) { - fclose (f); - return EISDIR; - } - if (st.st_uid != pwd->pw_uid && st.st_uid != 0) { - fclose (f); - return EACCES; - } - if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) { - fclose (f); - return EACCES; - } + ret = check_owner(context, 0, NULL, NULL, f, owner); + if (ret) + goto out; - while (fgets (buf, sizeof(buf), f) != NULL) { + while (fgets(buf, sizeof(buf), f) != NULL) { krb5_principal tmp; char *newline = buf + strcspn(buf, "\n"); - if(*newline != '\n') { + if (*newline != '\n') { int c; c = fgetc(f); - if(c != EOF) { - while(c != EOF && c != '\n') + if (c != EOF) { + while (c != EOF && c != '\n') c = fgetc(f); /* line was too long, so ignore it */ continue; } } *newline = '\0'; - ret = krb5_parse_name (context, buf, &tmp); + ret = krb5_parse_name(context, buf, &tmp); if (ret) continue; - *result = krb5_principal_compare (context, principal, tmp); - krb5_free_principal (context, tmp); + *result = krb5_principal_compare(context, principal, tmp); + krb5_free_principal(context, tmp); if (*result) { fclose (f); return 0; } } - fclose (f); + +out: + fclose(f); return 0; } static krb5_error_code check_directory(krb5_context context, const char *dirname, - struct passwd *pwd, - krb5_principal principal, + const char *owner, + krb5_boolean is_system_location, + krb5_const_principal principal, krb5_boolean *result) { DIR *d; @@ -120,82 +241,71 @@ check_directory(krb5_context context, *result = FALSE; - if(lstat(dirname, &st) < 0) + if (lstat(dirname, &st) < 0) return errno; if (!S_ISDIR(st.st_mode)) return ENOTDIR; - if (st.st_uid != pwd->pw_uid && st.st_uid != 0) - return EACCES; - if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) - return EACCES; - - if((d = opendir(dirname)) == NULL) + if ((d = opendir(dirname)) == NULL) return errno; - { - int fd; - struct stat st2; + ret = check_owner(context, is_system_location, d, &st, NULL, owner); + if (ret) + goto out; - fd = dirfd(d); - if(fstat(fd, &st2) < 0) { - closedir(d); - return errno; - } - if(st.st_dev != st2.st_dev || st.st_ino != st2.st_ino) { - closedir(d); - return EACCES; - } - } - - while((dent = readdir(d)) != NULL) { - if(strcmp(dent->d_name, ".") == 0 || + while ((dent = readdir(d)) != NULL) { + if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0 || dent->d_name[0] == '#' || /* emacs autosave */ dent->d_name[strlen(dent->d_name) - 1] == '~') /* emacs backup */ continue; snprintf(filename, sizeof(filename), "%s/%s", dirname, dent->d_name); - ret = check_one_file(context, filename, pwd, principal, result); - if(ret == 0 && *result == TRUE) + ret = check_one_file(context, filename, owner, is_system_location, + principal, result); + if (ret == 0 && *result == TRUE) break; ret = 0; /* don't propagate errors upstream */ } + +out: closedir(d); return ret; } -#endif /* !_WIN32 */ - -static krb5_boolean -match_local_principals(krb5_context context, - krb5_principal principal, - const char *luser) +static krb5_error_code +check_an2ln(krb5_context context, + krb5_const_principal principal, + const char *luser, + krb5_boolean *result) { krb5_error_code ret; - krb5_realm *realms, *r; - krb5_boolean result = FALSE; + char *lname; +#if 0 + /* XXX Should we make this an option? */ /* multi-component principals can never match */ - if(krb5_principal_get_comp_string(context, principal, 1) != NULL) - return FALSE; - - ret = krb5_get_default_realms (context, &realms); - if (ret) - return FALSE; - - for (r = realms; *r != NULL; ++r) { - if(strcmp(krb5_principal_get_realm(context, principal), - *r) != 0) - continue; - if(strcmp(krb5_principal_get_comp_string(context, principal, 0), - luser) == 0) { - result = TRUE; - break; - } + if (krb5_principal_get_comp_string(context, principal, 1) != NULL) { + *result = FALSE; + return 0; } - krb5_free_host_realm (context, realms); - return result; +#endif + + lname = malloc(strlen(luser) + 1); + if (lname == NULL) + return ENOMEM; + ret = krb5_aname_to_localname(context, principal, strlen(luser)+1, lname); + if (ret) + goto out; + if (strcmp(lname, luser) == 0) + *result = TRUE; + else + *result = FALSE; + +out: + free(lname); + return 0; + } /** @@ -234,70 +344,248 @@ match_local_principals(krb5_context context, */ KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL -krb5_kuserok (krb5_context context, - krb5_principal principal, - const char *luser) +krb5_kuserok(krb5_context context, + krb5_principal principal, + const char *luser) { -#ifndef _WIN32 - char *buf; - size_t buflen; - struct passwd *pwd = NULL; - char *profile_dir = NULL; + return _krb5_kuserok(context, principal, luser, TRUE); +} + + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +_krb5_kuserok(krb5_context context, + krb5_principal principal, + const char *luser, + krb5_boolean an2ln_ok) +{ + static heim_base_once_t reg_def_plugins = HEIM_BASE_ONCE_INIT; krb5_error_code ret; - krb5_boolean result = FALSE; + size_t i; + char **rules; + struct plctx ctx; - krb5_boolean found_file = FALSE; + /* + * XXX we should have a struct with a krb5_context field and a + * krb5_error_code fied and pass the address of that as the ctx + * argument of heim_base_once_f(). For now we use a static to + * communicate failures. Actually, we ignore failures anyways, + * since we can't return them. + */ + heim_base_once_f(®_def_plugins, context, reg_def_plugins_once); -#ifdef POSIX_GETPWNAM_R - char pwbuf[2048]; - struct passwd pw; + ctx.flags = 0; + ctx.luser = luser; + ctx.principal = principal; + ctx.result = FALSE; - if(getpwnam_r(luser, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) - return FALSE; -#else - pwd = getpwnam (luser); -#endif - if (pwd == NULL) - return FALSE; - profile_dir = pwd->pw_dir; + ctx.k5login_dir = krb5_config_get_string(context, NULL, "libdefaults", + "k5login_directory", NULL); -#define KLOGIN "/.k5login" - buflen = strlen(profile_dir) + sizeof(KLOGIN) + 2; /* 2 for .d */ - buf = malloc(buflen); - if(buf == NULL) - return FALSE; - /* check user's ~/.k5login */ - strlcpy(buf, profile_dir, buflen); - strlcat(buf, KLOGIN, buflen); - ret = check_one_file(context, buf, pwd, principal, &result); + if (an2ln_ok) + ctx.flags |= KUSEROK_ANAME_TO_LNAME_OK; + if (krb5_config_get_bool_default(context, NULL, FALSE, "libdefaults", + "k5login_authoritative", NULL)) + ctx.flags |= KUSEROK_K5LOGIN_IS_AUTHORITATIVE; - if(ret == 0 && result == TRUE) { - free(buf); - return TRUE; + if ((ctx.flags & KUSEROK_K5LOGIN_IS_AUTHORITATIVE) && plugin_reg_ret) + return plugin_reg_ret; /* fail safe */ + + rules = krb5_config_get_strings(context, NULL, "libdefaults", + "kuserok", NULL); + if (rules == NULL) { + /* Default: check ~/.k5login */ + ctx.rule = "USER-K5LOGIN"; + ret = plcallback(context, &kuserok_user_k5login_plug, NULL, &ctx); + if (ret == 0) + goto out; + ctx.rule = "SIMPLE"; + ret = plcallback(context, &kuserok_simple_plug, NULL, &ctx); + if (ret == 0) + goto out; + ctx.result = FALSE; + goto out; } - if(ret != ENOENT) - found_file = TRUE; + for (i = 0; rules[i]; i++) { + ctx.rule = rules[i]; + ret = _krb5_plugin_run_f(context, "krb5", KRB5_PLUGIN_KUSEROK, + KRB5_PLUGIN_KUSEROK_VERSION_0, 0, + &ctx, plcallback); + if (ret != KRB5_PLUGIN_NO_HANDLE) + goto out; + } - strlcat(buf, ".d", buflen); - ret = check_directory(context, buf, pwd, principal, &result); - free(buf); - if(ret == 0 && result == TRUE) - return TRUE; +out: + krb5_config_free_strings(rules); + return ctx.result; +} - if(ret != ENOENT && ret != ENOTDIR) - found_file = TRUE; +/* + * Simple kuserok: check that the lname for the aname matches luser. + */ - /* finally if no files exist, allow all principals matching - @ */ - if(found_file == FALSE) - return match_local_principals(context, principal, luser); +static krb5_error_code +kuserok_simple_plug_f(void *plug_ctx, krb5_context context, const char *rule, + unsigned int flags, const char *k5login_dir, + const char *luser, krb5_const_principal principal, + krb5_boolean *result) +{ + krb5_error_code ret; + if (strcmp(rule, "SIMPLE") != 0 || (flags & KUSEROK_ANAME_TO_LNAME_OK) == 0) + return KRB5_PLUGIN_NO_HANDLE; + ret = check_an2ln(context, principal, luser, result); + if (ret == 0 && *result == FALSE) + return KRB5_PLUGIN_NO_HANDLE; + return 0; +} - return FALSE; +/* + * Check k5login files in a system location, rather than in home + * directories. + */ + +static krb5_error_code +kuserok_sys_k5login_plug_f(void *plug_ctx, krb5_context context, + const char *rule, unsigned int flags, + const char *k5login_dir, const char *luser, + krb5_const_principal principal, krb5_boolean *result) +{ + char *path = NULL; + const char *profile_dir = NULL; + krb5_error_code ret; + + *result = FALSE; + if (strcmp(rule, "SYSTEM-K5LOGIN") != 0 && + strncmp(rule, "SYSTEM-K5LOGIN:", strlen("SYSTEM-K5LOGIN:")) != 0) + return KRB5_PLUGIN_NO_HANDLE; + + profile_dir = strchr(rule, ':'); + if (profile_dir == NULL) + profile_dir = k5login_dir ? k5login_dir : SYSTEM_K5LOGIN_DIR; + else + profile_dir++; + + ret = _krb5_expand_path_tokens(context, profile_dir, luser, &path); + if (ret) + return ret; + + ret = check_one_file(context, path, NULL, TRUE, principal, result); + free(path); + + if (ret == 0 && + ((flags & KUSEROK_K5LOGIN_IS_AUTHORITATIVE) || *result == TRUE)) + return 0; + + *result = FALSE; + return KRB5_PLUGIN_NO_HANDLE; +} + +/* + * Check ~luser/.k5login and/or ~/luser/.k5login.d + */ + +static krb5_error_code +kuserok_user_k5login_plug_f(void *plug_ctx, krb5_context context, + const char *rule, unsigned int flags, + const char *k5login_dir, const char *luser, + krb5_const_principal principal, + krb5_boolean *result) +{ +#ifdef _WIN32 + return KRB5_PLUGIN_NO_HANDLE; #else - /* The .k5login file may be on a remote profile and we don't have - access to the profile until we have a token handle for the - user's credentials. */ - return match_local_principals(context, principal, luser); + char *path; + const char *profile_dir = NULL; + krb5_error_code ret; + krb5_boolean found_file = FALSE; + struct passwd *pwd = NULL; +#ifdef POSIX_GETPWNAM_R + struct passwd pw; + char pwbuf[2048]; +#endif + + if (strcmp(rule, "USER-K5LOGIN") != 0) + return KRB5_PLUGIN_NO_HANDLE; + + profile_dir = k5login_dir; + if (profile_dir == NULL) { +#ifdef POSIX_GETPWNAM_R + if (getpwnam_r(luser, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) + return KRB5_PLUGIN_NO_HANDLE; +#else + pwd = getpwnam (luser); +#endif + if (pwd == NULL) + return KRB5_PLUGIN_NO_HANDLE; + profile_dir = pwd->pw_dir; + } + +#define KLOGIN "/.k5login" + + if (asprintf(&path, "%s/.k5login.d", profile_dir) == -1) + return ENOMEM; + /* check user's ~/.k5login */ + path[strlen(path) - strlen(".d")] = '\0'; + ret = check_one_file(context, path, luser, FALSE, principal, result); + + if (ret == 0 && + ((flags & KUSEROK_K5LOGIN_IS_AUTHORITATIVE) || *result == TRUE)) { + free(path); + return 0; + } + + if (ret != ENOENT) + found_file = TRUE; + + path[strlen(path)] = '.'; /* put back the .d; clever|hackish? you decide */ + ret = check_directory(context, path, luser, FALSE, principal, result); + free(path); + if (ret == 0 && + ((flags & KUSEROK_K5LOGIN_IS_AUTHORITATIVE) || *result == TRUE)) + return 0; + + if (ret != ENOENT && ret != ENOTDIR) + found_file = TRUE; + + *result = FALSE; + if (found_file == FALSE) + return KRB5_PLUGIN_NO_HANDLE; + + return 0; #endif } + +static krb5_error_code +kuser_ok_null_plugin_init(krb5_context context, void **ctx) +{ + *ctx = NULL; + return 0; +} + +static void +kuser_ok_null_plugin_fini(void *ctx) +{ + return; +} + +static krb5plugin_kuserok_ftable kuserok_simple_plug = { + KRB5_PLUGIN_KUSEROK_VERSION_0, + kuser_ok_null_plugin_init, + kuser_ok_null_plugin_fini, + kuserok_simple_plug_f, +}; + +static krb5plugin_kuserok_ftable kuserok_sys_k5login_plug = { + KRB5_PLUGIN_KUSEROK_VERSION_0, + kuser_ok_null_plugin_init, + kuser_ok_null_plugin_fini, + kuserok_sys_k5login_plug_f, +}; + +static krb5plugin_kuserok_ftable kuserok_user_k5login_plug = { + KRB5_PLUGIN_KUSEROK_VERSION_0, + kuser_ok_null_plugin_init, + kuser_ok_null_plugin_fini, + kuserok_user_k5login_plug_f, +}; + diff --git a/lib/krb5/kuserok_plugin.h b/lib/krb5/kuserok_plugin.h new file mode 100644 index 000000000..4ce50b859 --- /dev/null +++ b/lib/krb5/kuserok_plugin.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 + * COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + */ + +#ifndef HEIMDAL_KRB5_KUSEROK_PLUGIN_H +#define HEIMDAL_KRB5_KUSEROK_PLUGIN_H 1 + +#define KRB5_PLUGIN_KUSEROK "kuserok" +#define KRB5_PLUGIN_KUSEROK_VERSION_0 0 + +typedef krb5_error_code (*set_result_f)(void *, const char *); + +typedef struct krb5plugin_kuserok_ftable_desc { + int minor_version; + krb5_error_code (*init)(krb5_context, void **); + void (*fini)(void *); + krb5_error_code (*kuserok)(void *, krb5_context, const char *, + unsigned int, const char *, const char *, + krb5_const_principal, + krb5_boolean *); +} krb5plugin_kuserok_ftable; + +#define KUSEROK_ANAME_TO_LNAME_OK 1 +#define KUSEROK_K5LOGIN_IS_AUTHORITATIVE 2 + +#endif /* HEIMDAL_KRB5_KUSEROK_PLUGIN_H */ diff --git a/lib/krb5/pkinit.c b/lib/krb5/pkinit.c index 1103a1780..0617ec0d1 100644 --- a/lib/krb5/pkinit.c +++ b/lib/krb5/pkinit.c @@ -2220,7 +2220,7 @@ _krb5_parse_moduli(krb5_context context, const char *file, { char * exp_file; - if (_krb5_expand_path_tokens(context, file, &exp_file) == 0) { + if (_krb5_expand_path_tokens(context, file, NULL, &exp_file) == 0) { f = fopen(exp_file, "r"); krb5_xfree(exp_file); } else { diff --git a/lib/krb5/plugin.c b/lib/krb5/plugin.c index ec126f02b..5f9f6991b 100644 --- a/lib/krb5/plugin.c +++ b/lib/krb5/plugin.c @@ -241,7 +241,7 @@ load_plugins(krb5_context context) char * dir = *di; #ifdef KRB5_USE_PATH_TOKENS - if (_krb5_expand_path_tokens(context, *di, &dir)) + if (_krb5_expand_path_tokens(context, *di, NULL, &dir)) goto next_dir; #endif