1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <stdio.h> 33*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 34*7c478bd9Sstevel@tonic-gate #include <unistd.h> 35*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 36*7c478bd9Sstevel@tonic-gate #include <errno.h> 37*7c478bd9Sstevel@tonic-gate #include <ctype.h> 38*7c478bd9Sstevel@tonic-gate #include <string.h> 39*7c478bd9Sstevel@tonic-gate #include <signal.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 41*7c478bd9Sstevel@tonic-gate #include <utmpx.h> 42*7c478bd9Sstevel@tonic-gate #include <pwd.h> 43*7c478bd9Sstevel@tonic-gate #include <dirent.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/acl.h> 46*7c478bd9Sstevel@tonic-gate #include "ttymon.h" 47*7c478bd9Sstevel@tonic-gate #include "tmextern.h" 48*7c478bd9Sstevel@tonic-gate #include "tmstruct.h" 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate static char devbuf[BUFSIZ]; 51*7c478bd9Sstevel@tonic-gate static char *devname; 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate static int parse_args(); 54*7c478bd9Sstevel@tonic-gate static void ttymon_options(); 55*7c478bd9Sstevel@tonic-gate static void getty_options(); 56*7c478bd9Sstevel@tonic-gate static void usage(); 57*7c478bd9Sstevel@tonic-gate static char *find_ttyname(); 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate extern void tmchild(); 60*7c478bd9Sstevel@tonic-gate extern int vml(); 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate void revokedevaccess(char *, uid_t, gid_t, mode_t); 63*7c478bd9Sstevel@tonic-gate /* cannot include libdevinfo.h */ 64*7c478bd9Sstevel@tonic-gate extern int di_devperm_logout(const char *); 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * ttymon_express - This is call when ttymon is invoked with args 68*7c478bd9Sstevel@tonic-gate * or invoked as getty 69*7c478bd9Sstevel@tonic-gate * - This special version of ttymon will monitor 70*7c478bd9Sstevel@tonic-gate * one port only 71*7c478bd9Sstevel@tonic-gate * - It is intended to be used when some process 72*7c478bd9Sstevel@tonic-gate * wants to have a login session on the fly 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate void 75*7c478bd9Sstevel@tonic-gate ttymon_express(int argc, char **argv) 76*7c478bd9Sstevel@tonic-gate { 77*7c478bd9Sstevel@tonic-gate struct pmtab *pmtab; 78*7c478bd9Sstevel@tonic-gate struct sigaction sigact; 79*7c478bd9Sstevel@tonic-gate extern int Retry; 80*7c478bd9Sstevel@tonic-gate extern void open_device(); 81*7c478bd9Sstevel@tonic-gate extern void read_ttydefs(); 82*7c478bd9Sstevel@tonic-gate extern int checkut_line(); 83*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 84*7c478bd9Sstevel@tonic-gate extern FILE *Debugfp; 85*7c478bd9Sstevel@tonic-gate extern void opendebug(); 86*7c478bd9Sstevel@tonic-gate #endif 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 89*7c478bd9Sstevel@tonic-gate opendebug(TRUE); 90*7c478bd9Sstevel@tonic-gate #endif 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate sigact.sa_flags = 0; 93*7c478bd9Sstevel@tonic-gate sigact.sa_handler = SIG_IGN; 94*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&sigact.sa_mask); 95*7c478bd9Sstevel@tonic-gate (void) sigaction(SIGINT, &sigact, NULL); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate if ((pmtab = ALLOC_PMTAB) == PNULL) { 98*7c478bd9Sstevel@tonic-gate log("ttymon_express: ALLOC_PMTAB failed"); 99*7c478bd9Sstevel@tonic-gate exit(1); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate if (parse_args(argc, argv, pmtab) != 0) { 103*7c478bd9Sstevel@tonic-gate log("ttymon_express: parse_args failed"); 104*7c478bd9Sstevel@tonic-gate exit(1); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate read_ttydefs(NULL, FALSE); 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate if ((pmtab->p_device != NULL) && (*(pmtab->p_device) != '\0') && 110*7c478bd9Sstevel@tonic-gate strcmp(pmtab->p_device, "/dev/console") == 0) { 111*7c478bd9Sstevel@tonic-gate while (checkut_line(pmtab->p_device)) 112*7c478bd9Sstevel@tonic-gate sleep(15); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate if ((pmtab->p_device == NULL) || (*(pmtab->p_device) == '\0')) { 116*7c478bd9Sstevel@tonic-gate devname = find_ttyname(0); 117*7c478bd9Sstevel@tonic-gate if ((devname == NULL) || (*devname == '\0')) { 118*7c478bd9Sstevel@tonic-gate log("ttyname cannot find the device on fd 0"); 119*7c478bd9Sstevel@tonic-gate exit(1); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate pmtab->p_device = devname; 122*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 123*7c478bd9Sstevel@tonic-gate debug("ttymon_express: devname = %s", devname); 124*7c478bd9Sstevel@tonic-gate #endif 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * become session leader 127*7c478bd9Sstevel@tonic-gate * fd 0 is closed and reopened just to make sure 128*7c478bd9Sstevel@tonic-gate * controlling tty is set up right 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate (void) setsid(); 131*7c478bd9Sstevel@tonic-gate (void) close(0); 132*7c478bd9Sstevel@tonic-gate revokedevaccess(pmtab->p_device, 0, 0, 0); 133*7c478bd9Sstevel@tonic-gate if (open(pmtab->p_device, O_RDWR) < 0) { 134*7c478bd9Sstevel@tonic-gate log("open %s failed: %s", pmtab->p_device, 135*7c478bd9Sstevel@tonic-gate strerror(errno)); 136*7c478bd9Sstevel@tonic-gate exit(1); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate if ((pmtab->p_modules != NULL) && 139*7c478bd9Sstevel@tonic-gate (*(pmtab->p_modules) != '\0')) { 140*7c478bd9Sstevel@tonic-gate if (push_linedisc(0, pmtab->p_modules, 141*7c478bd9Sstevel@tonic-gate pmtab->p_device) == -1) 142*7c478bd9Sstevel@tonic-gate exit(1); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate if (initial_termio(0, pmtab) == -1) 145*7c478bd9Sstevel@tonic-gate exit(1); 146*7c478bd9Sstevel@tonic-gate di_devperm_logout((const char *)pmtab->p_device); 147*7c478bd9Sstevel@tonic-gate } else { 148*7c478bd9Sstevel@tonic-gate (void) setsid(); 149*7c478bd9Sstevel@tonic-gate (void) close(0); 150*7c478bd9Sstevel@tonic-gate Retry = FALSE; 151*7c478bd9Sstevel@tonic-gate open_device(pmtab); 152*7c478bd9Sstevel@tonic-gate if (Retry) /* open failed */ 153*7c478bd9Sstevel@tonic-gate exit(1); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate tmchild(pmtab); 156*7c478bd9Sstevel@tonic-gate exit(1); /*NOTREACHED*/ 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate /* 160*7c478bd9Sstevel@tonic-gate * parse_arg - parse cmd line arguments 161*7c478bd9Sstevel@tonic-gate */ 162*7c478bd9Sstevel@tonic-gate static int 163*7c478bd9Sstevel@tonic-gate parse_args(int argc, char **argv, struct pmtab *pmtab) 164*7c478bd9Sstevel@tonic-gate { 165*7c478bd9Sstevel@tonic-gate static char p_server[] = "/usr/bin/login"; 166*7c478bd9Sstevel@tonic-gate extern char *lastname(); 167*7c478bd9Sstevel@tonic-gate extern void getty_account(); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* initialize fields to some default first */ 170*7c478bd9Sstevel@tonic-gate pmtab->p_tag = ""; 171*7c478bd9Sstevel@tonic-gate pmtab->p_flags = 0; 172*7c478bd9Sstevel@tonic-gate pmtab->p_identity = "root"; 173*7c478bd9Sstevel@tonic-gate pmtab->p_res1 = "reserved"; 174*7c478bd9Sstevel@tonic-gate pmtab->p_res2 = "reserved"; 175*7c478bd9Sstevel@tonic-gate pmtab->p_res3 = "reserved"; 176*7c478bd9Sstevel@tonic-gate pmtab->p_uid = 0; 177*7c478bd9Sstevel@tonic-gate pmtab->p_gid = 0; 178*7c478bd9Sstevel@tonic-gate pmtab->p_dir = "/"; 179*7c478bd9Sstevel@tonic-gate pmtab->p_ttyflags = 0; 180*7c478bd9Sstevel@tonic-gate pmtab->p_count = 0; 181*7c478bd9Sstevel@tonic-gate pmtab->p_server = p_server; 182*7c478bd9Sstevel@tonic-gate pmtab->p_timeout = 0; 183*7c478bd9Sstevel@tonic-gate pmtab->p_modules = ""; 184*7c478bd9Sstevel@tonic-gate pmtab->p_prompt = "login: "; 185*7c478bd9Sstevel@tonic-gate pmtab->p_dmsg = ""; 186*7c478bd9Sstevel@tonic-gate pmtab->p_termtype = ""; 187*7c478bd9Sstevel@tonic-gate pmtab->p_device = ""; 188*7c478bd9Sstevel@tonic-gate pmtab->p_status = GETTY; 189*7c478bd9Sstevel@tonic-gate if (strcmp(lastname(argv[0]), "getty") == 0) { 190*7c478bd9Sstevel@tonic-gate pmtab->p_ttylabel = "300"; 191*7c478bd9Sstevel@tonic-gate getty_options(argc, argv, pmtab); 192*7c478bd9Sstevel@tonic-gate } else { 193*7c478bd9Sstevel@tonic-gate pmtab->p_ttylabel = "9600"; 194*7c478bd9Sstevel@tonic-gate ttymon_options(argc, argv, pmtab); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate if ((pmtab->p_device != NULL) && (*(pmtab->p_device) != '\0')) 197*7c478bd9Sstevel@tonic-gate getty_account(pmtab->p_device); /* utmp accounting */ 198*7c478bd9Sstevel@tonic-gate return (0); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* 203*7c478bd9Sstevel@tonic-gate * ttymon_options - scan and check args for ttymon express 204*7c478bd9Sstevel@tonic-gate */ 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate static void 207*7c478bd9Sstevel@tonic-gate ttymon_options(int argc, char **argv, struct pmtab *pmtab) 208*7c478bd9Sstevel@tonic-gate { 209*7c478bd9Sstevel@tonic-gate int c; /* option letter */ 210*7c478bd9Sstevel@tonic-gate char *timeout; 211*7c478bd9Sstevel@tonic-gate int gflag = 0; /* -g seen */ 212*7c478bd9Sstevel@tonic-gate int size = 0; 213*7c478bd9Sstevel@tonic-gate char tbuf[BUFSIZ]; 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate extern char *optarg; 216*7c478bd9Sstevel@tonic-gate extern int optind; 217*7c478bd9Sstevel@tonic-gate extern void copystr(); 218*7c478bd9Sstevel@tonic-gate extern char *strsave(); 219*7c478bd9Sstevel@tonic-gate extern char *getword(); 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "T:gd:ht:p:m:l:")) != -1) { 222*7c478bd9Sstevel@tonic-gate switch (c) { 223*7c478bd9Sstevel@tonic-gate case 'g': 224*7c478bd9Sstevel@tonic-gate gflag = 1; 225*7c478bd9Sstevel@tonic-gate break; 226*7c478bd9Sstevel@tonic-gate case 'd': 227*7c478bd9Sstevel@tonic-gate pmtab->p_device = optarg; 228*7c478bd9Sstevel@tonic-gate break; 229*7c478bd9Sstevel@tonic-gate case 'h': 230*7c478bd9Sstevel@tonic-gate pmtab->p_ttyflags &= ~H_FLAG; 231*7c478bd9Sstevel@tonic-gate break; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate case 'T': 234*7c478bd9Sstevel@tonic-gate pmtab->p_termtype = optarg; 235*7c478bd9Sstevel@tonic-gate break; 236*7c478bd9Sstevel@tonic-gate /* 237*7c478bd9Sstevel@tonic-gate * case 'b': 238*7c478bd9Sstevel@tonic-gate * pmtab->p_ttyflags |= B_FLAG; 239*7c478bd9Sstevel@tonic-gate * pmtab->p_ttyflags |= R_FLAG; 240*7c478bd9Sstevel@tonic-gate * break; 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate case 't': 243*7c478bd9Sstevel@tonic-gate timeout = optarg; 244*7c478bd9Sstevel@tonic-gate while (*optarg) { 245*7c478bd9Sstevel@tonic-gate if (!isdigit(*optarg++)) { 246*7c478bd9Sstevel@tonic-gate log("Invalid argument for " 247*7c478bd9Sstevel@tonic-gate "\"-t\" -- number expected."); 248*7c478bd9Sstevel@tonic-gate usage(); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate pmtab->p_timeout = atoi(timeout); 252*7c478bd9Sstevel@tonic-gate break; 253*7c478bd9Sstevel@tonic-gate case 'p': 254*7c478bd9Sstevel@tonic-gate copystr(tbuf, optarg); 255*7c478bd9Sstevel@tonic-gate pmtab->p_prompt = strsave(getword(tbuf, &size, TRUE)); 256*7c478bd9Sstevel@tonic-gate break; 257*7c478bd9Sstevel@tonic-gate case 'm': 258*7c478bd9Sstevel@tonic-gate pmtab->p_modules = optarg; 259*7c478bd9Sstevel@tonic-gate if (vml(pmtab->p_modules) != 0) 260*7c478bd9Sstevel@tonic-gate usage(); 261*7c478bd9Sstevel@tonic-gate break; 262*7c478bd9Sstevel@tonic-gate case 'l': 263*7c478bd9Sstevel@tonic-gate pmtab->p_ttylabel = optarg; 264*7c478bd9Sstevel@tonic-gate break; 265*7c478bd9Sstevel@tonic-gate case '?': 266*7c478bd9Sstevel@tonic-gate usage(); 267*7c478bd9Sstevel@tonic-gate break; /*NOTREACHED*/ 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate if (optind < argc) 271*7c478bd9Sstevel@tonic-gate usage(); 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate if (!gflag) 274*7c478bd9Sstevel@tonic-gate usage(); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate /* 278*7c478bd9Sstevel@tonic-gate * usage - print out a usage message 279*7c478bd9Sstevel@tonic-gate */ 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate static void 282*7c478bd9Sstevel@tonic-gate usage() 283*7c478bd9Sstevel@tonic-gate { 284*7c478bd9Sstevel@tonic-gate char *umsg = "Usage: ttymon\n ttymon -g [-h] [-d device] " 285*7c478bd9Sstevel@tonic-gate "[-l ttylabel] [-t timeout] [-p prompt] [-m modules]\n"; 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate if (isatty(STDERR_FILENO)) 288*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s", umsg); 289*7c478bd9Sstevel@tonic-gate else 290*7c478bd9Sstevel@tonic-gate cons_printf(umsg); 291*7c478bd9Sstevel@tonic-gate exit(1); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate /* 295*7c478bd9Sstevel@tonic-gate * getty_options - this is cut from getty.c 296*7c478bd9Sstevel@tonic-gate * - it scan getty cmd args 297*7c478bd9Sstevel@tonic-gate * - modification is made to stuff args in pmtab 298*7c478bd9Sstevel@tonic-gate */ 299*7c478bd9Sstevel@tonic-gate static void 300*7c478bd9Sstevel@tonic-gate getty_options(argc, argv, pmtab) 301*7c478bd9Sstevel@tonic-gate int argc; 302*7c478bd9Sstevel@tonic-gate char **argv; 303*7c478bd9Sstevel@tonic-gate struct pmtab *pmtab; 304*7c478bd9Sstevel@tonic-gate { 305*7c478bd9Sstevel@tonic-gate char *ptr; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* 308*7c478bd9Sstevel@tonic-gate * the pre-4.0 getty's hang_up_line() is a no-op. 309*7c478bd9Sstevel@tonic-gate * For compatibility, H_FLAG cannot be set for this "getty". 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate pmtab->p_ttyflags &= ~(H_FLAG); 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate while (--argc && **++argv == '-') { 314*7c478bd9Sstevel@tonic-gate for (ptr = *argv + 1; *ptr; ptr++) 315*7c478bd9Sstevel@tonic-gate switch (*ptr) { 316*7c478bd9Sstevel@tonic-gate case 'h': 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate case 't': 319*7c478bd9Sstevel@tonic-gate if (isdigit(*++ptr)) { 320*7c478bd9Sstevel@tonic-gate (void) sscanf(ptr, "%d", &(pmtab->p_timeout)); 321*7c478bd9Sstevel@tonic-gate while (isdigit(*++ptr)); 322*7c478bd9Sstevel@tonic-gate ptr--; 323*7c478bd9Sstevel@tonic-gate } else if (--argc) { 324*7c478bd9Sstevel@tonic-gate if (isdigit(*(ptr = *++argv))) 325*7c478bd9Sstevel@tonic-gate (void) sscanf(ptr, "%d", 326*7c478bd9Sstevel@tonic-gate &(pmtab->p_timeout)); 327*7c478bd9Sstevel@tonic-gate else { 328*7c478bd9Sstevel@tonic-gate log("getty: timeout argument <%s> " 329*7c478bd9Sstevel@tonic-gate "invalid", *argv); 330*7c478bd9Sstevel@tonic-gate exit(1); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate break; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate case 'c': 336*7c478bd9Sstevel@tonic-gate log("Use \"sttydefs -l\" to check /etc/ttydefs."); 337*7c478bd9Sstevel@tonic-gate exit(0); 338*7c478bd9Sstevel@tonic-gate default: 339*7c478bd9Sstevel@tonic-gate break; 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate if (argc < 1) { 344*7c478bd9Sstevel@tonic-gate log("getty: no terminal line specified."); 345*7c478bd9Sstevel@tonic-gate exit(1); 346*7c478bd9Sstevel@tonic-gate } else { 347*7c478bd9Sstevel@tonic-gate (void) strcat(devbuf, "/dev/"); 348*7c478bd9Sstevel@tonic-gate (void) strcat(devbuf, *argv); 349*7c478bd9Sstevel@tonic-gate pmtab->p_device = devbuf; 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate if (--argc > 0) { 353*7c478bd9Sstevel@tonic-gate pmtab->p_ttylabel = *++argv; 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * every thing after this will be ignored 358*7c478bd9Sstevel@tonic-gate * i.e. termtype and linedisc are ignored 359*7c478bd9Sstevel@tonic-gate */ 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* 363*7c478bd9Sstevel@tonic-gate * find_ttyname(fd) - find the name of device associated with fd. 364*7c478bd9Sstevel@tonic-gate * - it first tries utmpx to see if an entry exists 365*7c478bd9Sstevel@tonic-gate * - with my pid and ut_line is defined. If ut_line 366*7c478bd9Sstevel@tonic-gate * - is defined, it will see if the major and minor 367*7c478bd9Sstevel@tonic-gate * - number of fd and devname from utmpx match. 368*7c478bd9Sstevel@tonic-gate * - If utmpx search fails, ttyname(fd) will be called. 369*7c478bd9Sstevel@tonic-gate */ 370*7c478bd9Sstevel@tonic-gate static char * 371*7c478bd9Sstevel@tonic-gate find_ttyname(fd) 372*7c478bd9Sstevel@tonic-gate int fd; 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate pid_t ownpid; 375*7c478bd9Sstevel@tonic-gate struct utmpx *u; 376*7c478bd9Sstevel@tonic-gate static struct stat statf, statu; 377*7c478bd9Sstevel@tonic-gate static char buf[BUFSIZ]; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate ownpid = getpid(); 380*7c478bd9Sstevel@tonic-gate setutxent(); 381*7c478bd9Sstevel@tonic-gate while ((u = getutxent()) != NULL) { 382*7c478bd9Sstevel@tonic-gate if (u->ut_pid == ownpid) { 383*7c478bd9Sstevel@tonic-gate if (strlen(u->ut_line) != 0) { 384*7c478bd9Sstevel@tonic-gate if (*(u->ut_line) != '/') { 385*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, "/dev/"); 386*7c478bd9Sstevel@tonic-gate (void) strncat(buf, u->ut_line, 387*7c478bd9Sstevel@tonic-gate sizeof (u->ut_line)); 388*7c478bd9Sstevel@tonic-gate } else { 389*7c478bd9Sstevel@tonic-gate (void) strncat(buf, u->ut_line, 390*7c478bd9Sstevel@tonic-gate sizeof (u->ut_line)); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate else 394*7c478bd9Sstevel@tonic-gate u = NULL; 395*7c478bd9Sstevel@tonic-gate break; 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate endutxent(); 399*7c478bd9Sstevel@tonic-gate if ((u != NULL) && 400*7c478bd9Sstevel@tonic-gate (fstat(fd, &statf) == 0) && 401*7c478bd9Sstevel@tonic-gate (stat(buf, &statu) == 0) && 402*7c478bd9Sstevel@tonic-gate (statf.st_dev == statu.st_dev) && 403*7c478bd9Sstevel@tonic-gate (statf.st_rdev == statu.st_rdev)) { 404*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 405*7c478bd9Sstevel@tonic-gate debug("ttymon_express: find device name from utmpx."); 406*7c478bd9Sstevel@tonic-gate #endif 407*7c478bd9Sstevel@tonic-gate return (buf); 408*7c478bd9Sstevel@tonic-gate } else { 409*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 410*7c478bd9Sstevel@tonic-gate debug("ttymon_express: calling ttyname to find device name."); 411*7c478bd9Sstevel@tonic-gate #endif 412*7c478bd9Sstevel@tonic-gate return (ttyname(fd)); 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate /* 417*7c478bd9Sstevel@tonic-gate * Revoke all access to a device node and make sure that there are 418*7c478bd9Sstevel@tonic-gate * no interposed streams devices attached. Must be called before a 419*7c478bd9Sstevel@tonic-gate * device is actually opened. 420*7c478bd9Sstevel@tonic-gate * When fdetach is called, the underlying device node is revealed; it 421*7c478bd9Sstevel@tonic-gate * will have the previous owner and that owner can re-attach; so we 422*7c478bd9Sstevel@tonic-gate * retry until we win. 423*7c478bd9Sstevel@tonic-gate * Ignore non-existent devices. 424*7c478bd9Sstevel@tonic-gate */ 425*7c478bd9Sstevel@tonic-gate void 426*7c478bd9Sstevel@tonic-gate revokedevaccess(char *dev, uid_t uid, gid_t gid, mode_t mode) 427*7c478bd9Sstevel@tonic-gate { 428*7c478bd9Sstevel@tonic-gate do { 429*7c478bd9Sstevel@tonic-gate if (chown(dev, uid, gid) == -1) 430*7c478bd9Sstevel@tonic-gate return; 431*7c478bd9Sstevel@tonic-gate } while (fdetach(dev) == 0); 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate /* Remove ACLs */ 434*7c478bd9Sstevel@tonic-gate if (acl(dev, GETACLCNT, 0, NULL) > MIN_ACL_ENTRIES) { 435*7c478bd9Sstevel@tonic-gate aclent_t acls[3]; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate acls[0].a_type = USER_OBJ; 438*7c478bd9Sstevel@tonic-gate acls[0].a_id = uid; 439*7c478bd9Sstevel@tonic-gate acls[0].a_perm = 0; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate acls[1].a_type = GROUP_OBJ; 442*7c478bd9Sstevel@tonic-gate acls[1].a_id = gid; 443*7c478bd9Sstevel@tonic-gate acls[1].a_perm = 0; 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate acls[2].a_type = OTHER_OBJ; 446*7c478bd9Sstevel@tonic-gate acls[2].a_id = 0; 447*7c478bd9Sstevel@tonic-gate acls[2].a_perm = 0; 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate (void) acl(dev, SETACL, 3, acls); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate (void) chmod(dev, mode); 453*7c478bd9Sstevel@tonic-gate } 454