static void plugin_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, enum locate_service_type type) { struct plctx ctx = { type, kd, 0 }; if (_krb5_homedir_access(context)) ctx.flags |= KRB5_PLF_ALLOW_HOMEDIR; _krb5_plugin_run_f(context, "krb5", KRB5_PLUGIN_LOCATE, KRB5_PLUGIN_LOCATE_VERSION_0, 0, &ctx, plcallback); }
krb5_error_code KRB5_LIB_FUNCTION krb5_config_parse_file_multi (krb5_context context, const char *fname, krb5_config_section **res) { const char *str; char *newfname = NULL; unsigned lineno = 0; krb5_error_code ret; struct fileptr f; /** * If the fname starts with "~/" parse configuration file in the * current users home directory. The behavior can be disabled and * enabled by calling krb5_set_home_dir_access(). */ if (_krb5_homedir_access(context) && fname[0] == '~' && fname[1] == '/') { const char *home = NULL; if(!issuid()) home = getenv("HOME"); if (home == NULL) { struct passwd *pw = getpwuid(getuid()); if(pw != NULL) home = pw->pw_dir; } if (home) { asprintf(&newfname, "%s%s", home, &fname[1]); if (newfname == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } fname = newfname; } } f.f = fopen(fname, "r"); f.s = NULL; if(f.f == NULL) { ret = errno; krb5_set_error_message (context, ret, "open %s: %s", fname, strerror(ret)); if (newfname) free(newfname); return ret; } ret = krb5_config_parse_debug (&f, res, &lineno, &str); fclose(f.f); if (ret) { krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str); if (newfname) free(newfname); return ret; } if (newfname) free(newfname); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_config_parse_file_multi (krb5_context context, const char *fname, krb5_config_section **res) { const char *str; char *newfname = NULL; unsigned lineno = 0; krb5_error_code ret; struct fileptr f; /** * If the fname starts with "~/" parse configuration file in the * current users home directory. The behavior can be disabled and * enabled by calling krb5_set_home_dir_access(). */ if (fname[0] == '~' && fname[1] == '/') { #ifndef KRB5_USE_PATH_TOKENS const char *home = NULL; if (!_krb5_homedir_access(context)) { krb5_set_error_message(context, EPERM, "Access to home directory not allowed"); return EPERM; } if(!issuid()) home = getenv("HOME"); if (home == NULL) { struct passwd *pw = getpwuid(getuid()); if(pw != NULL) home = pw->pw_dir; } if (home) { asprintf(&newfname, "%s%s", home, &fname[1]); if (newfname == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } fname = newfname; } #else /* KRB5_USE_PATH_TOKENS */ if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 || newfname == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } fname = newfname; #endif } if (is_plist_file(fname)) { #ifdef __APPLE__ ret = parse_plist_config(context, fname, res); if (ret) { krb5_set_error_message(context, ret, "Failed to parse plist %s", fname); if (newfname) free(newfname); return ret; } #else krb5_set_error_message(context, ENOENT, "no support for plist configuration files"); return ENOENT; #endif } else { #ifdef KRB5_USE_PATH_TOKENS char * exp_fname = NULL; ret = _krb5_expand_path_tokens(context, fname, &exp_fname); if (ret) { if (newfname) free(newfname); return ret; } if (newfname) free(newfname); fname = newfname = exp_fname; #endif f.f = fopen(fname, "r"); f.s = NULL; if(f.f == NULL) { ret = errno; krb5_set_error_message (context, ret, "open %s: %s", fname, strerror(ret)); if (newfname) free(newfname); return ret; } ret = krb5_config_parse_debug (&f, res, &lineno, &str); fclose(f.f); if (ret) { krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str); if (newfname) free(newfname); return ret; } } return 0; }
static krb5_error_code KRB5_LIB_CALL 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 char *path; char *path_exp; const char *profile_dir = NULL; krb5_error_code ret; krb5_boolean found_file = FALSE; struct passwd pw, *pwd = NULL; char pwbuf[2048]; if (strcmp(rule, "USER-K5LOGIN") != 0) return KRB5_PLUGIN_NO_HANDLE; profile_dir = k5login_dir; if (profile_dir == NULL) { /* Don't deadlock with gssd or anything of the sort */ if (!_krb5_homedir_access(context)) return KRB5_PLUGIN_NO_HANDLE; if (getpwnam_r(luser, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) { krb5_set_error_message(context, errno, "User unknown (getpwnam_r())"); return KRB5_PLUGIN_NO_HANDLE; } if (pwd == NULL) { krb5_set_error_message(context, errno, "User unknown (getpwnam())"); return KRB5_PLUGIN_NO_HANDLE; } profile_dir = pwd->pw_dir; } #define KLOGIN "/.k5login" if (asprintf(&path, "%s/.k5login.d", profile_dir) == -1) return krb5_enomem(context); ret = _krb5_expand_path_tokensv(context, path, 1, &path_exp, "luser", luser, NULL); free(path); if (ret) return ret; path = path_exp; /* check user's ~/.k5login */ path[strlen(path) - strlen(".d")] = '\0'; ret = check_one_file(context, path, luser, FALSE, principal, result); /* * A match in ~/.k5login is sufficient. A non-match, falls through to the * .k5login.d code below. */ if (ret == 0 && *result == TRUE) { free(path); return 0; } if (ret != ENOENT) found_file = TRUE; /* * A match in ~/.k5login.d/somefile is sufficient. A non-match, falls * through to the code below that handles negative results. * * XXX: put back the .d; clever|hackish? you decide */ path[strlen(path)] = '.'; ret = check_directory(context, path, luser, FALSE, principal, result); free(path); if (ret == 0 && *result == TRUE) return 0; if (ret != ENOENT && ret != ENOTDIR) found_file = TRUE; /* * When either ~/.k5login or ~/.k5login.d/ exists, but neither matches * and we're authoritative, we're done. Otherwise, give other plugins * a chance. */ *result = FALSE; if (found_file && (flags & KUSEROK_K5LOGIN_IS_AUTHORITATIVE)) return 0; return KRB5_PLUGIN_NO_HANDLE; #endif }