119843Sdist /* 219843Sdist * Copyright (c) 1980 Regents of the University of California. 319843Sdist * All rights reserved. The Berkeley software License Agreement 419843Sdist * specifies the terms and conditions for redistribution. 519843Sdist */ 619843Sdist 712678Ssam #ifndef lint 819843Sdist char copyright[] = 919843Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1019843Sdist All rights reserved.\n"; 1119843Sdist #endif not lint 1212678Ssam 1319843Sdist #ifndef lint 14*30606Sbostic static char sccsid[] = "@(#)login.c 5.17 (Berkeley) 03/11/87"; 1519843Sdist #endif not lint 1619843Sdist 171043Sbill /* 181043Sbill * login [ name ] 1912687Ssam * login -r hostname (for rlogind) 2012687Ssam * login -h hostname (for telnetd, etc.) 211043Sbill */ 221043Sbill 2312984Ssam #include <sys/param.h> 2412687Ssam #include <sys/quota.h> 2512687Ssam #include <sys/stat.h> 2612687Ssam #include <sys/time.h> 2712687Ssam #include <sys/resource.h> 2816453Sroot #include <sys/file.h> 2912687Ssam 301043Sbill #include <sgtty.h> 311043Sbill #include <utmp.h> 321043Sbill #include <signal.h> 331043Sbill #include <pwd.h> 341043Sbill #include <stdio.h> 351043Sbill #include <lastlog.h> 3612678Ssam #include <errno.h> 3716453Sroot #include <ttyent.h> 3816453Sroot #include <syslog.h> 3926862Smckusick #include <grp.h> 401043Sbill 4127056Skarels #define TTYGRPNAME "tty" /* name of group to own ttys */ 4227056Skarels #define TTYGID(gid) tty_gid(gid) /* gid that owns all ttys */ 4326862Smckusick 4416453Sroot #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 452822Swnj #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 462822Swnj 476197Sroot #define NMAX sizeof(utmp.ut_name) 4825230Smckusick #define HMAX sizeof(utmp.ut_host) 491043Sbill 502822Swnj #define FALSE 0 512822Swnj #define TRUE -1 522822Swnj 532822Swnj char nolog[] = "/etc/nologin"; 542822Swnj char qlog[] = ".hushlogin"; 551043Sbill char maildir[30] = "/usr/spool/mail/"; 561043Sbill char lastlog[] = "/usr/adm/lastlog"; 579867Ssam struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" }; 581043Sbill struct sgttyb ttyb; 591043Sbill struct utmp utmp; 601043Sbill char minusnam[16] = "-"; 61*30606Sbostic char *envinit[1]; /* now set by setenv calls */ 6212687Ssam /* 6312687Ssam * This bounds the time given to login. We initialize it here 6412687Ssam * so it can be patched on machines where it's too small. 6512687Ssam */ 6612687Ssam int timeout = 60; 676005Swnj 6818549Ssam char term[64]; 696005Swnj 701043Sbill struct passwd *pwd; 71*30606Sbostic char *strcat(), *rindex(), *index(); 7212687Ssam int timedout(); 731043Sbill char *ttyname(); 741043Sbill char *crypt(); 751043Sbill char *getpass(); 761043Sbill char *stypeof(); 7712678Ssam extern int errno; 781043Sbill 7913074Ssam struct tchars tc = { 8013074Ssam CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 811365Sbill }; 8213074Ssam struct ltchars ltc = { 8313074Ssam CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT 8413074Ssam }; 851365Sbill 8618549Ssam struct winsize win = { 0, 0, 0, 0 }; 8718549Ssam 886005Swnj int rflag; 8924712Sbloom int usererr = -1; 906197Sroot char rusername[NMAX+1], lusername[NMAX+1]; 916005Swnj char rpassword[NMAX+1]; 926878Smckusick char name[NMAX+1]; 9329992Skarels char me[MAXHOSTNAMELEN]; 946197Sroot char *rhost; 956005Swnj 961043Sbill main(argc, argv) 9712687Ssam char *argv[]; 981043Sbill { 99*30606Sbostic extern char **environ; 1001043Sbill register char *namep; 10118549Ssam int pflag = 0, hflag = 0, t, f, c; 10212687Ssam int invalid, quietlog; 1032822Swnj FILE *nlfd; 10416453Sroot char *ttyn, *tty; 10518549Ssam int ldisc = 0, zero = 0, i; 10629992Skarels char *p, *domain, *index(); 1071043Sbill 10812687Ssam signal(SIGALRM, timedout); 10912687Ssam alarm(timeout); 1101043Sbill signal(SIGQUIT, SIG_IGN); 1111043Sbill signal(SIGINT, SIG_IGN); 11212687Ssam setpriority(PRIO_PROCESS, 0, 0); 11312678Ssam quota(Q_SETUID, 0, 0, 0); 11412687Ssam /* 11518549Ssam * -p is used by getty to tell login not to destroy the environment 11612687Ssam * -r is used by rlogind to cause the autologin protocol; 11712687Ssam * -h is used by other servers to pass the name of the 11812687Ssam * remote host to login so that it may be placed in utmp and wtmp 11912687Ssam */ 12029992Skarels (void) gethostname(me, sizeof(me)); 12129992Skarels domain = index(me, '.'); 12224712Sbloom while (argc > 1) { 12312687Ssam if (strcmp(argv[1], "-r") == 0) { 12424712Sbloom if (rflag || hflag) { 12524712Sbloom printf("Only one of -r and -h allowed\n"); 12624712Sbloom exit(1); 12724712Sbloom } 12824712Sbloom rflag = 1; 12924712Sbloom usererr = doremotelogin(argv[2]); 13029992Skarels if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) 13129992Skarels *p = 0; 13212687Ssam SCPYN(utmp.ut_host, argv[2]); 13324712Sbloom argc -= 2; 13424712Sbloom argv += 2; 13524712Sbloom continue; 1366197Sroot } 13712687Ssam if (strcmp(argv[1], "-h") == 0 && getuid() == 0) { 13824712Sbloom if (rflag || hflag) { 13924712Sbloom printf("Only one of -r and -h allowed\n"); 14024712Sbloom exit(1); 14124712Sbloom } 14218549Ssam hflag = 1; 14329992Skarels if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) 14429992Skarels *p = 0; 14512687Ssam SCPYN(utmp.ut_host, argv[2]); 14624712Sbloom argc -= 2; 14724712Sbloom argv += 2; 14824712Sbloom continue; 1496197Sroot } 15018549Ssam if (strcmp(argv[1], "-p") == 0) { 15118549Ssam argc--; 15218549Ssam argv++; 15318549Ssam pflag = 1; 15424712Sbloom continue; 15518549Ssam } 15624712Sbloom break; 1576005Swnj } 15813074Ssam ioctl(0, TIOCLSET, &zero); 1591547Sbill ioctl(0, TIOCNXCL, 0); 1606329Swnj ioctl(0, FIONBIO, &zero); 1616329Swnj ioctl(0, FIOASYNC, &zero); 16213074Ssam ioctl(0, TIOCGETP, &ttyb); 16312687Ssam /* 16412687Ssam * If talking to an rlogin process, 16512687Ssam * propagate the terminal type and 16612687Ssam * baud rate across the network. 16712687Ssam */ 16812687Ssam if (rflag) 16912687Ssam doremoteterm(term, &ttyb); 17026482Skarels ttyb.sg_erase = CERASE; 17126482Skarels ttyb.sg_kill = CKILL; 17213074Ssam ioctl(0, TIOCSLTC, <c); 17313074Ssam ioctl(0, TIOCSETC, &tc); 17413074Ssam ioctl(0, TIOCSETP, &ttyb); 17524849Smckusick for (t = getdtablesize(); t > 2; t--) 1761043Sbill close(t); 1771043Sbill ttyn = ttyname(0); 17825426Sbloom if (ttyn == (char *)0 || *ttyn == '\0') 1791043Sbill ttyn = "/dev/tty??"; 18016453Sroot tty = rindex(ttyn, '/'); 18116453Sroot if (tty == NULL) 18216453Sroot tty = ttyn; 18316453Sroot else 18416453Sroot tty++; 18524852Seric openlog("login", LOG_ODELAY, LOG_AUTH); 18616453Sroot t = 0; 18725163Sbloom invalid = FALSE; 1882822Swnj do { 1892822Swnj ldisc = 0; 1902822Swnj ioctl(0, TIOCSETD, &ldisc); 1912822Swnj SCPYN(utmp.ut_name, ""); 19212687Ssam /* 19312687Ssam * Name specified, take it. 19412687Ssam */ 19512687Ssam if (argc > 1) { 1962822Swnj SCPYN(utmp.ut_name, argv[1]); 1972822Swnj argc = 0; 1981043Sbill } 19912687Ssam /* 20012687Ssam * If remote login take given name, 20112687Ssam * otherwise prompt user for something. 20212687Ssam */ 20325163Sbloom if (rflag && !invalid) 2049867Ssam SCPYN(utmp.ut_name, lusername); 20524883Smckusick else 20612687Ssam getloginname(&utmp); 20725163Sbloom invalid = FALSE; 2082822Swnj if (!strcmp(pwd->pw_shell, "/bin/csh")) { 2092822Swnj ldisc = NTTYDISC; 2102822Swnj ioctl(0, TIOCSETD, &ldisc); 2112822Swnj } 21212687Ssam /* 21312687Ssam * If no remote login authentication and 21412687Ssam * a password exists for this user, prompt 21512687Ssam * for one and verify it. 21612687Ssam */ 21724712Sbloom if (usererr == -1 && *pwd->pw_passwd != '\0') { 21812687Ssam char *pp; 21912687Ssam 22012687Ssam setpriority(PRIO_PROCESS, 0, -4); 22112687Ssam pp = getpass("Password:"); 22212687Ssam namep = crypt(pp, pwd->pw_passwd); 22312687Ssam setpriority(PRIO_PROCESS, 0, 0); 22412687Ssam if (strcmp(namep, pwd->pw_passwd)) 22512687Ssam invalid = TRUE; 2262822Swnj } 22712687Ssam /* 22812687Ssam * If user not super-user, check for logins disabled. 22912687Ssam */ 2302822Swnj if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { 2312822Swnj while ((c = getc(nlfd)) != EOF) 2322822Swnj putchar(c); 2332822Swnj fflush(stdout); 2342822Swnj sleep(5); 2352822Swnj exit(0); 2362822Swnj } 23712687Ssam /* 23812687Ssam * If valid so far and root is logging in, 23912687Ssam * see if root logins on this terminal are permitted. 24012687Ssam */ 24116453Sroot if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) { 24225230Smckusick if (utmp.ut_host[0]) 24325230Smckusick syslog(LOG_CRIT, 24425230Smckusick "ROOT LOGIN REFUSED ON %s FROM %.*s", 24525230Smckusick tty, HMAX, utmp.ut_host); 24625230Smckusick else 24725230Smckusick syslog(LOG_CRIT, 24825230Smckusick "ROOT LOGIN REFUSED ON %s", tty); 2492822Swnj invalid = TRUE; 2502822Swnj } 2512822Swnj if (invalid) { 2521043Sbill printf("Login incorrect\n"); 25316453Sroot if (++t >= 5) { 25425230Smckusick if (utmp.ut_host[0]) 25525230Smckusick syslog(LOG_CRIT, 25625230Smckusick "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", 25725230Smckusick tty, HMAX, utmp.ut_host, 25825230Smckusick NMAX, utmp.ut_name); 25925230Smckusick else 26025230Smckusick syslog(LOG_CRIT, 26125230Smckusick "REPEATED LOGIN FAILURES ON %s, %.*s", 26225230Smckusick tty, NMAX, utmp.ut_name); 26316453Sroot ioctl(0, TIOCHPCL, (struct sgttyb *) 0); 26418549Ssam close(0), close(1), close(2); 26516453Sroot sleep(10); 26616453Sroot exit(1); 26716453Sroot } 2681043Sbill } 2692822Swnj if (*pwd->pw_shell == '\0') 2702822Swnj pwd->pw_shell = "/bin/sh"; 2712822Swnj if (chdir(pwd->pw_dir) < 0 && !invalid ) { 2722822Swnj if (chdir("/") < 0) { 2732822Swnj printf("No directory!\n"); 2742822Swnj invalid = TRUE; 2752822Swnj } else { 27612687Ssam printf("No directory! %s\n", 27712687Ssam "Logging in with home=/"); 2782822Swnj pwd->pw_dir = "/"; 2792822Swnj } 2801043Sbill } 28112687Ssam /* 28212687Ssam * Remote login invalid must have been because 28312687Ssam * of a restriction of some sort, no extra chances. 28412687Ssam */ 28524712Sbloom if (!usererr && invalid) 2866005Swnj exit(1); 2872822Swnj } while (invalid); 28812687Ssam /* committed to login turn off timeout */ 28912687Ssam alarm(0); 2901043Sbill 29121083Smckusick if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { 29212678Ssam if (errno == EUSERS) 29312678Ssam printf("%s.\n%s.\n", 29412678Ssam "Too many users logged on already", 29512678Ssam "Try again later"); 29612678Ssam else if (errno == EPROCLIM) 29712678Ssam printf("You have too many processes running.\n"); 29812678Ssam else 29917664Sserge perror("quota (Q_SETUID)"); 30012678Ssam sleep(5); 30112678Ssam exit(0); 30212678Ssam } 3031043Sbill time(&utmp.ut_time); 3041043Sbill t = ttyslot(); 30516453Sroot if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { 3061043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 30716453Sroot SCPYN(utmp.ut_line, tty); 3081043Sbill write(f, (char *)&utmp, sizeof(utmp)); 3091043Sbill close(f); 3101043Sbill } 31116453Sroot if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { 3121043Sbill write(f, (char *)&utmp, sizeof(utmp)); 3131043Sbill close(f); 3141043Sbill } 31516453Sroot quietlog = access(qlog, F_OK) == 0; 31616453Sroot if ((f = open(lastlog, O_RDWR)) >= 0) { 3172822Swnj struct lastlog ll; 3182822Swnj 3192822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 3202822Swnj if (read(f, (char *) &ll, sizeof ll) == sizeof ll && 32112687Ssam ll.ll_time != 0 && !quietlog) { 32212687Ssam printf("Last login: %.*s ", 32312687Ssam 24-5, (char *)ctime(&ll.ll_time)); 32412687Ssam if (*ll.ll_host != '\0') 32512687Ssam printf("from %.*s\n", 32612687Ssam sizeof (ll.ll_host), ll.ll_host); 32712687Ssam else 32812687Ssam printf("on %.*s\n", 32912687Ssam sizeof (ll.ll_line), ll.ll_line); 3302822Swnj } 3312822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 3322822Swnj time(&ll.ll_time); 33316453Sroot SCPYN(ll.ll_line, tty); 33412687Ssam SCPYN(ll.ll_host, utmp.ut_host); 3352822Swnj write(f, (char *) &ll, sizeof ll); 3362822Swnj close(f); 3372822Swnj } 33827056Skarels chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid)); 33924849Smckusick if (!hflag && !rflag) /* XXX */ 34018549Ssam ioctl(0, TIOCSWINSZ, &win); 34126862Smckusick chmod(ttyn, 0620); 3421043Sbill setgid(pwd->pw_gid); 3436878Smckusick strncpy(name, utmp.ut_name, NMAX); 3446878Smckusick name[NMAX] = '\0'; 3459224Ssam initgroups(name, pwd->pw_gid); 34612678Ssam quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); 3471043Sbill setuid(pwd->pw_uid); 348*30606Sbostic 34918549Ssam /* destroy environment unless user has asked to preserve it */ 35018549Ssam if (!pflag) 35118549Ssam environ = envinit; 352*30606Sbostic setenv("HOME", pwd->pw_dir, 1); 353*30606Sbostic setenv("SHELL", pwd->pw_shell, 1); 35418549Ssam if (term[0] == '\0') 35518549Ssam strncpy(term, stypeof(tty), sizeof(term)); 356*30606Sbostic setenv("TERM", term, 0); 357*30606Sbostic setenv("USER", pwd->pw_name, 1); 358*30606Sbostic setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0); 35918549Ssam 3601043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 3611043Sbill namep = pwd->pw_shell; 3621043Sbill else 3631043Sbill namep++; 3641043Sbill strcat(minusnam, namep); 36516453Sroot if (tty[sizeof("tty")-1] == 'd') 36618549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 36718549Ssam if (pwd->pw_uid == 0) 36825230Smckusick if (utmp.ut_host[0]) 36925230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", 37025230Smckusick tty, HMAX, utmp.ut_host); 37125230Smckusick else 37225230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); 3736329Swnj if (!quietlog) { 37417664Sserge struct stat st; 37518549Ssam 3762822Swnj showmotd(); 3772822Swnj strcat(maildir, pwd->pw_name); 37817664Sserge if (stat(maildir, &st) == 0 && st.st_size != 0) 37917664Sserge printf("You have %smail.\n", 38018549Ssam (st.st_mtime > st.st_atime) ? "new " : ""); 3812822Swnj } 38212687Ssam signal(SIGALRM, SIG_DFL); 3831043Sbill signal(SIGQUIT, SIG_DFL); 3841043Sbill signal(SIGINT, SIG_DFL); 3853935Sroot signal(SIGTSTP, SIG_IGN); 3861043Sbill execlp(pwd->pw_shell, minusnam, 0); 3872822Swnj perror(pwd->pw_shell); 3881043Sbill printf("No shell\n"); 3891043Sbill exit(0); 3901043Sbill } 3911043Sbill 39212687Ssam getloginname(up) 39312687Ssam register struct utmp *up; 39412687Ssam { 39512687Ssam register char *namep; 39612712Ssam char c; 39712687Ssam 39812687Ssam while (up->ut_name[0] == '\0') { 39914897Sedward namep = up->ut_name; 40012712Ssam printf("login: "); 40112687Ssam while ((c = getchar()) != '\n') { 40212687Ssam if (c == ' ') 40312687Ssam c = '_'; 40412687Ssam if (c == EOF) 40512687Ssam exit(0); 40612687Ssam if (namep < up->ut_name+NMAX) 40712687Ssam *namep++ = c; 40812687Ssam } 40912687Ssam } 41014897Sedward strncpy(lusername, up->ut_name, NMAX); 41114897Sedward lusername[NMAX] = 0; 41214897Sedward if ((pwd = getpwnam(lusername)) == NULL) 41312687Ssam pwd = &nouser; 41412687Ssam } 41512687Ssam 41612687Ssam timedout() 41712687Ssam { 41812687Ssam 41912687Ssam printf("Login timed out after %d seconds\n", timeout); 42012687Ssam exit(0); 42112687Ssam } 42212687Ssam 4231043Sbill int stopmotd; 4241043Sbill catch() 4251043Sbill { 4266466Swnj 4271043Sbill signal(SIGINT, SIG_IGN); 4281043Sbill stopmotd++; 4291043Sbill } 4301043Sbill 4312822Swnj rootterm(tty) 4326466Swnj char *tty; 4332822Swnj { 43416453Sroot register struct ttyent *t; 4352822Swnj 43616453Sroot if ((t = getttynam(tty)) != NULL) { 43716453Sroot if (t->ty_status & TTY_SECURE) 43816453Sroot return (1); 4392822Swnj } 44016453Sroot return (0); 4412822Swnj } 4422822Swnj 4431043Sbill showmotd() 4441043Sbill { 4451043Sbill FILE *mf; 4461043Sbill register c; 4471043Sbill 4481043Sbill signal(SIGINT, catch); 44916453Sroot if ((mf = fopen("/etc/motd", "r")) != NULL) { 4502822Swnj while ((c = getc(mf)) != EOF && stopmotd == 0) 4511043Sbill putchar(c); 4521043Sbill fclose(mf); 4531043Sbill } 4541043Sbill signal(SIGINT, SIG_IGN); 4551043Sbill } 4561043Sbill 4572822Swnj #undef UNKNOWN 4581043Sbill #define UNKNOWN "su" 4591043Sbill 4601043Sbill char * 4611043Sbill stypeof(ttyid) 46212687Ssam char *ttyid; 4631043Sbill { 46416453Sroot register struct ttyent *t; 4651043Sbill 46616453Sroot if (ttyid == NULL || (t = getttynam(ttyid)) == NULL) 4671043Sbill return (UNKNOWN); 46816453Sroot return (t->ty_type); 4691043Sbill } 4706005Swnj 47112687Ssam doremotelogin(host) 47212687Ssam char *host; 47312687Ssam { 47412687Ssam getstr(rusername, sizeof (rusername), "remuser"); 47512687Ssam getstr(lusername, sizeof (lusername), "locuser"); 47618549Ssam getstr(term, sizeof(term), "Terminal type"); 47713470Ssam if (getuid()) { 47813470Ssam pwd = &nouser; 47924712Sbloom return(-1); 48013470Ssam } 48112687Ssam pwd = getpwnam(lusername); 48213470Ssam if (pwd == NULL) { 48313470Ssam pwd = &nouser; 48424712Sbloom return(-1); 48513470Ssam } 48624712Sbloom return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername)); 48712687Ssam } 48812687Ssam 4896005Swnj getstr(buf, cnt, err) 4906005Swnj char *buf; 4916005Swnj int cnt; 4926005Swnj char *err; 4936005Swnj { 4946005Swnj char c; 4956005Swnj 4966005Swnj do { 4976005Swnj if (read(0, &c, 1) != 1) 4986005Swnj exit(1); 4996005Swnj if (--cnt < 0) { 5006005Swnj printf("%s too long\r\n", err); 5016005Swnj exit(1); 5026005Swnj } 5036005Swnj *buf++ = c; 5046005Swnj } while (c != 0); 5056005Swnj } 5066329Swnj 50712687Ssam char *speeds[] = 50812687Ssam { "0", "50", "75", "110", "134", "150", "200", "300", 50912687Ssam "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; 51012687Ssam #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0])) 51112687Ssam 51212687Ssam doremoteterm(term, tp) 51312687Ssam char *term; 51412687Ssam struct sgttyb *tp; 51512687Ssam { 51618549Ssam register char *cp = index(term, '/'), **cpp; 51718549Ssam char *speed; 51812687Ssam 51912687Ssam if (cp) { 52018549Ssam *cp++ = '\0'; 52118549Ssam speed = cp; 52218549Ssam cp = index(speed, '/'); 52318549Ssam if (cp) 52418549Ssam *cp++ = '\0'; 52518549Ssam for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 52618549Ssam if (strcmp(*cpp, speed) == 0) { 52718549Ssam tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; 52812687Ssam break; 52912687Ssam } 53012687Ssam } 53112687Ssam tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; 53212687Ssam } 53318549Ssam 53427056Skarels tty_gid(default_gid) 53526876Smckusick int default_gid; 53626862Smckusick { 53726862Smckusick struct group *getgrnam(), *gr; 53826876Smckusick int gid = default_gid; 53926862Smckusick 54027056Skarels gr = getgrnam(TTYGRPNAME); 54126862Smckusick if (gr != (struct group *) 0) 54226862Smckusick gid = gr->gr_gid; 54326862Smckusick 54426862Smckusick endgrent(); 54526862Smckusick 54626876Smckusick return (gid); 54726862Smckusick } 548