summaryrefslogtreecommitdiffstats
path: root/login-utils/login.c
diff options
context:
space:
mode:
authorOndrej Oprala2014-04-08 13:26:33 +0200
committerKarel Zak2014-05-15 13:55:59 +0200
commit78dd74508931a2990a20f973854e0749505fdea0 (patch)
tree19421097ccabbb7f14649764cfcdab552ac77677 /login-utils/login.c
parentlslogins: move to login-utils (diff)
downloadkernel-qcow2-util-linux-78dd74508931a2990a20f973854e0749505fdea0.tar.gz
kernel-qcow2-util-linux-78dd74508931a2990a20f973854e0749505fdea0.tar.xz
kernel-qcow2-util-linux-78dd74508931a2990a20f973854e0749505fdea0.zip
login: extract get_hushlogin_status
Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
Diffstat (limited to 'login-utils/login.c')
-rw-r--r--login-utils/login.c118
1 files changed, 0 insertions, 118 deletions
diff --git a/login-utils/login.c b/login-utils/login.c
index 89df48955..b16a81231 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -921,124 +921,6 @@ static void loginpam_session(struct login_context *cxt)
}
/*
- * We need to check the effective UID/GID. For example, $HOME could be on a
- * root-squashed NFS or on an NFS with UID mapping, and access(2) uses the
- * real UID/GID. Then open(2) seems as the surest solution.
- * -- kzak@redhat.com (10-Apr-2009)
- */
-static int effective_access(const char *path, int mode)
-{
- int fd = open(path, mode);
- if (fd != -1)
- close(fd);
- return fd == -1 ? -1 : 0;
-}
-
-/*
- * Check the per-account or the global hush-login setting.
- *
- * Hushed mode is enabled:
- *
- * a) if a global (e.g. /etc/hushlogins) hush file exists:
- * 1) for ALL ACCOUNTS if the file is empty
- * 2) for the current user if the username or shell is found in the file
- *
- * b) if a ~/.hushlogin file exists
- *
- * The ~/.hushlogin file is ignored if the global hush file exists.
- *
- * The HUSHLOGIN_FILE login.def variable overrides the default hush filename.
- *
- * Note that shadow-utils login(1) does not support "a1)". The "a1)" is
- * necessary if you want to use PAM for "Last login" message.
- *
- * -- Karel Zak <kzak@redhat.com> (26-Aug-2011)
- *
- *
- * The per-account check requires some explanation: As root we may not be able
- * to read the directory of the user if it is on an NFS-mounted filesystem. We
- * temporarily set our effective uid to the user-uid, making sure that we keep
- * root privileges in the real uid.
- *
- * A portable solution would require a fork(), but we rely on Linux having the
- * BSD setreuid().
- */
-static int get_hushlogin_status(struct passwd *pwd)
-{
- const char *files[] = { _PATH_HUSHLOGINS, _PATH_HUSHLOGIN, NULL };
- const char *file;
- char buf[BUFSIZ];
- int i;
-
- file = getlogindefs_str("HUSHLOGIN_FILE", NULL);
- if (file) {
- if (!*file)
- return 0; /* empty HUSHLOGIN_FILE defined */
-
- files[0] = file;
- files[1] = NULL;
- }
-
- for (i = 0; files[i]; i++) {
- int ok = 0;
-
- file = files[i];
-
- /* global hush-file */
- if (*file == '/') {
- struct stat st;
- FILE *f;
-
- if (stat(file, &st) != 0)
- continue; /* file does not exist */
-
- if (st.st_size == 0)
- return 1; /* for all accounts */
-
- f = fopen(file, "r");
- if (!f)
- continue; /* ignore errors... */
-
- while (ok == 0 && fgets(buf, sizeof(buf), f)) {
- buf[strlen(buf) - 1] = '\0';
- ok = !strcmp(buf, *buf == '/' ? pwd->pw_shell :
- pwd->pw_name);
- }
- fclose(f);
- if (ok)
- return 1; /* found username/shell */
-
- return 0; /* ignore per-account files */
- }
-
- /* per-account setting */
- if (strlen(pwd->pw_dir) + sizeof(file) + 2 > sizeof(buf))
- continue;
- else {
- uid_t ruid = getuid();
- gid_t egid = getegid();
-
- sprintf(buf, "%s/%s", pwd->pw_dir, file);
-
- if (setregid(-1, pwd->pw_gid) == 0 &&
- setreuid(0, pwd->pw_uid) == 0)
- ok = effective_access(buf, O_RDONLY) == 0;
-
- if (setuid(0) != 0 ||
- setreuid(ruid, 0) != 0 ||
- setregid(-1, egid) != 0) {
- syslog(LOG_ALERT, _("hush login status: restore original IDs failed"));
- exit(EXIT_FAILURE);
- }
- if (ok)
- return 1; /* enabled by user */
- }
- }
-
- return 0;
-}
-
-/*
* Detach the controlling terminal, fork, restore syslog stuff, and create
* a new session.
*/