Beispiel #1
0
void KRB5_CALLCONV
profile_release(profile_t profile)
{
	prf_file_t	p, next;

	if (!profile || profile->magic != PROF_MAGIC_PROFILE)
		return;

	for (p = profile->first_file; p; p = next) {
		next = p->next;
		profile_close_file(p);
	}
	profile->magic = 0;
	free(profile);
}
Beispiel #2
0
void KRB5_CALLCONV
profile_release(profile_t profile)
{
    prf_file_t      p, next;

    if (!profile || profile->magic != PROF_MAGIC_PROFILE)
        return;

    if (profile->vt) {
        /* Flush the profile and then delegate to profile_abandon. */
        if (profile->vt->flush)
            profile->vt->flush(profile->cbdata);
        profile_abandon(profile);
        return;
    } else {
        for (p = profile->first_file; p; p = next) {
            next = p->next;
            profile_close_file(p);
        }
    }
    profile->magic = 0;
    free(profile);
}
Beispiel #3
0
errcode_t profile_open_file(const_profile_filespec_t filespec,
			    prf_file_t *ret_prof)
{
	prf_file_t	prf;
	errcode_t	retval;
	char		*home_env = 0;
	prf_data_t	data;
	char		*expanded_filename;

	retval = CALL_INIT_FUNCTION(profile_library_initializer);
	if (retval)
		return retval;

	scan_shared_trees_unlocked();

	prf = malloc(sizeof(struct _prf_file_t));
	if (!prf)
		return ENOMEM;
	memset(prf, 0, sizeof(struct _prf_file_t));
	prf->magic = PROF_MAGIC_FILE;

	if (filespec[0] == '~' && filespec[1] == '/') {
		home_env = getenv("HOME");
#ifdef HAVE_PWD_H
		if (home_env == NULL) {
		    uid_t uid;
		    struct passwd *pw, pwx;
		    char pwbuf[BUFSIZ];

		    uid = getuid();
		    if (!k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw)
			&& pw != NULL && pw->pw_dir[0] != 0)
			home_env = pw->pw_dir;
		}
#endif
	}
	if (home_env) {
	    if (asprintf(&expanded_filename, "%s%s", home_env,
			 filespec + 1) < 0)
		expanded_filename = 0;
	} else
	    expanded_filename = strdup(filespec);
	if (expanded_filename == 0) {
	    free(prf);
	    return ENOMEM;
	}

	retval = k5_mutex_lock(&g_shared_trees_mutex);
	if (retval) {
	    free(expanded_filename);
	    free(prf);
	    scan_shared_trees_unlocked();
	    return retval;
	}
	scan_shared_trees_locked();
	for (data = g_shared_trees; data; data = data->next) {
	    if (!strcmp(data->filespec, expanded_filename)
		/* Check that current uid has read access.  */
		&& r_access(data->filespec))
		break;
	}
	if (data) {
	    data->refcount++;
	    (void) k5_mutex_unlock(&g_shared_trees_mutex);
	    retval = profile_update_file_data(data);
	    free(expanded_filename);
	    prf->data = data;
	    *ret_prof = prf;
	    scan_shared_trees_unlocked();
	    return retval;
	}
	(void) k5_mutex_unlock(&g_shared_trees_mutex);
	data = profile_make_prf_data(expanded_filename);
	if (data == NULL) {
	    free(prf);
	    free(expanded_filename);
	    return ENOMEM;
	}
	free(expanded_filename);
	prf->data = data;

	retval = k5_mutex_init(&data->lock);
	if (retval) {
	    free(data);
	    free(prf);
	    return retval;
	}

	retval = profile_update_file(prf);
	if (retval) {
		profile_close_file(prf);
		return retval;
	}

	retval = k5_mutex_lock(&g_shared_trees_mutex);
	if (retval) {
	    profile_close_file(prf);
	    scan_shared_trees_unlocked();
	    return retval;
	}
	scan_shared_trees_locked();
	data->flags |= PROFILE_FILE_SHARED;
	data->next = g_shared_trees;
	g_shared_trees = data;
	scan_shared_trees_locked();
	(void) k5_mutex_unlock(&g_shared_trees_mutex);

	*ret_prof = prf;
	return 0;
}