예제 #1
0
/* Import regular and PAM environment from subprocess */
static void
import_environments(struct sshbuf *b)
{
	char *env;
	u_int n, i, num_env;
	int r;

	debug3("PAM: %s entering", __func__);

#ifndef UNSUPPORTED_POSIX_THREADS_HACK
	/* Import variables set by do_pam_account */
	if ((r = sshbuf_get_u32(b, &n)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	if (n > INT_MAX)
		fatal("%s: invalid PAM account status %u", __func__, n);
	sshpam_account_status = (int)n;
	if ((r = sshbuf_get_u32(b, &n)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	sshpam_password_change_required(n != 0);

	/* Import environment from subprocess */
	if ((r = sshbuf_get_u32(b, &num_env)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	if (num_env > 1024)
		fatal("%s: received %u environment variables, expected <= 1024",
		    __func__, num_env);
	sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
	debug3("PAM: num env strings %d", num_env);
	for(i = 0; i < num_env; i++) {
		if ((r = sshbuf_get_cstring(b, &(sshpam_env[i]), NULL)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
	}
	sshpam_env[num_env] = NULL;

	/* Import PAM environment from subprocess */
	if ((r = sshbuf_get_u32(b, &num_env)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	debug("PAM: num PAM env strings %d", num_env);
	for (i = 0; i < num_env; i++) {
		if ((r = sshbuf_get_cstring(b, &env, NULL)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
#ifdef HAVE_PAM_PUTENV
		/* Errors are not fatal here */
		if ((r = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
			error("PAM: pam_putenv: %s",
			    pam_strerror(sshpam_handle, r));
		}
#endif
		/* XXX leak env? */
	}
#endif
}
예제 #2
0
파일: auth-pam.c 프로젝트: Alkzndr/freebsd
/* Import regular and PAM environment from subprocess */
static void
import_environments(Buffer *b)
{
	char *env;
	u_int i, num_env;
	int err;

	debug3("PAM: %s entering", __func__);

#ifndef UNSUPPORTED_POSIX_THREADS_HACK
	/* Import variables set by do_pam_account */
	sshpam_account_status = buffer_get_int(b);
	sshpam_password_change_required(buffer_get_int(b));

	/* Import environment from subprocess */
	num_env = buffer_get_int(b);
	if (num_env > 1024)
		fatal("%s: received %u environment variables, expected <= 1024",
		    __func__, num_env);
	sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
	debug3("PAM: num env strings %d", num_env);
	for(i = 0; i < num_env; i++)
		sshpam_env[i] = buffer_get_string(b, NULL);

	sshpam_env[num_env] = NULL;

	/* Import PAM environment from subprocess */
	num_env = buffer_get_int(b);
	debug("PAM: num PAM env strings %d", num_env);
	for(i = 0; i < num_env; i++) {
		env = buffer_get_string(b, NULL);

#ifdef HAVE_PAM_PUTENV
		/* Errors are not fatal here */
		if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
			error("PAM: pam_putenv: %s",
			    pam_strerror(sshpam_handle, sshpam_err));
		}
#endif
	}
#endif
}
예제 #3
0
파일: auth-pam.c 프로젝트: Alkzndr/freebsd
u_int
do_pam_account(void)
{
	debug("%s: called", __func__);
	if (sshpam_account_status != -1)
		return (sshpam_account_status);

	sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
	    pam_strerror(sshpam_handle, sshpam_err));

	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
		sshpam_account_status = 0;
		return (sshpam_account_status);
	}

	if (sshpam_err == PAM_NEW_AUTHTOK_REQD)
		sshpam_password_change_required(1);

	sshpam_account_status = 1;
	return (sshpam_account_status);
}
예제 #4
0
파일: auth-pam.c 프로젝트: Alkzndr/freebsd
/*
 * Authentication thread.
 */
static void *
sshpam_thread(void *ctxtp)
{
	struct pam_ctxt *ctxt = ctxtp;
	Buffer buffer;
	struct pam_conv sshpam_conv;
	int flags = (options.permit_empty_passwd == 0 ?
	    PAM_DISALLOW_NULL_AUTHTOK : 0);
#ifndef UNSUPPORTED_POSIX_THREADS_HACK
	extern char **environ;
	char **env_from_pam;
	u_int i;
	const char *pam_user;
	const char **ptr_pam_user = &pam_user;
	char *tz = getenv("TZ");

	sshpam_err = pam_get_item(sshpam_handle, PAM_USER,
	    (sshpam_const void **)ptr_pam_user);
	if (sshpam_err != PAM_SUCCESS)
		goto auth_fail;

	environ[0] = NULL;
	if (tz != NULL)
		if (setenv("TZ", tz, 1) == -1)
			error("PAM: could not set TZ environment: %s",
			    strerror(errno));

	if (sshpam_authctxt != NULL) {
		setproctitle("%s [pam]",
		    sshpam_authctxt->valid ? pam_user : "******");
	}
#endif

	sshpam_conv.conv = sshpam_thread_conv;
	sshpam_conv.appdata_ptr = ctxt;

	if (sshpam_authctxt == NULL)
		fatal("%s: PAM authctxt not initialized", __func__);

	buffer_init(&buffer);
	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
	    (const void *)&sshpam_conv);
	if (sshpam_err != PAM_SUCCESS)
		goto auth_fail;
	sshpam_err = pam_authenticate(sshpam_handle, flags);
	if (sshpam_err != PAM_SUCCESS)
		goto auth_fail;

	if (compat20) {
		if (!do_pam_account()) {
			sshpam_err = PAM_ACCT_EXPIRED;
			goto auth_fail;
		}
		if (sshpam_authctxt->force_pwchange) {
			sshpam_err = pam_chauthtok(sshpam_handle,
			    PAM_CHANGE_EXPIRED_AUTHTOK);
			if (sshpam_err != PAM_SUCCESS)
				goto auth_fail;
			sshpam_password_change_required(0);
		}
	}

	buffer_put_cstring(&buffer, "OK");

#ifndef UNSUPPORTED_POSIX_THREADS_HACK
	/* Export variables set by do_pam_account */
	buffer_put_int(&buffer, sshpam_account_status);
	buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);

	/* Export any environment strings set in child */
	for(i = 0; environ[i] != NULL; i++)
		; /* Count */
	buffer_put_int(&buffer, i);
	for(i = 0; environ[i] != NULL; i++)
		buffer_put_cstring(&buffer, environ[i]);

	/* Export any environment strings set by PAM in child */
	env_from_pam = pam_getenvlist(sshpam_handle);
	for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
		; /* Count */
	buffer_put_int(&buffer, i);
	for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
		buffer_put_cstring(&buffer, env_from_pam[i]);
#endif /* UNSUPPORTED_POSIX_THREADS_HACK */

	/* XXX - can't do much about an error here */
	ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
	buffer_free(&buffer);
	pthread_exit(NULL);

 auth_fail:
	buffer_put_cstring(&buffer,
	    pam_strerror(sshpam_handle, sshpam_err));
	/* XXX - can't do much about an error here */
	if (sshpam_err == PAM_ACCT_EXPIRED)
		ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
	else
		ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
	buffer_free(&buffer);
	pthread_exit(NULL);

	return (NULL); /* Avoid warning for non-pthread case */
}