xref: /titanic_41/usr/src/cmd/ypcmd/shared/utils.c (revision 70cbfe41f2338b77c15f79c6625eca6e70c412f3)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
36 
37 /*
38  * DESCRIPTION:	This file contains various functions used by more than one NIS
39  *		components. A lot of this code started off in ypxfr and then
40  *		got used by other components. Some of it has become a little
41  *		'quirky' and should probably be re-worked.
42  */
43 
44 #include <unistd.h>
45 #include <syslog.h>
46 #include <sys/mman.h>
47 #include <thread.h>
48 #include <synch.h>
49 #include <stdarg.h>
50 #include <ndbm.h>
51 #include "../ypsym.h"
52 #include "../ypdefs.h"
53 #include "shim.h"
54 
55 USE_DBM
56 
57 /*
58  * Globals
59  */
60 
61 /*
62  * DESCRIPTION : Utility functions used by everything.
63  */
64 bool check_map_existence(char *);
65 void logprintf2(char *format, ...);
66 extern bool ypcheck_map_existence_yptol();
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 stat64 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 (stat64(dbfile, &filestat) != -1) {
207 		(void) strcpy(dbfile, pname);
208 		(void) strcat(dbfile, dbm_pag);
209 
210 		if (stat64(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  * Calls ypcheck_map_existence_yptol() defined in
274  * usr/src/lib/libnisdb/yptol/shim_ancil.c
275  */
276 bool
277 ypcheck_map_existence(char *pname)
278 {
279 	return (ypcheck_map_existence_yptol(pname));
280 }
281