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 /*
36 * DESCRIPTION: This file contains various functions used by more than one NIS
37 * components. A lot of this code started off in ypxfr and then
38 * got used by other components. Some of it has become a little
39 * 'quirky' and should probably be re-worked.
40 */
41
42 #include <unistd.h>
43 #include <syslog.h>
44 #include <sys/mman.h>
45 #include <thread.h>
46 #include <synch.h>
47 #include <stdarg.h>
48 #include <ndbm.h>
49 #include "../ypsym.h"
50 #include "../ypdefs.h"
51 #include "shim.h"
52
53 USE_DBM
54
55 /*
56 * Globals
57 */
58
59 /*
60 * DESCRIPTION : Utility functions used by everything.
61 */
62 bool check_map_existence(char *);
63 void logprintf2(char *format, ...);
64 extern bool ypcheck_map_existence_yptol();
65
66 /*
67 * This checks to see if the source map files exist, then renames them to the
68 * target names. This is a boolean function. The file names from.pag and
69 * from.dir will be changed to to.pag and to.dir in the success case.
70 *
71 * Note: If the second of the two renames fails, yprename_map will try to
72 * un-rename the first pair, and leave the world in the state it was on entry.
73 * This might fail, too, though...
74 *
75 * GIVEN : Name of map to copy from
76 * Name of map to copy to
77 * Flag indicating if map is secure.
78 */
79 bool
rename_map(from,to,secure_map)80 rename_map(from, to, secure_map)
81 char *from;
82 char *to;
83 bool_t secure_map;
84 {
85 char fromfile[MAXNAMLEN + 1];
86 char tofile[MAXNAMLEN + 1];
87 char savefile[MAXNAMLEN + 1];
88
89 if (!from || !to) {
90 return (FALSE);
91 }
92
93 if (!check_map_existence(from)) {
94 return (FALSE);
95 }
96
97 (void) strcpy(fromfile, from);
98 (void) strcat(fromfile, dbm_pag);
99 (void) strcpy(tofile, to);
100 (void) strcat(tofile, dbm_pag);
101
102 if (rename(fromfile, tofile)) {
103 logprintf2("Can't mv %s to %s.\n", fromfile,
104 tofile);
105 return (FALSE);
106 }
107
108 (void) strcpy(savefile, tofile);
109 (void) strcpy(fromfile, from);
110 (void) strcat(fromfile, dbm_dir);
111 (void) strcpy(tofile, to);
112 (void) strcat(tofile, dbm_dir);
113
114 if (rename(fromfile, tofile)) {
115 logprintf2("Can't mv %s to %s.\n", fromfile,
116 tofile);
117 (void) strcpy(fromfile, from);
118 (void) strcat(fromfile, dbm_pag);
119 (void) strcpy(tofile, to);
120 (void) strcat(tofile, dbm_pag);
121
122 if (rename(tofile, fromfile)) {
123 logprintf2(
124 "Can't recover from rename failure.\n");
125 return (FALSE);
126 }
127
128 return (FALSE);
129 }
130
131 if (!secure_map) {
132 chmod(savefile, 0644);
133 chmod(tofile, 0644);
134 }
135
136 return (TRUE);
137 }
138
139 /*
140 * Function : delete_map()
141 *
142 * Description: Deletes a map
143 *
144 * Given : Map name
145 *
146 * Return : TRUE = Map deleted
147 * FALSE = Map not completly deleted
148 */
149 bool
delete_map(name)150 delete_map(name)
151 char *name;
152 {
153 char fromfile[MAXNAMLEN + 1];
154
155 if (!name) {
156 return (FALSE);
157 }
158
159 if (!check_map_existence(name)) {
160 /* Already gone */
161 return (TRUE);
162 }
163
164 (void) strcpy(fromfile, name);
165 (void) strcat(fromfile, dbm_pag);
166
167 if (unlink(fromfile)) {
168 logprintf2("Can't unlink %s.\n", fromfile);
169 return (FALSE);
170 }
171
172 (void) strcpy(fromfile, name);
173 (void) strcat(fromfile, dbm_dir);
174
175 if (unlink(fromfile)) {
176 logprintf2("Can't unlink %s.\n", fromfile);
177 return (FALSE);
178 }
179
180 return (TRUE);
181 }
182
183 /*
184 * This performs an existence check on the dbm data base files <pname>.pag and
185 * <pname>.dir.
186 */
187 bool
check_map_existence(pname)188 check_map_existence(pname)
189 char *pname;
190 {
191 char dbfile[MAXNAMLEN + 1];
192 struct stat64 filestat;
193 int len;
194
195 if (!pname || ((len = strlen(pname)) == 0) ||
196 (len + 5) > (MAXNAMLEN + 1)) {
197 return (FALSE);
198 }
199
200 errno = 0;
201 (void) strcpy(dbfile, pname);
202 (void) strcat(dbfile, dbm_dir);
203
204 if (stat64(dbfile, &filestat) != -1) {
205 (void) strcpy(dbfile, pname);
206 (void) strcat(dbfile, dbm_pag);
207
208 if (stat64(dbfile, &filestat) != -1) {
209 return (TRUE);
210 } else {
211
212 if (errno != ENOENT) {
213 logprintf2(
214 "Stat error on map file %s.\n",
215 dbfile);
216 }
217
218 return (FALSE);
219 }
220
221 } else {
222
223 if (errno != ENOENT) {
224 logprintf2(
225 "Stat error on map file %s.\n",
226 dbfile);
227 }
228
229 return (FALSE);
230 }
231 }
232
233 /*
234 * FUNCTION : logprintf2()
235 *
236 * DESCRIPTION: The functions in this file were oringinaly shared between
237 * ypxfr and ypserv. On error they called logprintf().
238 * Unfortunatly this had been implemented differently in the two
239 * sources and not at all in some of the NIS components required
240 * for N2L.
241 *
242 * This function is simplified version of logprinf() as/when
243 * possible the other error calls should be migrated to use this
244 * common version. If a common set of functionality can be found
245 * this versions should be modified to support it.
246 */
247 void
logprintf2(char * format,...)248 logprintf2(char *format, ...)
249 {
250 va_list ap;
251
252 va_start(ap, format);
253
254 syslog(LOG_ERR, format, ap);
255
256 va_end(ap);
257 }
258
259 /*
260 * This performs an existence check on the dbm data base files <name>.pag and
261 * <name>.dir. pname is a ptr to the filename. This should be an absolute
262 * path.
263 * Returns TRUE if the map exists and is accessable; else FALSE.
264 *
265 * Note: The file name should be a "base" form, without a file "extension" of
266 * .dir or .pag appended. See ypmkfilename for a function which will generate
267 * the name correctly. Errors in the stat call will be reported at this level,
268 * however, the non-existence of a file is not considered an error, and so will
269 * not be reported.
270 *
271 * Calls ypcheck_map_existence_yptol() defined in
272 * usr/src/lib/libnisdb/yptol/shim_ancil.c
273 */
274 bool
ypcheck_map_existence(char * pname)275 ypcheck_map_existence(char *pname)
276 {
277 return (ypcheck_map_existence_yptol(pname));
278 }
279