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 2000 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /* 43*7c478bd9Sstevel@tonic-gate * Administrative tool to add a new user to the publickey database 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate #include <stdio.h> 46*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 47*7c478bd9Sstevel@tonic-gate #include <unistd.h> 48*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 49*7c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h> 50*7c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 52*7c478bd9Sstevel@tonic-gate #include <netdb.h> 53*7c478bd9Sstevel@tonic-gate #include <string.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 55*7c478bd9Sstevel@tonic-gate #include <errno.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #define MAXMAPNAMELEN 256 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate extern char *program_name; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate static char *basename(char *path); 62*7c478bd9Sstevel@tonic-gate static int match(char *line, char *name); 63*7c478bd9Sstevel@tonic-gate static int _openchild(char *command, FILE **fto, FILE **ffrom); 64*7c478bd9Sstevel@tonic-gate static char SHELL[] = "/bin/sh"; 65*7c478bd9Sstevel@tonic-gate static char UPDATEFILE[] = "updaters"; 66*7c478bd9Sstevel@tonic-gate static char MAKE[] = "/usr/ccs/bin/make"; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate /* 69*7c478bd9Sstevel@tonic-gate * Determine if requester is allowed to update the given map, 70*7c478bd9Sstevel@tonic-gate * and update it if so. Returns the yp status, which is zero 71*7c478bd9Sstevel@tonic-gate * if there is no access violation. 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate int 74*7c478bd9Sstevel@tonic-gate mapupdate(char *name, char *mapname, uint_t op, char *data) 75*7c478bd9Sstevel@tonic-gate { 76*7c478bd9Sstevel@tonic-gate char updater[MAXMAPNAMELEN + 40]; 77*7c478bd9Sstevel@tonic-gate FILE *childargs; 78*7c478bd9Sstevel@tonic-gate FILE *childrslt; 79*7c478bd9Sstevel@tonic-gate #ifdef WEXITSTATUS 80*7c478bd9Sstevel@tonic-gate int status; 81*7c478bd9Sstevel@tonic-gate #else 82*7c478bd9Sstevel@tonic-gate union wait status; 83*7c478bd9Sstevel@tonic-gate #endif 84*7c478bd9Sstevel@tonic-gate pid_t pid; 85*7c478bd9Sstevel@tonic-gate uint_t yperrno; 86*7c478bd9Sstevel@tonic-gate int namelen, datalen; 87*7c478bd9Sstevel@tonic-gate struct stat stbuf; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 90*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s %s\n", name, data); 91*7c478bd9Sstevel@tonic-gate #endif 92*7c478bd9Sstevel@tonic-gate namelen = strlen(name); 93*7c478bd9Sstevel@tonic-gate datalen = strlen(data); 94*7c478bd9Sstevel@tonic-gate errno = 0; 95*7c478bd9Sstevel@tonic-gate if (stat(MAKE, &stbuf) < 0) 96*7c478bd9Sstevel@tonic-gate switch (errno) { 97*7c478bd9Sstevel@tonic-gate case ENOENT: 98*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 99*7c478bd9Sstevel@tonic-gate "%s: %s not found, please install on the system\n", 100*7c478bd9Sstevel@tonic-gate program_name, MAKE); 101*7c478bd9Sstevel@tonic-gate return (1); 102*7c478bd9Sstevel@tonic-gate default: 103*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 104*7c478bd9Sstevel@tonic-gate "%s: cannot access %s, errno=%d.\n", 105*7c478bd9Sstevel@tonic-gate program_name, MAKE, errno); 106*7c478bd9Sstevel@tonic-gate return (1); 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate (void) sprintf(updater, "%s -s -f %s %s", 109*7c478bd9Sstevel@tonic-gate MAKE, UPDATEFILE, mapname); 110*7c478bd9Sstevel@tonic-gate pid = _openchild(updater, &childargs, &childrslt); 111*7c478bd9Sstevel@tonic-gate if (pid < 0) 112*7c478bd9Sstevel@tonic-gate return (YPERR_YPERR); 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * Write to child 116*7c478bd9Sstevel@tonic-gate */ 117*7c478bd9Sstevel@tonic-gate (void) fprintf(childargs, "%s\n", name); 118*7c478bd9Sstevel@tonic-gate (void) fprintf(childargs, "%u\n", op); 119*7c478bd9Sstevel@tonic-gate (void) fprintf(childargs, "%u\n", namelen); 120*7c478bd9Sstevel@tonic-gate (void) fwrite(name, namelen, 1, childargs); 121*7c478bd9Sstevel@tonic-gate (void) fprintf(childargs, "\n"); 122*7c478bd9Sstevel@tonic-gate (void) fprintf(childargs, "%u\n", datalen); 123*7c478bd9Sstevel@tonic-gate (void) fwrite(data, datalen, 1, childargs); 124*7c478bd9Sstevel@tonic-gate (void) fprintf(childargs, "\n"); 125*7c478bd9Sstevel@tonic-gate (void) fclose(childargs); 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate /* 128*7c478bd9Sstevel@tonic-gate * Read from child 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate (void) fscanf(childrslt, "%d", &yperrno); 131*7c478bd9Sstevel@tonic-gate (void) fclose(childrslt); 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate (void) wait(&status); 134*7c478bd9Sstevel@tonic-gate #ifdef WEXITSTATUS 135*7c478bd9Sstevel@tonic-gate if (WEXITSTATUS(status) != 0) { 136*7c478bd9Sstevel@tonic-gate #else 137*7c478bd9Sstevel@tonic-gate if (status.w_retcode != 0) { 138*7c478bd9Sstevel@tonic-gate #endif 139*7c478bd9Sstevel@tonic-gate return (YPERR_YPERR); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate return (yperrno); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* 145*7c478bd9Sstevel@tonic-gate * returns pid, or -1 for failure 146*7c478bd9Sstevel@tonic-gate */ 147*7c478bd9Sstevel@tonic-gate static int 148*7c478bd9Sstevel@tonic-gate _openchild(char *command, FILE **fto, FILE **ffrom) 149*7c478bd9Sstevel@tonic-gate { 150*7c478bd9Sstevel@tonic-gate int i; 151*7c478bd9Sstevel@tonic-gate pid_t pid; 152*7c478bd9Sstevel@tonic-gate int pdto[2]; 153*7c478bd9Sstevel@tonic-gate int pdfrom[2]; 154*7c478bd9Sstevel@tonic-gate char *com; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate if (pipe(pdto) < 0) { 157*7c478bd9Sstevel@tonic-gate goto error1; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate if (pipe(pdfrom) < 0) { 160*7c478bd9Sstevel@tonic-gate goto error2; 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate #ifdef VFORK 163*7c478bd9Sstevel@tonic-gate switch (pid = vfork()) { 164*7c478bd9Sstevel@tonic-gate #else 165*7c478bd9Sstevel@tonic-gate switch (pid = fork()) { 166*7c478bd9Sstevel@tonic-gate #endif 167*7c478bd9Sstevel@tonic-gate case -1: 168*7c478bd9Sstevel@tonic-gate goto error3; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate case 0: 171*7c478bd9Sstevel@tonic-gate /* 172*7c478bd9Sstevel@tonic-gate * child: read from pdto[0], write into pdfrom[1] 173*7c478bd9Sstevel@tonic-gate */ 174*7c478bd9Sstevel@tonic-gate (void) close(0); 175*7c478bd9Sstevel@tonic-gate (void) dup(pdto[0]); 176*7c478bd9Sstevel@tonic-gate (void) close(1); 177*7c478bd9Sstevel@tonic-gate (void) dup(pdfrom[1]); 178*7c478bd9Sstevel@tonic-gate closefrom(3); 179*7c478bd9Sstevel@tonic-gate com = malloc((unsigned)strlen(command) + 6); 180*7c478bd9Sstevel@tonic-gate if (com == NULL) { 181*7c478bd9Sstevel@tonic-gate _exit(~0); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate (void) sprintf(com, "exec %s", command); 184*7c478bd9Sstevel@tonic-gate execl(SHELL, basename(SHELL), "-c", com, NULL); 185*7c478bd9Sstevel@tonic-gate _exit(~0); 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate default: 188*7c478bd9Sstevel@tonic-gate /* 189*7c478bd9Sstevel@tonic-gate * parent: write into pdto[1], read from pdfrom[0] 190*7c478bd9Sstevel@tonic-gate */ 191*7c478bd9Sstevel@tonic-gate *fto = fdopen(pdto[1], "w"); 192*7c478bd9Sstevel@tonic-gate (void) close(pdto[0]); 193*7c478bd9Sstevel@tonic-gate *ffrom = fdopen(pdfrom[0], "r"); 194*7c478bd9Sstevel@tonic-gate (void) close(pdfrom[1]); 195*7c478bd9Sstevel@tonic-gate break; 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate return (pid); 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* 200*7c478bd9Sstevel@tonic-gate * error cleanup and return 201*7c478bd9Sstevel@tonic-gate */ 202*7c478bd9Sstevel@tonic-gate error3: 203*7c478bd9Sstevel@tonic-gate (void) close(pdfrom[0]); 204*7c478bd9Sstevel@tonic-gate (void) close(pdfrom[1]); 205*7c478bd9Sstevel@tonic-gate error2: 206*7c478bd9Sstevel@tonic-gate (void) close(pdto[0]); 207*7c478bd9Sstevel@tonic-gate (void) close(pdto[1]); 208*7c478bd9Sstevel@tonic-gate error1: 209*7c478bd9Sstevel@tonic-gate return (-1); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate static char * 213*7c478bd9Sstevel@tonic-gate basename(char *path) 214*7c478bd9Sstevel@tonic-gate { 215*7c478bd9Sstevel@tonic-gate char *p; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate p = strrchr(path, '/'); 218*7c478bd9Sstevel@tonic-gate if (p == NULL) 219*7c478bd9Sstevel@tonic-gate return (path); 220*7c478bd9Sstevel@tonic-gate return (p + 1); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * Determine if requester is allowed to update the given map, 225*7c478bd9Sstevel@tonic-gate * and update it if so. Returns the status, which is zero 226*7c478bd9Sstevel@tonic-gate * if there is no access violation, 1 otherwise. 227*7c478bd9Sstevel@tonic-gate * This function updates the local file. 228*7c478bd9Sstevel@tonic-gate */ 229*7c478bd9Sstevel@tonic-gate int 230*7c478bd9Sstevel@tonic-gate localupdate(char *name, char *filename, uint_t op, char *data) 231*7c478bd9Sstevel@tonic-gate { 232*7c478bd9Sstevel@tonic-gate char line[256]; 233*7c478bd9Sstevel@tonic-gate FILE *rf; 234*7c478bd9Sstevel@tonic-gate FILE *wf; 235*7c478bd9Sstevel@tonic-gate int wfd; 236*7c478bd9Sstevel@tonic-gate char tmpname[80]; 237*7c478bd9Sstevel@tonic-gate int err; 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * Check permission 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate if (strcmp(name, "nobody") == 0) { 243*7c478bd9Sstevel@tonic-gate /* cannot change keys for nobody */ 244*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 245*7c478bd9Sstevel@tonic-gate "%s: cannot change key-pair for %s\n", 246*7c478bd9Sstevel@tonic-gate program_name, name); 247*7c478bd9Sstevel@tonic-gate return (1); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* 251*7c478bd9Sstevel@tonic-gate * Open files 252*7c478bd9Sstevel@tonic-gate */ 253*7c478bd9Sstevel@tonic-gate (void) memset(tmpname, 0, 80); 254*7c478bd9Sstevel@tonic-gate (void) sprintf(tmpname, "%s.tmp", filename); 255*7c478bd9Sstevel@tonic-gate rf = fopen(filename, "r"); 256*7c478bd9Sstevel@tonic-gate if (rf == NULL) { 257*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 258*7c478bd9Sstevel@tonic-gate "%s: cannot read %s\n", program_name, filename); 259*7c478bd9Sstevel@tonic-gate return (1); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate (void) umask(0); 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * Create the new file with the correct permissions 266*7c478bd9Sstevel@tonic-gate */ 267*7c478bd9Sstevel@tonic-gate wfd = open(tmpname, O_CREAT|O_RDWR|O_TRUNC, 268*7c478bd9Sstevel@tonic-gate S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 269*7c478bd9Sstevel@tonic-gate if (wfd == -1) { 270*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: cannot create '%s' to write to.\n", 271*7c478bd9Sstevel@tonic-gate program_name, tmpname); 272*7c478bd9Sstevel@tonic-gate (void) fclose(rf); 273*7c478bd9Sstevel@tonic-gate return (1); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate wf = fdopen(wfd, "w"); 276*7c478bd9Sstevel@tonic-gate if (wf == NULL) { 277*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: cannot fdopen '%s'.\n", 278*7c478bd9Sstevel@tonic-gate program_name, tmpname); 279*7c478bd9Sstevel@tonic-gate (void) close(wfd); 280*7c478bd9Sstevel@tonic-gate (void) fclose(rf); 281*7c478bd9Sstevel@tonic-gate return (1); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate err = -1; 285*7c478bd9Sstevel@tonic-gate while (fgets(line, sizeof (line), rf)) { 286*7c478bd9Sstevel@tonic-gate if (err < 0 && match(line, name)) { 287*7c478bd9Sstevel@tonic-gate switch (op) { 288*7c478bd9Sstevel@tonic-gate case YPOP_INSERT: 289*7c478bd9Sstevel@tonic-gate err = 1; 290*7c478bd9Sstevel@tonic-gate break; 291*7c478bd9Sstevel@tonic-gate case YPOP_STORE: 292*7c478bd9Sstevel@tonic-gate case YPOP_CHANGE: 293*7c478bd9Sstevel@tonic-gate (void) fprintf(wf, "%s\t%s\n", name, data); 294*7c478bd9Sstevel@tonic-gate err = 0; 295*7c478bd9Sstevel@tonic-gate break; 296*7c478bd9Sstevel@tonic-gate case YPOP_DELETE: 297*7c478bd9Sstevel@tonic-gate /* do nothing */ 298*7c478bd9Sstevel@tonic-gate err = 0; 299*7c478bd9Sstevel@tonic-gate break; 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate } else { 302*7c478bd9Sstevel@tonic-gate fputs(line, wf); 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate if (err < 0) { 306*7c478bd9Sstevel@tonic-gate switch (op) { 307*7c478bd9Sstevel@tonic-gate case YPOP_CHANGE: 308*7c478bd9Sstevel@tonic-gate case YPOP_DELETE: 309*7c478bd9Sstevel@tonic-gate err = 1; 310*7c478bd9Sstevel@tonic-gate break; 311*7c478bd9Sstevel@tonic-gate case YPOP_INSERT: 312*7c478bd9Sstevel@tonic-gate case YPOP_STORE: 313*7c478bd9Sstevel@tonic-gate err = 0; 314*7c478bd9Sstevel@tonic-gate (void) fprintf(wf, "%s\t%s\n", name, data); 315*7c478bd9Sstevel@tonic-gate break; 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate (void) fclose(wf); 319*7c478bd9Sstevel@tonic-gate (void) fclose(rf); 320*7c478bd9Sstevel@tonic-gate if (err == 0) { 321*7c478bd9Sstevel@tonic-gate if (rename(tmpname, filename) < 0) { 322*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 323*7c478bd9Sstevel@tonic-gate "%s: cannot rename %s to %s\n", 324*7c478bd9Sstevel@tonic-gate program_name, tmpname, filename); 325*7c478bd9Sstevel@tonic-gate return (1); 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate } else { 328*7c478bd9Sstevel@tonic-gate if (unlink(tmpname) < 0) { 329*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 330*7c478bd9Sstevel@tonic-gate "%s: cannot delete %s\n", 331*7c478bd9Sstevel@tonic-gate program_name, tmpname); 332*7c478bd9Sstevel@tonic-gate return (1); 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate return (err); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate static int 339*7c478bd9Sstevel@tonic-gate match(char *line, char *name) 340*7c478bd9Sstevel@tonic-gate { 341*7c478bd9Sstevel@tonic-gate int len; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate len = strlen(name); 344*7c478bd9Sstevel@tonic-gate return (strncmp(line, name, len) == 0 && 345*7c478bd9Sstevel@tonic-gate (line[len] == ' ' || line[len] == '\t')); 346*7c478bd9Sstevel@tonic-gate } 347