Accepting request 1010118 from home:schubi2

- pam_env: Using libeconf for reading configuration and environment
  files.

OBS-URL: https://build.opensuse.org/request/show/1010118
OBS-URL: https://build.opensuse.org/package/show/Linux-PAM/pam?expand=0&rev=264
This commit is contained in:
Thorsten Kukuk 2022-10-12 09:48:57 +00:00 committed by Git OBS Bridge
parent 99fd8d508e
commit a7257563cb
4 changed files with 1288 additions and 0 deletions

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue Oct 11 14:44:56 UTC 2022 - Stefan Schubert <schubi@suse.com>
- pam_env: Using libeconf for reading configuration and environment
files.
-------------------------------------------------------------------
Fri Jun 17 15:26:20 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>

View File

@ -64,12 +64,14 @@ Source12: pam-login_defs-check.sh
Source13: pam.tmpfiles
Source14: Linux-PAM-%{version}-docs.tar.xz.asc
Source15: Linux-PAM-%{version}.tar.xz.asc
Source16: tst-pam_env-retval.c
Patch1: pam-limit-nproc.patch
Patch2: pam-hostnames-in-access_conf.patch
Patch3: pam-xauth_ownership.patch
Patch4: pam-bsc1177858-dont-free-environment-string.patch
Patch10: pam_xauth_data.3.xml.patch
Patch11: pam-git.diff
Patch12: pam_env_econf.patch
BuildRequires: audit-devel
BuildRequires: bison
BuildRequires: flex
@ -175,12 +177,14 @@ building both PAM-aware applications and modules for use with PAM.
%prep
%setup -q -n Linux-PAM-%{version} -b 1
cp -a %{SOURCE12} .
cp %{SOURCE16} ./modules/pam_env
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%build
bash ./pam-login_defs-check.sh

1019
pam_env_econf.patch Normal file

File diff suppressed because it is too large Load Diff

259
tst-pam_env-retval.c Normal file
View File

