Beispiel #1
0
int
pam_setenv(pam_handle_t *pamh,
           const char *name,
           const char *value,
           int overwrite)
{
    char *env;
    int r;

    ENTER();
    if (pamh == NULL)
        RETURNC(PAM_SYSTEM_ERR);

    /* sanity checks */
    if (name == NULL || value == NULL || strchr(name, '=') != NULL)
        RETURNC(PAM_SYSTEM_ERR);

    /* is it already there? */
    if (!overwrite && openpam_findenv(pamh, name, strlen(name)) >= 0)
        RETURNC(PAM_SUCCESS);

    /* set it... */
    if (asprintf(&env, "%s=%s", name, value) < 0)
        RETURNC(PAM_BUF_ERR);
    r = pam_putenv(pamh, env);
    FREE(env);
    RETURNC(r);
}
Beispiel #2
0
int
pam_get_user(pam_handle_t *pamh,
	const char **user,
	const char *prompt)
{
	const void *promptp;
	char *resp;
	int r;

	ENTER();
	if (pamh == NULL || user == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	r = pam_get_item(pamh, PAM_USER, (const void **)user);
	if (r == PAM_SUCCESS && *user != NULL)
		RETURNC(PAM_SUCCESS);
	if (prompt == NULL) {
		r = pam_get_item(pamh, PAM_USER_PROMPT, &promptp);
		if (r != PAM_SUCCESS || promptp == NULL)
			prompt = user_prompt;
		else
			prompt = promptp;
	}
	r = pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &resp, "%s", prompt);
	if (r != PAM_SUCCESS)
		RETURNC(r);
	r = pam_set_item(pamh, PAM_USER, resp);
	FREE(resp);
	if (r != PAM_SUCCESS)
		RETURNC(r);
	r = pam_get_item(pamh, PAM_USER, (const void **)user);
	RETURNC(r);
}
Beispiel #3
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 #4
0
int
pam_get_item(const pam_handle_t *pamh,
	int item_type,
	const void **item)
{

	ENTERI(item_type);
	if (pamh == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	switch (item_type) {
	case PAM_SERVICE:
	case PAM_USER:
	case PAM_AUTHTOK:
	case PAM_OLDAUTHTOK:
	case PAM_TTY:
	case PAM_RHOST:
	case PAM_RUSER:
	case PAM_CONV:
	case PAM_USER_PROMPT:
	case PAM_REPOSITORY:
	case PAM_AUTHTOK_PROMPT:
	case PAM_OLDAUTHTOK_PROMPT:
	case PAM_HOST:
		*item = pamh->item[item_type];
		RETURNC(PAM_SUCCESS);
	default:
		RETURNC(PAM_SYMBOL_ERR);
	}
}
Beispiel #5
0
int
pam_start(const char *service,
	const char *user,
	const struct pam_conv *pam_conv,
	pam_handle_t **pamh)
{
	char hostname[HOST_NAME_MAX + 1];
	struct pam_handle *ph;
	int r;

	ENTER();
	if ((ph = calloc(1, sizeof *ph)) == NULL)
		RETURNC(PAM_BUF_ERR);
	if ((r = pam_set_item(ph, PAM_SERVICE, service)) != PAM_SUCCESS)
		goto fail;
	if (gethostname(hostname, sizeof hostname) != 0)
		strlcpy(hostname, "localhost", sizeof hostname);
	if ((r = pam_set_item(ph, PAM_HOST, hostname)) != PAM_SUCCESS)
		goto fail;
	if ((r = pam_set_item(ph, PAM_USER, user)) != PAM_SUCCESS)
		goto fail;
	if ((r = pam_set_item(ph, PAM_CONV, pam_conv)) != PAM_SUCCESS)
		goto fail;
	if ((r = openpam_configure(ph, service)) != PAM_SUCCESS)
		goto fail;
	*pamh = ph;
	openpam_log(PAM_LOG_DEBUG, "pam_start(\"%s\") succeeded", service);
	RETURNC(PAM_SUCCESS);
fail:
	pam_end(ph, r);
	RETURNC(r);
}
Beispiel #6
0
int
pam_vprompt(const pam_handle_t *pamh,
	int style,
	char **resp,
	const char *fmt,
	va_list ap)
{
	char msgbuf[PAM_MAX_MSG_SIZE];
	struct pam_message msg;
	const struct pam_message *msgp;
	struct pam_response *rsp;
	const struct pam_conv *conv;
	const void *convp;
	int r;

	ENTER();
	r = pam_get_item(pamh, PAM_CONV, &convp);
	if (r != PAM_SUCCESS)
		RETURNC(r);
	conv = convp;
	if (conv == NULL || conv->conv == NULL) {
		openpam_log(PAM_LOG_ERROR, "no conversation function");
		RETURNC(PAM_SYSTEM_ERR);
	}
	vsnprintf(msgbuf, (size_t)PAM_MAX_MSG_SIZE, fmt, ap);
	msg.msg_style = style;
	msg.msg = msgbuf;
	msgp = &msg;
	rsp = NULL;
	r = (conv->conv)(1, &msgp, &rsp, conv->appdata_ptr);
	*resp = rsp == NULL ? NULL : rsp->resp;
	FREE(rsp);
	RETURNC(r);
	/*NOTREACHED*/
}
Beispiel #7
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 #8
0
int
pam_set_item(pam_handle_t *pamh,
	int item_type,
	const void *item)
{
	void **slot, *tmp;
	size_t nsize, osize;

	ENTERI(item_type);
	if (pamh == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	slot = &pamh->item[item_type];
	osize = nsize = 0;
	switch (item_type) {
	case PAM_SERVICE:
		/* set once only, by pam_start() */
		if (*slot != NULL)
			RETURNC(PAM_SYSTEM_ERR);
		/* fall through */
	case PAM_USER:
	case PAM_AUTHTOK:
	case PAM_OLDAUTHTOK:
	case PAM_TTY:
	case PAM_RHOST:
	case PAM_RUSER:
	case PAM_USER_PROMPT:
	case PAM_AUTHTOK_PROMPT:
	case PAM_OLDAUTHTOK_PROMPT:
	case PAM_HOST:
		if (*slot != NULL)
			osize = strlen(*slot) + 1;
		if (item != NULL)
			nsize = strlen(item) + 1;
		break;
	case PAM_REPOSITORY:
		osize = nsize = sizeof(struct pam_repository);
		break;
	case PAM_CONV:
		osize = nsize = sizeof(struct pam_conv);
		break;
	default:
		RETURNC(PAM_SYMBOL_ERR);
	}
	if (*slot != NULL) {
		memset(*slot, 0xd0, osize);
		FREE(*slot);
	}
	if (item != NULL) {
		if ((tmp = malloc(nsize)) == NULL)
			RETURNC(PAM_BUF_ERR);
		memcpy(tmp, item, nsize);
	} else {
		tmp = NULL;
	}
	*slot = tmp;
	RETURNC(PAM_SUCCESS);
}
int
openpam_get_feature(int feature, int *onoff)
{

	ENTERF(feature);
	if (feature < 0 || feature >= OPENPAM_NUM_FEATURES)
		RETURNC(PAM_SYMBOL_ERR);
	*onoff = openpam_features[feature].onoff;
	RETURNC(PAM_SUCCESS);
}
Beispiel #10
0
int
pam_open_session(pam_handle_t *pamh,
	int flags)
{
	int r;

	ENTER();
	if (flags & ~(PAM_SILENT))
		RETURNC(PAM_SYMBOL_ERR);
	r = openpam_dispatch(pamh, PAM_SM_OPEN_SESSION, flags);
	RETURNC(r);
}
Beispiel #11
0
int
pam_authenticate(pam_handle_t *pamh,
	int flags)
{
	int r;

	ENTER();
	if (flags & ~(PAM_SILENT|PAM_DISALLOW_NULL_AUTHTOK))
		RETURNC(PAM_SYMBOL_ERR);
	r = openpam_dispatch(pamh, PAM_SM_AUTHENTICATE, flags);
	pam_set_item(pamh, PAM_AUTHTOK, NULL);
	RETURNC(r);
}
Beispiel #12
0
int
pam_setcred(pam_handle_t *pamh,
	int flags)
{
	int r;

	ENTER();
	if (flags & ~(PAM_SILENT|PAM_ESTABLISH_CRED|PAM_DELETE_CRED|
		PAM_REINITIALIZE_CRED|PAM_REFRESH_CRED))
		RETURNC(PAM_SYMBOL_ERR);
	/* XXX enforce exclusivity */
	r = openpam_dispatch(pamh, PAM_SM_SETCRED, flags);
	RETURNC(r);
	/*NOTREACHED*/
}
Beispiel #13
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 #14
0
int
pam_start(const char *service,
	const char *user,
	const struct pam_conv *pam_conv,
	pam_handle_t **pamh)
{
	char *hostname = NULL;
	struct pam_handle *ph;
	int r;
	size_t hostname_size;
	long h;

#ifdef _SC_HOST_NAME_MAX
	h = sysconf(_SC_HOST_NAME_MAX);
#else
	h = -1;
#endif
	hostname_size = (size_t)(h < 10 ? 1024 : h) + 1;

	ENTER();
	if ((ph = calloc((size_t)1, sizeof *ph)) == NULL)
		RETURNC(PAM_BUF_ERR);
	if ((r = pam_set_item(ph, PAM_SERVICE, service)) != PAM_SUCCESS)
		goto fail;
	if ((hostname = malloc(hostname_size)) == NULL)
		goto fail;
	if (gethostname(hostname, hostname_size) != 0)
		strlcpy(hostname, "localhost", hostname_size);
	if ((r = pam_set_item(ph, PAM_HOST, hostname)) != PAM_SUCCESS)
		goto fail;
	if ((r = pam_set_item(ph, PAM_USER, user)) != PAM_SUCCESS)
		goto fail;
	if ((r = pam_set_item(ph, PAM_CONV, pam_conv)) != PAM_SUCCESS)
		goto fail;
	if ((r = openpam_configure(ph, service)) != PAM_SUCCESS)
		goto fail;
	free(hostname);
	*pamh = ph;
	openpam_log(PAM_LOG_DEBUG, "pam_start(\"%s\") succeeded", service);
	RETURNC(PAM_SUCCESS);
fail:
	free(hostname);
	pam_end(ph, r);
	RETURNC(r);
}
Beispiel #15
0
int
pam_chauthtok(pam_handle_t *pamh,
	int flags)
{
	int r;

	ENTER();
	if (flags & ~(PAM_SILENT|PAM_CHANGE_EXPIRED_AUTHTOK))
		RETURNC(PAM_SYMBOL_ERR);
	r = openpam_dispatch(pamh, PAM_SM_CHAUTHTOK,
	    flags | PAM_PRELIM_CHECK);
	if (r == PAM_SUCCESS)
		r = openpam_dispatch(pamh, PAM_SM_CHAUTHTOK,
		    flags | PAM_UPDATE_AUTHTOK);
	pam_set_item(pamh, PAM_OLDAUTHTOK, NULL);
	pam_set_item(pamh, PAM_AUTHTOK, NULL);
	RETURNC(r);
}
Beispiel #16
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 #17
0
int
pam_get_user(pam_handle_t *pamh,
	const char **user,
	const char *prompt)
{
	char prompt_buf[1024];
	size_t prompt_size;
	const void *promptp;
	char *resp;
	int r;

	ENTER();
	if (pamh == NULL || user == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	r = pam_get_item(pamh, PAM_USER, (const void **)user);
	if (r == PAM_SUCCESS && *user != NULL)
		RETURNC(PAM_SUCCESS);
	/* pam policy overrides the module's choice */
	if ((promptp = openpam_get_option(pamh, "user_prompt")) != NULL)
		prompt = promptp;
	/* no prompt provided, see if there is one tucked away somewhere */
	if (prompt == NULL)
		if (pam_get_item(pamh, PAM_USER_PROMPT, &promptp) &&
		    promptp != NULL)
			prompt = promptp;
	/* fall back to hardcoded default */
	if (prompt == NULL)
		prompt = user_prompt;
	/* expand */
	prompt_size = sizeof prompt_buf;
	r = openpam_subst(pamh, prompt_buf, &prompt_size, prompt);
	if (r == PAM_SUCCESS && prompt_size <= sizeof prompt_buf)
		prompt = prompt_buf;
	r = pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &resp, "%s", prompt);
	if (r != PAM_SUCCESS)
		RETURNC(r);
	r = pam_set_item(pamh, PAM_USER, resp);
	FREE(resp);
	if (r != PAM_SUCCESS)
		RETURNC(r);
	r = pam_get_item(pamh, PAM_USER, (const void **)user);
	RETURNC(r);
}
int
pam_sm_authenticate(pam_handle_t *pamh,
	int flags,
	int argc,
	const char **argv)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
int
pam_sm_open_session(pam_handle_t *pamh,
	int flags,
	int argc,
	const char **argv)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
Beispiel #20
0
int
pam_acct_mgmt(pam_handle_t *pamh,
	int flags)
{
	int r;

	ENTER();
	r = openpam_dispatch(pamh, PAM_SM_ACCT_MGMT, flags);
	RETURNC(r);
}
int
pam_sm_acct_mgmt(pam_handle_t *pamh,
	int flags,
	int argc,
	const char **argv)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
Beispiel #22
0
int
pam_sm_set_mapped_username(pam_handle_t *pamh,
	char *target_module_username,
	char *target_module_type,
	char *target_authn_domain,
	int argc,
	const char **argv)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
int
pam_set_mapped_authtok(pam_handle_t *pamh,
	const char *target_module_username,
	size_t target_authtok_len,
	unsigned char *target_module_authtok,
	const char *target_module_type,
	const char *target_authn_domain)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
int
pam_authenticate_secondary(pam_handle_t *pamh,
	char *target_username,
	char *target_module_type,
	char *target_authn_domain,
	char *target_supp_data,
	char *target_module_authtok,
	int flags)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
int
pam_set_mapped_username(pam_handle_t *pamh,
	char *src_username,
	char *src_module_type,
	char *src_authn_domain,
	char *target_module_username,
	char *target_module_type,
	char *target_authn_domain)
{

	ENTER();
	RETURNC(PAM_SYSTEM_ERR);
}
int
openpam_nullconv(int n,
	 const struct pam_message **msg,
	 struct pam_response **resp,
	 void *data)
{

	ENTER();
	(void)n;
	(void)msg;
	(void)resp;
	(void)data;
	RETURNC(PAM_CONV_ERR);
}
int
openpam_restore_cred(pam_handle_t *pamh)
{
	const struct pam_saved_cred *scred;
	const void *scredp;
	int r;

	ENTER();
	r = pam_get_data(pamh, PAM_SAVED_CRED, &scredp);
	if (r != PAM_SUCCESS)
		RETURNC(r);
	if (scredp == NULL)
		RETURNC(PAM_SYSTEM_ERR);
	scred = scredp;
	if (scred->euid != geteuid()) {
		if (seteuid(scred->euid) < 0 ||
		    setgroups(scred->ngroups, scred->groups) < 0 ||
		    setegid(scred->egid) < 0)
			RETURNC(PAM_SYSTEM_ERR);
	}
	pam_set_data(pamh, PAM_SAVED_CRED, NULL, NULL);
	RETURNC(PAM_SUCCESS);
}
int
pam_sm_get_mapped_authtok(pam_handle_t *pamh,
                          char *target_module_username,
                          char *target_module_type,
                          char *target_authn_domain,
                          size_t *target_authtok_len,
                          unsigned char **target_module_authtok,
                          int argc,
                          char *argv)
{

    ENTER();
    RETURNC(PAM_SYSTEM_ERR);
}
int
openpam_borrow_cred(pam_handle_t *pamh,
	const struct passwd *pwd)
{
	struct pam_saved_cred *scred;
	const void *scredp;
	int r;

	ENTERI(pwd->pw_uid);
	r = pam_get_data(pamh, PAM_SAVED_CRED, &scredp);
	if (r == PAM_SUCCESS && scredp != NULL) {
		openpam_log(PAM_LOG_DEBUG,
		    "already operating under borrowed credentials");
		RETURNC(PAM_SYSTEM_ERR);
	}
	if (geteuid() != 0 && geteuid() != pwd->pw_uid) {
		openpam_log(PAM_LOG_DEBUG, "called with non-zero euid: %d",
		    (int)geteuid());
		RETURNC(PAM_PERM_DENIED);
	}
	scred = calloc((size_t)1, sizeof *scred);
	if (scred == NULL)
		RETURNC(PAM_BUF_ERR);
	scred->euid = geteuid();
	scred->egid = getegid();
	r = getgroups(NGROUPS_MAX, scred->groups);
	if (r < 0) {
		FREE(scred);
		RETURNC(PAM_SYSTEM_ERR);
	}
	scred->ngroups = r;
	r = pam_set_data(pamh, PAM_SAVED_CRED, scred, &openpam_free_data);
	if (r != PAM_SUCCESS) {
		FREE(scred);
		RETURNC(r);
	}
	if (geteuid() == pwd->pw_uid)
		RETURNC(PAM_SUCCESS);
	if (initgroups(pwd->pw_name, pwd->pw_gid) < 0 ||
	      setegid(pwd->pw_gid) < 0 || seteuid(pwd->pw_uid) < 0) {
		openpam_restore_cred(pamh);
		RETURNC(PAM_SYSTEM_ERR);
	}
	RETURNC(PAM_SUCCESS);
	/*NOTREACHED*/
}
Beispiel #30
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);
}