xref: /titanic_52/usr/src/cmd/ypcmd/shared/utils.c (revision 25cf1a301a396c38e8adf52c15f537b80d2483f7)
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 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /*	  All Rights Reserved   */
29 
30 /*
31  * Portions of this source code were derived from Berkeley
32  * under license from the Regents of the University of
33  * California.
34  */
35 
36 #pragma ident	"%Z%%M%	%I%	%E% SMI"
37 
38 /*
39  * DESCRIPTION:	This file contains various functions used by more than one NIS
40  *		components. A lot of this code started off in ypxfr and then
41  *		got used by other components. Some of it has become a little
42  *		'quirky' and should probably be re-worked.
43  */
44 
45 #include <unistd.h>
46 #include <syslog.h>
47 #include <sys/mman.h>
48 #include <thread.h>
49 #include <synch.h>
50 #include <stdarg.h>
51 #include <ndbm.h>
52 #include "../ypsym.h"
53 #include "../ypdefs.h"
54 #include "shim.h"
55 
56 USE_DBM
57 
58 /*
59  * Globals
60  */
61 
62 /*
63  * DESCRIPTION : Utility functions used by everything.
64  */
65 bool check_map_existence(char *);
66 void logprintf2(char *format, ...);
67 
68 /*
69  * This checks to see if the source map files exist, then renames them to the
70  * target names.  This is a boolean function.  The file names from.pag and
71  * from.dir will be changed to to.pag and to.dir in the success case.
72  *
73  * Note:  If the second of the two renames fails, yprename_map will try to
74  * un-rename the first pair, and leave the world in the state it was on entry.
75  * This might fail, too, though...
76  *
77  * GIVEN :	Name of map to copy from
78  *		Name of map to copy to
79  *		Flag indicating if map is secure.
80  */
81 bool
82 rename_map(from, to, secure_map)
83 	char *from;
84 	char *to;
85 	bool_t secure_map;
86 {
87 	char fromfile[MAXNAMLEN + 1];
88 	char tofile[MAXNAMLEN + 1];
89 	char savefile[MAXNAMLEN + 1];
90 
91 	if (!from || !to) {
92 		return (FALSE);
93 	}
94 
95 	if (!check_map_existence(from)) {
96 		return (FALSE);
97 	}
98 
99 	(void) strcpy(fromfile, from);
100 	(void) strcat(fromfile, dbm_pag);
101 	(void) strcpy(tofile, to);
102 	(void) strcat(tofile, dbm_pag);
103 
104 	if (rename(fromfile, tofile)) {
105 		logprintf2("Can't mv %s to %s.\n", fromfile,
106 		    tofile);
107 		return (FALSE);
108 	}
109 
110 	(void) strcpy(savefile, tofile);
111 	(void) strcpy(fromfile, from);
112 	(void) strcat(fromfile, dbm_dir);
113 	(void) strcpy(tofile, to);
114 	(void) strcat(tofile, dbm_dir);
115 
116 	if (rename(fromfile, tofile)) {
117 		logprintf2("Can't mv %s to %s.\n", fromfile,
118 		    tofile);
119 		(void) strcpy(fromfile, from);
120 		(void) strcat(fromfile, dbm_pag);
121 		(void) strcpy(tofile, to);
122 		(void) strcat(tofile, dbm_pag);
123 
124 		if (rename(tofile, fromfile)) {
125 			logprintf2(
126 			    "Can't recover from rename failure.\n");
127 			return (FALSE);
128 		}
129 
130 		return (FALSE);
131 	}
132 
133 	if (!secure_map) {
134 		chmod(savefile, 0644);
135 		chmod(tofile, 0644);
136 	}
137 
138 	return (TRUE);
139 }
140 
141 /*
142  * Function :	delete_map()
143  *
144  * Description:	Deletes a map
145  *
146  * Given :	Map name
147  *
148  * Return :	TRUE = Map deleted
149  *		FALSE = Map not completly deleted
150  */
151 bool
152 delete_map(name)
153 	char *name;
154 {
155 	char fromfile[MAXNAMLEN + 1];
156 
157 	if (!name) {
158 		return (FALSE);
159 	}
160 
161 	if (!check_map_existence(name)) {
162 		/* Already gone */
163 		return (TRUE);
164 	}
165 
166 	(void) strcpy(fromfile, name);
167 	(void) strcat(fromfile, dbm_pag);
168 
169 	if (unlink(fromfile)) {
170 		logprintf2("Can't unlink %s.\n", fromfile);
171 		return (FALSE);
172 	}
173 
174 	(void) strcpy(fromfile, name);
175 	(void) strcat(fromfile, dbm_dir);
176 
177 	if (unlink(fromfile)) {
178 		logprintf2("Can't unlink %s.\n", fromfile);
179 		return (FALSE);
180 	}
181 
182 	return (TRUE);
183 }
184 
185 /*
186  * This performs an existence check on the dbm data base files <pname>.pag and
187  * <pname>.dir.
188  */
189 bool
190 check_map_existence(pname)
191 	char *pname;
192 {
193 	char dbfile[MAXNAMLEN + 1];
194 	struct stat filestat;
195 	int len;
196 
197 	if (!pname || ((len = strlen(pname)) == 0) ||
198 	    (len + 5) > (MAXNAMLEN + 1)) {
199 		return (FALSE);
200 	}
201 
202 	errno = 0;
203 	(void) strcpy(dbfile, pname);
204 	(void) strcat(dbfile, dbm_dir);
205 
206 	if (stat(dbfile, &filestat) != -1) {
207 		(void) strcpy(dbfile, pname);
208 		(void) strcat(dbfile, dbm_pag);
209 
210 		if (stat(dbfile, &filestat) != -1) {
211 			return (TRUE);
212 		} else {
213 
214 			if (errno != ENOENT) {
215 				logprintf2(
216 				    "Stat error on map file %s.\n",
217 				    dbfile);
218 			}
219 
220 			return (FALSE);
221 		}
222 
223 	} else {
224 
225 		if (errno != ENOENT) {
226 			logprintf2(
227 			    "Stat error on map file %s.\n",
228 			    dbfile);
229 		}
230 
231 		return (FALSE);
232 	}
233 }
234 
235 /*
236  * FUNCTION :	logprintf2()
237  *
238  * DESCRIPTION:	The functions in this file were oringinaly shared between
239  *		ypxfr and ypserv. On error they called logprintf().
240  *		Unfortunatly this had been implemented differently in the two
241  *		sources and not at all in some of the NIS components required
242  *		for N2L.
243  *
244  *		This function is simplified version of logprinf() as/when
245  *		possible the other error calls should be migrated to use this
246  *		common version. If a common set of functionality can be found
247  *		this versions should be modified to support it.
248  */
249 void
250 logprintf2(char *format, ...)
251 {
252 	va_list ap;
253 
254 	va_start(ap, format);
255 
256 	syslog(LOG_ERR, format, ap);
257 
258 	va_end(ap);
259 }
260 
261 /*
262  * This performs an existence check on the dbm data base files <name>.pag and
263  * <name>.dir.  pname is a ptr to the filename.  This should be an absolute
264  * path.
265  * Returns TRUE if the map exists and is accessable; else FALSE.
266  *
267  * Note:  The file name should be a "base" form, without a file "extension" of
268  * .dir or .pag appended.  See ypmkfilename for a function which will generate
269  * the name correctly.  Errors in the stat call will be reported at this level,
270  * however, the non-existence of a file is not considered an error, and so will
271  * not be reported.
272  */
273 bool
274 ypcheck_map_existence(char *pname)
275 {
276 	char dbfile[MAXNAMLEN + sizeof (TTL_POSTFIX) + 1];
277 	struct stat filestat;
278 	int len;
279 
280 	if (!pname || ((len = (int)strlen(pname)) == 0) ||
281 		(len + sizeof (dbm_pag)) > (MAXNAMLEN + 1)) {
282 		return (FALSE);
283 	}
284 
285 	errno = 0;
286 
287 	/* Check for existance of .dir file */
288 	(void) strcpy(dbfile, pname);
289 	(void) strcat(dbfile, dbm_dir);
290 
291 	if (stat(dbfile, &filestat) == -1) {
292 		if (errno != ENOENT) {
293 			(void) fprintf(stderr,
294 				"ypserv:  Stat error on map file %s.\n",
295 									dbfile);
296 		}
297 		return (FALSE);
298 	}
299 
300 	/* Check for existance of .pag file */
301 	(void) strcpy(dbfile, pname);
302 	(void) strcat(dbfile, dbm_pag);
303 
304 	if (stat(dbfile, &filestat) == -1) {
305 		if (errno != ENOENT) {
306 			(void) fprintf(stderr,
307 				"ypserv:  Stat error on map file %s.\n",
308 									dbfile);
309 		    }
310 		return (FALSE);
311 	}
312 
313 	if (yptol_mode) {
314 		/* Check for existance of TTL .dir file */
315 		(void) strcpy(dbfile, pname);
316 		(void) strcat(dbfile, TTL_POSTFIX);
317 		(void) strcat(dbfile, dbm_dir);
318 
319 		if (stat(dbfile, &filestat) == -1) {
320 			if (errno != ENOENT) {
321 				(void) fprintf(stderr,
322 					"ypserv:  Stat error on map file %s.\n",
323 									dbfile);
324 			}
325 			return (FALSE);
326 		}
327 
328 		/* Check for existance of TTL .pag file */
329 		(void) strcpy(dbfile, pname);
330 		(void) strcat(dbfile, TTL_POSTFIX);
331 		(void) strcat(dbfile, dbm_pag);
332 
333 		if (stat(dbfile, &filestat) == -1) {
334 			if (errno != ENOENT) {
335 				(void) fprintf(stderr,
336 					"ypserv:  Stat error on map file %s.\n",
337 									dbfile);
338 			    }
339 			    return (FALSE);
340 		}
341 	}
342 
343 	return (TRUE);
344 }
345