diff options
author | Stefan Schubert <schubi@suse.de> | 2021-12-09 15:19:29 +0100 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2022-01-25 14:24:26 +0000 |
commit | c11b0f5d8f9f6abcc76594af9e3b5e647b19f61f (patch) | |
tree | a5c4bb2b95ee796fc85719715d8662235d37965b /modules/pam_group | |
parent | 4d96b59360a57a7a96443e6c34d2cfd13ea3f5e3 (diff) | |
download | pam-c11b0f5d8f9f6abcc76594af9e3b5e647b19f61f.tar.gz pam-c11b0f5d8f9f6abcc76594af9e3b5e647b19f61f.tar.bz2 pam-c11b0f5d8f9f6abcc76594af9e3b5e647b19f61f.zip |
pam_group: use vendor specific group.conf as fallback
Use the vendor directory defined by --enable-vendordir=DIR configure
option as fallback for the distribution provided default config file
if there is no configuration in /etc.
* modules/pam_group/pam_group.c: Include <errno.h>.
[VENDOR_SCONFIGDIR] (VENDOR_PAM_GROUP_CONF): New macro.
(read_field): Add conf_filename argument, use it instead of PAM_GROUP_CONF.
(check_account) <conf_filename>: New variable, initialize it to
PAM_GROUP_CONF, pass it to read_field().
[VENDOR_PAM_GROUP_CONF]: Assign VENDOR_PAM_GROUP_CONF to conf_filename
when PAM_GROUP_CONF file does not exist.
* modules/pam_group/pam_group.8.xml: Describe it.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
Resolves: https://github.com/linux-pam/linux-pam/pull/412
Diffstat (limited to 'modules/pam_group')
-rw-r--r-- | modules/pam_group/pam_group.8.xml | 4 | ||||
-rw-r--r-- | modules/pam_group/pam_group.c | 45 |
2 files changed, 35 insertions, 14 deletions
diff --git a/modules/pam_group/pam_group.8.xml b/modules/pam_group/pam_group.8.xml index 2c1c9058..e4a59dfd 100644 --- a/modules/pam_group/pam_group.8.xml +++ b/modules/pam_group/pam_group.8.xml @@ -38,6 +38,10 @@ By default rules for group memberships are taken from config file <filename>/etc/security/group.conf</filename>. </para> + <para condition="with_vendordir"> + If <filename>/etc/security/group.conf</filename> does not exist, + <filename>%vendordir%/security/group.conf</filename> is used. + </para> <para> This module's usefulness relies on the file-systems accessible to the user. The point being that once granted the diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c index 4e1fd648..c49358a1 100644 --- a/modules/pam_group/pam_group.c +++ b/modules/pam_group/pam_group.c @@ -16,6 +16,7 @@ #include <time.h> #include <syslog.h> #include <string.h> +#include <errno.h> #include <grp.h> #include <sys/types.h> @@ -24,6 +25,9 @@ #include <netdb.h> #define PAM_GROUP_CONF SCONFIGDIR "/group.conf" +#ifdef VENDOR_SCONFIGDIR +# define VENDOR_PAM_GROUP_CONF VENDOR_SCONFIGDIR "/group.conf" +#endif #define PAM_GROUP_BUFLEN 1000 #define FIELD_SEPARATOR ';' /* this is new as of .02 */ @@ -71,7 +75,8 @@ trim_spaces(char *buf, char *from) #define STATE_EOF 3 /* end of file or error */ static int -read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state) +read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state, + const char *conf_filename) { char *to; char *src; @@ -90,9 +95,9 @@ read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state) } *from = 0; *state = STATE_NL; - fd = open(PAM_GROUP_CONF, O_RDONLY); + fd = open(conf_filename, O_RDONLY); if (fd < 0) { - pam_syslog(pamh, LOG_ERR, "error opening %s: %m", PAM_GROUP_CONF); + pam_syslog(pamh, LOG_ERR, "error opening %s: %m", conf_filename); _pam_drop(*buf); *state = STATE_EOF; return -1; @@ -107,7 +112,7 @@ read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state) while (fd != -1 && to - *buf < PAM_GROUP_BUFLEN) { i = pam_modutil_read(fd, to, PAM_GROUP_BUFLEN - (to - *buf)); if (i < 0) { - pam_syslog(pamh, LOG_ERR, "error reading %s: %m", PAM_GROUP_CONF); + pam_syslog(pamh, LOG_ERR, "error reading %s: %m", conf_filename); close(fd); memset(*buf, 0, PAM_GROUP_BUFLEN); _pam_drop(*buf); @@ -574,6 +579,18 @@ static int check_account(pam_handle_t *pamh, const char *service, int retval=PAM_SUCCESS; gid_t *grps; int no_grps; + const char *conf_filename = PAM_GROUP_CONF; + +#ifdef VENDOR_PAM_GROUP_CONF + /* + * Check whether PAM_GROUP_CONF file is available. + * If it does not exist, fall back to VENDOR_PAM_GROUP_CONF file. + */ + struct stat stat_buffer; + if (stat(conf_filename, &stat_buffer) != 0 && errno == ENOENT) { + conf_filename = VENDOR_PAM_GROUP_CONF; + } +#endif /* * first we get the current list of groups - the application @@ -612,7 +629,7 @@ static int check_account(pam_handle_t *pamh, const char *service, /* here we get the service name field */ - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (!buffer || !buffer[0]) { /* empty line .. ? */ continue; @@ -622,7 +639,7 @@ static int check_account(pam_handle_t *pamh, const char *service, if (state != STATE_FIELD) { pam_syslog(pamh, LOG_ERR, - "%s: malformed rule #%d", PAM_GROUP_CONF, count); + "%s: malformed rule #%d", conf_filename, count); continue; } @@ -631,10 +648,10 @@ static int check_account(pam_handle_t *pamh, const char *service, /* here we get the terminal name field */ - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state != STATE_FIELD) { pam_syslog(pamh, LOG_ERR, - "%s: malformed rule #%d", PAM_GROUP_CONF, count); + "%s: malformed rule #%d", conf_filename, count); continue; } good &= logic_field(pamh,tty, buffer, count, is_same); @@ -642,10 +659,10 @@ static int check_account(pam_handle_t *pamh, const char *service, /* here we get the username field */ - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state != STATE_FIELD) { pam_syslog(pamh, LOG_ERR, - "%s: malformed rule #%d", PAM_GROUP_CONF, count); + "%s: malformed rule #%d", conf_filename, count); continue; } /* If buffer starts with @, we are using netgroups */ @@ -664,20 +681,20 @@ static int check_account(pam_handle_t *pamh, const char *service, /* here we get the time field */ - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state != STATE_FIELD) { pam_syslog(pamh, LOG_ERR, - "%s: malformed rule #%d", PAM_GROUP_CONF, count); + "%s: malformed rule #%d", conf_filename, count); continue; } good &= logic_field(pamh,&here_and_now, buffer, count, check_time); D(("with time: %s", good ? "passes":"fails" )); - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state == STATE_FIELD) { pam_syslog(pamh, LOG_ERR, - "%s: poorly terminated rule #%d", PAM_GROUP_CONF, count); + "%s: poorly terminated rule #%d", conf_filename, count); continue; } |