URI: 
       login.c - ubase - suckless linux base utils
  HTML git clone git://git.suckless.org/ubase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       login.c (2363B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <sys/ioctl.h>
            3 #include <sys/types.h>
            4 
            5 #include <errno.h>
            6 #include <grp.h>
            7 #include <pwd.h>
            8 #include <stdio.h>
            9 #include <stdlib.h>
           10 #include <string.h>
           11 #include <time.h>
           12 #include <unistd.h>
           13 #include <utmp.h>
           14 
           15 #include "config.h"
           16 #include "passwd.h"
           17 #include "util.h"
           18 
           19 /* Write utmp entry */
           20 static void
           21 writeutmp(const char *user, const char *tty)
           22 {
           23         struct utmp usr;
           24         FILE *fp;
           25 
           26         memset(&usr, 0, sizeof(usr));
           27 
           28         usr.ut_type = USER_PROCESS;
           29         usr.ut_pid = getpid();
           30         strlcpy(usr.ut_user, user, sizeof(usr.ut_user));
           31         strlcpy(usr.ut_line, tty, sizeof(usr.ut_line));
           32         usr.ut_tv.tv_sec = time(NULL);
           33 
           34         fp = fopen(UTMP_PATH, "a");
           35         if (fp) {
           36                 if (fwrite(&usr, sizeof(usr), 1, fp) != 1)
           37                         if (ferror(fp))
           38                                 weprintf("%s: write error:", UTMP_PATH);
           39                 fclose(fp);
           40         } else {
           41                 weprintf("fopen %s:", UTMP_PATH);
           42         }
           43 }
           44 
           45 static int
           46 dologin(struct passwd *pw, int preserve)
           47 {
           48         char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell;
           49 
           50         if (preserve == 0)
           51                 clearenv();
           52         setenv("HOME", pw->pw_dir, 1);
           53         setenv("SHELL", shell, 1);
           54         setenv("USER", pw->pw_name, 1);
           55         setenv("LOGNAME", pw->pw_name, 1);
           56         setenv("PATH", ENV_PATH, 1);
           57         if (chdir(pw->pw_dir) < 0)
           58                 eprintf("chdir %s:", pw->pw_dir);
           59         execlp(shell, shell, "-l", NULL);
           60         weprintf("execlp %s:", shell);
           61         return (errno == ENOENT) ? 127 : 126;
           62 }
           63 
           64 static void
           65 usage(void)
           66 {
           67         eprintf("usage: %s [-p] username\n", argv0);
           68 }
           69 
           70 int
           71 main(int argc, char *argv[])
           72 {
           73         struct passwd *pw;
           74         char *pass, *user;
           75         char *tty;
           76         uid_t uid;
           77         gid_t gid;
           78         int pflag = 0;
           79 
           80         ARGBEGIN {
           81         case 'p':
           82                 pflag = 1;
           83                 break;
           84         default:
           85                 usage();
           86         } ARGEND;
           87 
           88         if (argc < 1)
           89                 usage();
           90 
           91         if (isatty(0) == 0 || isatty(1) == 0 || isatty(2) == 0)
           92                 eprintf("no tty");
           93 
           94         user = argv[0];
           95         errno = 0;
           96         pw = getpwnam(user);
           97         if (!pw) {
           98                 if (errno)
           99                         eprintf("getpwnam %s:", user);
          100                 else
          101                         eprintf("who are you?\n");
          102         }
          103 
          104         uid = pw->pw_uid;
          105         gid = pw->pw_gid;
          106 
          107         /* Flush pending input */
          108         ioctl(0, TCFLSH, (void *)0);
          109 
          110         pass = getpass("Password: ");
          111         if (!pass)
          112                 eprintf("getpass:");
          113         if (pw_check(pw, pass) <= 0)
          114                 exit(1);
          115 
          116         tty = ttyname(0);
          117         if (!tty)
          118                 eprintf("ttyname:");
          119 
          120         writeutmp(user, tty);
          121 
          122         if (initgroups(user, gid) < 0)
          123                 eprintf("initgroups:");
          124         if (setgid(gid) < 0)
          125                 eprintf("setgid:");
          126         if (setuid(uid) < 0)
          127                 eprintf("setuid:");
          128 
          129         return dologin(pw, pflag);
          130 }