@ -0,0 +1,259 @@
/*
* Check pam_env return values.
*
* Copyright (c) 2020-2022 Dmitry V. Levin <ldv@altlinux.org>
* Copyright (c) 2022 Stefan Schubert <schubi@suse.de>
*/
#include "test_assert.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <security/pam_appl.h>
#define MODULE_NAME "pam_env"
#define TEST_NAME "tst-" MODULE_NAME "-retval"
#define TEST_NAME_DIR TEST_NAME ".dir"
static const char service_file[] = TEST_NAME ".service";
static const char missing_file[] = TEST_NAME ".missing";
static const char dir[] = TEST_NAME_DIR;
static const char dir_usr[] = TEST_NAME_DIR "/usr";
static const char dir_usr_etc[] = TEST_NAME_DIR "/usr/etc";
static const char dir_usr_etc_security[] = TEST_NAME_DIR "/usr/etc/security";
static const char my_conf[] = TEST_NAME ".conf";
static const char my_env[] = TEST_NAME ".env";
static const char usr_env[] = TEST_NAME_DIR "/usr/etc/environment";
static const char usr_conf[] = TEST_NAME_DIR "/usr/etc/security/pam_env.conf";
static struct pam_conv conv;
static void
setup(void)
{
FILE *fp;
ASSERT_EQ(0, mkdir(dir, 0755));
ASSERT_EQ(0, mkdir(dir_usr, 0755));
ASSERT_EQ(0, mkdir(dir_usr_etc, 0755));
ASSERT_EQ(0, mkdir(dir_usr_etc_security, 0755));
ASSERT_NE(NULL, fp = fopen(my_conf, "w"));
ASSERT_LT(0, fprintf(fp,
"EDITOR\tDEFAULT=vim\n"
"PAGER\tDEFAULT=more\n"));
ASSERT_EQ(0, fclose(fp));
ASSERT_NE(NULL, fp = fopen(my_env, "w"));
ASSERT_LT(0, fprintf(fp,
"test_value=foo\n"
"test2_value=bar\n"));
ASSERT_EQ(0, fclose(fp));
ASSERT_NE(NULL, fp = fopen(usr_env, "w"));
ASSERT_LT(0, fprintf(fp,
"usr_etc_test=foo\n"
"usr_etc_test2=bar\n"));
ASSERT_EQ(0, fclose(fp));
ASSERT_NE(NULL, fp = fopen(usr_conf, "w"));
ASSERT_LT(0, fprintf(fp,
"PAGER DEFAULT=emacs\n"
"MANPAGER DEFAULT=less\n"));
ASSERT_EQ(0, fclose(fp));
}
static void
cleanup(void)
{
ASSERT_EQ(0, unlink(my_conf));
ASSERT_EQ(0, unlink(my_env));
ASSERT_EQ(0, unlink(usr_env));
ASSERT_EQ(0, unlink(usr_conf));
ASSERT_EQ(0, rmdir(dir_usr_etc_security));
ASSERT_EQ(0, rmdir(dir_usr_etc));
ASSERT_EQ(0, rmdir(dir_usr));
ASSERT_EQ(0, rmdir(dir));
}
static void
check_array(const char **array1, char **array2)
{
for (const char **a1 = array1; *a1 != NULL; ++a1) {
char **a2;
for (a2 = array2; *a2 != NULL; ++a2) {
if (strcmp(*a1, *a2) == 0)
break;
}
ASSERT_NE(NULL, *a2);
}
}
static void
check_env(const char **list)
{
pam_handle_t *pamh = NULL;
ASSERT_EQ(PAM_SUCCESS,
pam_start_confdir(service_file, "", &conv, ".", &pamh));
ASSERT_NE(NULL, pamh);
ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
char **env_list = pam_getenvlist(pamh);
ASSERT_NE(NULL, env_list);
check_array(list, env_list);
for (char **e = env_list; *e != NULL; ++e)
free(*e);
free(env_list);
ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
}
int
main(void)
{
pam_handle_t *pamh = NULL;
FILE *fp;
char cwd[PATH_MAX];
ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
setup();
/*
* When conffile= specifies a missing file, all methods except
* pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE.
* The return code of the stack where every module returns PAM_IGNORE
* is PAM_PERM_DENIED.
*/
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"auth required %s/.libs/%s.so conffile=%s/%s\n"
"account required %s/.libs/%s.so conffile=%s/%s\n"
"password required %s/.libs/%s.so conffile=%s/%s\n"
"session required %s/.libs/%s.so conffile=%s/%s\n",
cwd, MODULE_NAME, cwd, missing_file,
cwd, MODULE_NAME, cwd, missing_file,
cwd, MODULE_NAME, cwd, missing_file,
cwd, MODULE_NAME, cwd, missing_file));
ASSERT_EQ(0, fclose(fp));
ASSERT_EQ(PAM_SUCCESS,
pam_start_confdir(service_file, "", &conv, ".", &pamh));
ASSERT_NE(NULL, pamh);
ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0));
ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0));
ASSERT_EQ(PAM_PERM_DENIED, pam_open_session(pamh, 0));
ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
pamh = NULL;
/*
* When conffile= specifies a missing file, all methods except
* pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE.
* pam_permit is added after pam_env to convert PAM_IGNORE to PAM_SUCCESS.
*/
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"auth required %s/.libs/%s.so conffile=%s/%s\n"
"auth required %s/../pam_permit/.libs/pam_permit.so\n"
"account required %s/.libs/%s.so conffile=%s/%s\n"
"account required %s/../pam_permit/.libs/pam_permit.so\n"
"password required %s/.libs/%s.so conffile=%s/%s\n"
"password required %s/../pam_permit/.libs/pam_permit.so\n"
"session required %s/.libs/%s.so conffile=%s/%s\n"
"session required %s/../pam_permit/.libs/pam_permit.so\n",
cwd, MODULE_NAME, cwd, missing_file, cwd,
cwd, MODULE_NAME, cwd, missing_file, cwd,
cwd, MODULE_NAME, cwd, missing_file, cwd,
cwd, MODULE_NAME, cwd, missing_file, cwd));
ASSERT_EQ(0, fclose(fp));
ASSERT_EQ(PAM_SUCCESS,
pam_start_confdir(service_file, "", &conv, ".", &pamh));
ASSERT_NE(NULL, pamh);
ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0));
ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
pamh = NULL;
/*
* conffile= specifies an existing file,
* envfile= specifies an empty file.
*/
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s/%s envfile=%s\n",
cwd, MODULE_NAME,
cwd, my_conf, "/dev/null"));
ASSERT_EQ(0, fclose(fp));
const char *env1[] = { "EDITOR=vim", "PAGER=more", NULL };
check_env(env1);
/*
* conffile= specifies an empty file,
* envfile= specifies an existing file.
*/
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s envfile=%s/%s\n",
cwd, MODULE_NAME,
"/dev/null", cwd, my_env));
ASSERT_EQ(0, fclose(fp));
const char *env2[] = { "test_value=foo", "test2_value=bar", NULL };
check_env(env2);
#if defined (USE_ECONF) && defined (VENDORDIR)
/* envfile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s envfile=%s/%s/\n",
cwd, MODULE_NAME,
"/dev/null",
cwd, dir));
ASSERT_EQ(0, fclose(fp));
const char *env3[] = {"usr_etc_test=foo", "usr_etc_test2=bar", NULL};
check_env(env3);
/* conffile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s/%s/ envfile=%s\n",
cwd, MODULE_NAME,
cwd, dir,
"/dev/null"));
ASSERT_EQ(0, fclose(fp));
const char *env4[] = {"PAGER=emacs", "MANPAGER=less", NULL};
check_env(env4);
#endif
/* cleanup */
cleanup();
ASSERT_EQ(0, unlink(service_file));
return 0;
}