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