Beispiel #1
0
int
openpam_configure(pam_handle_t *pamh,
	const char *service)
{
	pam_facility_t fclt;
	int serrno;

	ENTERS(service);
	if (!valid_service_name(service)) {
		openpam_log(PAM_LOG_ERROR, "invalid service name");
		RETURNC(PAM_SYSTEM_ERR);
	}
	if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0) {
		if (errno != ENOENT)
			goto load_err;
	}
	for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
		if (pamh->chains[fclt] != NULL)
			continue;
		if (openpam_load_chain(pamh, PAM_OTHER, fclt) < 0)
			goto load_err;
	}
	RETURNC(PAM_SUCCESS);
load_err:
	serrno = errno;
	openpam_clear_chains(pamh->chains);
	errno = serrno;
	RETURNC(PAM_SYSTEM_ERR);
}
Beispiel #2
0
int
pam_set_data(pam_handle_t *pamh,
	const char *module_data_name,
	void *data,
	void (*cleanup)(pam_handle_t *pamh,
		void *data,
		int pam_end_status))
{
	pam_data_t *dp;

	ENTERS(module_data_name);
	if (pamh == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	for (dp = pamh->module_data; dp != NULL; dp = dp->next) {
		if (strcmp(dp->name, module_data_name) == 0) {
			if (dp->cleanup)
				(dp->cleanup)(pamh, dp->data, PAM_SUCCESS);
			dp->data = data;
			dp->cleanup = cleanup;
			RETURNC(PAM_SUCCESS);
		}
	}
	if ((dp = malloc(sizeof *dp)) == NULL)
		RETURNC(PAM_BUF_ERR);
	if ((dp->name = strdup(module_data_name)) == NULL) {
		FREE(dp);
		RETURNC(PAM_BUF_ERR);
	}
	dp->data = data;
	dp->cleanup = cleanup;
	dp->next = pamh->module_data;
	pamh->module_data = dp;
	RETURNC(PAM_SUCCESS);
}
Beispiel #3
0
/*
 * Locates the policy file for a given service and reads the given chains
 * from it.
 *
 * Returns the number of policy entries which were found for the specified
 * service and facility, or -1 if a system error occurred or a syntax
 * error was encountered.
 */
static int
openpam_load_chain(pam_handle_t *pamh,
	const char *service,
	pam_facility_t facility)
{
	const char *p, **path;
	char filename[PATH_MAX];
	size_t len;
	openpam_style_t style;
	int ret;

	ENTERS(facility < 0 ? "any" : pam_facility_name[facility]);

	/* either absolute or relative to cwd */
	if (strchr(service, '/') != NULL) {
		if ((p = strrchr(service, '.')) != NULL && strcmp(p, ".conf") == 0)
			style = pam_conf_style;
		else
			style = pam_d_style;
		ret = openpam_load_file(pamh, service, facility,
		    service, style);
		RETURNN(ret);
	}

	/* search standard locations */
	for (path = openpam_policy_path; *path != NULL; ++path) {
		/* construct filename */
		len = strlcpy(filename, *path, sizeof filename);
		if (filename[len - 1] == '/') {
			len = strlcat(filename, service, sizeof filename);
			if (len >= sizeof filename) {
				errno = ENAMETOOLONG;
				RETURNN(-1);
			}
			style = pam_d_style;
		} else {
			style = pam_conf_style;
		}
		ret = openpam_load_file(pamh, service, facility,
		    filename, style);
		/* success */
		if (ret > 0)
			RETURNN(ret);
		/* the file exists, but an error occurred */
		if (ret == -1 && errno != ENOENT)
			RETURNN(ret);
		/* in pam.d style, an empty file counts as a hit */
		if (ret == 0 && style == pam_d_style)
			RETURNN(ret);
	}

	/* no hit */
	errno = ENOENT;
	RETURNN(-1);
}
Beispiel #4
0
int
openpam_set_option(pam_handle_t *pamh,
	const char *option,
	const char *value)
{
	pam_chain_t *cur;
	char *opt, **optv;
	size_t len;
	int i;

	ENTERS(option);
	if (pamh == NULL || pamh->current == NULL || option == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	cur = pamh->current;
	for (len = 0; option[len] != '\0'; ++len)
		if (option[len] == '=')
			break;
	for (i = 0; i < cur->optc; ++i) {
		if (strncmp(cur->optv[i], option, len) == 0 &&
		    (cur->optv[i][len] == '\0' || cur->optv[i][len] == '='))
			break;
	}
	if (value == NULL) {
		/* remove */
		if (i == cur->optc)
			RETURNC(PAM_SUCCESS);
		for (free(cur->optv[i]); i < cur->optc; ++i)
			cur->optv[i] = cur->optv[i + 1];
		cur->optv[i] = NULL;
		RETURNC(PAM_SUCCESS);
	}
	if (asprintf(&opt, "%.*s=%s", (int)len, option, value) < 0)
		RETURNC(PAM_BUF_ERR);
	if (i == cur->optc) {
		/* add */
		optv = realloc(cur->optv,
		    sizeof(*optv) * ((size_t)cur->optc + 2));
		if (optv == NULL) {
			FREE(opt);
			RETURNC(PAM_BUF_ERR);
		}
		optv[i] = opt;
		optv[i + 1] = NULL;
		cur->optv = optv;
		++cur->optc;
	} else {
		/* replace */
		FREE(cur->optv[i]);
		cur->optv[i] = opt;
	}
	RETURNC(PAM_SUCCESS);
}
	TESTCASE() {
		MAX_WAIT_TIME(0);

		FUNCT(bounded_buf_get);
		FUNCT(bounded_buf_put);

		TVAR(P1);
		TVAR(C1);
		TVAR(C2);

		WAIT_FOR_THREAD(P1, ENTERS(bounded_buf_put), "Wait for a producer.");

		WAIT_FOR_DISTINCT_THREADS((C1, C2), ENTERS(bounded_buf_get), "Wait for 2 consumers.");

		RUN_THREAD_THROUGH(P1, RETURNS(bounded_buf_put), "Producer inserts an item.");

		RUN_THREAD_THROUGH(C1, HITS_MANUAL_PC(42), "First consumer runs first phase.");

		RUN_THREAD_THROUGH(C2, RETURNS(bounded_buf_get), "Second consumer removes the item.");

		// ERROR!
		RUN_THREAD_THROUGH(C1, ENDS(), "First consumer runs the second phase.");

	}
Beispiel #6
0
int
openpam_configure(pam_handle_t *pamh,
	const char *service)
{
	pam_facility_t fclt;
	int serrno;

	ENTERS(service);
	if (!valid_service_name(service)) {
		openpam_log(PAM_LOG_ERROR, "invalid service name");
		RETURNC(PAM_SYSTEM_ERR);
	}
	if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0)
		goto load_err;
	for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
		if (pamh->chains[fclt] != NULL)
			continue;
		if (openpam_load_chain(pamh, PAM_OTHER, fclt) < 0)
			goto load_err;
	}
#ifdef __NetBSD__
	/*
	 * On NetBSD we require the AUTH chain to have a binding
	 * or a required module.
	 */
	{
		pam_chain_t *this = pamh->chains[PAM_AUTH];
		for (; this != NULL; this = this->next)
			if (this->flag == PAM_BINDING ||
			    this->flag == PAM_REQUIRED)
				break;
		if (this == NULL) {
			openpam_log(PAM_LOG_ERROR,
			    "No required or binding component "
			    "in service %s, facility %s",
			    service, pam_facility_name[PAM_AUTH]);
			goto load_err;
		}
	}
#endif
	RETURNC(PAM_SUCCESS);
load_err:
	serrno = errno;
	openpam_clear_chains(pamh->chains);
	errno = serrno;
	RETURNC(PAM_SYSTEM_ERR);
}
Beispiel #7
0
int
pam_get_data(const pam_handle_t *pamh,
	const char *module_data_name,
	const void **data)
{
	pam_data_t *dp;

	ENTERS(module_data_name);
	if (pamh == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	for (dp = pamh->module_data; dp != NULL; dp = dp->next) {
		if (strcmp(dp->name, module_data_name) == 0) {
			*data = (void *)dp->data;
			RETURNC(PAM_SUCCESS);
		}
	}
	RETURNC(PAM_NO_MODULE_DATA);
}
Beispiel #8
0
const char *
pam_getenv(pam_handle_t *pamh,
	const char *name)
{
	char *str;
	int i;

	ENTERS(name);
	if (pamh == NULL)
		RETURNS(NULL);
	if (name == NULL || strchr(name, '=') != NULL)
		RETURNS(NULL);
	if ((i = openpam_findenv(pamh, name, strlen(name))) < 0)
		RETURNS(NULL);
	for (str = pamh->env[i]; *str != '\0'; ++str) {
		if (*str == '=') {
			++str;
			break;
		}
	}
	RETURNS(str);
}
const char *
openpam_get_option(pam_handle_t *pamh,
	const char *option)
{
	pam_chain_t *cur;
	size_t len;
	int i;

	ENTERS(option);
	if (pamh == NULL || pamh->current == NULL || option == NULL)
		RETURNS(NULL);
	cur = pamh->current;
	len = strlen(option);
	for (i = 0; i < cur->optc; ++i) {
		if (strncmp(cur->optv[i], option, len) == 0) {
			if (cur->optv[i][len] == '\0')
				RETURNS(&cur->optv[i][len]);
			else if (cur->optv[i][len] == '=')
				RETURNS(&cur->optv[i][len + 1]);
		}
	}
	RETURNS(NULL);
}