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.
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.
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]
22 * Copyright 2015 Gary Mills
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
43 #include "../ldap_util.h"
46 * This constructs a file name from a passed domain name, a passed map name,
47 * and a globally known YP data base path prefix.
49 * Has to be in shim because it needs the N2L prefix
51 * RETURNS : TRUE = A name was successfully created
52 * FALSE = A name could not be created
56 ypmkfilename(domain
, map
, path
)
63 /* Do not allow any path as a domain name. */
64 if (strchr(domain
, '/') != NULL
)
67 length
= strlen(domain
) + strlen(map
) + ypdbpath_sz
+ 3;
69 length
+= strlen(NTOL_PREFIX
) + 1;
71 if ((MAXNAMLEN
+ 1) < length
) {
72 (void) fprintf(stderr
, "ypserv: Map name string too long.\n");
76 strcpy(path
, ypdbpath
);
81 /* If in N2L mode add N2L prefix */
83 strcat(path
, NTOL_PREFIX
);
90 * check whether a map is already in an array/list
92 * RETURNS: TRUE if yes
96 on_maplist(char *mapname
, char **list
) {
103 while (list
[i
] != NULL
) {
104 if (strcmp(mapname
, list
[i
++]) == 0) {
113 * add a map at the end of an array/list
115 * list_len: if -1, we do not know list length
117 * RETURNS: TRUE if map was added
121 add_in_maplist(char *mapname
, char ***list
, int *list_len
) {
131 if (list_tmp
== NULL
) {
134 /* find 1st free element */
135 while (list_tmp
[i
] != NULL
) {
137 * increment in loop so that
138 * list_tmp[i] == NULL
145 /* if we don't know list length, assume we reach its end */
146 if (*list_len
== -1) {
150 /* do we need to reallocate ? */
151 if (i
+1 >= *list_len
) {
152 list_tmp
= (char **)realloc(list_tmp
,
153 (*list_len
+ ARRAY_CHUNK
) *
155 if (list_tmp
== NULL
) {
159 *list_len
+= ARRAY_CHUNK
;
163 (*list
)[i
] = strdup(mapname
);
164 if ((*list
)[i
] == NULL
) {
165 /* strdup() failed */
174 * This checks to see whether a domain name is present at the local node as a
175 * subdirectory of ypdbpath
177 * Was originally in cmd/ypcmd/shared/ancil.c as ypcheck_domain(domain).
178 * Now ypcheck_domain(domain) calls this function.
181 ypcheck_domain_yptol(char *domain
)
183 char path
[MAXNAMLEN
+ 1];
184 struct stat filestat
;
185 bool present
= FALSE
;
187 strcpy(path
, ypdbpath
);
189 if (strlcat(path
, domain
, MAXNAMLEN
+ 1) >= MAXNAMLEN
+ 1)
192 if (stat(path
, &filestat
) != -1) {
193 if (S_ISDIR(filestat
.st_mode
))
200 * This performs an existence check on the dbm data base files <name>.pag and
201 * <name>.dir. pname is a ptr to the filename. This should be an absolute
203 * Returns TRUE if the map exists and is accessible; else FALSE.
205 * Note: The file name should be a "base" form, without a file "extension" of
206 * .dir or .pag appended. See ypmkfilename for a function which will generate
207 * the name correctly. Errors in the stat call will be reported at this level,
208 * however, the non-existence of a file is not considered an error, and so will
211 * Was originally in cmd/ypcmd/shared/utils.c as ypcheck_map_existence().
212 * Now ypcheck_map_existence() calls this function.
215 ypcheck_map_existence_yptol(char *pname
)
217 char dbfile
[MAXNAMLEN
+ sizeof (TTL_POSTFIX
) + 1];
218 struct stat64 filestat
;
221 if (!pname
|| ((len
= (int)strlen(pname
)) == 0) ||
222 (len
+ sizeof (dbm_pag
) + sizeof (TTL_POSTFIX
)) >
229 /* Check for existance of .dir file */
230 (void) strcpy(dbfile
, pname
);
231 (void) strcat(dbfile
, dbm_dir
);
233 if (stat64(dbfile
, &filestat
) == -1) {
234 if (errno
!= ENOENT
) {
235 (void) fprintf(stderr
,
236 "ypserv: Stat error on map file %s.\n",
242 /* Check for existance of .pag file */
243 (void) strcpy(dbfile
, pname
);
244 (void) strcat(dbfile
, dbm_pag
);
246 if (stat64(dbfile
, &filestat
) == -1) {
247 if (errno
!= ENOENT
) {
248 (void) fprintf(stderr
,
249 "ypserv: Stat error on map file %s.\n",
256 /* Check for existance of TTL .dir file */
257 (void) strcpy(dbfile
, pname
);
258 (void) strcat(dbfile
, TTL_POSTFIX
);
259 (void) strcat(dbfile
, dbm_dir
);
261 if (stat64(dbfile
, &filestat
) == -1) {
262 if (errno
!= ENOENT
) {
263 (void) fprintf(stderr
,
264 "ypserv: Stat error on map file %s.\n",
270 /* Check for existance of TTL .pag file */
271 (void) strcpy(dbfile
, pname
);
272 (void) strcat(dbfile
, TTL_POSTFIX
);
273 (void) strcat(dbfile
, dbm_pag
);
275 if (stat64(dbfile
, &filestat
) == -1) {
276 if (errno
!= ENOENT
) {
277 (void) fprintf(stderr
,
278 "ypserv: Stat error on map file %s.\n",
289 * This adds maps in a domain to a given list,
290 * from maps in /var/yp/<domain>
291 * Inspired from yplist_maps() in cmd/ypcmd/ypserv_ancil.c
293 * domain is the relevant domain name
294 * map_list is the list of maps in an array of map names,
295 * which may or may not be empty
297 * RETURNS : TRUE = everything went fine
298 * FALSE = an error occured
301 add_map_domain_to_list(char *domain
, char ***map_list
)
303 char domdir
[MAXNAMLEN
+ 1];
304 char path
[MAXNAMLEN
+ 1];
305 int domdir_len
= sizeof (domdir
);
309 int dbm_pag_len
= sizeof (dbm_pag
);
312 int map_list_len
= -1;
314 if (map_list
== NULL
) {
318 /* no domain, not a problem */
319 if (domain
== NULL
) {
323 /* not a valid domain, not a problem */
324 if (!ypcheck_domain_yptol(domain
)) {
328 if (snprintf(domdir
, domdir_len
, "%s/%s", ypdbpath
, domain
)
333 if ((dirp
= opendir(domdir
)) == NULL
) {
337 for (dp
= readdir(dirp
); dp
!= NULL
;
338 dp
= readdir(dirp
)) {
340 * If it's possible that the file name is one of the two files
341 * implementing a map, remove the extension (dbm_pag or dbm_dir)
343 name_len
= (int)strlen(dp
->d_name
);
345 if (name_len
< dbm_pag_len
- 1) {
346 continue; /* Too Short */
349 ext
= &(dp
->d_name
[name_len
- (dbm_pag_len
- 1)]);
351 if (strcmp(ext
, dbm_pag
) != 0) {
352 continue; /* No dbm file extension */
358 * In yptol mode look at LDAP_ prefixed maps. In non yptol mode
362 if (0 != strncmp(dp
->d_name
, NTOL_PREFIX
,
363 strlen(NTOL_PREFIX
))) {
368 * Already have an LDAP_ prefix. Don't want to add it
371 mapname
= dp
->d_name
+ strlen(NTOL_PREFIX
);
373 if (0 == strncmp(dp
->d_name
, NTOL_PREFIX
,
374 strlen(NTOL_PREFIX
))) {
377 mapname
= dp
->d_name
;
380 if (ypmkfilename(domain
, mapname
, path
) == FALSE
) {
381 (void) closedir(dirp
);
386 * At this point, path holds the map file base name (no dbm
387 * file extension), and mapname holds the map name.
389 if (ypcheck_map_existence_yptol(path
) &&
390 !on_maplist(mapname
, *map_list
)) {
391 if (add_in_maplist(mapname
, map_list
, &map_list_len
) ==
393 (void) closedir(dirp
);
399 (void) closedir(dirp
);