diff options
author | Allison Karlitskaya <allison.karlitskaya@redhat.com> | 2018-05-16 14:44:41 +0200 |
---|---|---|
committer | Tomáš Mráz <t8m@users.noreply.github.com> | 2018-05-16 14:44:41 +0200 |
commit | 9532d85871990d41ccd3d851fff10386a4925270 (patch) | |
tree | e91d7a8b1e8ab371393bb19fb308521030ff83de /modules/pam_motd | |
parent | 042a387924acb3f7dd36ec48f123127500ceca8f (diff) | |
download | pam-9532d85871990d41ccd3d851fff10386a4925270.tar.gz pam-9532d85871990d41ccd3d851fff10386a4925270.tar.bz2 pam-9532d85871990d41ccd3d851fff10386a4925270.zip |
pam_motd: add support for a motd.d directory (#48)
Add a new feature to pam_motd to allow packages to install their own
message files in a "motd.d" directory, to be displayed after the primary
motd.
Add an option motd_d= to specify the location of this directory.
Modify the defaults, in the case where no options are given, to display
both /etc/motd and /etc/motd.d.
Fixes #47
* modules/pam_motd/pam_motd.c: add support for motd.d
* modules/pam_motd/pam_motd.8.xml: update the manpage
Diffstat (limited to 'modules/pam_motd')
-rw-r--r-- | modules/pam_motd/pam_motd.8.xml | 36 | ||||
-rw-r--r-- | modules/pam_motd/pam_motd.c | 100 |
2 files changed, 108 insertions, 28 deletions
diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml index ff92154e..906c4ed0 100644 --- a/modules/pam_motd/pam_motd.8.xml +++ b/modules/pam_motd/pam_motd.8.xml @@ -52,7 +52,24 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <option>motd_dir=<replaceable>/path/dirname.d</replaceable></option> + </term> + <listitem> + <para> + The <filename>/path/dirname.d</filename> directory is scanned + and each file contained inside of it is displayed. + </para> + </listitem> + </varlistentry> </variablelist> + <para> + When no options are given, the default is to display both + <filename>/etc/motd</filename> and the contents of + <filename>/etc/motd.d</filename>. Specifying either option (or both) + will disable this default behavior. + </para> </refsect1> <refsect1 id="pam_motd-types"> @@ -81,7 +98,20 @@ <para> The suggested usage for <filename>/etc/pam.d/login</filename> is: <programlisting> -session optional pam_motd.so motd=/etc/motd +session optional pam_motd.so + </programlisting> + </para> + <para> + To use a <filename>motd</filename> file from a different location: + <programlisting> +session optional pam_motd.so motd=/elsewhere/motd + </programlisting> + </para> + <para> + To use a <filename>motd</filename> file from elsewhere, along with a + corresponding <filename>.d</filename> directory: + <programlisting> +session optional pam_motd.so motd=/elsewhere/motd motd_dir=/elsewhere/motd.d </programlisting> </para> </refsect1> @@ -109,6 +139,10 @@ session optional pam_motd.so motd=/etc/motd <para> pam_motd was written by Ben Collins <bcollins@debian.org>. </para> + <para> + The <option>motd_dir=</option> option was added by + Allison Karlitskaya <allison.karlitskaya@redhat.com>. + </para> </refsect1> </refentry> diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c index 11c7b565..cc828d7e 100644 --- a/modules/pam_motd/pam_motd.c +++ b/modules/pam_motd/pam_motd.c @@ -17,6 +17,7 @@ #include <stdlib.h> #include <unistd.h> #include <fcntl.h> +#include <dirent.h> #include <sys/types.h> #include <sys/stat.h> #include <pwd.h> @@ -33,6 +34,7 @@ #define PAM_SM_SESSION #define DEFAULT_MOTD "/etc/motd" +#define DEFAULT_MOTD_D "/etc/motd.d" #include <security/pam_modules.h> #include <security/pam_modutil.h> @@ -47,14 +49,60 @@ pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, } static char default_motd[] = DEFAULT_MOTD; +static char default_motd_dir[] = DEFAULT_MOTD_D; + +static void try_to_display_fd(pam_handle_t *pamh, int fd) +{ + struct stat st; + char *mtmp = NULL; + + /* fill in message buffer with contents of motd */ + if ((fstat(fd, &st) < 0) || !st.st_size || st.st_size > 0x10000) + return; + + if (!(mtmp = malloc(st.st_size+1))) + return; + + if (pam_modutil_read(fd, mtmp, st.st_size) == st.st_size) { + if (mtmp[st.st_size-1] == '\n') + mtmp[st.st_size-1] = '\0'; + else + mtmp[st.st_size] = '\0'; + + pam_info (pamh, "%s", mtmp); + } + + _pam_drop(mtmp); +} + +static void try_to_display_directory(pam_handle_t *pamh, const char *dirname) +{ + DIR *dirp; + + dirp = opendir(dirname); + + if (dirp != NULL) { + struct dirent *entry; + + while ((entry = readdir(dirp))) { + int fd = openat(dirfd(dirp), entry->d_name, O_RDONLY); + + if (fd >= 0) { + try_to_display_fd(pamh, fd); + close(fd); + } + } + + closedir(dirp); + } +} int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval = PAM_IGNORE; - int fd; const char *motd_path = NULL; - char *mtmp = NULL; + const char *motd_dir_path = NULL; if (flags & PAM_SILENT) { return retval; @@ -72,41 +120,39 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, "motd= specification missing argument - ignored"); } } + else if (!strncmp(*argv,"motd_dir=",9)) { + + motd_dir_path = 9 + *argv; + if (*motd_dir_path != '\0') { + D(("set motd.d path: %s", motd_dir_path)); + } else { + motd_dir_path = NULL; + pam_syslog(pamh, LOG_ERR, + "motd_dir= specification missing argument - ignored"); + } + } else pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); } - if (motd_path == NULL) + if (motd_path == NULL && motd_dir_path == NULL) { motd_path = default_motd; + motd_dir_path = default_motd_dir; + } - while ((fd = open(motd_path, O_RDONLY, 0)) >= 0) { - struct stat st; - - /* fill in message buffer with contents of motd */ - if ((fstat(fd, &st) < 0) || !st.st_size || st.st_size > 0x10000) - break; - - if (!(mtmp = malloc(st.st_size+1))) - break; - - if (pam_modutil_read(fd, mtmp, st.st_size) != st.st_size) - break; + if (motd_path != NULL) { + int fd = open(motd_path, O_RDONLY, 0); - if (mtmp[st.st_size-1] == '\n') - mtmp[st.st_size-1] = '\0'; - else - mtmp[st.st_size] = '\0'; - - pam_info (pamh, "%s", mtmp); - break; + if (fd >= 0) { + try_to_display_fd(pamh, fd); + close(fd); + } } - _pam_drop (mtmp); - - if (fd >= 0) - close(fd); + if (motd_dir_path != NULL) + try_to_display_directory(pamh, motd_dir_path); - return retval; + return retval; } /* end of module definition */ |