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 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * Portions of this source code were derived from Berkeley 31 * under license from the Regents of the University of 32 * California. 33 */ 34 35 /* 36 * YP updater for public key map 37 */ 38 #include <stdio.h> 39 #include <rpc/rpc.h> 40 #include <rpcsvc/ypclnt.h> 41 #include <sys/file.h> 42 43 extern char *malloc(); 44 45 int 46 main(argc, argv) 47 int argc; 48 char *argv[]; 49 { 50 unsigned op; 51 char name[MAXNETNAMELEN + 1]; 52 char key[256]; 53 char data[256]; 54 char line[256]; 55 unsigned keylen; 56 unsigned datalen; 57 FILE *rf; 58 FILE *wf; 59 char *fname; 60 char *tmpname; 61 int err; 62 63 64 if (argc != 3) { 65 exit(YPERR_YPERR); 66 } 67 fname = argv[1]; 68 tmpname = malloc(strlen(fname) + 4); 69 if (tmpname == NULL) { 70 exit(YPERR_YPERR); 71 } 72 sprintf(tmpname, "%s.tmp", fname); 73 74 /* 75 * Get input 76 */ 77 if (! scanf("%s\n", name)) { 78 exit(YPERR_YPERR); 79 } 80 if (! scanf("%u\n", &op)) { 81 exit(YPERR_YPERR); 82 } 83 if (! scanf("%u\n", &keylen)) { 84 exit(YPERR_YPERR); 85 } 86 if (! fread(key, keylen, 1, stdin)) { 87 exit(YPERR_YPERR); 88 } 89 key[keylen] = 0; 90 if (! scanf("%u\n", &datalen)) { 91 exit(YPERR_YPERR); 92 } 93 if (! fread(data, datalen, 1, stdin)) { 94 exit(YPERR_YPERR); 95 } 96 data[datalen] = 0; 97 98 /* 99 * Check permission 100 */ 101 if (strcmp(name, key) != 0) { 102 exit(YPERR_ACCESS); 103 } 104 if (strcmp(name, "nobody") == 0) { 105 /* 106 * Can't change "nobody"s key. 107 */ 108 exit(YPERR_ACCESS); 109 } 110 111 /* 112 * Open files 113 */ 114 rf = fopen(fname, "r"); 115 if (rf == NULL) { 116 exit(YPERR_YPERR); 117 } 118 wf = fopen(tmpname, "w"); 119 if (wf == NULL) { 120 exit(YPERR_YPERR); 121 } 122 err = -1; 123 while (fgets(line, sizeof (line), rf)) { 124 if (err < 0 && match(line, name)) { 125 switch (op) { 126 case YPOP_INSERT: 127 err = YPERR_KEY; 128 break; 129 case YPOP_STORE: 130 case YPOP_CHANGE: 131 fprintf(wf, "%s %s\n", key, data); 132 err = 0; 133 break; 134 case YPOP_DELETE: 135 /* do nothing */ 136 err = 0; 137 break; 138 } 139 } else { 140 fputs(line, wf); 141 } 142 } 143 if (err < 0) { 144 switch (op) { 145 case YPOP_CHANGE: 146 case YPOP_DELETE: 147 err = YPERR_KEY; 148 break; 149 case YPOP_INSERT: 150 case YPOP_STORE: 151 err = 0; 152 fprintf(wf, "%s %s\n", key, data); 153 break; 154 } 155 } 156 fclose(wf); 157 fclose(rf); 158 if (err == 0) { 159 if (rename(tmpname, fname) < 0) { 160 exit(YPERR_YPERR); 161 } 162 } else { 163 if (unlink(tmpname) < 0) { 164 exit(YPERR_YPERR); 165 } 166 } 167 if (fork() == 0) { 168 close(0); close(1); close(2); 169 open("/dev/null", O_RDWR, 0); 170 dup(0); dup(0); 171 execl("/bin/sh", "sh", "-c", argv[2], NULL); 172 } 173 return (err); 174 /* NOTREACHED */ 175 } 176 177 178 int 179 match(line, name) 180 char *line; 181 char *name; 182 { 183 int len; 184 185 len = strlen(name); 186 return (strncmp(line, name, len) == 0 && 187 (line[len] == ' ' || line[len] == '\t')); 188 } 189