Exemple #1
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
load_plugins(krb5_context context)
{
    struct plugin *e;
    krb5_error_code ret;
    char **dirs = NULL, **di;
    struct dirent *entry;
    char *path;
    DIR *d = NULL;

    if (!plugins_needs_scan)
	return 0;
    plugins_needs_scan = 0;

#ifdef HAVE_DLOPEN

    dirs = krb5_config_get_strings(context, NULL, "libdefaults",
				   "plugin_dir", NULL);
    if (dirs == NULL)
	dirs = rk_UNCONST(sysplugin_dirs);

    for (di = dirs; *di != NULL; di++) {
        char * dir = *di;

#ifdef KRB5_USE_PATH_TOKENS
        if (_krb5_expand_path_tokens(context, *di, &dir))
            goto next_dir;
#endif

        trim_trailing_slash(dir);

        d = opendir(dir);

	if (d == NULL)
	    goto next_dir;

	rk_cloexec_dir(d);

	while ((entry = readdir(d)) != NULL) {
	    char *n = entry->d_name;

	    /* skip . and .. */
            if (!is_valid_plugin_filename(n))
		continue;

	    path = NULL;
	    ret = 0;
#ifdef __APPLE__
	    { /* support loading bundles on MacOS */
		size_t len = strlen(n);
		if (len > 7 && strcmp(&n[len - 7],  ".bundle") == 0)
		    ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", dir, n, (int)(len - 7), n);
	    }
#endif
	    if (ret < 0 || path == NULL)
		ret = asprintf(&path, "%s/%s", dir, n);

	    if (ret < 0 || path == NULL) {
		ret = ENOMEM;
		krb5_set_error_message(context, ret, "malloc: out of memory");
		return ret;
	    }

	    /* check if already tried */
	    for (e = registered; e != NULL; e = e->next)
		if (e->type == DSO && strcmp(e->u.dso.path, path) == 0)
		    break;
	    if (e) {
		free(path);
	    } else {
		loadlib(context, path); /* store or frees path */
	    }
	}
	closedir(d);

    next_dir:
        if (dir != *di)
            free(dir);
    }
    if (dirs != rk_UNCONST(sysplugin_dirs))
	krb5_config_free_strings(dirs);
#endif /* HAVE_DLOPEN */
    return 0;
}
Exemple #3
0
static krb5_error_code
init_ccapi(krb5_context context)
{
    const char *lib = NULL;

    HEIMDAL_MUTEX_lock(&acc_mutex);
    if (init_func) {
	HEIMDAL_MUTEX_unlock(&acc_mutex);
	if (context)
	    krb5_clear_error_message(context);
	return 0;
    }

    if (context)
	lib = krb5_config_get_string(context, NULL,
				     "libdefaults", "ccapi_library",
				     NULL);
    if (lib == NULL) {
#ifdef __APPLE__
	lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos";
#elif defined(KRB5_USE_PATH_TOKENS) && defined(_WIN32)
	lib = "%{LIBDIR}/libkrb5_cc.dll";
#else
	lib = "/usr/lib/libkrb5_cc.so";
#endif
    }

#ifdef HAVE_DLOPEN

#ifndef RTLD_LAZY
#define RTLD_LAZY 0
#endif
#ifndef RTLD_LOCAL
#define RTLD_LOCAL 0
#endif

#ifdef KRB5_USE_PATH_TOKENS
    {
      char * explib = NULL;
      if (_krb5_expand_path_tokens(context, lib, &explib) == 0) {
	cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL);
	free(explib);
      }
    }
#else
    cc_handle = dlopen(lib, RTLD_LAZY|RTLD_LOCAL);
#endif

    if (cc_handle == NULL) {
	HEIMDAL_MUTEX_unlock(&acc_mutex);
	if (context)
	    krb5_set_error_message(context, KRB5_CC_NOSUPP,
				   N_("Failed to load API cache module %s", "file"),
				   lib);
	return KRB5_CC_NOSUPP;
    }

    init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize");
    set_target_uid = (void (KRB5_CALLCONV *)(uid_t))
	dlsym(cc_handle, "krb5_ipc_client_set_target_uid");
    clear_target = (void (KRB5_CALLCONV *)(void))
	dlsym(cc_handle, "krb5_ipc_client_clear_target");
    HEIMDAL_MUTEX_unlock(&acc_mutex);
    if (init_func == NULL) {
	if (context)
	    krb5_set_error_message(context, KRB5_CC_NOSUPP,
				   N_("Failed to find cc_initialize"
				      "in %s: %s", "file, error"), lib, dlerror());
	dlclose(cc_handle);
	return KRB5_CC_NOSUPP;
    }

    return 0;
#else
    HEIMDAL_MUTEX_unlock(&acc_mutex);
    if (context)
	krb5_set_error_message(context, KRB5_CC_NOSUPP,
			       N_("no support for shared object", ""));
    return KRB5_CC_NOSUPP;
#endif
}