1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro * Copyright (c) 1998-2008 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro * All rights reserved.
4c2aa98e2SPeter Wemm * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved.
5c2aa98e2SPeter Wemm * Copyright (c) 1992, 1993
6c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved.
7c2aa98e2SPeter Wemm *
8c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm * the sendmail distribution.
11c2aa98e2SPeter Wemm *
12c2aa98e2SPeter Wemm */
13c2aa98e2SPeter Wemm
1406f25ae9SGregory Neil Shapiro #include <sendmail.h>
1506f25ae9SGregory Neil Shapiro
164313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: map.c,v 8.713 2013-11-22 20:51:55 ca Exp $")
172fb4f839SGregory Neil Shapiro #include <sm/sendmail.h>
18c2aa98e2SPeter Wemm
1940266059SGregory Neil Shapiro #if LDAPMAP
2040266059SGregory Neil Shapiro # include <sm/ldap.h>
215b0945b5SGregory Neil Shapiro #endif
2240266059SGregory Neil Shapiro
2340266059SGregory Neil Shapiro #if NDBM
24c2aa98e2SPeter Wemm # include <ndbm.h>
25c2aa98e2SPeter Wemm # ifdef R_FIRST
262fb4f839SGregory Neil Shapiro # error "README: You are running the Berkeley DB version of ndbm.h. See"
272fb4f839SGregory Neil Shapiro # error "README: the README file about tweaking Berkeley DB so it can"
282fb4f839SGregory Neil Shapiro # error "README: coexist with NDBM, or delete -DNDBM from the Makefile"
292fb4f839SGregory Neil Shapiro # error "README: and use -DNEWDB instead."
3006f25ae9SGregory Neil Shapiro # endif /* R_FIRST */
3106f25ae9SGregory Neil Shapiro #endif /* NDBM */
3240266059SGregory Neil Shapiro #if NEWDB
3313bd1963SGregory Neil Shapiro # include "sm/bdb.h"
345b0945b5SGregory Neil Shapiro #endif
3540266059SGregory Neil Shapiro #if NIS
36c2aa98e2SPeter Wemm struct dom_binding; /* forward reference needed on IRIX */
37c2aa98e2SPeter Wemm # include <rpcsvc/ypclnt.h>
3840266059SGregory Neil Shapiro # if NDBM
39c2aa98e2SPeter Wemm # define NDBM_YP_COMPAT /* create YP-compatible NDBM files */
405b0945b5SGregory Neil Shapiro # endif
4106f25ae9SGregory Neil Shapiro #endif /* NIS */
425b0945b5SGregory Neil Shapiro #if CDB
435b0945b5SGregory Neil Shapiro # include <cdb.h>
445b0945b5SGregory Neil Shapiro #endif
4506f25ae9SGregory Neil Shapiro
46d0cef73dSGregory Neil Shapiro #include "map.h"
47d0cef73dSGregory Neil Shapiro
4840266059SGregory Neil Shapiro #if NEWDB
4906f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR < 2
5006f25ae9SGregory Neil Shapiro static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
515b0945b5SGregory Neil Shapiro # endif
5206f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR == 2
5306f25ae9SGregory Neil Shapiro static bool db_map_open __P((MAP *, int, char *, DBTYPE, DB_INFO *));
545b0945b5SGregory Neil Shapiro # endif
5506f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR > 2
5606f25ae9SGregory Neil Shapiro static bool db_map_open __P((MAP *, int, char *, DBTYPE, void **));
575b0945b5SGregory Neil Shapiro # endif
5806f25ae9SGregory Neil Shapiro #endif /* NEWDB */
59602a2b1bSGregory Neil Shapiro static bool extract_canonname __P((char *, char *, char *, char[], int));
6006f25ae9SGregory Neil Shapiro static void map_close __P((STAB *, int));
6106f25ae9SGregory Neil Shapiro static void map_init __P((STAB *, int));
6240266059SGregory Neil Shapiro #ifdef LDAPMAP
6340266059SGregory Neil Shapiro static STAB *ldapmap_findconn __P((SM_LDAP_STRUCT *));
645b0945b5SGregory Neil Shapiro #endif
6540266059SGregory Neil Shapiro #if NISPLUS
6606f25ae9SGregory Neil Shapiro static bool nisplus_getcanonname __P((char *, int, int *));
675b0945b5SGregory Neil Shapiro #endif
6840266059SGregory Neil Shapiro #if NIS
6906f25ae9SGregory Neil Shapiro static bool nis_getcanonname __P((char *, int, int *));
705b0945b5SGregory Neil Shapiro #endif
7106f25ae9SGregory Neil Shapiro #if NETINFO
7206f25ae9SGregory Neil Shapiro static bool ni_getcanonname __P((char *, int, int *));
735b0945b5SGregory Neil Shapiro #endif
7406f25ae9SGregory Neil Shapiro static bool text_getcanonname __P((char *, int, int *));
75e92d3f3fSGregory Neil Shapiro #if SOCKETMAP
76e92d3f3fSGregory Neil Shapiro static STAB *socket_map_findconn __P((const char*));
77e92d3f3fSGregory Neil Shapiro
78e92d3f3fSGregory Neil Shapiro /* XXX arbitrary limit for sanity */
79e92d3f3fSGregory Neil Shapiro # define SOCKETMAP_MAXL 1000000
80e92d3f3fSGregory Neil Shapiro #endif /* SOCKETMAP */
81c2aa98e2SPeter Wemm
8240266059SGregory Neil Shapiro /* default error message for trying to open a map in write mode */
8340266059SGregory Neil Shapiro #ifdef ENOSYS
8440266059SGregory Neil Shapiro # define SM_EMAPCANTWRITE ENOSYS
8540266059SGregory Neil Shapiro #else /* ENOSYS */
8640266059SGregory Neil Shapiro # ifdef EFTYPE
8740266059SGregory Neil Shapiro # define SM_EMAPCANTWRITE EFTYPE
885b0945b5SGregory Neil Shapiro # else
8940266059SGregory Neil Shapiro # define SM_EMAPCANTWRITE ENXIO
905b0945b5SGregory Neil Shapiro # endif
9140266059SGregory Neil Shapiro #endif /* ENOSYS */
9240266059SGregory Neil Shapiro
93c2aa98e2SPeter Wemm /*
94*d39bd2c1SGregory Neil Shapiro ** MAP_HAS_CHGED -- check whether fd was updated or fn refers to a different file
95*d39bd2c1SGregory Neil Shapiro **
96*d39bd2c1SGregory Neil Shapiro ** Parameters:
97*d39bd2c1SGregory Neil Shapiro ** map -- map being checked
98*d39bd2c1SGregory Neil Shapiro ** fn -- (full) file name of map.
99*d39bd2c1SGregory Neil Shapiro ** fd -- fd of map.
100*d39bd2c1SGregory Neil Shapiro **
101*d39bd2c1SGregory Neil Shapiro ** Returns:
102*d39bd2c1SGregory Neil Shapiro ** true iff file referenced by fd was updated
103*d39bd2c1SGregory Neil Shapiro ** or fn refers to a different file.
104*d39bd2c1SGregory Neil Shapiro */
105*d39bd2c1SGregory Neil Shapiro
106*d39bd2c1SGregory Neil Shapiro static bool map_has_chged __P((MAP *, const char *, int));
107*d39bd2c1SGregory Neil Shapiro
108*d39bd2c1SGregory Neil Shapiro static bool
map_has_chged(map,fn,fd)109*d39bd2c1SGregory Neil Shapiro map_has_chged(map, fn, fd)
110*d39bd2c1SGregory Neil Shapiro MAP *map;
111*d39bd2c1SGregory Neil Shapiro const char *fn;
112*d39bd2c1SGregory Neil Shapiro int fd;
113*d39bd2c1SGregory Neil Shapiro {
114*d39bd2c1SGregory Neil Shapiro struct stat stbuf;
115*d39bd2c1SGregory Neil Shapiro #if _FFR_MAP_CHK_FILE
116*d39bd2c1SGregory Neil Shapiro struct stat nstbuf;
117*d39bd2c1SGregory Neil Shapiro #endif
118*d39bd2c1SGregory Neil Shapiro
119*d39bd2c1SGregory Neil Shapiro #if _FFR_MAP_CHK_FILE > 1
120*d39bd2c1SGregory Neil Shapiro if (tTd(38, 8))
121*d39bd2c1SGregory Neil Shapiro sm_dprintf("map_has_chged: fn=%s, fd=%d, checked=%d\n",
122*d39bd2c1SGregory Neil Shapiro fn, fd, bitset(MF_CHKED_CHGD, map->map_mflags));
123*d39bd2c1SGregory Neil Shapiro if (fd < 0)
124*d39bd2c1SGregory Neil Shapiro return true;
125*d39bd2c1SGregory Neil Shapiro
126*d39bd2c1SGregory Neil Shapiro /* XXX check can be disabled via -d38.101 for testing */
127*d39bd2c1SGregory Neil Shapiro if (bitset(MF_CHKED_CHGD, map->map_mflags) && !tTd(38, 101))
128*d39bd2c1SGregory Neil Shapiro return false;
129*d39bd2c1SGregory Neil Shapiro map->map_mflags |= MF_CHKED_CHGD;
130*d39bd2c1SGregory Neil Shapiro #endif
131*d39bd2c1SGregory Neil Shapiro if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
132*d39bd2c1SGregory Neil Shapiro {
133*d39bd2c1SGregory Neil Shapiro if (tTd(38, 4))
134*d39bd2c1SGregory Neil Shapiro sm_dprintf("reopen map: name=%s, fd=%d\n", map->map_mname, fd);
135*d39bd2c1SGregory Neil Shapiro return true;
136*d39bd2c1SGregory Neil Shapiro }
137*d39bd2c1SGregory Neil Shapiro #if _FFR_MAP_CHK_FILE
138*d39bd2c1SGregory Neil Shapiro if (stat(fn, &nstbuf) == 0 &&
139*d39bd2c1SGregory Neil Shapiro (nstbuf.st_dev != stbuf.st_dev || nstbuf.st_ino != stbuf.st_ino))
140*d39bd2c1SGregory Neil Shapiro {
141*d39bd2c1SGregory Neil Shapiro if (tTd(38, 4) && stat(fn, &nstbuf) == 0)
142*d39bd2c1SGregory Neil Shapiro sm_dprintf("reopen map: fn=%s, ndev=%d, dev=%d, nino=%d, ino=%d\n",
143*d39bd2c1SGregory Neil Shapiro fn, (int) nstbuf.st_dev, (int) stbuf.st_dev,
144*d39bd2c1SGregory Neil Shapiro (int) nstbuf.st_ino, (int) stbuf.st_ino);
145*d39bd2c1SGregory Neil Shapiro return true;
146*d39bd2c1SGregory Neil Shapiro }
147*d39bd2c1SGregory Neil Shapiro #endif
148*d39bd2c1SGregory Neil Shapiro return false;
149*d39bd2c1SGregory Neil Shapiro }
150*d39bd2c1SGregory Neil Shapiro
151*d39bd2c1SGregory Neil Shapiro #if _FFR_MAP_CHK_FILE > 1
152*d39bd2c1SGregory Neil Shapiro
153*d39bd2c1SGregory Neil Shapiro /*
154*d39bd2c1SGregory Neil Shapiro ** MAP_RESET_CHGD -- reset MF_CHKED_CHGD in a map
155*d39bd2c1SGregory Neil Shapiro **
156*d39bd2c1SGregory Neil Shapiro ** Parameters:
157*d39bd2c1SGregory Neil Shapiro ** s -- STAB entry: if map: reset MF_CHKED_CHGD
158*d39bd2c1SGregory Neil Shapiro ** unused -- unused variable
159*d39bd2c1SGregory Neil Shapiro **
160*d39bd2c1SGregory Neil Shapiro ** Returns:
161*d39bd2c1SGregory Neil Shapiro ** none.
162*d39bd2c1SGregory Neil Shapiro */
163*d39bd2c1SGregory Neil Shapiro
164*d39bd2c1SGregory Neil Shapiro static void map_reset_chged __P((STAB *, int));
165*d39bd2c1SGregory Neil Shapiro
166*d39bd2c1SGregory Neil Shapiro /* ARGSUSED1 */
167*d39bd2c1SGregory Neil Shapiro static void
map_reset_chged(s,unused)168*d39bd2c1SGregory Neil Shapiro map_reset_chged(s, unused)
169*d39bd2c1SGregory Neil Shapiro STAB *s;
170*d39bd2c1SGregory Neil Shapiro int unused;
171*d39bd2c1SGregory Neil Shapiro {
172*d39bd2c1SGregory Neil Shapiro MAP *map;
173*d39bd2c1SGregory Neil Shapiro
174*d39bd2c1SGregory Neil Shapiro /* has to be a map */
175*d39bd2c1SGregory Neil Shapiro if (ST_MAP != s->s_symtype
176*d39bd2c1SGregory Neil Shapiro #if _FFR_DYN_CLASS
177*d39bd2c1SGregory Neil Shapiro && ST_DYNMAP != s->s_symtype
178*d39bd2c1SGregory Neil Shapiro #endif
179*d39bd2c1SGregory Neil Shapiro )
180*d39bd2c1SGregory Neil Shapiro return;
181*d39bd2c1SGregory Neil Shapiro map = &s->s_map;
182*d39bd2c1SGregory Neil Shapiro if (!bitset(MF_VALID, map->map_mflags))
183*d39bd2c1SGregory Neil Shapiro return;
184*d39bd2c1SGregory Neil Shapiro if (tTd(38, 8))
185*d39bd2c1SGregory Neil Shapiro sm_dprintf("map_reset_chged: name=%s, checked=%d\n",
186*d39bd2c1SGregory Neil Shapiro map->map_mname, bitset(MF_CHKED_CHGD, map->map_mflags));
187*d39bd2c1SGregory Neil Shapiro map->map_mflags &= ~MF_CHKED_CHGD;
188*d39bd2c1SGregory Neil Shapiro }
189*d39bd2c1SGregory Neil Shapiro
190*d39bd2c1SGregory Neil Shapiro /*
191*d39bd2c1SGregory Neil Shapiro ** MAPS_RESET_CHGD -- reset MF_CHKED_CHGD in all maps
192*d39bd2c1SGregory Neil Shapiro **
193*d39bd2c1SGregory Neil Shapiro ** Parameters:
194*d39bd2c1SGregory Neil Shapiro ** msg - caller (for debugging)
195*d39bd2c1SGregory Neil Shapiro **
196*d39bd2c1SGregory Neil Shapiro ** Returns:
197*d39bd2c1SGregory Neil Shapiro ** none.
198*d39bd2c1SGregory Neil Shapiro */
199*d39bd2c1SGregory Neil Shapiro
200*d39bd2c1SGregory Neil Shapiro void
maps_reset_chged(msg)201*d39bd2c1SGregory Neil Shapiro maps_reset_chged(msg)
202*d39bd2c1SGregory Neil Shapiro const char *msg;
203*d39bd2c1SGregory Neil Shapiro {
204*d39bd2c1SGregory Neil Shapiro if (tTd(38, 16))
205*d39bd2c1SGregory Neil Shapiro sm_dprintf("maps_reset_chged: msg=%s\n", msg);
206*d39bd2c1SGregory Neil Shapiro stabapply(map_reset_chged, 0);
207*d39bd2c1SGregory Neil Shapiro }
208*d39bd2c1SGregory Neil Shapiro #endif /* _FFR_MAP_CHK_FILE > 1 */
209*d39bd2c1SGregory Neil Shapiro
210*d39bd2c1SGregory Neil Shapiro
211*d39bd2c1SGregory Neil Shapiro #if NEWDB || CDB || (NDBM && _FFR_MAP_CHK_FILE)
212*d39bd2c1SGregory Neil Shapiro static bool smdb_add_extension __P((char *, int, char *, char *));
213*d39bd2c1SGregory Neil Shapiro
214*d39bd2c1SGregory Neil Shapiro /*
215*d39bd2c1SGregory Neil Shapiro ** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
216*d39bd2c1SGregory Neil Shapiro **
217*d39bd2c1SGregory Neil Shapiro ** Just adds a . followed by a string to a db_name if there
218*d39bd2c1SGregory Neil Shapiro ** is room and the db_name does not already have that extension.
219*d39bd2c1SGregory Neil Shapiro **
220*d39bd2c1SGregory Neil Shapiro ** Parameters:
221*d39bd2c1SGregory Neil Shapiro ** full_name -- The final file name.
222*d39bd2c1SGregory Neil Shapiro ** max_full_name_len -- The max length for full_name.
223*d39bd2c1SGregory Neil Shapiro ** db_name -- The name of the db.
224*d39bd2c1SGregory Neil Shapiro ** extension -- The extension to add.
225*d39bd2c1SGregory Neil Shapiro **
226*d39bd2c1SGregory Neil Shapiro ** Returns:
227*d39bd2c1SGregory Neil Shapiro ** SMDBE_OK -- Success.
228*d39bd2c1SGregory Neil Shapiro ** Anything else is an error. Look up more info about the
229*d39bd2c1SGregory Neil Shapiro ** error in the comments for the specific open() used.
230*d39bd2c1SGregory Neil Shapiro */
231*d39bd2c1SGregory Neil Shapiro
232*d39bd2c1SGregory Neil Shapiro static bool
smdb_add_extension(full_name,max_full_name_len,db_name,extension)233*d39bd2c1SGregory Neil Shapiro smdb_add_extension(full_name, max_full_name_len, db_name, extension)
234*d39bd2c1SGregory Neil Shapiro char *full_name;
235*d39bd2c1SGregory Neil Shapiro int max_full_name_len;
236*d39bd2c1SGregory Neil Shapiro char *db_name;
237*d39bd2c1SGregory Neil Shapiro char *extension;
238*d39bd2c1SGregory Neil Shapiro {
239*d39bd2c1SGregory Neil Shapiro int extension_len;
240*d39bd2c1SGregory Neil Shapiro int db_name_len;
241*d39bd2c1SGregory Neil Shapiro
242*d39bd2c1SGregory Neil Shapiro if (full_name == NULL || db_name == NULL || extension == NULL)
243*d39bd2c1SGregory Neil Shapiro return false; /* SMDBE_INVALID_PARAMETER; */
244*d39bd2c1SGregory Neil Shapiro
245*d39bd2c1SGregory Neil Shapiro extension_len = strlen(extension);
246*d39bd2c1SGregory Neil Shapiro db_name_len = strlen(db_name);
247*d39bd2c1SGregory Neil Shapiro
248*d39bd2c1SGregory Neil Shapiro if (extension_len + db_name_len + 2 > max_full_name_len)
249*d39bd2c1SGregory Neil Shapiro return false; /* SMDBE_DB_NAME_TOO_LONG; */
250*d39bd2c1SGregory Neil Shapiro
251*d39bd2c1SGregory Neil Shapiro if (db_name_len < extension_len + 1 ||
252*d39bd2c1SGregory Neil Shapiro db_name[db_name_len - extension_len - 1] != '.' ||
253*d39bd2c1SGregory Neil Shapiro strcmp(&db_name[db_name_len - extension_len], extension) != 0)
254*d39bd2c1SGregory Neil Shapiro (void) sm_snprintf(full_name, max_full_name_len, "%s.%s",
255*d39bd2c1SGregory Neil Shapiro db_name, extension);
256*d39bd2c1SGregory Neil Shapiro else
257*d39bd2c1SGregory Neil Shapiro (void) sm_strlcpy(full_name, db_name, max_full_name_len);
258*d39bd2c1SGregory Neil Shapiro
259*d39bd2c1SGregory Neil Shapiro return true;
260*d39bd2c1SGregory Neil Shapiro }
261*d39bd2c1SGregory Neil Shapiro #endif /* NEWDB || CDB || (NDBM && _FFR_MAP_CHK_FILE) */
262*d39bd2c1SGregory Neil Shapiro
263*d39bd2c1SGregory Neil Shapiro /*
264c2aa98e2SPeter Wemm ** MAP.C -- implementations for various map classes.
265c2aa98e2SPeter Wemm **
266c2aa98e2SPeter Wemm ** Each map class implements a series of functions:
267c2aa98e2SPeter Wemm **
268c2aa98e2SPeter Wemm ** bool map_parse(MAP *map, char *args)
26940266059SGregory Neil Shapiro ** Parse the arguments from the config file. Return true
27040266059SGregory Neil Shapiro ** if they were ok, false otherwise. Fill in map with the
271c2aa98e2SPeter Wemm ** values.
272c2aa98e2SPeter Wemm **
273c2aa98e2SPeter Wemm ** char *map_lookup(MAP *map, char *key, char **args, int *pstat)
274c2aa98e2SPeter Wemm ** Look up the key in the given map. If found, do any
275c2aa98e2SPeter Wemm ** rewriting the map wants (including "args" if desired)
276c2aa98e2SPeter Wemm ** and return the value. Set *pstat to the appropriate status
277c2aa98e2SPeter Wemm ** on error and return NULL. Args will be NULL if called
278c2aa98e2SPeter Wemm ** from the alias routines, although this should probably
279c2aa98e2SPeter Wemm ** not be relied upon. It is suggested you call map_rewrite
280c2aa98e2SPeter Wemm ** to return the results -- it takes care of null termination
281c2aa98e2SPeter Wemm ** and uses a dynamically expanded buffer as needed.
282c2aa98e2SPeter Wemm **
283c2aa98e2SPeter Wemm ** void map_store(MAP *map, char *key, char *value)
284c2aa98e2SPeter Wemm ** Store the key:value pair in the map.
285c2aa98e2SPeter Wemm **
286c2aa98e2SPeter Wemm ** bool map_open(MAP *map, int mode)
287c2aa98e2SPeter Wemm ** Open the map for the indicated mode. Mode should
28840266059SGregory Neil Shapiro ** be either O_RDONLY or O_RDWR. Return true if it
28940266059SGregory Neil Shapiro ** was opened successfully, false otherwise. If the open
29040266059SGregory Neil Shapiro ** failed and the MF_OPTIONAL flag is not set, it should
291c2aa98e2SPeter Wemm ** also print an error. If the MF_ALIAS bit is set
292c2aa98e2SPeter Wemm ** and this map class understands the @:@ convention, it
293c2aa98e2SPeter Wemm ** should call aliaswait() before returning.
294c2aa98e2SPeter Wemm **
295c2aa98e2SPeter Wemm ** void map_close(MAP *map)
296c2aa98e2SPeter Wemm ** Close the map.
297c2aa98e2SPeter Wemm **
298c2aa98e2SPeter Wemm ** This file also includes the implementation for getcanonname.
299c2aa98e2SPeter Wemm ** It is currently implemented in a pretty ad-hoc manner; it ought
300c2aa98e2SPeter Wemm ** to be more properly integrated into the map structure.
301c2aa98e2SPeter Wemm */
302c2aa98e2SPeter Wemm
303*d39bd2c1SGregory Neil Shapiro /* XREF: conf.c must use the same expression */
304c2aa98e2SPeter Wemm #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
305c2aa98e2SPeter Wemm # define LOCK_ON_OPEN 1 /* we can open/create a locked file */
3065b0945b5SGregory Neil Shapiro #else
307c2aa98e2SPeter Wemm # define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
3085b0945b5SGregory Neil Shapiro #endif
309c2aa98e2SPeter Wemm
31040266059SGregory Neil Shapiro /*
311c2aa98e2SPeter Wemm ** MAP_PARSEARGS -- parse config line arguments for database lookup
312c2aa98e2SPeter Wemm **
313c2aa98e2SPeter Wemm ** This is a generic version of the map_parse method.
314c2aa98e2SPeter Wemm **
315c2aa98e2SPeter Wemm ** Parameters:
316c2aa98e2SPeter Wemm ** map -- the map being initialized.
317c2aa98e2SPeter Wemm ** ap -- a pointer to the args on the config line.
318c2aa98e2SPeter Wemm **
319c2aa98e2SPeter Wemm ** Returns:
32040266059SGregory Neil Shapiro ** true -- if everything parsed OK.
32140266059SGregory Neil Shapiro ** false -- otherwise.
322c2aa98e2SPeter Wemm **
323c2aa98e2SPeter Wemm ** Side Effects:
324c2aa98e2SPeter Wemm ** null terminates the filename; stores it in map
325c2aa98e2SPeter Wemm */
326c2aa98e2SPeter Wemm
327c2aa98e2SPeter Wemm bool
map_parseargs(map,ap)328c2aa98e2SPeter Wemm map_parseargs(map, ap)
329c2aa98e2SPeter Wemm MAP *map;
330c2aa98e2SPeter Wemm char *ap;
331c2aa98e2SPeter Wemm {
332c2aa98e2SPeter Wemm register char *p = ap;
333c2aa98e2SPeter Wemm
33406f25ae9SGregory Neil Shapiro /*
33540266059SGregory Neil Shapiro ** There is no check whether there is really an argument,
33640266059SGregory Neil Shapiro ** but that's not important enough to warrant extra code.
33706f25ae9SGregory Neil Shapiro */
33840266059SGregory Neil Shapiro
339c2aa98e2SPeter Wemm map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
34006f25ae9SGregory Neil Shapiro map->map_spacesub = SpaceSub; /* default value */
341c2aa98e2SPeter Wemm for (;;)
342c2aa98e2SPeter Wemm {
3435b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
344c2aa98e2SPeter Wemm p++;
345c2aa98e2SPeter Wemm if (*p != '-')
346c2aa98e2SPeter Wemm break;
347c2aa98e2SPeter Wemm switch (*++p)
348c2aa98e2SPeter Wemm {
349c2aa98e2SPeter Wemm case 'A':
350c2aa98e2SPeter Wemm map->map_mflags |= MF_APPEND;
351c2aa98e2SPeter Wemm break;
352c2aa98e2SPeter Wemm
353c2aa98e2SPeter Wemm case 'a':
354c2aa98e2SPeter Wemm map->map_app = ++p;
355c2aa98e2SPeter Wemm break;
356c2aa98e2SPeter Wemm
3575b0945b5SGregory Neil Shapiro case 'D':
3585b0945b5SGregory Neil Shapiro map->map_mflags |= MF_DEFER;
3595b0945b5SGregory Neil Shapiro break;
3605b0945b5SGregory Neil Shapiro
361da7d7b9cSGregory Neil Shapiro case 'd':
362da7d7b9cSGregory Neil Shapiro {
363da7d7b9cSGregory Neil Shapiro char *h;
364da7d7b9cSGregory Neil Shapiro
365da7d7b9cSGregory Neil Shapiro ++p;
366da7d7b9cSGregory Neil Shapiro h = strchr(p, ' ');
367da7d7b9cSGregory Neil Shapiro if (h != NULL)
368da7d7b9cSGregory Neil Shapiro *h = '\0';
369da7d7b9cSGregory Neil Shapiro map->map_timeout = convtime(p, 's');
370da7d7b9cSGregory Neil Shapiro if (h != NULL)
371da7d7b9cSGregory Neil Shapiro *h = ' ';
372da7d7b9cSGregory Neil Shapiro }
373da7d7b9cSGregory Neil Shapiro break;
374da7d7b9cSGregory Neil Shapiro
3755b0945b5SGregory Neil Shapiro case 'f':
3765b0945b5SGregory Neil Shapiro map->map_mflags |= MF_NOFOLDCASE;
377c2aa98e2SPeter Wemm break;
378c2aa98e2SPeter Wemm
379c2aa98e2SPeter Wemm case 'k':
380c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p))
381c2aa98e2SPeter Wemm continue;
382c2aa98e2SPeter Wemm map->map_keycolnm = p;
383c2aa98e2SPeter Wemm break;
384c2aa98e2SPeter Wemm
3855b0945b5SGregory Neil Shapiro case 'm':
3865b0945b5SGregory Neil Shapiro map->map_mflags |= MF_MATCHONLY;
3875b0945b5SGregory Neil Shapiro break;
3885b0945b5SGregory Neil Shapiro
3895b0945b5SGregory Neil Shapiro case 'N':
3905b0945b5SGregory Neil Shapiro map->map_mflags |= MF_INCLNULL;
3915b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_TRY0NULL;
3925b0945b5SGregory Neil Shapiro break;
3935b0945b5SGregory Neil Shapiro
3945b0945b5SGregory Neil Shapiro case 'O':
3955b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_TRY1NULL;
3965b0945b5SGregory Neil Shapiro break;
3975b0945b5SGregory Neil Shapiro
3985b0945b5SGregory Neil Shapiro case 'o':
3995b0945b5SGregory Neil Shapiro map->map_mflags |= MF_OPTIONAL;
4005b0945b5SGregory Neil Shapiro break;
4015b0945b5SGregory Neil Shapiro
4025b0945b5SGregory Neil Shapiro case 'q':
4035b0945b5SGregory Neil Shapiro map->map_mflags |= MF_KEEPQUOTES;
4045b0945b5SGregory Neil Shapiro break;
4055b0945b5SGregory Neil Shapiro
4065b0945b5SGregory Neil Shapiro case 'S':
4075b0945b5SGregory Neil Shapiro map->map_spacesub = *++p;
4085b0945b5SGregory Neil Shapiro break;
4095b0945b5SGregory Neil Shapiro
4105b0945b5SGregory Neil Shapiro case 'T':
4115b0945b5SGregory Neil Shapiro map->map_tapp = ++p;
4125b0945b5SGregory Neil Shapiro break;
4135b0945b5SGregory Neil Shapiro
4145b0945b5SGregory Neil Shapiro case 't':
4155b0945b5SGregory Neil Shapiro map->map_mflags |= MF_NODEFER;
4165b0945b5SGregory Neil Shapiro break;
4175b0945b5SGregory Neil Shapiro
418c2aa98e2SPeter Wemm case 'v':
419c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p))
420c2aa98e2SPeter Wemm continue;
421c2aa98e2SPeter Wemm map->map_valcolnm = p;
422c2aa98e2SPeter Wemm break;
423c2aa98e2SPeter Wemm
424c2aa98e2SPeter Wemm case 'z':
425c2aa98e2SPeter Wemm if (*++p != '\\')
426c2aa98e2SPeter Wemm map->map_coldelim = *p;
427c2aa98e2SPeter Wemm else
428c2aa98e2SPeter Wemm {
429c2aa98e2SPeter Wemm switch (*++p)
430c2aa98e2SPeter Wemm {
431c2aa98e2SPeter Wemm case 'n':
432c2aa98e2SPeter Wemm map->map_coldelim = '\n';
433c2aa98e2SPeter Wemm break;
434c2aa98e2SPeter Wemm
435c2aa98e2SPeter Wemm case 't':
436c2aa98e2SPeter Wemm map->map_coldelim = '\t';
437c2aa98e2SPeter Wemm break;
438c2aa98e2SPeter Wemm
439c2aa98e2SPeter Wemm default:
440c2aa98e2SPeter Wemm map->map_coldelim = '\\';
441c2aa98e2SPeter Wemm }
442c2aa98e2SPeter Wemm }
443c2aa98e2SPeter Wemm break;
444c2aa98e2SPeter Wemm
44506f25ae9SGregory Neil Shapiro default:
44606f25ae9SGregory Neil Shapiro syserr("Illegal option %c map %s", *p, map->map_mname);
44706f25ae9SGregory Neil Shapiro break;
448c2aa98e2SPeter Wemm }
4495b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
450c2aa98e2SPeter Wemm p++;
451c2aa98e2SPeter Wemm if (*p != '\0')
452c2aa98e2SPeter Wemm *p++ = '\0';
453c2aa98e2SPeter Wemm }
454c2aa98e2SPeter Wemm if (map->map_app != NULL)
455c2aa98e2SPeter Wemm map->map_app = newstr(map->map_app);
456c2aa98e2SPeter Wemm if (map->map_tapp != NULL)
457c2aa98e2SPeter Wemm map->map_tapp = newstr(map->map_tapp);
458c2aa98e2SPeter Wemm if (map->map_keycolnm != NULL)
459c2aa98e2SPeter Wemm map->map_keycolnm = newstr(map->map_keycolnm);
460c2aa98e2SPeter Wemm if (map->map_valcolnm != NULL)
461c2aa98e2SPeter Wemm map->map_valcolnm = newstr(map->map_valcolnm);
462c2aa98e2SPeter Wemm
463c2aa98e2SPeter Wemm if (*p != '\0')
464c2aa98e2SPeter Wemm {
465c2aa98e2SPeter Wemm map->map_file = p;
4665b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
467c2aa98e2SPeter Wemm p++;
468c2aa98e2SPeter Wemm if (*p != '\0')
469c2aa98e2SPeter Wemm *p++ = '\0';
470c2aa98e2SPeter Wemm map->map_file = newstr(map->map_file);
471c2aa98e2SPeter Wemm }
472c2aa98e2SPeter Wemm
4735b0945b5SGregory Neil Shapiro while (*p != '\0' && SM_ISSPACE(*p))
474c2aa98e2SPeter Wemm p++;
475c2aa98e2SPeter Wemm if (*p != '\0')
476c2aa98e2SPeter Wemm map->map_rebuild = newstr(p);
477c2aa98e2SPeter Wemm
478c2aa98e2SPeter Wemm if (map->map_file == NULL &&
479c2aa98e2SPeter Wemm !bitset(MCF_OPTFILE, map->map_class->map_cflags))
480c2aa98e2SPeter Wemm {
481c2aa98e2SPeter Wemm syserr("No file name for %s map %s",
482c2aa98e2SPeter Wemm map->map_class->map_cname, map->map_mname);
48340266059SGregory Neil Shapiro return false;
484c2aa98e2SPeter Wemm }
48540266059SGregory Neil Shapiro return true;
486c2aa98e2SPeter Wemm }
48740266059SGregory Neil Shapiro /*
488c2aa98e2SPeter Wemm ** MAP_REWRITE -- rewrite a database key, interpolating %n indications.
489c2aa98e2SPeter Wemm **
490c2aa98e2SPeter Wemm ** It also adds the map_app string. It can be used as a utility
491c2aa98e2SPeter Wemm ** in the map_lookup method.
492c2aa98e2SPeter Wemm **
493c2aa98e2SPeter Wemm ** Parameters:
494c2aa98e2SPeter Wemm ** map -- the map that causes this.
495c2aa98e2SPeter Wemm ** s -- the string to rewrite, NOT necessarily null terminated.
496c2aa98e2SPeter Wemm ** slen -- the length of s.
497c2aa98e2SPeter Wemm ** av -- arguments to interpolate into buf.
498c2aa98e2SPeter Wemm **
499c2aa98e2SPeter Wemm ** Returns:
500c2aa98e2SPeter Wemm ** Pointer to rewritten result. This is static data that
501c2aa98e2SPeter Wemm ** should be copied if it is to be saved!
502c2aa98e2SPeter Wemm */
503c2aa98e2SPeter Wemm
504c2aa98e2SPeter Wemm char *
map_rewrite(map,s,slen,av)505c2aa98e2SPeter Wemm map_rewrite(map, s, slen, av)
506c2aa98e2SPeter Wemm register MAP *map;
507c2aa98e2SPeter Wemm register const char *s;
508c2aa98e2SPeter Wemm size_t slen;
509c2aa98e2SPeter Wemm char **av;
510c2aa98e2SPeter Wemm {
511c2aa98e2SPeter Wemm register char *bp;
512c2aa98e2SPeter Wemm register char c;
513c2aa98e2SPeter Wemm char **avp;
514c2aa98e2SPeter Wemm register char *ap;
515c2aa98e2SPeter Wemm size_t l;
516c2aa98e2SPeter Wemm size_t len;
517c2aa98e2SPeter Wemm static size_t buflen = 0;
518c2aa98e2SPeter Wemm static char *buf = NULL;
519c2aa98e2SPeter Wemm
520c2aa98e2SPeter Wemm if (tTd(39, 1))
521c2aa98e2SPeter Wemm {
52240266059SGregory Neil Shapiro sm_dprintf("map_rewrite(%.*s), av =", (int) slen, s);
523c2aa98e2SPeter Wemm if (av == NULL)
52440266059SGregory Neil Shapiro sm_dprintf(" (nullv)");
525c2aa98e2SPeter Wemm else
526c2aa98e2SPeter Wemm {
527c2aa98e2SPeter Wemm for (avp = av; *avp != NULL; avp++)
52840266059SGregory Neil Shapiro sm_dprintf("\n\t%s", *avp);
529c2aa98e2SPeter Wemm }
53040266059SGregory Neil Shapiro sm_dprintf("\n");
531c2aa98e2SPeter Wemm }
532c2aa98e2SPeter Wemm
533c2aa98e2SPeter Wemm /* count expected size of output (can safely overestimate) */
534c2aa98e2SPeter Wemm l = len = slen;
535c2aa98e2SPeter Wemm if (av != NULL)
536c2aa98e2SPeter Wemm {
537c2aa98e2SPeter Wemm const char *sp = s;
538c2aa98e2SPeter Wemm
539c2aa98e2SPeter Wemm while (l-- > 0 && (c = *sp++) != '\0')
540c2aa98e2SPeter Wemm {
541c2aa98e2SPeter Wemm if (c != '%')
542c2aa98e2SPeter Wemm continue;
543c2aa98e2SPeter Wemm if (l-- <= 0)
544c2aa98e2SPeter Wemm break;
545c2aa98e2SPeter Wemm c = *sp++;
546c2aa98e2SPeter Wemm if (!(isascii(c) && isdigit(c)))
547c2aa98e2SPeter Wemm continue;
548c2aa98e2SPeter Wemm for (avp = av; --c >= '0' && *avp != NULL; avp++)
549c2aa98e2SPeter Wemm continue;
550c2aa98e2SPeter Wemm if (*avp == NULL)
551c2aa98e2SPeter Wemm continue;
552c2aa98e2SPeter Wemm len += strlen(*avp);
553c2aa98e2SPeter Wemm }
554c2aa98e2SPeter Wemm }
555c2aa98e2SPeter Wemm if (map->map_app != NULL)
556c2aa98e2SPeter Wemm len += strlen(map->map_app);
557c2aa98e2SPeter Wemm if (buflen < ++len)
558c2aa98e2SPeter Wemm {
559c2aa98e2SPeter Wemm /* need to malloc additional space */
560c2aa98e2SPeter Wemm buflen = len;
5612fb4f839SGregory Neil Shapiro SM_FREE(buf);
56240266059SGregory Neil Shapiro buf = sm_pmalloc_x(buflen);
563c2aa98e2SPeter Wemm }
564c2aa98e2SPeter Wemm
565c2aa98e2SPeter Wemm bp = buf;
566c2aa98e2SPeter Wemm if (av == NULL)
567c2aa98e2SPeter Wemm {
56806f25ae9SGregory Neil Shapiro memmove(bp, s, slen);
569c2aa98e2SPeter Wemm bp += slen;
57006f25ae9SGregory Neil Shapiro
57106f25ae9SGregory Neil Shapiro /* assert(len > slen); */
57206f25ae9SGregory Neil Shapiro len -= slen;
573c2aa98e2SPeter Wemm }
574c2aa98e2SPeter Wemm else
575c2aa98e2SPeter Wemm {
576c2aa98e2SPeter Wemm while (slen-- > 0 && (c = *s++) != '\0')
577c2aa98e2SPeter Wemm {
578c2aa98e2SPeter Wemm if (c != '%')
579c2aa98e2SPeter Wemm {
580c2aa98e2SPeter Wemm pushc:
581a7ec597cSGregory Neil Shapiro if (len-- <= 1)
58206f25ae9SGregory Neil Shapiro break;
583c2aa98e2SPeter Wemm *bp++ = c;
584c2aa98e2SPeter Wemm continue;
585c2aa98e2SPeter Wemm }
586c2aa98e2SPeter Wemm if (slen-- <= 0 || (c = *s++) == '\0')
587c2aa98e2SPeter Wemm c = '%';
588c2aa98e2SPeter Wemm if (c == '%')
589c2aa98e2SPeter Wemm goto pushc;
590c2aa98e2SPeter Wemm if (!(isascii(c) && isdigit(c)))
591c2aa98e2SPeter Wemm {
592a7ec597cSGregory Neil Shapiro if (len-- <= 1)
593a7ec597cSGregory Neil Shapiro break;
594c2aa98e2SPeter Wemm *bp++ = '%';
595c2aa98e2SPeter Wemm goto pushc;
596c2aa98e2SPeter Wemm }
597c2aa98e2SPeter Wemm for (avp = av; --c >= '0' && *avp != NULL; avp++)
598c2aa98e2SPeter Wemm continue;
599c2aa98e2SPeter Wemm if (*avp == NULL)
600c2aa98e2SPeter Wemm continue;
601c2aa98e2SPeter Wemm
602c2aa98e2SPeter Wemm /* transliterate argument into output string */
60306f25ae9SGregory Neil Shapiro for (ap = *avp; (c = *ap++) != '\0' && len > 0; --len)
604c2aa98e2SPeter Wemm *bp++ = c;
605c2aa98e2SPeter Wemm }
606c2aa98e2SPeter Wemm }
60706f25ae9SGregory Neil Shapiro if (map->map_app != NULL && len > 0)
60840266059SGregory Neil Shapiro (void) sm_strlcpy(bp, map->map_app, len);
609c2aa98e2SPeter Wemm else
610c2aa98e2SPeter Wemm *bp = '\0';
6112fb4f839SGregory Neil Shapiro #if _FFR_8BITENVADDR
6122fb4f839SGregory Neil Shapiro if (!bitset(MF_KEEPXFMT, map->map_mflags))
6132fb4f839SGregory Neil Shapiro {
6142fb4f839SGregory Neil Shapiro int newlen;
6152fb4f839SGregory Neil Shapiro char *quoted;
6162fb4f839SGregory Neil Shapiro
6172fb4f839SGregory Neil Shapiro newlen = 0;
6182fb4f839SGregory Neil Shapiro quoted = quote_internal_chars(buf, NULL, &newlen, NULL);
6192fb4f839SGregory Neil Shapiro if (newlen > buflen)
6202fb4f839SGregory Neil Shapiro {
6212fb4f839SGregory Neil Shapiro buflen = newlen;
6222fb4f839SGregory Neil Shapiro SM_FREE(buf);
6232fb4f839SGregory Neil Shapiro buf = sm_pmalloc_x(buflen);
6242fb4f839SGregory Neil Shapiro }
6252fb4f839SGregory Neil Shapiro (void) sm_strlcpy(buf, quoted, buflen);
6262fb4f839SGregory Neil Shapiro SM_FREE(quoted);
6272fb4f839SGregory Neil Shapiro }
6282fb4f839SGregory Neil Shapiro #endif
629c2aa98e2SPeter Wemm if (tTd(39, 1))
63040266059SGregory Neil Shapiro sm_dprintf("map_rewrite => %s\n", buf);
631c2aa98e2SPeter Wemm return buf;
632c2aa98e2SPeter Wemm }
633*d39bd2c1SGregory Neil Shapiro
634*d39bd2c1SGregory Neil Shapiro /*
635*d39bd2c1SGregory Neil Shapiro ** MAPCHOWN -- if available fchown() the fds to TrustedUid
636*d39bd2c1SGregory Neil Shapiro **
637*d39bd2c1SGregory Neil Shapiro ** Parameters:
638*d39bd2c1SGregory Neil Shapiro ** mapname - name of map (for error reporting)
639*d39bd2c1SGregory Neil Shapiro ** fd0 - first fd (must be valid)
640*d39bd2c1SGregory Neil Shapiro ** fd1 - second fd (<0: do not use)
641*d39bd2c1SGregory Neil Shapiro ** filename - name of file (for error reporting)
642*d39bd2c1SGregory Neil Shapiro **
643*d39bd2c1SGregory Neil Shapiro ** Returns:
644*d39bd2c1SGregory Neil Shapiro ** none.
645*d39bd2c1SGregory Neil Shapiro */
646*d39bd2c1SGregory Neil Shapiro
647*d39bd2c1SGregory Neil Shapiro static void mapchown __P((const char *, int, int, const char *));
648*d39bd2c1SGregory Neil Shapiro
649*d39bd2c1SGregory Neil Shapiro static void
mapchown(mapname,fd0,fd1,filename)650*d39bd2c1SGregory Neil Shapiro mapchown(mapname, fd0, fd1, filename)
651*d39bd2c1SGregory Neil Shapiro const char *mapname;
652*d39bd2c1SGregory Neil Shapiro int fd0;
653*d39bd2c1SGregory Neil Shapiro int fd1;
654*d39bd2c1SGregory Neil Shapiro const char *filename;
655*d39bd2c1SGregory Neil Shapiro {
656*d39bd2c1SGregory Neil Shapiro if (!(geteuid() == 0 && TrustedUid != 0))
657*d39bd2c1SGregory Neil Shapiro return;
658*d39bd2c1SGregory Neil Shapiro #if HASFCHOWN
659*d39bd2c1SGregory Neil Shapiro if (fchown(fd0, TrustedUid, -1) < 0 ||
660*d39bd2c1SGregory Neil Shapiro (fd1 >= 0 && fchown(fd1, TrustedUid, -1) < 0))
661*d39bd2c1SGregory Neil Shapiro {
662*d39bd2c1SGregory Neil Shapiro int err = errno;
663*d39bd2c1SGregory Neil Shapiro
664*d39bd2c1SGregory Neil Shapiro sm_syslog(LOG_ALERT, NOQID,
665*d39bd2c1SGregory Neil Shapiro "ownership change on %s failed: %s",
666*d39bd2c1SGregory Neil Shapiro filename, sm_errstring(err));
667*d39bd2c1SGregory Neil Shapiro message("050 ownership change on %s failed: %s",
668*d39bd2c1SGregory Neil Shapiro filename, sm_errstring(err));
669*d39bd2c1SGregory Neil Shapiro }
670*d39bd2c1SGregory Neil Shapiro #else /* HASFCHOWN */
671*d39bd2c1SGregory Neil Shapiro sm_syslog(LOG_ALERT, NOQID,
672*d39bd2c1SGregory Neil Shapiro "no fchown(): cannot change ownership on %s",
673*d39bd2c1SGregory Neil Shapiro mapname);
674*d39bd2c1SGregory Neil Shapiro message("050 no fchown(): cannot change ownership on %s",
675*d39bd2c1SGregory Neil Shapiro mapname);
676*d39bd2c1SGregory Neil Shapiro #endif /* HASFCHOWN */
677*d39bd2c1SGregory Neil Shapiro }
678*d39bd2c1SGregory Neil Shapiro
67940266059SGregory Neil Shapiro /*
68006f25ae9SGregory Neil Shapiro ** INITMAPS -- rebuild alias maps
681c2aa98e2SPeter Wemm **
682c2aa98e2SPeter Wemm ** Parameters:
68306f25ae9SGregory Neil Shapiro ** none.
68406f25ae9SGregory Neil Shapiro **
68506f25ae9SGregory Neil Shapiro ** Returns:
68606f25ae9SGregory Neil Shapiro ** none.
68706f25ae9SGregory Neil Shapiro */
68806f25ae9SGregory Neil Shapiro
68906f25ae9SGregory Neil Shapiro void
initmaps()69006f25ae9SGregory Neil Shapiro initmaps()
69106f25ae9SGregory Neil Shapiro {
69206f25ae9SGregory Neil Shapiro checkfd012("entering initmaps");
69306f25ae9SGregory Neil Shapiro stabapply(map_init, 0);
69406f25ae9SGregory Neil Shapiro checkfd012("exiting initmaps");
69506f25ae9SGregory Neil Shapiro }
696*d39bd2c1SGregory Neil Shapiro
69740266059SGregory Neil Shapiro /*
69806f25ae9SGregory Neil Shapiro ** MAP_INIT -- rebuild a map
69906f25ae9SGregory Neil Shapiro **
70006f25ae9SGregory Neil Shapiro ** Parameters:
70106f25ae9SGregory Neil Shapiro ** s -- STAB entry: if map: try to rebuild
70206f25ae9SGregory Neil Shapiro ** unused -- unused variable
703c2aa98e2SPeter Wemm **
704c2aa98e2SPeter Wemm ** Returns:
705c2aa98e2SPeter Wemm ** none.
706c2aa98e2SPeter Wemm **
707c2aa98e2SPeter Wemm ** Side Effects:
70806f25ae9SGregory Neil Shapiro ** will close already open rebuildable map.
709c2aa98e2SPeter Wemm */
710c2aa98e2SPeter Wemm
71106f25ae9SGregory Neil Shapiro /* ARGSUSED1 */
71206f25ae9SGregory Neil Shapiro static void
map_init(s,unused)71306f25ae9SGregory Neil Shapiro map_init(s, unused)
714c2aa98e2SPeter Wemm register STAB *s;
71506f25ae9SGregory Neil Shapiro int unused;
716c2aa98e2SPeter Wemm {
717c2aa98e2SPeter Wemm register MAP *map;
718c2aa98e2SPeter Wemm
719c2aa98e2SPeter Wemm /* has to be a map */
72040266059SGregory Neil Shapiro if (s->s_symtype != ST_MAP)
721c2aa98e2SPeter Wemm return;
722c2aa98e2SPeter Wemm
723c2aa98e2SPeter Wemm map = &s->s_map;
724c2aa98e2SPeter Wemm if (!bitset(MF_VALID, map->map_mflags))
725c2aa98e2SPeter Wemm return;
726c2aa98e2SPeter Wemm
727c2aa98e2SPeter Wemm if (tTd(38, 2))
72840266059SGregory Neil Shapiro sm_dprintf("map_init(%s:%s, %s)\n",
729c2aa98e2SPeter Wemm map->map_class->map_cname == NULL ? "NULL" :
730c2aa98e2SPeter Wemm map->map_class->map_cname,
731c2aa98e2SPeter Wemm map->map_mname == NULL ? "NULL" : map->map_mname,
73206f25ae9SGregory Neil Shapiro map->map_file == NULL ? "NULL" : map->map_file);
733c2aa98e2SPeter Wemm
73406f25ae9SGregory Neil Shapiro if (!bitset(MF_ALIAS, map->map_mflags) ||
73506f25ae9SGregory Neil Shapiro !bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
736c2aa98e2SPeter Wemm {
737c2aa98e2SPeter Wemm if (tTd(38, 3))
73840266059SGregory Neil Shapiro sm_dprintf("\tnot rebuildable\n");
739c2aa98e2SPeter Wemm return;
740c2aa98e2SPeter Wemm }
741c2aa98e2SPeter Wemm
742c2aa98e2SPeter Wemm /* if already open, close it (for nested open) */
743c2aa98e2SPeter Wemm if (bitset(MF_OPEN, map->map_mflags))
744c2aa98e2SPeter Wemm {
7458774250cSGregory Neil Shapiro map->map_mflags |= MF_CLOSING;
746c2aa98e2SPeter Wemm map->map_class->map_close(map);
7478774250cSGregory Neil Shapiro map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
748c2aa98e2SPeter Wemm }
749c2aa98e2SPeter Wemm
750*d39bd2c1SGregory Neil Shapiro (void) rebuildaliases(map);
751c2aa98e2SPeter Wemm return;
752c2aa98e2SPeter Wemm }
75340266059SGregory Neil Shapiro /*
75406f25ae9SGregory Neil Shapiro ** OPENMAP -- open a map
75506f25ae9SGregory Neil Shapiro **
75606f25ae9SGregory Neil Shapiro ** Parameters:
75706f25ae9SGregory Neil Shapiro ** map -- map to open (it must not be open).
75806f25ae9SGregory Neil Shapiro **
75906f25ae9SGregory Neil Shapiro ** Returns:
76006f25ae9SGregory Neil Shapiro ** whether open succeeded.
76106f25ae9SGregory Neil Shapiro */
762c2aa98e2SPeter Wemm
76306f25ae9SGregory Neil Shapiro bool
openmap(map)76406f25ae9SGregory Neil Shapiro openmap(map)
76506f25ae9SGregory Neil Shapiro MAP *map;
76606f25ae9SGregory Neil Shapiro {
76740266059SGregory Neil Shapiro bool restore = false;
76806f25ae9SGregory Neil Shapiro bool savehold = HoldErrs;
76906f25ae9SGregory Neil Shapiro bool savequick = QuickAbort;
77006f25ae9SGregory Neil Shapiro int saveerrors = Errors;
77106f25ae9SGregory Neil Shapiro
77206f25ae9SGregory Neil Shapiro if (!bitset(MF_VALID, map->map_mflags))
77340266059SGregory Neil Shapiro return false;
77406f25ae9SGregory Neil Shapiro
77506f25ae9SGregory Neil Shapiro /* better safe than sorry... */
77606f25ae9SGregory Neil Shapiro if (bitset(MF_OPEN, map->map_mflags))
77740266059SGregory Neil Shapiro return true;
77806f25ae9SGregory Neil Shapiro
77906f25ae9SGregory Neil Shapiro /* Don't send a map open error out via SMTP */
78006f25ae9SGregory Neil Shapiro if ((OnlyOneError || QuickAbort) &&
78106f25ae9SGregory Neil Shapiro (OpMode == MD_SMTP || OpMode == MD_DAEMON))
78206f25ae9SGregory Neil Shapiro {
78340266059SGregory Neil Shapiro restore = true;
78440266059SGregory Neil Shapiro HoldErrs = true;
78540266059SGregory Neil Shapiro QuickAbort = false;
78606f25ae9SGregory Neil Shapiro }
78706f25ae9SGregory Neil Shapiro
78806f25ae9SGregory Neil Shapiro errno = 0;
789c2aa98e2SPeter Wemm if (map->map_class->map_open(map, O_RDONLY))
790c2aa98e2SPeter Wemm {
791c2aa98e2SPeter Wemm if (tTd(38, 4))
79240266059SGregory Neil Shapiro sm_dprintf("openmap()\t%s:%s %s: valid\n",
793c2aa98e2SPeter Wemm map->map_class->map_cname == NULL ? "NULL" :
794c2aa98e2SPeter Wemm map->map_class->map_cname,
795c2aa98e2SPeter Wemm map->map_mname == NULL ? "NULL" :
796c2aa98e2SPeter Wemm map->map_mname,
797c2aa98e2SPeter Wemm map->map_file == NULL ? "NULL" :
798c2aa98e2SPeter Wemm map->map_file);
799c2aa98e2SPeter Wemm map->map_mflags |= MF_OPEN;
80040266059SGregory Neil Shapiro map->map_pid = CurrentPid;
801c2aa98e2SPeter Wemm }
802c2aa98e2SPeter Wemm else
803c2aa98e2SPeter Wemm {
804c2aa98e2SPeter Wemm if (tTd(38, 4))
80540266059SGregory Neil Shapiro sm_dprintf("openmap()\t%s:%s %s: invalid%s%s\n",
806c2aa98e2SPeter Wemm map->map_class->map_cname == NULL ? "NULL" :
807c2aa98e2SPeter Wemm map->map_class->map_cname,
808c2aa98e2SPeter Wemm map->map_mname == NULL ? "NULL" :
809c2aa98e2SPeter Wemm map->map_mname,
810c2aa98e2SPeter Wemm map->map_file == NULL ? "NULL" :
811c2aa98e2SPeter Wemm map->map_file,
81206f25ae9SGregory Neil Shapiro errno == 0 ? "" : ": ",
81340266059SGregory Neil Shapiro errno == 0 ? "" : sm_errstring(errno));
814c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
815c2aa98e2SPeter Wemm {
816c2aa98e2SPeter Wemm extern MAPCLASS BogusMapClass;
817c2aa98e2SPeter Wemm
81840266059SGregory Neil Shapiro map->map_orgclass = map->map_class;
819c2aa98e2SPeter Wemm map->map_class = &BogusMapClass;
82040266059SGregory Neil Shapiro map->map_mflags |= MF_OPEN|MF_OPENBOGUS;
82140266059SGregory Neil Shapiro map->map_pid = CurrentPid;
822c2aa98e2SPeter Wemm }
82306f25ae9SGregory Neil Shapiro else
82406f25ae9SGregory Neil Shapiro {
82506f25ae9SGregory Neil Shapiro /* don't try again */
82606f25ae9SGregory Neil Shapiro map->map_mflags &= ~MF_VALID;
827c2aa98e2SPeter Wemm }
828c2aa98e2SPeter Wemm }
82906f25ae9SGregory Neil Shapiro
83006f25ae9SGregory Neil Shapiro if (restore)
83106f25ae9SGregory Neil Shapiro {
83206f25ae9SGregory Neil Shapiro Errors = saveerrors;
83306f25ae9SGregory Neil Shapiro HoldErrs = savehold;
83406f25ae9SGregory Neil Shapiro QuickAbort = savequick;
83506f25ae9SGregory Neil Shapiro }
83606f25ae9SGregory Neil Shapiro
83706f25ae9SGregory Neil Shapiro return bitset(MF_OPEN, map->map_mflags);
83806f25ae9SGregory Neil Shapiro }
83940266059SGregory Neil Shapiro /*
840065a643dSPeter Wemm ** CLOSEMAPS -- close all open maps opened by the current pid.
841065a643dSPeter Wemm **
842065a643dSPeter Wemm ** Parameters:
84340266059SGregory Neil Shapiro ** bogus -- only close bogus maps.
844065a643dSPeter Wemm **
845065a643dSPeter Wemm ** Returns:
846065a643dSPeter Wemm ** none.
847065a643dSPeter Wemm */
848065a643dSPeter Wemm
849065a643dSPeter Wemm void
closemaps(bogus)85040266059SGregory Neil Shapiro closemaps(bogus)
85140266059SGregory Neil Shapiro bool bogus;
852065a643dSPeter Wemm {
85340266059SGregory Neil Shapiro stabapply(map_close, bogus);
854065a643dSPeter Wemm }
85540266059SGregory Neil Shapiro /*
85606f25ae9SGregory Neil Shapiro ** MAP_CLOSE -- close a map opened by the current pid.
85706f25ae9SGregory Neil Shapiro **
85806f25ae9SGregory Neil Shapiro ** Parameters:
85940266059SGregory Neil Shapiro ** s -- STAB entry: if map: try to close
86040266059SGregory Neil Shapiro ** bogus -- only close bogus maps or MCF_NOTPERSIST maps.
86106f25ae9SGregory Neil Shapiro **
86206f25ae9SGregory Neil Shapiro ** Returns:
86306f25ae9SGregory Neil Shapiro ** none.
86406f25ae9SGregory Neil Shapiro */
865065a643dSPeter Wemm
86606f25ae9SGregory Neil Shapiro static void
map_close(s,bogus)86740266059SGregory Neil Shapiro map_close(s, bogus)
868065a643dSPeter Wemm register STAB *s;
86940266059SGregory Neil Shapiro int bogus; /* int because of stabapply(), used as bool */
870065a643dSPeter Wemm {
871065a643dSPeter Wemm MAP *map;
87240266059SGregory Neil Shapiro extern MAPCLASS BogusMapClass;
873065a643dSPeter Wemm
87440266059SGregory Neil Shapiro if (s->s_symtype != ST_MAP)
875065a643dSPeter Wemm return;
876065a643dSPeter Wemm
877065a643dSPeter Wemm map = &s->s_map;
878065a643dSPeter Wemm
87940266059SGregory Neil Shapiro /*
88040266059SGregory Neil Shapiro ** close the map iff:
88140266059SGregory Neil Shapiro ** it is valid and open and opened by this process
88240266059SGregory Neil Shapiro ** and (!bogus or it's a bogus map or it is not persistent)
88340266059SGregory Neil Shapiro ** negate this: return iff
88440266059SGregory Neil Shapiro ** it is not valid or it is not open or not opened by this process
88540266059SGregory Neil Shapiro ** or (bogus and it's not a bogus map and it's not not-persistent)
88640266059SGregory Neil Shapiro */
88740266059SGregory Neil Shapiro
888065a643dSPeter Wemm if (!bitset(MF_VALID, map->map_mflags) ||
889065a643dSPeter Wemm !bitset(MF_OPEN, map->map_mflags) ||
8908774250cSGregory Neil Shapiro bitset(MF_CLOSING, map->map_mflags) ||
89140266059SGregory Neil Shapiro map->map_pid != CurrentPid ||
89240266059SGregory Neil Shapiro (bogus && map->map_class != &BogusMapClass &&
89340266059SGregory Neil Shapiro !bitset(MCF_NOTPERSIST, map->map_class->map_cflags)))
894065a643dSPeter Wemm return;
895065a643dSPeter Wemm
89640266059SGregory Neil Shapiro if (map->map_class == &BogusMapClass && map->map_orgclass != NULL &&
89740266059SGregory Neil Shapiro map->map_orgclass != &BogusMapClass)
89840266059SGregory Neil Shapiro map->map_class = map->map_orgclass;
899065a643dSPeter Wemm if (tTd(38, 5))
90040266059SGregory Neil Shapiro sm_dprintf("closemaps: closing %s (%s)\n",
901065a643dSPeter Wemm map->map_mname == NULL ? "NULL" : map->map_mname,
902065a643dSPeter Wemm map->map_file == NULL ? "NULL" : map->map_file);
903065a643dSPeter Wemm
90440266059SGregory Neil Shapiro if (!bitset(MF_OPENBOGUS, map->map_mflags))
90540266059SGregory Neil Shapiro {
9068774250cSGregory Neil Shapiro map->map_mflags |= MF_CLOSING;
907065a643dSPeter Wemm map->map_class->map_close(map);
908065a643dSPeter Wemm }
909*d39bd2c1SGregory Neil Shapiro map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_OPENBOGUS|MF_CLOSING|MF_CHKED_CHGD);
91040266059SGregory Neil Shapiro }
911d0cef73dSGregory Neil Shapiro
912d0cef73dSGregory Neil Shapiro #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
913d0cef73dSGregory Neil Shapiro extern int getdomainname();
914d0cef73dSGregory Neil Shapiro
915d0cef73dSGregory Neil Shapiro /* this is mainly for backward compatibility in Sun environment */
916d0cef73dSGregory Neil Shapiro static char *
sun_init_domain()917d0cef73dSGregory Neil Shapiro sun_init_domain()
918d0cef73dSGregory Neil Shapiro {
919d0cef73dSGregory Neil Shapiro /*
920d0cef73dSGregory Neil Shapiro ** Get the domain name from the kernel.
921d0cef73dSGregory Neil Shapiro ** If it does not start with a leading dot, then remove
922d0cef73dSGregory Neil Shapiro ** the first component. Since leading dots are funny Unix
923d0cef73dSGregory Neil Shapiro ** files, we treat a leading "+" the same as a leading dot.
924d0cef73dSGregory Neil Shapiro ** Finally, force there to be at least one dot in the domain name
925d0cef73dSGregory Neil Shapiro ** (i.e. top-level domains are not allowed, like "com", must be
926d0cef73dSGregory Neil Shapiro ** something like "sun.com").
927d0cef73dSGregory Neil Shapiro */
928d0cef73dSGregory Neil Shapiro
9292fb4f839SGregory Neil Shapiro char buf[MAXNAME]; /* EAI:ok (domainname) */
930d0cef73dSGregory Neil Shapiro char *period, *autodomain;
931d0cef73dSGregory Neil Shapiro
932d0cef73dSGregory Neil Shapiro if (getdomainname(buf, sizeof buf) < 0)
933d0cef73dSGregory Neil Shapiro return NULL;
934d0cef73dSGregory Neil Shapiro
935d0cef73dSGregory Neil Shapiro if (buf[0] == '\0')
936d0cef73dSGregory Neil Shapiro return NULL;
937d0cef73dSGregory Neil Shapiro
938d0cef73dSGregory Neil Shapiro if (tTd(0, 20))
939d0cef73dSGregory Neil Shapiro printf("domainname = %s\n", buf);
940d0cef73dSGregory Neil Shapiro
941d0cef73dSGregory Neil Shapiro if (buf[0] == '+')
942d0cef73dSGregory Neil Shapiro buf[0] = '.';
943d0cef73dSGregory Neil Shapiro period = strchr(buf, '.');
944d0cef73dSGregory Neil Shapiro if (period == NULL)
945d0cef73dSGregory Neil Shapiro autodomain = buf;
946d0cef73dSGregory Neil Shapiro else
947d0cef73dSGregory Neil Shapiro autodomain = period + 1;
948d0cef73dSGregory Neil Shapiro if (strchr(autodomain, '.') == NULL)
949d0cef73dSGregory Neil Shapiro return newstr(buf);
950d0cef73dSGregory Neil Shapiro else
951d0cef73dSGregory Neil Shapiro return newstr(autodomain);
952d0cef73dSGregory Neil Shapiro }
953d0cef73dSGregory Neil Shapiro #endif /* SUN_EXTENSIONS && SUN_INIT_DOMAIN */
954d0cef73dSGregory Neil Shapiro
95540266059SGregory Neil Shapiro /*
956c2aa98e2SPeter Wemm ** GETCANONNAME -- look up name using service switch
957c2aa98e2SPeter Wemm **
958c2aa98e2SPeter Wemm ** Parameters:
959c2aa98e2SPeter Wemm ** host -- the host name to look up.
960c2aa98e2SPeter Wemm ** hbsize -- the size of the host buffer.
961c2aa98e2SPeter Wemm ** trymx -- if set, try MX records.
96240266059SGregory Neil Shapiro ** pttl -- pointer to return TTL (can be NULL).
963c2aa98e2SPeter Wemm **
964c2aa98e2SPeter Wemm ** Returns:
9655b0945b5SGregory Neil Shapiro ** >0 -- if the host was found.
9665b0945b5SGregory Neil Shapiro ** 0 -- otherwise.
967c2aa98e2SPeter Wemm */
968c2aa98e2SPeter Wemm
9695b0945b5SGregory Neil Shapiro int
getcanonname(host,hbsize,trymx,pttl)97040266059SGregory Neil Shapiro getcanonname(host, hbsize, trymx, pttl)
971c2aa98e2SPeter Wemm char *host;
972c2aa98e2SPeter Wemm int hbsize;
973c2aa98e2SPeter Wemm bool trymx;
97440266059SGregory Neil Shapiro int *pttl;
975c2aa98e2SPeter Wemm {
976c2aa98e2SPeter Wemm int nmaps;
977c2aa98e2SPeter Wemm int mapno;
97840266059SGregory Neil Shapiro bool found = false;
97940266059SGregory Neil Shapiro bool got_tempfail = false;
9809bd497b8SGregory Neil Shapiro auto int status = EX_UNAVAILABLE;
981c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK];
982c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS];
983d0cef73dSGregory Neil Shapiro #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
984d0cef73dSGregory Neil Shapiro bool should_try_nis_domain = false;
985d0cef73dSGregory Neil Shapiro static char *nis_domain = NULL;
986d0cef73dSGregory Neil Shapiro #endif
9875b0945b5SGregory Neil Shapiro bool secure = true; /* consider all maps secure by default */
988c2aa98e2SPeter Wemm
989c2aa98e2SPeter Wemm nmaps = switch_map_find("hosts", maptype, mapreturn);
9905b0945b5SGregory Neil Shapiro if (pttl != NULL)
99140266059SGregory Neil Shapiro *pttl = SM_DEFAULT_TTL;
992c2aa98e2SPeter Wemm for (mapno = 0; mapno < nmaps; mapno++)
993c2aa98e2SPeter Wemm {
994c2aa98e2SPeter Wemm int i;
995c2aa98e2SPeter Wemm
996c2aa98e2SPeter Wemm if (tTd(38, 20))
99740266059SGregory Neil Shapiro sm_dprintf("getcanonname(%s), trying %s\n",
998c2aa98e2SPeter Wemm host, maptype[mapno]);
999c2aa98e2SPeter Wemm if (strcmp("files", maptype[mapno]) == 0)
1000c2aa98e2SPeter Wemm {
100106f25ae9SGregory Neil Shapiro found = text_getcanonname(host, hbsize, &status);
1002c2aa98e2SPeter Wemm }
100340266059SGregory Neil Shapiro #if NIS
1004c2aa98e2SPeter Wemm else if (strcmp("nis", maptype[mapno]) == 0)
1005c2aa98e2SPeter Wemm {
100606f25ae9SGregory Neil Shapiro found = nis_getcanonname(host, hbsize, &status);
1007d0cef73dSGregory Neil Shapiro # if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
1008d0cef73dSGregory Neil Shapiro if (nis_domain == NULL)
1009d0cef73dSGregory Neil Shapiro nis_domain = sun_init_domain();
10105b0945b5SGregory Neil Shapiro # endif
1011c2aa98e2SPeter Wemm }
101206f25ae9SGregory Neil Shapiro #endif /* NIS */
101340266059SGregory Neil Shapiro #if NISPLUS
1014c2aa98e2SPeter Wemm else if (strcmp("nisplus", maptype[mapno]) == 0)
1015c2aa98e2SPeter Wemm {
101606f25ae9SGregory Neil Shapiro found = nisplus_getcanonname(host, hbsize, &status);
1017d0cef73dSGregory Neil Shapiro # if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
1018d0cef73dSGregory Neil Shapiro if (nis_domain == NULL)
1019d0cef73dSGregory Neil Shapiro nis_domain = sun_init_domain();
10205b0945b5SGregory Neil Shapiro # endif
1021c2aa98e2SPeter Wemm }
102206f25ae9SGregory Neil Shapiro #endif /* NISPLUS */
1023c2aa98e2SPeter Wemm #if NAMED_BIND
1024c2aa98e2SPeter Wemm else if (strcmp("dns", maptype[mapno]) == 0)
1025c2aa98e2SPeter Wemm {
10265b0945b5SGregory Neil Shapiro int r;
10275b0945b5SGregory Neil Shapiro
10285b0945b5SGregory Neil Shapiro r = dns_getcanonname(host, hbsize, trymx, &status,
10295b0945b5SGregory Neil Shapiro pttl);
10305b0945b5SGregory Neil Shapiro secure = HOST_SECURE == r;
10315b0945b5SGregory Neil Shapiro found = r > 0;
1032c2aa98e2SPeter Wemm }
103306f25ae9SGregory Neil Shapiro #endif /* NAMED_BIND */
1034c2aa98e2SPeter Wemm #if NETINFO
1035c2aa98e2SPeter Wemm else if (strcmp("netinfo", maptype[mapno]) == 0)
1036c2aa98e2SPeter Wemm {
103706f25ae9SGregory Neil Shapiro found = ni_getcanonname(host, hbsize, &status);
1038c2aa98e2SPeter Wemm }
103906f25ae9SGregory Neil Shapiro #endif /* NETINFO */
1040c2aa98e2SPeter Wemm else
1041c2aa98e2SPeter Wemm {
104240266059SGregory Neil Shapiro found = false;
104306f25ae9SGregory Neil Shapiro status = EX_UNAVAILABLE;
1044c2aa98e2SPeter Wemm }
1045c2aa98e2SPeter Wemm
1046c2aa98e2SPeter Wemm /*
1047c2aa98e2SPeter Wemm ** Heuristic: if $m is not set, we are running during system
1048c2aa98e2SPeter Wemm ** startup. In this case, when a name is apparently found
1049c2aa98e2SPeter Wemm ** but has no dot, treat is as not found. This avoids
1050c2aa98e2SPeter Wemm ** problems if /etc/hosts has no FQDN but is listed first
1051c2aa98e2SPeter Wemm ** in the service switch.
1052c2aa98e2SPeter Wemm */
1053c2aa98e2SPeter Wemm
1054c2aa98e2SPeter Wemm if (found &&
1055c2aa98e2SPeter Wemm (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL))
1056c2aa98e2SPeter Wemm break;
1057c2aa98e2SPeter Wemm
1058d0cef73dSGregory Neil Shapiro #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
1059d0cef73dSGregory Neil Shapiro if (found)
1060d0cef73dSGregory Neil Shapiro should_try_nis_domain = true;
1061d0cef73dSGregory Neil Shapiro /* but don't break, as we need to try all methods first */
1062d0cef73dSGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
1063d0cef73dSGregory Neil Shapiro
1064c2aa98e2SPeter Wemm /* see if we should continue */
106506f25ae9SGregory Neil Shapiro if (status == EX_TEMPFAIL)
1066c2aa98e2SPeter Wemm {
1067c2aa98e2SPeter Wemm i = MA_TRYAGAIN;
106840266059SGregory Neil Shapiro got_tempfail = true;
1069c2aa98e2SPeter Wemm }
107006f25ae9SGregory Neil Shapiro else if (status == EX_NOTFOUND)
1071c2aa98e2SPeter Wemm i = MA_NOTFOUND;
1072c2aa98e2SPeter Wemm else
1073c2aa98e2SPeter Wemm i = MA_UNAVAIL;
1074c2aa98e2SPeter Wemm if (bitset(1 << mapno, mapreturn[i]))
1075c2aa98e2SPeter Wemm break;
1076c2aa98e2SPeter Wemm }
1077c2aa98e2SPeter Wemm
1078c2aa98e2SPeter Wemm if (found)
1079c2aa98e2SPeter Wemm {
1080c2aa98e2SPeter Wemm char *d;
1081c2aa98e2SPeter Wemm
1082c2aa98e2SPeter Wemm if (tTd(38, 20))
10835b0945b5SGregory Neil Shapiro sm_dprintf("getcanonname(%s), found, ad=%d\n", host, secure);
1084c2aa98e2SPeter Wemm
1085c2aa98e2SPeter Wemm /*
1086c2aa98e2SPeter Wemm ** If returned name is still single token, compensate
1087c2aa98e2SPeter Wemm ** by tagging on $m. This is because some sites set
1088c2aa98e2SPeter Wemm ** up their DNS or NIS databases wrong.
1089c2aa98e2SPeter Wemm */
1090c2aa98e2SPeter Wemm
1091c2aa98e2SPeter Wemm if ((d = strchr(host, '.')) == NULL || d[1] == '\0')
1092c2aa98e2SPeter Wemm {
1093c2aa98e2SPeter Wemm d = macvalue('m', CurEnv);
1094c2aa98e2SPeter Wemm if (d != NULL &&
1095c2aa98e2SPeter Wemm hbsize > (int) (strlen(host) + strlen(d) + 1))
1096c2aa98e2SPeter Wemm {
1097c2aa98e2SPeter Wemm if (host[strlen(host) - 1] != '.')
109840266059SGregory Neil Shapiro (void) sm_strlcat2(host, ".", d,
109940266059SGregory Neil Shapiro hbsize);
110040266059SGregory Neil Shapiro else
110140266059SGregory Neil Shapiro (void) sm_strlcat(host, d, hbsize);
1102c2aa98e2SPeter Wemm }
1103c2aa98e2SPeter Wemm else
1104d0cef73dSGregory Neil Shapiro {
1105d0cef73dSGregory Neil Shapiro #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
1106d0cef73dSGregory Neil Shapiro if (VendorCode == VENDOR_SUN &&
1107d0cef73dSGregory Neil Shapiro should_try_nis_domain)
1108d0cef73dSGregory Neil Shapiro {
1109d0cef73dSGregory Neil Shapiro goto try_nis_domain;
1110d0cef73dSGregory Neil Shapiro }
1111d0cef73dSGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
11125b0945b5SGregory Neil Shapiro return HOST_NOTFOUND;
1113c2aa98e2SPeter Wemm }
1114d0cef73dSGregory Neil Shapiro }
11155b0945b5SGregory Neil Shapiro return secure ? HOST_SECURE : HOST_OK;
1116c2aa98e2SPeter Wemm }
1117c2aa98e2SPeter Wemm
1118d0cef73dSGregory Neil Shapiro #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
1119d0cef73dSGregory Neil Shapiro if (VendorCode == VENDOR_SUN && should_try_nis_domain)
1120d0cef73dSGregory Neil Shapiro {
1121d0cef73dSGregory Neil Shapiro try_nis_domain:
1122d0cef73dSGregory Neil Shapiro if (nis_domain != NULL &&
1123d0cef73dSGregory Neil Shapiro strlen(nis_domain) + strlen(host) + 1 < hbsize)
1124d0cef73dSGregory Neil Shapiro {
1125d0cef73dSGregory Neil Shapiro (void) sm_strlcat2(host, ".", nis_domain, hbsize);
11265b0945b5SGregory Neil Shapiro return HOST_OK;
1127d0cef73dSGregory Neil Shapiro }
1128d0cef73dSGregory Neil Shapiro }
1129d0cef73dSGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
1130d0cef73dSGregory Neil Shapiro
1131c2aa98e2SPeter Wemm if (tTd(38, 20))
113240266059SGregory Neil Shapiro sm_dprintf("getcanonname(%s), failed, status=%d\n", host,
113340266059SGregory Neil Shapiro status);
1134c2aa98e2SPeter Wemm
1135c2aa98e2SPeter Wemm if (got_tempfail)
1136602a2b1bSGregory Neil Shapiro SM_SET_H_ERRNO(TRY_AGAIN);
1137c2aa98e2SPeter Wemm else
1138602a2b1bSGregory Neil Shapiro SM_SET_H_ERRNO(HOST_NOT_FOUND);
113940266059SGregory Neil Shapiro
11405b0945b5SGregory Neil Shapiro return HOST_NOTFOUND;
1141c2aa98e2SPeter Wemm }
114240266059SGregory Neil Shapiro /*
1143c2aa98e2SPeter Wemm ** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry
1144c2aa98e2SPeter Wemm **
1145c2aa98e2SPeter Wemm ** Parameters:
1146c2aa98e2SPeter Wemm ** name -- the name against which to match.
1147602a2b1bSGregory Neil Shapiro ** dot -- where to reinsert '.' to get FQDN
1148c2aa98e2SPeter Wemm ** line -- the /etc/hosts line.
1149c2aa98e2SPeter Wemm ** cbuf -- the location to store the result.
1150c2aa98e2SPeter Wemm ** cbuflen -- the size of cbuf.
1151c2aa98e2SPeter Wemm **
1152c2aa98e2SPeter Wemm ** Returns:
115340266059SGregory Neil Shapiro ** true -- if the line matched the desired name.
115440266059SGregory Neil Shapiro ** false -- otherwise.
1155c2aa98e2SPeter Wemm */
1156c2aa98e2SPeter Wemm
115706f25ae9SGregory Neil Shapiro static bool
extract_canonname(name,dot,line,cbuf,cbuflen)1158602a2b1bSGregory Neil Shapiro extract_canonname(name, dot, line, cbuf, cbuflen)
1159c2aa98e2SPeter Wemm char *name;
1160602a2b1bSGregory Neil Shapiro char *dot;
1161c2aa98e2SPeter Wemm char *line;
1162c2aa98e2SPeter Wemm char cbuf[];
1163c2aa98e2SPeter Wemm int cbuflen;
1164c2aa98e2SPeter Wemm {
1165c2aa98e2SPeter Wemm int i;
1166c2aa98e2SPeter Wemm char *p;
116740266059SGregory Neil Shapiro bool found = false;
1168c2aa98e2SPeter Wemm
1169c2aa98e2SPeter Wemm cbuf[0] = '\0';
1170c2aa98e2SPeter Wemm if (line[0] == '#')
117140266059SGregory Neil Shapiro return false;
1172c2aa98e2SPeter Wemm
1173c2aa98e2SPeter Wemm for (i = 1; ; i++)
1174c2aa98e2SPeter Wemm {
11752fb4f839SGregory Neil Shapiro char nbuf[MAXNAME + 1]; /* EAI:hostname */
1176c2aa98e2SPeter Wemm
1177d0cef73dSGregory Neil Shapiro p = get_column(line, i, '\0', nbuf, sizeof(nbuf));
1178c2aa98e2SPeter Wemm if (p == NULL)
1179c2aa98e2SPeter Wemm break;
1180c2aa98e2SPeter Wemm if (*p == '\0')
1181c2aa98e2SPeter Wemm continue;
1182c2aa98e2SPeter Wemm if (cbuf[0] == '\0' ||
1183c2aa98e2SPeter Wemm (strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL))
1184c2aa98e2SPeter Wemm {
118540266059SGregory Neil Shapiro (void) sm_strlcpy(cbuf, p, cbuflen);
1186c2aa98e2SPeter Wemm }
11872fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ(name, p))
118840266059SGregory Neil Shapiro found = true;
1189602a2b1bSGregory Neil Shapiro else if (dot != NULL)
1190602a2b1bSGregory Neil Shapiro {
1191602a2b1bSGregory Neil Shapiro /* try looking for the FQDN as well */
1192602a2b1bSGregory Neil Shapiro *dot = '.';
11932fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ(name, p))
119440266059SGregory Neil Shapiro found = true;
1195602a2b1bSGregory Neil Shapiro *dot = '\0';
1196602a2b1bSGregory Neil Shapiro }
1197c2aa98e2SPeter Wemm }
1198c2aa98e2SPeter Wemm if (found && strchr(cbuf, '.') == NULL)
1199c2aa98e2SPeter Wemm {
1200c2aa98e2SPeter Wemm /* try to add a domain on the end of the name */
1201c2aa98e2SPeter Wemm char *domain = macvalue('m', CurEnv);
1202c2aa98e2SPeter Wemm
1203c2aa98e2SPeter Wemm if (domain != NULL &&
120406f25ae9SGregory Neil Shapiro strlen(domain) + (i = strlen(cbuf)) + 1 < (size_t) cbuflen)
1205c2aa98e2SPeter Wemm {
120606f25ae9SGregory Neil Shapiro p = &cbuf[i];
1207c2aa98e2SPeter Wemm *p++ = '.';
120840266059SGregory Neil Shapiro (void) sm_strlcpy(p, domain, cbuflen - i - 1);
1209c2aa98e2SPeter Wemm }
1210c2aa98e2SPeter Wemm }
1211c2aa98e2SPeter Wemm return found;
1212c2aa98e2SPeter Wemm }
121340266059SGregory Neil Shapiro
121440266059SGregory Neil Shapiro /*
121540266059SGregory Neil Shapiro ** DNS modules
121640266059SGregory Neil Shapiro */
121740266059SGregory Neil Shapiro
121840266059SGregory Neil Shapiro #if NAMED_BIND
121940266059SGregory Neil Shapiro # if DNSMAP
122040266059SGregory Neil Shapiro
122140266059SGregory Neil Shapiro # include "sm_resolve.h"
122240266059SGregory Neil Shapiro # if NETINET || NETINET6
122340266059SGregory Neil Shapiro # include <arpa/inet.h>
12245b0945b5SGregory Neil Shapiro # endif
122540266059SGregory Neil Shapiro
122640266059SGregory Neil Shapiro /*
122740266059SGregory Neil Shapiro ** DNS_MAP_OPEN -- stub to check proper value for dns map type
122840266059SGregory Neil Shapiro */
122940266059SGregory Neil Shapiro
123040266059SGregory Neil Shapiro bool
dns_map_open(map,mode)123140266059SGregory Neil Shapiro dns_map_open(map, mode)
123240266059SGregory Neil Shapiro MAP *map;
123340266059SGregory Neil Shapiro int mode;
123440266059SGregory Neil Shapiro {
123540266059SGregory Neil Shapiro if (tTd(38,2))
123640266059SGregory Neil Shapiro sm_dprintf("dns_map_open(%s, %d)\n", map->map_mname, mode);
123740266059SGregory Neil Shapiro
123840266059SGregory Neil Shapiro mode &= O_ACCMODE;
123940266059SGregory Neil Shapiro if (mode != O_RDONLY)
124040266059SGregory Neil Shapiro {
124140266059SGregory Neil Shapiro /* issue a pseudo-error message */
124240266059SGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
124340266059SGregory Neil Shapiro return false;
124440266059SGregory Neil Shapiro }
124540266059SGregory Neil Shapiro return true;
124640266059SGregory Neil Shapiro }
124740266059SGregory Neil Shapiro
124840266059SGregory Neil Shapiro /*
124940266059SGregory Neil Shapiro ** DNS_MAP_PARSEARGS -- parse dns map definition args.
125040266059SGregory Neil Shapiro **
125140266059SGregory Neil Shapiro ** Parameters:
125240266059SGregory Neil Shapiro ** map -- pointer to MAP
125340266059SGregory Neil Shapiro ** args -- pointer to the args on the config line.
125440266059SGregory Neil Shapiro **
125540266059SGregory Neil Shapiro ** Returns:
125640266059SGregory Neil Shapiro ** true -- if everything parsed OK.
125740266059SGregory Neil Shapiro ** false -- otherwise.
125840266059SGregory Neil Shapiro */
125940266059SGregory Neil Shapiro
126040266059SGregory Neil Shapiro #define map_sizelimit map_lockfd /* overload field */
126140266059SGregory Neil Shapiro
126240266059SGregory Neil Shapiro struct dns_map
126340266059SGregory Neil Shapiro {
126440266059SGregory Neil Shapiro int dns_m_type;
12655b0945b5SGregory Neil Shapiro unsigned int dns_m_options;
126640266059SGregory Neil Shapiro };
126740266059SGregory Neil Shapiro
126840266059SGregory Neil Shapiro bool
dns_map_parseargs(map,args)126940266059SGregory Neil Shapiro dns_map_parseargs(map,args)
127040266059SGregory Neil Shapiro MAP *map;
127140266059SGregory Neil Shapiro char *args;
127240266059SGregory Neil Shapiro {
127340266059SGregory Neil Shapiro register char *p = args;
127440266059SGregory Neil Shapiro struct dns_map *map_p;
127540266059SGregory Neil Shapiro
1276d0cef73dSGregory Neil Shapiro map_p = (struct dns_map *) xalloc(sizeof(*map_p));
12775b0945b5SGregory Neil Shapiro memset(map_p, '\0', sizeof(*map_p));
127840266059SGregory Neil Shapiro map_p->dns_m_type = -1;
127940266059SGregory Neil Shapiro map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
128040266059SGregory Neil Shapiro
128140266059SGregory Neil Shapiro for (;;)
128240266059SGregory Neil Shapiro {
12835b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
128440266059SGregory Neil Shapiro p++;
128540266059SGregory Neil Shapiro if (*p != '-')
128640266059SGregory Neil Shapiro break;
128740266059SGregory Neil Shapiro switch (*++p)
128840266059SGregory Neil Shapiro {
1289*d39bd2c1SGregory Neil Shapiro # if DNSSEC_TEST || _FFR_NAMESERVER
12905b0945b5SGregory Neil Shapiro case '@':
12915b0945b5SGregory Neil Shapiro ++p;
12925b0945b5SGregory Neil Shapiro if (nsportip(p) < 0)
12935b0945b5SGregory Neil Shapiro syserr("dns map %s: nsportip(%s)=failed",
12945b0945b5SGregory Neil Shapiro map->map_mname, p);
129540266059SGregory Neil Shapiro break;
1296*d39bd2c1SGregory Neil Shapiro # endif /* DNSSEC_TEST || _FFR_NAMESERVER */
129740266059SGregory Neil Shapiro
129840266059SGregory Neil Shapiro case 'A':
129940266059SGregory Neil Shapiro map->map_mflags |= MF_APPEND;
130040266059SGregory Neil Shapiro break;
130140266059SGregory Neil Shapiro
130240266059SGregory Neil Shapiro case 'a':
130340266059SGregory Neil Shapiro map->map_app = ++p;
130440266059SGregory Neil Shapiro break;
130540266059SGregory Neil Shapiro
13065b0945b5SGregory Neil Shapiro case 'B': /* base domain */
13075b0945b5SGregory Neil Shapiro {
13085b0945b5SGregory Neil Shapiro char *h;
13095b0945b5SGregory Neil Shapiro
13105b0945b5SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
13115b0945b5SGregory Neil Shapiro continue;
13125b0945b5SGregory Neil Shapiro h = strchr(p, ' ');
13135b0945b5SGregory Neil Shapiro if (h != NULL)
13145b0945b5SGregory Neil Shapiro *h = '\0';
13155b0945b5SGregory Neil Shapiro
13165b0945b5SGregory Neil Shapiro /*
13175b0945b5SGregory Neil Shapiro ** slight abuse of map->map_file; it isn't
13185b0945b5SGregory Neil Shapiro ** used otherwise in this map type.
13195b0945b5SGregory Neil Shapiro */
13205b0945b5SGregory Neil Shapiro
13215b0945b5SGregory Neil Shapiro map->map_file = newstr(p);
13225b0945b5SGregory Neil Shapiro if (h != NULL)
13235b0945b5SGregory Neil Shapiro *h = ' ';
13245b0945b5SGregory Neil Shapiro }
132540266059SGregory Neil Shapiro break;
132640266059SGregory Neil Shapiro
132740266059SGregory Neil Shapiro case 'd':
132840266059SGregory Neil Shapiro {
132940266059SGregory Neil Shapiro char *h;
133040266059SGregory Neil Shapiro
133140266059SGregory Neil Shapiro ++p;
133240266059SGregory Neil Shapiro h = strchr(p, ' ');
133340266059SGregory Neil Shapiro if (h != NULL)
133440266059SGregory Neil Shapiro *h = '\0';
133540266059SGregory Neil Shapiro map->map_timeout = convtime(p, 's');
133640266059SGregory Neil Shapiro if (h != NULL)
133740266059SGregory Neil Shapiro *h = ' ';
133840266059SGregory Neil Shapiro }
133940266059SGregory Neil Shapiro break;
134040266059SGregory Neil Shapiro
13415b0945b5SGregory Neil Shapiro case 'f':
13425b0945b5SGregory Neil Shapiro map->map_mflags |= MF_NOFOLDCASE;
13435b0945b5SGregory Neil Shapiro break;
13445b0945b5SGregory Neil Shapiro
13455b0945b5SGregory Neil Shapiro case 'm':
13465b0945b5SGregory Neil Shapiro map->map_mflags |= MF_MATCHONLY;
13475b0945b5SGregory Neil Shapiro break;
13485b0945b5SGregory Neil Shapiro
13495b0945b5SGregory Neil Shapiro case 'N':
13505b0945b5SGregory Neil Shapiro map->map_mflags |= MF_INCLNULL;
13515b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_TRY0NULL;
13525b0945b5SGregory Neil Shapiro break;
13535b0945b5SGregory Neil Shapiro
13545b0945b5SGregory Neil Shapiro case 'O':
13555b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_TRY1NULL;
13565b0945b5SGregory Neil Shapiro break;
13575b0945b5SGregory Neil Shapiro
13585b0945b5SGregory Neil Shapiro case 'o':
13595b0945b5SGregory Neil Shapiro map->map_mflags |= MF_OPTIONAL;
13605b0945b5SGregory Neil Shapiro break;
13615b0945b5SGregory Neil Shapiro
13625b0945b5SGregory Neil Shapiro case 'q':
13635b0945b5SGregory Neil Shapiro map->map_mflags |= MF_KEEPQUOTES;
13645b0945b5SGregory Neil Shapiro break;
13655b0945b5SGregory Neil Shapiro
13665b0945b5SGregory Neil Shapiro case 'S':
13675b0945b5SGregory Neil Shapiro # if defined(RES_USE_EDNS0) && defined(RES_USE_DNSSEC)
13685b0945b5SGregory Neil Shapiro map_p->dns_m_options |= SM_RES_DNSSEC;
13695b0945b5SGregory Neil Shapiro # endif
13705b0945b5SGregory Neil Shapiro break;
13715b0945b5SGregory Neil Shapiro
137240266059SGregory Neil Shapiro case 'r':
137340266059SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
137440266059SGregory Neil Shapiro continue;
137540266059SGregory Neil Shapiro map->map_retry = atoi(p);
137640266059SGregory Neil Shapiro break;
137740266059SGregory Neil Shapiro
13785b0945b5SGregory Neil Shapiro case 't':
13795b0945b5SGregory Neil Shapiro map->map_mflags |= MF_NODEFER;
13805b0945b5SGregory Neil Shapiro break;
13815b0945b5SGregory Neil Shapiro
13825b0945b5SGregory Neil Shapiro case 'T':
13835b0945b5SGregory Neil Shapiro map->map_tapp = ++p;
13845b0945b5SGregory Neil Shapiro break;
13855b0945b5SGregory Neil Shapiro
138640266059SGregory Neil Shapiro case 'z':
138740266059SGregory Neil Shapiro if (*++p != '\\')
138840266059SGregory Neil Shapiro map->map_coldelim = *p;
138940266059SGregory Neil Shapiro else
139040266059SGregory Neil Shapiro {
139140266059SGregory Neil Shapiro switch (*++p)
139240266059SGregory Neil Shapiro {
139340266059SGregory Neil Shapiro case 'n':
139440266059SGregory Neil Shapiro map->map_coldelim = '\n';
139540266059SGregory Neil Shapiro break;
139640266059SGregory Neil Shapiro
139740266059SGregory Neil Shapiro case 't':
139840266059SGregory Neil Shapiro map->map_coldelim = '\t';
139940266059SGregory Neil Shapiro break;
140040266059SGregory Neil Shapiro
140140266059SGregory Neil Shapiro default:
140240266059SGregory Neil Shapiro map->map_coldelim = '\\';
140340266059SGregory Neil Shapiro }
140440266059SGregory Neil Shapiro }
140540266059SGregory Neil Shapiro break;
140640266059SGregory Neil Shapiro
140740266059SGregory Neil Shapiro case 'Z':
140840266059SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
140940266059SGregory Neil Shapiro continue;
141040266059SGregory Neil Shapiro map->map_sizelimit = atoi(p);
141140266059SGregory Neil Shapiro break;
141240266059SGregory Neil Shapiro
141340266059SGregory Neil Shapiro /* Start of dns_map specific args */
141440266059SGregory Neil Shapiro case 'R': /* search field */
141540266059SGregory Neil Shapiro {
141640266059SGregory Neil Shapiro char *h;
141740266059SGregory Neil Shapiro
141840266059SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
141940266059SGregory Neil Shapiro continue;
142040266059SGregory Neil Shapiro h = strchr(p, ' ');
142140266059SGregory Neil Shapiro if (h != NULL)
142240266059SGregory Neil Shapiro *h = '\0';
142340266059SGregory Neil Shapiro map_p->dns_m_type = dns_string_to_type(p);
142440266059SGregory Neil Shapiro if (h != NULL)
142540266059SGregory Neil Shapiro *h = ' ';
142640266059SGregory Neil Shapiro if (map_p->dns_m_type < 0)
142740266059SGregory Neil Shapiro syserr("dns map %s: wrong type %s",
142840266059SGregory Neil Shapiro map->map_mname, p);
142940266059SGregory Neil Shapiro }
143040266059SGregory Neil Shapiro break;
143140266059SGregory Neil Shapiro
143240266059SGregory Neil Shapiro }
14335b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
143440266059SGregory Neil Shapiro p++;
143540266059SGregory Neil Shapiro if (*p != '\0')
143640266059SGregory Neil Shapiro *p++ = '\0';
143740266059SGregory Neil Shapiro }
143840266059SGregory Neil Shapiro if (map_p->dns_m_type < 0)
143940266059SGregory Neil Shapiro syserr("dns map %s: missing -R type", map->map_mname);
144040266059SGregory Neil Shapiro if (map->map_app != NULL)
144140266059SGregory Neil Shapiro map->map_app = newstr(map->map_app);
144240266059SGregory Neil Shapiro if (map->map_tapp != NULL)
144340266059SGregory Neil Shapiro map->map_tapp = newstr(map->map_tapp);
144440266059SGregory Neil Shapiro
144540266059SGregory Neil Shapiro /*
1446d0cef73dSGregory Neil Shapiro ** Assumption: assert(sizeof(int) <= sizeof(ARBPTR_T));
144740266059SGregory Neil Shapiro ** Even if this assumption is wrong, we use only one byte,
144840266059SGregory Neil Shapiro ** so it doesn't really matter.
144940266059SGregory Neil Shapiro */
145040266059SGregory Neil Shapiro
145140266059SGregory Neil Shapiro map->map_db1 = (ARBPTR_T) map_p;
145240266059SGregory Neil Shapiro return true;
145340266059SGregory Neil Shapiro }
145440266059SGregory Neil Shapiro
145540266059SGregory Neil Shapiro /*
145640266059SGregory Neil Shapiro ** DNS_MAP_LOOKUP -- perform dns map lookup.
145740266059SGregory Neil Shapiro **
145840266059SGregory Neil Shapiro ** Parameters:
145940266059SGregory Neil Shapiro ** map -- pointer to MAP
146040266059SGregory Neil Shapiro ** name -- name to look up
146140266059SGregory Neil Shapiro ** av -- arguments to interpolate into buf.
146240266059SGregory Neil Shapiro ** statp -- pointer to status (EX_)
146340266059SGregory Neil Shapiro **
146440266059SGregory Neil Shapiro ** Returns:
146540266059SGregory Neil Shapiro ** result of lookup if succeeded.
146640266059SGregory Neil Shapiro ** NULL -- otherwise.
146740266059SGregory Neil Shapiro */
146840266059SGregory Neil Shapiro
146940266059SGregory Neil Shapiro char *
dns_map_lookup(map,name,av,statp)147040266059SGregory Neil Shapiro dns_map_lookup(map, name, av, statp)
147140266059SGregory Neil Shapiro MAP *map;
147240266059SGregory Neil Shapiro char *name;
147340266059SGregory Neil Shapiro char **av;
147440266059SGregory Neil Shapiro int *statp;
147540266059SGregory Neil Shapiro {
147640266059SGregory Neil Shapiro int resnum = 0;
147740266059SGregory Neil Shapiro char *vp = NULL, *result = NULL;
147840266059SGregory Neil Shapiro size_t vsize;
147940266059SGregory Neil Shapiro struct dns_map *map_p;
148040266059SGregory Neil Shapiro RESOURCE_RECORD_T *rr = NULL;
148140266059SGregory Neil Shapiro DNS_REPLY_T *r = NULL;
14825b0945b5SGregory Neil Shapiro unsigned int options;
148340266059SGregory Neil Shapiro # if NETINET6
148440266059SGregory Neil Shapiro static char buf6[INET6_ADDRSTRLEN];
14855b0945b5SGregory Neil Shapiro # endif
148640266059SGregory Neil Shapiro
148740266059SGregory Neil Shapiro if (tTd(38, 20))
148840266059SGregory Neil Shapiro sm_dprintf("dns_map_lookup(%s, %s)\n",
148940266059SGregory Neil Shapiro map->map_mname, name);
149040266059SGregory Neil Shapiro
149140266059SGregory Neil Shapiro map_p = (struct dns_map *)(map->map_db1);
14925b0945b5SGregory Neil Shapiro options = map_p->dns_m_options;
149340266059SGregory Neil Shapiro if (map->map_file != NULL && *map->map_file != '\0')
149440266059SGregory Neil Shapiro {
149540266059SGregory Neil Shapiro size_t len;
149640266059SGregory Neil Shapiro char *appdomain;
149740266059SGregory Neil Shapiro
149840266059SGregory Neil Shapiro len = strlen(map->map_file) + strlen(name) + 2;
149940266059SGregory Neil Shapiro appdomain = (char *) sm_malloc(len);
150040266059SGregory Neil Shapiro if (appdomain == NULL)
150140266059SGregory Neil Shapiro {
150240266059SGregory Neil Shapiro *statp = EX_UNAVAILABLE;
150340266059SGregory Neil Shapiro return NULL;
150440266059SGregory Neil Shapiro }
150540266059SGregory Neil Shapiro (void) sm_strlcpyn(appdomain, len, 3, name, ".", map->map_file);
15065b0945b5SGregory Neil Shapiro r = dns_lookup_map(appdomain, C_IN, map_p->dns_m_type,
15075b0945b5SGregory Neil Shapiro map->map_timeout, map->map_retry, options);
150840266059SGregory Neil Shapiro sm_free(appdomain);
150940266059SGregory Neil Shapiro }
151040266059SGregory Neil Shapiro else
151140266059SGregory Neil Shapiro {
15125b0945b5SGregory Neil Shapiro r = dns_lookup_map(name, C_IN, map_p->dns_m_type,
15135b0945b5SGregory Neil Shapiro map->map_timeout, map->map_retry, options);
151440266059SGregory Neil Shapiro }
151540266059SGregory Neil Shapiro
151640266059SGregory Neil Shapiro if (r == NULL)
151740266059SGregory Neil Shapiro {
151840266059SGregory Neil Shapiro result = NULL;
1519a7ec597cSGregory Neil Shapiro if (h_errno == TRY_AGAIN || transienterror(errno))
152040266059SGregory Neil Shapiro *statp = EX_TEMPFAIL;
152140266059SGregory Neil Shapiro else
152240266059SGregory Neil Shapiro *statp = EX_NOTFOUND;
152340266059SGregory Neil Shapiro goto cleanup;
152440266059SGregory Neil Shapiro }
152540266059SGregory Neil Shapiro *statp = EX_OK;
152640266059SGregory Neil Shapiro for (rr = r->dns_r_head; rr != NULL; rr = rr->rr_next)
152740266059SGregory Neil Shapiro {
152840266059SGregory Neil Shapiro char *type = NULL;
152940266059SGregory Neil Shapiro char *value = NULL;
153040266059SGregory Neil Shapiro
153140266059SGregory Neil Shapiro switch (rr->rr_type)
153240266059SGregory Neil Shapiro {
153340266059SGregory Neil Shapiro case T_NS:
153440266059SGregory Neil Shapiro type = "T_NS";
153540266059SGregory Neil Shapiro value = rr->rr_u.rr_txt;
153640266059SGregory Neil Shapiro break;
153740266059SGregory Neil Shapiro case T_CNAME:
153840266059SGregory Neil Shapiro type = "T_CNAME";
153940266059SGregory Neil Shapiro value = rr->rr_u.rr_txt;
154040266059SGregory Neil Shapiro break;
154140266059SGregory Neil Shapiro case T_AFSDB:
154240266059SGregory Neil Shapiro type = "T_AFSDB";
154340266059SGregory Neil Shapiro value = rr->rr_u.rr_mx->mx_r_domain;
154440266059SGregory Neil Shapiro break;
154540266059SGregory Neil Shapiro case T_SRV:
154640266059SGregory Neil Shapiro type = "T_SRV";
154740266059SGregory Neil Shapiro value = rr->rr_u.rr_srv->srv_r_target;
154840266059SGregory Neil Shapiro break;
154940266059SGregory Neil Shapiro case T_PTR:
155040266059SGregory Neil Shapiro type = "T_PTR";
155140266059SGregory Neil Shapiro value = rr->rr_u.rr_txt;
155240266059SGregory Neil Shapiro break;
155340266059SGregory Neil Shapiro case T_TXT:
155440266059SGregory Neil Shapiro type = "T_TXT";
155540266059SGregory Neil Shapiro value = rr->rr_u.rr_txt;
155640266059SGregory Neil Shapiro break;
155740266059SGregory Neil Shapiro case T_MX:
155840266059SGregory Neil Shapiro type = "T_MX";
155940266059SGregory Neil Shapiro value = rr->rr_u.rr_mx->mx_r_domain;
156040266059SGregory Neil Shapiro break;
156140266059SGregory Neil Shapiro # if NETINET
156240266059SGregory Neil Shapiro case T_A:
156340266059SGregory Neil Shapiro type = "T_A";
156440266059SGregory Neil Shapiro value = inet_ntoa(*(rr->rr_u.rr_a));
156540266059SGregory Neil Shapiro break;
156640266059SGregory Neil Shapiro # endif /* NETINET */
156740266059SGregory Neil Shapiro # if NETINET6
156840266059SGregory Neil Shapiro case T_AAAA:
156940266059SGregory Neil Shapiro type = "T_AAAA";
157040266059SGregory Neil Shapiro value = anynet_ntop(rr->rr_u.rr_aaaa, buf6,
1571d0cef73dSGregory Neil Shapiro sizeof(buf6));
157240266059SGregory Neil Shapiro break;
157340266059SGregory Neil Shapiro # endif /* NETINET6 */
15745b0945b5SGregory Neil Shapiro # ifdef T_TLSA
15755b0945b5SGregory Neil Shapiro case T_TLSA:
15765b0945b5SGregory Neil Shapiro type = "T_TLSA";
15775b0945b5SGregory Neil Shapiro value = rr->rr_u.rr_txt;
15785b0945b5SGregory Neil Shapiro break;
15795b0945b5SGregory Neil Shapiro # endif /* T_TLSA */
158040266059SGregory Neil Shapiro }
158140266059SGregory Neil Shapiro
1582739ac4d4SGregory Neil Shapiro (void) strreplnonprt(value, 'X');
158340266059SGregory Neil Shapiro if (map_p->dns_m_type != rr->rr_type)
158440266059SGregory Neil Shapiro {
158540266059SGregory Neil Shapiro if (tTd(38, 40))
158640266059SGregory Neil Shapiro sm_dprintf("\tskipping type %s (%d) value %s\n",
158740266059SGregory Neil Shapiro type != NULL ? type : "<UNKNOWN>",
158840266059SGregory Neil Shapiro rr->rr_type,
158940266059SGregory Neil Shapiro value != NULL ? value : "<NO VALUE>");
159040266059SGregory Neil Shapiro continue;
159140266059SGregory Neil Shapiro }
159240266059SGregory Neil Shapiro
159340266059SGregory Neil Shapiro # if NETINET6
159440266059SGregory Neil Shapiro if (rr->rr_type == T_AAAA && value == NULL)
159540266059SGregory Neil Shapiro {
159640266059SGregory Neil Shapiro result = NULL;
159740266059SGregory Neil Shapiro *statp = EX_DATAERR;
159840266059SGregory Neil Shapiro if (tTd(38, 40))
159940266059SGregory Neil Shapiro sm_dprintf("\tbad T_AAAA conversion\n");
160040266059SGregory Neil Shapiro goto cleanup;
160140266059SGregory Neil Shapiro }
160240266059SGregory Neil Shapiro # endif /* NETINET6 */
160340266059SGregory Neil Shapiro if (tTd(38, 40))
160440266059SGregory Neil Shapiro sm_dprintf("\tfound type %s (%d) value %s\n",
160540266059SGregory Neil Shapiro type != NULL ? type : "<UNKNOWN>",
160640266059SGregory Neil Shapiro rr->rr_type,
160740266059SGregory Neil Shapiro value != NULL ? value : "<NO VALUE>");
160840266059SGregory Neil Shapiro if (value != NULL &&
160940266059SGregory Neil Shapiro (map->map_coldelim == '\0' ||
161040266059SGregory Neil Shapiro map->map_sizelimit == 1 ||
161140266059SGregory Neil Shapiro bitset(MF_MATCHONLY, map->map_mflags)))
161240266059SGregory Neil Shapiro {
161340266059SGregory Neil Shapiro /* Only care about the first match */
161440266059SGregory Neil Shapiro vp = newstr(value);
161540266059SGregory Neil Shapiro break;
161640266059SGregory Neil Shapiro }
161740266059SGregory Neil Shapiro else if (vp == NULL)
161840266059SGregory Neil Shapiro {
161940266059SGregory Neil Shapiro /* First result */
162040266059SGregory Neil Shapiro vp = newstr(value);
162140266059SGregory Neil Shapiro }
162240266059SGregory Neil Shapiro else
162340266059SGregory Neil Shapiro {
162440266059SGregory Neil Shapiro /* concatenate the results */
162540266059SGregory Neil Shapiro int sz;
162640266059SGregory Neil Shapiro char *new;
162740266059SGregory Neil Shapiro
162840266059SGregory Neil Shapiro sz = strlen(vp) + strlen(value) + 2;
162940266059SGregory Neil Shapiro new = xalloc(sz);
163040266059SGregory Neil Shapiro (void) sm_snprintf(new, sz, "%s%c%s",
163140266059SGregory Neil Shapiro vp, map->map_coldelim, value);
163240266059SGregory Neil Shapiro sm_free(vp);
163340266059SGregory Neil Shapiro vp = new;
163440266059SGregory Neil Shapiro if (map->map_sizelimit > 0 &&
163540266059SGregory Neil Shapiro ++resnum >= map->map_sizelimit)
163640266059SGregory Neil Shapiro break;
163740266059SGregory Neil Shapiro }
163840266059SGregory Neil Shapiro }
163940266059SGregory Neil Shapiro if (vp == NULL)
164040266059SGregory Neil Shapiro {
164140266059SGregory Neil Shapiro result = NULL;
164240266059SGregory Neil Shapiro *statp = EX_NOTFOUND;
164340266059SGregory Neil Shapiro if (tTd(38, 40))
164440266059SGregory Neil Shapiro sm_dprintf("\tno match found\n");
164540266059SGregory Neil Shapiro goto cleanup;
164640266059SGregory Neil Shapiro }
164740266059SGregory Neil Shapiro
164840266059SGregory Neil Shapiro /* Cleanly truncate for rulesets */
164940266059SGregory Neil Shapiro truncate_at_delim(vp, PSBUFSIZE / 2, map->map_coldelim);
165040266059SGregory Neil Shapiro
165140266059SGregory Neil Shapiro vsize = strlen(vp);
165240266059SGregory Neil Shapiro
165340266059SGregory Neil Shapiro if (LogLevel > 9)
165440266059SGregory Neil Shapiro sm_syslog(LOG_INFO, CurEnv->e_id, "dns %.100s => %s",
165540266059SGregory Neil Shapiro name, vp);
165640266059SGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
165740266059SGregory Neil Shapiro result = map_rewrite(map, name, strlen(name), NULL);
165840266059SGregory Neil Shapiro else
165940266059SGregory Neil Shapiro result = map_rewrite(map, vp, vsize, av);
166040266059SGregory Neil Shapiro
166140266059SGregory Neil Shapiro cleanup:
16622fb4f839SGregory Neil Shapiro SM_FREE(vp);
166340266059SGregory Neil Shapiro dns_free_data(r);
166440266059SGregory Neil Shapiro return result;
166540266059SGregory Neil Shapiro }
166640266059SGregory Neil Shapiro # endif /* DNSMAP */
166740266059SGregory Neil Shapiro #endif /* NAMED_BIND */
166840266059SGregory Neil Shapiro
166940266059SGregory Neil Shapiro /*
1670c2aa98e2SPeter Wemm ** NDBM modules
1671c2aa98e2SPeter Wemm */
1672c2aa98e2SPeter Wemm
167340266059SGregory Neil Shapiro #if NDBM
1674c2aa98e2SPeter Wemm
1675c2aa98e2SPeter Wemm /*
1676c2aa98e2SPeter Wemm ** NDBM_MAP_OPEN -- DBM-style map open
1677c2aa98e2SPeter Wemm */
1678c2aa98e2SPeter Wemm
1679c2aa98e2SPeter Wemm bool
ndbm_map_open(map,mode)1680c2aa98e2SPeter Wemm ndbm_map_open(map, mode)
1681c2aa98e2SPeter Wemm MAP *map;
1682c2aa98e2SPeter Wemm int mode;
1683c2aa98e2SPeter Wemm {
1684c2aa98e2SPeter Wemm register DBM *dbm;
168506f25ae9SGregory Neil Shapiro int save_errno;
1686c2aa98e2SPeter Wemm int dfd;
1687c2aa98e2SPeter Wemm int pfd;
168806f25ae9SGregory Neil Shapiro long sff;
1689c2aa98e2SPeter Wemm int ret;
1690c2aa98e2SPeter Wemm int smode = S_IREAD;
169194c01205SGregory Neil Shapiro char dirfile[MAXPATHLEN];
169294c01205SGregory Neil Shapiro char pagfile[MAXPATHLEN];
169306f25ae9SGregory Neil Shapiro struct stat st;
1694c2aa98e2SPeter Wemm struct stat std, stp;
1695c2aa98e2SPeter Wemm
1696c2aa98e2SPeter Wemm if (tTd(38, 2))
169740266059SGregory Neil Shapiro sm_dprintf("ndbm_map_open(%s, %s, %d)\n",
1698c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
1699c2aa98e2SPeter Wemm map->map_lockfd = -1;
1700c2aa98e2SPeter Wemm mode &= O_ACCMODE;
1701c2aa98e2SPeter Wemm
1702c2aa98e2SPeter Wemm /* do initial file and directory checks */
1703d0cef73dSGregory Neil Shapiro if (sm_strlcpyn(dirfile, sizeof(dirfile), 2,
1704d0cef73dSGregory Neil Shapiro map->map_file, ".dir") >= sizeof(dirfile) ||
1705d0cef73dSGregory Neil Shapiro sm_strlcpyn(pagfile, sizeof(pagfile), 2,
1706d0cef73dSGregory Neil Shapiro map->map_file, ".pag") >= sizeof(pagfile))
170794c01205SGregory Neil Shapiro {
170894c01205SGregory Neil Shapiro errno = 0;
170994c01205SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
171094c01205SGregory Neil Shapiro syserr("dbm map \"%s\": map file %s name too long",
171194c01205SGregory Neil Shapiro map->map_mname, map->map_file);
171294c01205SGregory Neil Shapiro return false;
171394c01205SGregory Neil Shapiro }
1714c2aa98e2SPeter Wemm sff = SFF_ROOTOK|SFF_REGONLY;
1715c2aa98e2SPeter Wemm if (mode == O_RDWR)
1716c2aa98e2SPeter Wemm {
1717c2aa98e2SPeter Wemm sff |= SFF_CREAT;
171806f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
1719c2aa98e2SPeter Wemm sff |= SFF_NOSLINK;
172006f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
1721c2aa98e2SPeter Wemm sff |= SFF_NOHLINK;
1722c2aa98e2SPeter Wemm smode = S_IWRITE;
1723c2aa98e2SPeter Wemm }
1724c2aa98e2SPeter Wemm else
1725c2aa98e2SPeter Wemm {
172606f25ae9SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
1727c2aa98e2SPeter Wemm sff |= SFF_NOWLINK;
1728c2aa98e2SPeter Wemm }
172906f25ae9SGregory Neil Shapiro if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
1730c2aa98e2SPeter Wemm sff |= SFF_SAFEDIRPATH;
1731c2aa98e2SPeter Wemm ret = safefile(dirfile, RunAsUid, RunAsGid, RunAsUserName,
1732c2aa98e2SPeter Wemm sff, smode, &std);
1733c2aa98e2SPeter Wemm if (ret == 0)
1734c2aa98e2SPeter Wemm ret = safefile(pagfile, RunAsUid, RunAsGid, RunAsUserName,
1735c2aa98e2SPeter Wemm sff, smode, &stp);
173606f25ae9SGregory Neil Shapiro
1737c2aa98e2SPeter Wemm if (ret != 0)
1738c2aa98e2SPeter Wemm {
1739c2aa98e2SPeter Wemm char *prob = "unsafe";
1740c2aa98e2SPeter Wemm
1741c2aa98e2SPeter Wemm /* cannot open this map */
1742c2aa98e2SPeter Wemm if (ret == ENOENT)
1743c2aa98e2SPeter Wemm prob = "missing";
1744c2aa98e2SPeter Wemm if (tTd(38, 2))
174540266059SGregory Neil Shapiro sm_dprintf("\t%s map file: %d\n", prob, ret);
1746c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
1747c2aa98e2SPeter Wemm syserr("dbm map \"%s\": %s map file %s",
1748c2aa98e2SPeter Wemm map->map_mname, prob, map->map_file);
174940266059SGregory Neil Shapiro return false;
1750c2aa98e2SPeter Wemm }
1751c2aa98e2SPeter Wemm if (std.st_mode == ST_MODE_NOFILE)
1752c2aa98e2SPeter Wemm mode |= O_CREAT|O_EXCL;
1753c2aa98e2SPeter Wemm
1754c2aa98e2SPeter Wemm # if LOCK_ON_OPEN
1755c2aa98e2SPeter Wemm if (mode == O_RDONLY)
1756c2aa98e2SPeter Wemm mode |= O_SHLOCK;
1757c2aa98e2SPeter Wemm else
1758c2aa98e2SPeter Wemm mode |= O_TRUNC|O_EXLOCK;
175906f25ae9SGregory Neil Shapiro # else /* LOCK_ON_OPEN */
1760c2aa98e2SPeter Wemm if ((mode & O_ACCMODE) == O_RDWR)
1761c2aa98e2SPeter Wemm {
1762c2aa98e2SPeter Wemm # if NOFTRUNCATE
1763c2aa98e2SPeter Wemm /*
1764c2aa98e2SPeter Wemm ** Warning: race condition. Try to lock the file as
1765c2aa98e2SPeter Wemm ** quickly as possible after opening it.
1766c2aa98e2SPeter Wemm ** This may also have security problems on some systems,
1767c2aa98e2SPeter Wemm ** but there isn't anything we can do about it.
1768c2aa98e2SPeter Wemm */
1769c2aa98e2SPeter Wemm
1770c2aa98e2SPeter Wemm mode |= O_TRUNC;
177106f25ae9SGregory Neil Shapiro # else /* NOFTRUNCATE */
1772c2aa98e2SPeter Wemm /*
1773c2aa98e2SPeter Wemm ** This ugly code opens the map without truncating it,
1774c2aa98e2SPeter Wemm ** locks the file, then truncates it. Necessary to
1775c2aa98e2SPeter Wemm ** avoid race conditions.
1776c2aa98e2SPeter Wemm */
1777c2aa98e2SPeter Wemm
1778c2aa98e2SPeter Wemm int dirfd;
1779c2aa98e2SPeter Wemm int pagfd;
178006f25ae9SGregory Neil Shapiro long sff = SFF_CREAT|SFF_OPENASROOT;
1781c2aa98e2SPeter Wemm
178206f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
1783c2aa98e2SPeter Wemm sff |= SFF_NOSLINK;
178406f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
1785c2aa98e2SPeter Wemm sff |= SFF_NOHLINK;
1786c2aa98e2SPeter Wemm
1787c2aa98e2SPeter Wemm dirfd = safeopen(dirfile, mode, DBMMODE, sff);
1788c2aa98e2SPeter Wemm pagfd = safeopen(pagfile, mode, DBMMODE, sff);
1789c2aa98e2SPeter Wemm
1790c2aa98e2SPeter Wemm if (dirfd < 0 || pagfd < 0)
1791c2aa98e2SPeter Wemm {
179206f25ae9SGregory Neil Shapiro save_errno = errno;
1793c2aa98e2SPeter Wemm if (dirfd >= 0)
1794c2aa98e2SPeter Wemm (void) close(dirfd);
1795c2aa98e2SPeter Wemm if (pagfd >= 0)
1796c2aa98e2SPeter Wemm (void) close(pagfd);
1797c2aa98e2SPeter Wemm errno = save_errno;
1798c2aa98e2SPeter Wemm syserr("ndbm_map_open: cannot create database %s",
1799c2aa98e2SPeter Wemm map->map_file);
180040266059SGregory Neil Shapiro return false;
1801c2aa98e2SPeter Wemm }
1802c2aa98e2SPeter Wemm if (ftruncate(dirfd, (off_t) 0) < 0 ||
1803c2aa98e2SPeter Wemm ftruncate(pagfd, (off_t) 0) < 0)
1804c2aa98e2SPeter Wemm {
180506f25ae9SGregory Neil Shapiro save_errno = errno;
1806c2aa98e2SPeter Wemm (void) close(dirfd);
1807c2aa98e2SPeter Wemm (void) close(pagfd);
1808c2aa98e2SPeter Wemm errno = save_errno;
1809c2aa98e2SPeter Wemm syserr("ndbm_map_open: cannot truncate %s.{dir,pag}",
1810c2aa98e2SPeter Wemm map->map_file);
181140266059SGregory Neil Shapiro return false;
1812c2aa98e2SPeter Wemm }
1813c2aa98e2SPeter Wemm
1814c2aa98e2SPeter Wemm /* if new file, get "before" bits for later filechanged check */
1815c2aa98e2SPeter Wemm if (std.st_mode == ST_MODE_NOFILE &&
1816c2aa98e2SPeter Wemm (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0))
1817c2aa98e2SPeter Wemm {
181806f25ae9SGregory Neil Shapiro save_errno = errno;
1819c2aa98e2SPeter Wemm (void) close(dirfd);
1820c2aa98e2SPeter Wemm (void) close(pagfd);
1821c2aa98e2SPeter Wemm errno = save_errno;
1822c2aa98e2SPeter Wemm syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file",
1823c2aa98e2SPeter Wemm map->map_file);
182440266059SGregory Neil Shapiro return false;
1825c2aa98e2SPeter Wemm }
1826c2aa98e2SPeter Wemm
1827c2aa98e2SPeter Wemm /* have to save the lock for the duration (bletch) */
1828c2aa98e2SPeter Wemm map->map_lockfd = dirfd;
182906f25ae9SGregory Neil Shapiro (void) close(pagfd);
1830c2aa98e2SPeter Wemm
1831c2aa98e2SPeter Wemm /* twiddle bits for dbm_open */
1832c2aa98e2SPeter Wemm mode &= ~(O_CREAT|O_EXCL);
183306f25ae9SGregory Neil Shapiro # endif /* NOFTRUNCATE */
1834c2aa98e2SPeter Wemm }
183506f25ae9SGregory Neil Shapiro # endif /* LOCK_ON_OPEN */
1836c2aa98e2SPeter Wemm
1837c2aa98e2SPeter Wemm /* open the database */
1838c2aa98e2SPeter Wemm dbm = dbm_open(map->map_file, mode, DBMMODE);
1839c2aa98e2SPeter Wemm if (dbm == NULL)
1840c2aa98e2SPeter Wemm {
184106f25ae9SGregory Neil Shapiro save_errno = errno;
1842c2aa98e2SPeter Wemm if (bitset(MF_ALIAS, map->map_mflags) &&
184340266059SGregory Neil Shapiro aliaswait(map, ".pag", false))
184440266059SGregory Neil Shapiro return true;
1845c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN && !NOFTRUNCATE
1846c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
184706f25ae9SGregory Neil Shapiro (void) close(map->map_lockfd);
18485b0945b5SGregory Neil Shapiro # endif
1849c2aa98e2SPeter Wemm errno = save_errno;
1850c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
1851c2aa98e2SPeter Wemm syserr("Cannot open DBM database %s", map->map_file);
185240266059SGregory Neil Shapiro return false;
1853c2aa98e2SPeter Wemm }
1854c2aa98e2SPeter Wemm dfd = dbm_dirfno(dbm);
1855c2aa98e2SPeter Wemm pfd = dbm_pagfno(dbm);
1856c2aa98e2SPeter Wemm if (dfd == pfd)
1857c2aa98e2SPeter Wemm {
1858c2aa98e2SPeter Wemm /* heuristic: if files are linked, this is actually gdbm */
1859c2aa98e2SPeter Wemm dbm_close(dbm);
1860c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN && !NOFTRUNCATE
1861c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
186206f25ae9SGregory Neil Shapiro (void) close(map->map_lockfd);
18635b0945b5SGregory Neil Shapiro # endif
1864c2aa98e2SPeter Wemm errno = 0;
1865c2aa98e2SPeter Wemm syserr("dbm map \"%s\": cannot support GDBM",
1866c2aa98e2SPeter Wemm map->map_mname);
186740266059SGregory Neil Shapiro return false;
1868c2aa98e2SPeter Wemm }
1869c2aa98e2SPeter Wemm
1870c2aa98e2SPeter Wemm if (filechanged(dirfile, dfd, &std) ||
1871c2aa98e2SPeter Wemm filechanged(pagfile, pfd, &stp))
1872c2aa98e2SPeter Wemm {
187306f25ae9SGregory Neil Shapiro save_errno = errno;
1874c2aa98e2SPeter Wemm dbm_close(dbm);
1875c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN && !NOFTRUNCATE
1876c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
187706f25ae9SGregory Neil Shapiro (void) close(map->map_lockfd);
18785b0945b5SGregory Neil Shapiro # endif
1879c2aa98e2SPeter Wemm errno = save_errno;
1880c2aa98e2SPeter Wemm syserr("ndbm_map_open(%s): file changed after open",
1881c2aa98e2SPeter Wemm map->map_file);
188240266059SGregory Neil Shapiro return false;
1883c2aa98e2SPeter Wemm }
1884c2aa98e2SPeter Wemm
1885c2aa98e2SPeter Wemm map->map_db1 = (ARBPTR_T) dbm;
188606f25ae9SGregory Neil Shapiro
188706f25ae9SGregory Neil Shapiro /*
188806f25ae9SGregory Neil Shapiro ** Need to set map_mtime before the call to aliaswait()
188906f25ae9SGregory Neil Shapiro ** as aliaswait() will call map_lookup() which requires
189006f25ae9SGregory Neil Shapiro ** map_mtime to be set
189106f25ae9SGregory Neil Shapiro */
189206f25ae9SGregory Neil Shapiro
18938774250cSGregory Neil Shapiro if (fstat(pfd, &st) >= 0)
189406f25ae9SGregory Neil Shapiro map->map_mtime = st.st_mtime;
189506f25ae9SGregory Neil Shapiro
1896c2aa98e2SPeter Wemm if (mode == O_RDONLY)
1897c2aa98e2SPeter Wemm {
1898c2aa98e2SPeter Wemm # if LOCK_ON_OPEN
1899c2aa98e2SPeter Wemm if (dfd >= 0)
1900c2aa98e2SPeter Wemm (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
1901c2aa98e2SPeter Wemm if (pfd >= 0)
1902c2aa98e2SPeter Wemm (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN);
190306f25ae9SGregory Neil Shapiro # endif /* LOCK_ON_OPEN */
1904c2aa98e2SPeter Wemm if (bitset(MF_ALIAS, map->map_mflags) &&
190540266059SGregory Neil Shapiro !aliaswait(map, ".pag", true))
190640266059SGregory Neil Shapiro return false;
1907c2aa98e2SPeter Wemm }
1908c2aa98e2SPeter Wemm else
1909c2aa98e2SPeter Wemm {
1910c2aa98e2SPeter Wemm map->map_mflags |= MF_LOCKED;
1911*d39bd2c1SGregory Neil Shapiro mapchown(map->map_file, dfd, pfd, map->map_file);
1912c2aa98e2SPeter Wemm }
191340266059SGregory Neil Shapiro return true;
1914c2aa98e2SPeter Wemm }
1915c2aa98e2SPeter Wemm
1916c2aa98e2SPeter Wemm
1917c2aa98e2SPeter Wemm /*
1918c2aa98e2SPeter Wemm ** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map
1919c2aa98e2SPeter Wemm */
1920c2aa98e2SPeter Wemm
1921c2aa98e2SPeter Wemm char *
ndbm_map_lookup(map,name,av,statp)1922c2aa98e2SPeter Wemm ndbm_map_lookup(map, name, av, statp)
1923c2aa98e2SPeter Wemm MAP *map;
1924c2aa98e2SPeter Wemm char *name;
1925c2aa98e2SPeter Wemm char **av;
1926c2aa98e2SPeter Wemm int *statp;
1927c2aa98e2SPeter Wemm {
1928c2aa98e2SPeter Wemm datum key, val;
19298774250cSGregory Neil Shapiro int dfd, pfd;
19302fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
1931*d39bd2c1SGregory Neil Shapiro # if _FFR_MAP_CHK_FILE
1932*d39bd2c1SGregory Neil Shapiro char buf[MAXPATHLEN];
1933*d39bd2c1SGregory Neil Shapiro # endif
1934*d39bd2c1SGregory Neil Shapiro const char *fn = NULL;
1935c2aa98e2SPeter Wemm
1936c2aa98e2SPeter Wemm if (tTd(38, 20))
193740266059SGregory Neil Shapiro sm_dprintf("ndbm_map_lookup(%s, %s)\n",
1938c2aa98e2SPeter Wemm map->map_mname, name);
1939c2aa98e2SPeter Wemm
1940c2aa98e2SPeter Wemm key.dptr = name;
1941c2aa98e2SPeter Wemm key.dsize = strlen(name);
1942c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
1943c2aa98e2SPeter Wemm {
1944d0cef73dSGregory Neil Shapiro if (key.dsize > sizeof(keybuf) - 1)
1945d0cef73dSGregory Neil Shapiro key.dsize = sizeof(keybuf) - 1;
194606f25ae9SGregory Neil Shapiro memmove(keybuf, key.dptr, key.dsize);
1947c2aa98e2SPeter Wemm keybuf[key.dsize] = '\0';
19482fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
1949c2aa98e2SPeter Wemm key.dptr = keybuf;
1950c2aa98e2SPeter Wemm }
1951*d39bd2c1SGregory Neil Shapiro # if _FFR_MAP_CHK_FILE
1952*d39bd2c1SGregory Neil Shapiro if (!smdb_add_extension(buf, sizeof(buf), map->map_file, "pag"))
1953*d39bd2c1SGregory Neil Shapiro {
1954*d39bd2c1SGregory Neil Shapiro errno = 0;
1955*d39bd2c1SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
1956*d39bd2c1SGregory Neil Shapiro syserr("ndbm map \"%s\": map file %s name too long",
1957*d39bd2c1SGregory Neil Shapiro map->map_mname, map->map_file);
1958*d39bd2c1SGregory Neil Shapiro return NULL;
1959*d39bd2c1SGregory Neil Shapiro }
1960*d39bd2c1SGregory Neil Shapiro fn = buf;
1961*d39bd2c1SGregory Neil Shapiro # endif
1962c2aa98e2SPeter Wemm lockdbm:
19638774250cSGregory Neil Shapiro dfd = dbm_dirfno((DBM *) map->map_db1);
19648774250cSGregory Neil Shapiro if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
19658774250cSGregory Neil Shapiro (void) lockfile(dfd, map->map_file, ".dir", LOCK_SH);
19668774250cSGregory Neil Shapiro pfd = dbm_pagfno((DBM *) map->map_db1);
1967*d39bd2c1SGregory Neil Shapiro
1968*d39bd2c1SGregory Neil Shapiro if (map_has_chged(map, fn, pfd))
1969c2aa98e2SPeter Wemm {
1970c2aa98e2SPeter Wemm /* Reopen the database to sync the cache */
1971c2aa98e2SPeter Wemm int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
1972c2aa98e2SPeter Wemm : O_RDONLY;
1973c2aa98e2SPeter Wemm
19748774250cSGregory Neil Shapiro if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
19758774250cSGregory Neil Shapiro (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
19768774250cSGregory Neil Shapiro map->map_mflags |= MF_CLOSING;
1977c2aa98e2SPeter Wemm map->map_class->map_close(map);
19788774250cSGregory Neil Shapiro map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
1979c2aa98e2SPeter Wemm if (map->map_class->map_open(map, omode))
1980c2aa98e2SPeter Wemm {
1981c2aa98e2SPeter Wemm map->map_mflags |= MF_OPEN;
198240266059SGregory Neil Shapiro map->map_pid = CurrentPid;
19839bd497b8SGregory Neil Shapiro if ((omode & O_ACCMODE) == O_RDWR)
1984c2aa98e2SPeter Wemm map->map_mflags |= MF_WRITABLE;
1985c2aa98e2SPeter Wemm goto lockdbm;
1986c2aa98e2SPeter Wemm }
1987c2aa98e2SPeter Wemm else
1988c2aa98e2SPeter Wemm {
1989c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
1990c2aa98e2SPeter Wemm {
1991c2aa98e2SPeter Wemm extern MAPCLASS BogusMapClass;
1992c2aa98e2SPeter Wemm
1993c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
199440266059SGregory Neil Shapiro map->map_orgclass = map->map_class;
1995c2aa98e2SPeter Wemm map->map_class = &BogusMapClass;
1996c2aa98e2SPeter Wemm map->map_mflags |= MF_OPEN;
199740266059SGregory Neil Shapiro map->map_pid = CurrentPid;
1998c2aa98e2SPeter Wemm syserr("Cannot reopen NDBM database %s",
1999c2aa98e2SPeter Wemm map->map_file);
2000c2aa98e2SPeter Wemm }
2001c2aa98e2SPeter Wemm return NULL;
2002c2aa98e2SPeter Wemm }
2003c2aa98e2SPeter Wemm }
2004c2aa98e2SPeter Wemm val.dptr = NULL;
2005c2aa98e2SPeter Wemm if (bitset(MF_TRY0NULL, map->map_mflags))
2006c2aa98e2SPeter Wemm {
2007c2aa98e2SPeter Wemm val = dbm_fetch((DBM *) map->map_db1, key);
2008c2aa98e2SPeter Wemm if (val.dptr != NULL)
2009c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY1NULL;
2010c2aa98e2SPeter Wemm }
2011c2aa98e2SPeter Wemm if (val.dptr == NULL && bitset(MF_TRY1NULL, map->map_mflags))
2012c2aa98e2SPeter Wemm {
2013c2aa98e2SPeter Wemm key.dsize++;
2014c2aa98e2SPeter Wemm val = dbm_fetch((DBM *) map->map_db1, key);
2015c2aa98e2SPeter Wemm if (val.dptr != NULL)
2016c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY0NULL;
2017c2aa98e2SPeter Wemm }
20188774250cSGregory Neil Shapiro if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
20198774250cSGregory Neil Shapiro (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
2020c2aa98e2SPeter Wemm if (val.dptr == NULL)
2021c2aa98e2SPeter Wemm return NULL;
2022c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
2023c2aa98e2SPeter Wemm return map_rewrite(map, name, strlen(name), NULL);
2024c2aa98e2SPeter Wemm else
2025c2aa98e2SPeter Wemm return map_rewrite(map, val.dptr, val.dsize, av);
2026c2aa98e2SPeter Wemm }
2027c2aa98e2SPeter Wemm
2028c2aa98e2SPeter Wemm
2029c2aa98e2SPeter Wemm /*
2030c2aa98e2SPeter Wemm ** NDBM_MAP_STORE -- store a datum in the database
2031c2aa98e2SPeter Wemm */
2032c2aa98e2SPeter Wemm
2033c2aa98e2SPeter Wemm void
ndbm_map_store(map,lhs,rhs)2034c2aa98e2SPeter Wemm ndbm_map_store(map, lhs, rhs)
2035c2aa98e2SPeter Wemm register MAP *map;
2036c2aa98e2SPeter Wemm char *lhs;
2037c2aa98e2SPeter Wemm char *rhs;
2038c2aa98e2SPeter Wemm {
2039c2aa98e2SPeter Wemm datum key;
2040c2aa98e2SPeter Wemm datum data;
204106f25ae9SGregory Neil Shapiro int status;
20422fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
2043c2aa98e2SPeter Wemm
2044c2aa98e2SPeter Wemm if (tTd(38, 12))
204540266059SGregory Neil Shapiro sm_dprintf("ndbm_map_store(%s, %s, %s)\n",
2046c2aa98e2SPeter Wemm map->map_mname, lhs, rhs);
2047c2aa98e2SPeter Wemm
2048c2aa98e2SPeter Wemm key.dsize = strlen(lhs);
2049c2aa98e2SPeter Wemm key.dptr = lhs;
2050c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
2051c2aa98e2SPeter Wemm {
2052d0cef73dSGregory Neil Shapiro if (key.dsize > sizeof(keybuf) - 1)
2053d0cef73dSGregory Neil Shapiro key.dsize = sizeof(keybuf) - 1;
205406f25ae9SGregory Neil Shapiro memmove(keybuf, key.dptr, key.dsize);
2055c2aa98e2SPeter Wemm keybuf[key.dsize] = '\0';
20562fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
2057c2aa98e2SPeter Wemm key.dptr = keybuf;
2058c2aa98e2SPeter Wemm }
2059c2aa98e2SPeter Wemm
2060c2aa98e2SPeter Wemm data.dsize = strlen(rhs);
2061c2aa98e2SPeter Wemm data.dptr = rhs;
2062c2aa98e2SPeter Wemm
2063c2aa98e2SPeter Wemm if (bitset(MF_INCLNULL, map->map_mflags))
2064c2aa98e2SPeter Wemm {
2065c2aa98e2SPeter Wemm key.dsize++;
2066c2aa98e2SPeter Wemm data.dsize++;
2067c2aa98e2SPeter Wemm }
2068c2aa98e2SPeter Wemm
206906f25ae9SGregory Neil Shapiro status = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT);
207006f25ae9SGregory Neil Shapiro if (status > 0)
2071c2aa98e2SPeter Wemm {
2072c2aa98e2SPeter Wemm if (!bitset(MF_APPEND, map->map_mflags))
2073c2aa98e2SPeter Wemm message("050 Warning: duplicate alias name %s", lhs);
2074c2aa98e2SPeter Wemm else
2075c2aa98e2SPeter Wemm {
2076c2aa98e2SPeter Wemm static char *buf = NULL;
2077c2aa98e2SPeter Wemm static int bufsiz = 0;
2078c2aa98e2SPeter Wemm auto int xstat;
2079c2aa98e2SPeter Wemm datum old;
2080c2aa98e2SPeter Wemm
2081c2aa98e2SPeter Wemm old.dptr = ndbm_map_lookup(map, key.dptr,
2082c2aa98e2SPeter Wemm (char **) NULL, &xstat);
2083c2aa98e2SPeter Wemm if (old.dptr != NULL && *(char *) old.dptr != '\0')
2084c2aa98e2SPeter Wemm {
2085c2aa98e2SPeter Wemm old.dsize = strlen(old.dptr);
2086c2aa98e2SPeter Wemm if (data.dsize + old.dsize + 2 > bufsiz)
2087c2aa98e2SPeter Wemm {
20882fb4f839SGregory Neil Shapiro SM_FREE(buf);
2089c2aa98e2SPeter Wemm bufsiz = data.dsize + old.dsize + 2;
209040266059SGregory Neil Shapiro buf = sm_pmalloc_x(bufsiz);
2091c2aa98e2SPeter Wemm }
209240266059SGregory Neil Shapiro (void) sm_strlcpyn(buf, bufsiz, 3,
209340266059SGregory Neil Shapiro data.dptr, ",", old.dptr);
2094c2aa98e2SPeter Wemm data.dsize = data.dsize + old.dsize + 1;
2095c2aa98e2SPeter Wemm data.dptr = buf;
2096c2aa98e2SPeter Wemm if (tTd(38, 9))
209740266059SGregory Neil Shapiro sm_dprintf("ndbm_map_store append=%s\n",
20985b0945b5SGregory Neil Shapiro data.dptr);
2099c2aa98e2SPeter Wemm }
2100c2aa98e2SPeter Wemm }
210106f25ae9SGregory Neil Shapiro status = dbm_store((DBM *) map->map_db1,
210206f25ae9SGregory Neil Shapiro key, data, DBM_REPLACE);
2103c2aa98e2SPeter Wemm }
210406f25ae9SGregory Neil Shapiro if (status != 0)
210506f25ae9SGregory Neil Shapiro syserr("readaliases: dbm put (%s): %d", lhs, status);
2106c2aa98e2SPeter Wemm }
2107c2aa98e2SPeter Wemm
2108c2aa98e2SPeter Wemm
2109c2aa98e2SPeter Wemm /*
2110c2aa98e2SPeter Wemm ** NDBM_MAP_CLOSE -- close the database
2111c2aa98e2SPeter Wemm */
2112c2aa98e2SPeter Wemm
2113c2aa98e2SPeter Wemm void
ndbm_map_close(map)2114c2aa98e2SPeter Wemm ndbm_map_close(map)
2115c2aa98e2SPeter Wemm register MAP *map;
2116c2aa98e2SPeter Wemm {
2117c2aa98e2SPeter Wemm if (tTd(38, 9))
211840266059SGregory Neil Shapiro sm_dprintf("ndbm_map_close(%s, %s, %lx)\n",
2119c2aa98e2SPeter Wemm map->map_mname, map->map_file, map->map_mflags);
2120c2aa98e2SPeter Wemm
2121c2aa98e2SPeter Wemm if (bitset(MF_WRITABLE, map->map_mflags))
2122c2aa98e2SPeter Wemm {
2123c2aa98e2SPeter Wemm # ifdef NDBM_YP_COMPAT
2124c2aa98e2SPeter Wemm bool inclnull;
2125065a643dSPeter Wemm char buf[MAXHOSTNAMELEN];
2126c2aa98e2SPeter Wemm
2127c2aa98e2SPeter Wemm inclnull = bitset(MF_INCLNULL, map->map_mflags);
2128c2aa98e2SPeter Wemm map->map_mflags &= ~MF_INCLNULL;
2129c2aa98e2SPeter Wemm
2130c2aa98e2SPeter Wemm if (strstr(map->map_file, "/yp/") != NULL)
2131c2aa98e2SPeter Wemm {
2132c2aa98e2SPeter Wemm long save_mflags = map->map_mflags;
2133c2aa98e2SPeter Wemm
2134c2aa98e2SPeter Wemm map->map_mflags |= MF_NOFOLDCASE;
2135c2aa98e2SPeter Wemm
2136d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%010ld", curtime());
2137c2aa98e2SPeter Wemm ndbm_map_store(map, "YP_LAST_MODIFIED", buf);
2138c2aa98e2SPeter Wemm
2139d0cef73dSGregory Neil Shapiro (void) gethostname(buf, sizeof(buf));
2140c2aa98e2SPeter Wemm ndbm_map_store(map, "YP_MASTER_NAME", buf);
2141c2aa98e2SPeter Wemm
2142c2aa98e2SPeter Wemm map->map_mflags = save_mflags;
2143c2aa98e2SPeter Wemm }
2144c2aa98e2SPeter Wemm
2145c2aa98e2SPeter Wemm if (inclnull)
2146c2aa98e2SPeter Wemm map->map_mflags |= MF_INCLNULL;
214706f25ae9SGregory Neil Shapiro # endif /* NDBM_YP_COMPAT */
2148c2aa98e2SPeter Wemm
2149c2aa98e2SPeter Wemm /* write out the distinguished alias */
2150c2aa98e2SPeter Wemm ndbm_map_store(map, "@", "@");
2151c2aa98e2SPeter Wemm }
2152c2aa98e2SPeter Wemm dbm_close((DBM *) map->map_db1);
2153c2aa98e2SPeter Wemm
2154c2aa98e2SPeter Wemm /* release lock (if needed) */
2155c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN
2156c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
2157c2aa98e2SPeter Wemm (void) close(map->map_lockfd);
21585b0945b5SGregory Neil Shapiro # endif
2159c2aa98e2SPeter Wemm }
2160c2aa98e2SPeter Wemm
216106f25ae9SGregory Neil Shapiro #endif /* NDBM */
216240266059SGregory Neil Shapiro /*
2163c2aa98e2SPeter Wemm ** NEWDB (Hash and BTree) Modules
2164c2aa98e2SPeter Wemm */
2165c2aa98e2SPeter Wemm
216640266059SGregory Neil Shapiro #if NEWDB
2167c2aa98e2SPeter Wemm
2168c2aa98e2SPeter Wemm /*
2169c2aa98e2SPeter Wemm ** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives.
2170c2aa98e2SPeter Wemm **
2171c2aa98e2SPeter Wemm ** These do rather bizarre locking. If you can lock on open,
2172c2aa98e2SPeter Wemm ** do that to avoid the condition of opening a database that
2173c2aa98e2SPeter Wemm ** is being rebuilt. If you don't, we'll try to fake it, but
2174c2aa98e2SPeter Wemm ** there will be a race condition. If opening for read-only,
2175c2aa98e2SPeter Wemm ** we immediately release the lock to avoid freezing things up.
2176c2aa98e2SPeter Wemm ** We really ought to hold the lock, but guarantee that we won't
2177c2aa98e2SPeter Wemm ** be pokey about it. That's hard to do.
2178c2aa98e2SPeter Wemm */
2179c2aa98e2SPeter Wemm
2180c2aa98e2SPeter Wemm /* these should be K line arguments */
2181c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2182c2aa98e2SPeter Wemm # define db_cachesize cachesize
2183c2aa98e2SPeter Wemm # define h_nelem nelem
2184c2aa98e2SPeter Wemm # ifndef DB_CACHE_SIZE
2185c2aa98e2SPeter Wemm # define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
21865b0945b5SGregory Neil Shapiro # endif
2187c2aa98e2SPeter Wemm # ifndef DB_HASH_NELEM
2188c2aa98e2SPeter Wemm # define DB_HASH_NELEM 4096 /* (starting) size of hash table */
21895b0945b5SGregory Neil Shapiro # endif
219006f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2191c2aa98e2SPeter Wemm
2192c2aa98e2SPeter Wemm bool
bt_map_open(map,mode)2193c2aa98e2SPeter Wemm bt_map_open(map, mode)
2194c2aa98e2SPeter Wemm MAP *map;
2195c2aa98e2SPeter Wemm int mode;
2196c2aa98e2SPeter Wemm {
2197c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2198c2aa98e2SPeter Wemm BTREEINFO btinfo;
21995b0945b5SGregory Neil Shapiro # endif
220006f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR == 2
2201c2aa98e2SPeter Wemm DB_INFO btinfo;
22025b0945b5SGregory Neil Shapiro # endif
220306f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR > 2
220406f25ae9SGregory Neil Shapiro void *btinfo = NULL;
22055b0945b5SGregory Neil Shapiro # endif
2206c2aa98e2SPeter Wemm
2207c2aa98e2SPeter Wemm if (tTd(38, 2))
220840266059SGregory Neil Shapiro sm_dprintf("bt_map_open(%s, %s, %d)\n",
2209c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
2210c2aa98e2SPeter Wemm
221106f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR < 3
2212d0cef73dSGregory Neil Shapiro memset(&btinfo, '\0', sizeof(btinfo));
2213c2aa98e2SPeter Wemm # ifdef DB_CACHE_SIZE
2214c2aa98e2SPeter Wemm btinfo.db_cachesize = DB_CACHE_SIZE;
22155b0945b5SGregory Neil Shapiro # endif
221606f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 3 */
221706f25ae9SGregory Neil Shapiro
2218c2aa98e2SPeter Wemm return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
2219c2aa98e2SPeter Wemm }
2220c2aa98e2SPeter Wemm
2221c2aa98e2SPeter Wemm bool
hash_map_open(map,mode)2222c2aa98e2SPeter Wemm hash_map_open(map, mode)
2223c2aa98e2SPeter Wemm MAP *map;
2224c2aa98e2SPeter Wemm int mode;
2225c2aa98e2SPeter Wemm {
2226c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2227c2aa98e2SPeter Wemm HASHINFO hinfo;
22285b0945b5SGregory Neil Shapiro # endif
222906f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR == 2
2230c2aa98e2SPeter Wemm DB_INFO hinfo;
22315b0945b5SGregory Neil Shapiro # endif
223206f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR > 2
223306f25ae9SGregory Neil Shapiro void *hinfo = NULL;
22345b0945b5SGregory Neil Shapiro # endif
2235c2aa98e2SPeter Wemm
2236c2aa98e2SPeter Wemm if (tTd(38, 2))
223740266059SGregory Neil Shapiro sm_dprintf("hash_map_open(%s, %s, %d)\n",
2238c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
2239c2aa98e2SPeter Wemm
224006f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR < 3
2241d0cef73dSGregory Neil Shapiro memset(&hinfo, '\0', sizeof(hinfo));
2242c2aa98e2SPeter Wemm # ifdef DB_HASH_NELEM
2243c2aa98e2SPeter Wemm hinfo.h_nelem = DB_HASH_NELEM;
22445b0945b5SGregory Neil Shapiro # endif
2245c2aa98e2SPeter Wemm # ifdef DB_CACHE_SIZE
2246c2aa98e2SPeter Wemm hinfo.db_cachesize = DB_CACHE_SIZE;
22475b0945b5SGregory Neil Shapiro # endif
224806f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 3 */
224906f25ae9SGregory Neil Shapiro
2250c2aa98e2SPeter Wemm return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
2251c2aa98e2SPeter Wemm }
2252c2aa98e2SPeter Wemm
225306f25ae9SGregory Neil Shapiro static bool
2254c2aa98e2SPeter Wemm db_map_open(map, mode, mapclassname, dbtype, openinfo)
2255c2aa98e2SPeter Wemm MAP *map;
2256c2aa98e2SPeter Wemm int mode;
2257c2aa98e2SPeter Wemm char *mapclassname;
2258c2aa98e2SPeter Wemm DBTYPE dbtype;
2259c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2260c2aa98e2SPeter Wemm const void *openinfo;
22615b0945b5SGregory Neil Shapiro # endif
226206f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR == 2
2263c2aa98e2SPeter Wemm DB_INFO *openinfo;
22645b0945b5SGregory Neil Shapiro # endif
226506f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR > 2
226606f25ae9SGregory Neil Shapiro void **openinfo;
22675b0945b5SGregory Neil Shapiro # endif
2268c2aa98e2SPeter Wemm {
2269c2aa98e2SPeter Wemm DB *db = NULL;
2270c2aa98e2SPeter Wemm int i;
2271c2aa98e2SPeter Wemm int omode;
2272c2aa98e2SPeter Wemm int smode = S_IREAD;
2273c2aa98e2SPeter Wemm int fd;
227406f25ae9SGregory Neil Shapiro long sff;
227506f25ae9SGregory Neil Shapiro int save_errno;
2276c2aa98e2SPeter Wemm struct stat st;
227794c01205SGregory Neil Shapiro char buf[MAXPATHLEN];
2278c2aa98e2SPeter Wemm
2279c2aa98e2SPeter Wemm /* do initial file and directory checks */
2280*d39bd2c1SGregory Neil Shapiro if (!smdb_add_extension(buf, sizeof(buf), map->map_file, "db"))
228194c01205SGregory Neil Shapiro {
228294c01205SGregory Neil Shapiro errno = 0;
228394c01205SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
2284*d39bd2c1SGregory Neil Shapiro syserr("db map \"%s\": map file %s name too long",
228594c01205SGregory Neil Shapiro map->map_mname, map->map_file);
228694c01205SGregory Neil Shapiro return false;
228794c01205SGregory Neil Shapiro }
2288c2aa98e2SPeter Wemm
2289c2aa98e2SPeter Wemm mode &= O_ACCMODE;
2290c2aa98e2SPeter Wemm omode = mode;
2291c2aa98e2SPeter Wemm
2292c2aa98e2SPeter Wemm sff = SFF_ROOTOK|SFF_REGONLY;
2293c2aa98e2SPeter Wemm if (mode == O_RDWR)
2294c2aa98e2SPeter Wemm {
2295c2aa98e2SPeter Wemm sff |= SFF_CREAT;
229606f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
2297c2aa98e2SPeter Wemm sff |= SFF_NOSLINK;
229806f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
2299c2aa98e2SPeter Wemm sff |= SFF_NOHLINK;
2300c2aa98e2SPeter Wemm smode = S_IWRITE;
2301c2aa98e2SPeter Wemm }
2302c2aa98e2SPeter Wemm else
2303c2aa98e2SPeter Wemm {
230406f25ae9SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
2305c2aa98e2SPeter Wemm sff |= SFF_NOWLINK;
2306c2aa98e2SPeter Wemm }
230706f25ae9SGregory Neil Shapiro if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
2308c2aa98e2SPeter Wemm sff |= SFF_SAFEDIRPATH;
2309c2aa98e2SPeter Wemm i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st);
231006f25ae9SGregory Neil Shapiro
2311c2aa98e2SPeter Wemm if (i != 0)
2312c2aa98e2SPeter Wemm {
2313c2aa98e2SPeter Wemm char *prob = "unsafe";
2314c2aa98e2SPeter Wemm
2315c2aa98e2SPeter Wemm /* cannot open this map */
2316c2aa98e2SPeter Wemm if (i == ENOENT)
2317c2aa98e2SPeter Wemm prob = "missing";
2318c2aa98e2SPeter Wemm if (tTd(38, 2))
2319*d39bd2c1SGregory Neil Shapiro sm_dprintf("\t%s map file %s: %s\n", prob, buf, sm_errstring(i));
2320c2aa98e2SPeter Wemm errno = i;
2321c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
2322c2aa98e2SPeter Wemm syserr("%s map \"%s\": %s map file %s",
2323c2aa98e2SPeter Wemm mapclassname, map->map_mname, prob, buf);
232440266059SGregory Neil Shapiro return false;
2325c2aa98e2SPeter Wemm }
2326c2aa98e2SPeter Wemm if (st.st_mode == ST_MODE_NOFILE)
2327c2aa98e2SPeter Wemm omode |= O_CREAT|O_EXCL;
2328c2aa98e2SPeter Wemm
2329c2aa98e2SPeter Wemm map->map_lockfd = -1;
2330c2aa98e2SPeter Wemm
2331c2aa98e2SPeter Wemm # if LOCK_ON_OPEN
2332c2aa98e2SPeter Wemm if (mode == O_RDWR)
2333c2aa98e2SPeter Wemm omode |= O_TRUNC|O_EXLOCK;
2334c2aa98e2SPeter Wemm else
2335c2aa98e2SPeter Wemm omode |= O_SHLOCK;
233606f25ae9SGregory Neil Shapiro # else /* LOCK_ON_OPEN */
2337c2aa98e2SPeter Wemm /*
2338c2aa98e2SPeter Wemm ** Pre-lock the file to avoid race conditions. In particular,
2339c2aa98e2SPeter Wemm ** since dbopen returns NULL if the file is zero length, we
2340c2aa98e2SPeter Wemm ** must have a locked instance around the dbopen.
2341c2aa98e2SPeter Wemm */
2342c2aa98e2SPeter Wemm
2343c2aa98e2SPeter Wemm fd = open(buf, omode, DBMMODE);
2344c2aa98e2SPeter Wemm if (fd < 0)
2345c2aa98e2SPeter Wemm {
2346c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
2347c2aa98e2SPeter Wemm syserr("db_map_open: cannot pre-open database %s", buf);
234840266059SGregory Neil Shapiro return false;
2349c2aa98e2SPeter Wemm }
2350c2aa98e2SPeter Wemm
2351c2aa98e2SPeter Wemm /* make sure no baddies slipped in just before the open... */
2352c2aa98e2SPeter Wemm if (filechanged(buf, fd, &st))
2353c2aa98e2SPeter Wemm {
235406f25ae9SGregory Neil Shapiro save_errno = errno;
2355c2aa98e2SPeter Wemm (void) close(fd);
2356c2aa98e2SPeter Wemm errno = save_errno;
2357c2aa98e2SPeter Wemm syserr("db_map_open(%s): file changed after pre-open", buf);
235840266059SGregory Neil Shapiro return false;
2359c2aa98e2SPeter Wemm }
2360c2aa98e2SPeter Wemm
2361c2aa98e2SPeter Wemm /* if new file, get the "before" bits for later filechanged check */
2362c2aa98e2SPeter Wemm if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0)
2363c2aa98e2SPeter Wemm {
236406f25ae9SGregory Neil Shapiro save_errno = errno;
2365c2aa98e2SPeter Wemm (void) close(fd);
2366c2aa98e2SPeter Wemm errno = save_errno;
2367c2aa98e2SPeter Wemm syserr("db_map_open(%s): cannot fstat pre-opened file",
2368c2aa98e2SPeter Wemm buf);
236940266059SGregory Neil Shapiro return false;
2370c2aa98e2SPeter Wemm }
2371c2aa98e2SPeter Wemm
2372c2aa98e2SPeter Wemm /* actually lock the pre-opened file */
2373c2aa98e2SPeter Wemm if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
2374c2aa98e2SPeter Wemm syserr("db_map_open: cannot lock %s", buf);
2375c2aa98e2SPeter Wemm
2376c2aa98e2SPeter Wemm /* set up mode bits for dbopen */
2377c2aa98e2SPeter Wemm if (mode == O_RDWR)
2378c2aa98e2SPeter Wemm omode |= O_TRUNC;
2379c2aa98e2SPeter Wemm omode &= ~(O_EXCL|O_CREAT);
238006f25ae9SGregory Neil Shapiro # endif /* LOCK_ON_OPEN */
2381c2aa98e2SPeter Wemm
2382c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2383c2aa98e2SPeter Wemm db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
238406f25ae9SGregory Neil Shapiro # else /* DB_VERSION_MAJOR < 2 */
2385c2aa98e2SPeter Wemm {
2386c2aa98e2SPeter Wemm int flags = 0;
238706f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR > 2
238806f25ae9SGregory Neil Shapiro int ret;
23895b0945b5SGregory Neil Shapiro # endif
2390c2aa98e2SPeter Wemm
2391c2aa98e2SPeter Wemm if (mode == O_RDONLY)
2392c2aa98e2SPeter Wemm flags |= DB_RDONLY;
2393c2aa98e2SPeter Wemm if (bitset(O_CREAT, omode))
2394c2aa98e2SPeter Wemm flags |= DB_CREATE;
2395c2aa98e2SPeter Wemm if (bitset(O_TRUNC, omode))
2396c2aa98e2SPeter Wemm flags |= DB_TRUNCATE;
239713bd1963SGregory Neil Shapiro SM_DB_FLAG_ADD(flags);
239806f25ae9SGregory Neil Shapiro
239906f25ae9SGregory Neil Shapiro # if DB_VERSION_MAJOR > 2
240006f25ae9SGregory Neil Shapiro ret = db_create(&db, NULL, 0);
240106f25ae9SGregory Neil Shapiro # ifdef DB_CACHE_SIZE
240206f25ae9SGregory Neil Shapiro if (ret == 0 && db != NULL)
240306f25ae9SGregory Neil Shapiro {
240406f25ae9SGregory Neil Shapiro ret = db->set_cachesize(db, 0, DB_CACHE_SIZE, 0);
240506f25ae9SGregory Neil Shapiro if (ret != 0)
240606f25ae9SGregory Neil Shapiro {
240706f25ae9SGregory Neil Shapiro (void) db->close(db, 0);
240806f25ae9SGregory Neil Shapiro db = NULL;
240906f25ae9SGregory Neil Shapiro }
241006f25ae9SGregory Neil Shapiro }
241106f25ae9SGregory Neil Shapiro # endif /* DB_CACHE_SIZE */
241206f25ae9SGregory Neil Shapiro # ifdef DB_HASH_NELEM
241306f25ae9SGregory Neil Shapiro if (dbtype == DB_HASH && ret == 0 && db != NULL)
241406f25ae9SGregory Neil Shapiro {
241506f25ae9SGregory Neil Shapiro ret = db->set_h_nelem(db, DB_HASH_NELEM);
241606f25ae9SGregory Neil Shapiro if (ret != 0)
241706f25ae9SGregory Neil Shapiro {
241806f25ae9SGregory Neil Shapiro (void) db->close(db, 0);
241906f25ae9SGregory Neil Shapiro db = NULL;
242006f25ae9SGregory Neil Shapiro }
242106f25ae9SGregory Neil Shapiro }
242206f25ae9SGregory Neil Shapiro # endif /* DB_HASH_NELEM */
242306f25ae9SGregory Neil Shapiro if (ret == 0 && db != NULL)
242406f25ae9SGregory Neil Shapiro {
242513bd1963SGregory Neil Shapiro ret = db->open(db,
242613bd1963SGregory Neil Shapiro DBTXN /* transaction for DB 4.1 */
242713bd1963SGregory Neil Shapiro buf, NULL, dbtype, flags, DBMMODE);
242806f25ae9SGregory Neil Shapiro if (ret != 0)
242906f25ae9SGregory Neil Shapiro {
2430602a2b1bSGregory Neil Shapiro # ifdef DB_OLD_VERSION
2431602a2b1bSGregory Neil Shapiro if (ret == DB_OLD_VERSION)
2432602a2b1bSGregory Neil Shapiro ret = EINVAL;
2433602a2b1bSGregory Neil Shapiro # endif /* DB_OLD_VERSION */
243406f25ae9SGregory Neil Shapiro (void) db->close(db, 0);
243506f25ae9SGregory Neil Shapiro db = NULL;
243606f25ae9SGregory Neil Shapiro }
243706f25ae9SGregory Neil Shapiro }
243806f25ae9SGregory Neil Shapiro errno = ret;
243906f25ae9SGregory Neil Shapiro # else /* DB_VERSION_MAJOR > 2 */
2440c2aa98e2SPeter Wemm errno = db_open(buf, dbtype, flags, DBMMODE,
2441c2aa98e2SPeter Wemm NULL, openinfo, &db);
244206f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR > 2 */
2443c2aa98e2SPeter Wemm }
244406f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
244506f25ae9SGregory Neil Shapiro save_errno = errno;
2446c2aa98e2SPeter Wemm
2447c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN
2448c2aa98e2SPeter Wemm if (mode == O_RDWR)
2449c2aa98e2SPeter Wemm map->map_lockfd = fd;
2450c2aa98e2SPeter Wemm else
2451c2aa98e2SPeter Wemm (void) close(fd);
245206f25ae9SGregory Neil Shapiro # endif /* !LOCK_ON_OPEN */
2453c2aa98e2SPeter Wemm
2454c2aa98e2SPeter Wemm if (db == NULL)
2455c2aa98e2SPeter Wemm {
2456c2aa98e2SPeter Wemm if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
245740266059SGregory Neil Shapiro aliaswait(map, ".db", false))
245840266059SGregory Neil Shapiro return true;
2459c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN
2460c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
2461c2aa98e2SPeter Wemm (void) close(map->map_lockfd);
24625b0945b5SGregory Neil Shapiro # endif
246306f25ae9SGregory Neil Shapiro errno = save_errno;
2464c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
2465c2aa98e2SPeter Wemm syserr("Cannot open %s database %s",
2466c2aa98e2SPeter Wemm mapclassname, buf);
246740266059SGregory Neil Shapiro return false;
2468c2aa98e2SPeter Wemm }
2469c2aa98e2SPeter Wemm
2470c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2471c2aa98e2SPeter Wemm fd = db->fd(db);
24725b0945b5SGregory Neil Shapiro # else
2473c2aa98e2SPeter Wemm fd = -1;
2474c2aa98e2SPeter Wemm errno = db->fd(db, &fd);
247506f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2476c2aa98e2SPeter Wemm if (filechanged(buf, fd, &st))
2477c2aa98e2SPeter Wemm {
247806f25ae9SGregory Neil Shapiro save_errno = errno;
2479c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
248006f25ae9SGregory Neil Shapiro (void) db->close(db);
24815b0945b5SGregory Neil Shapiro # else
2482c2aa98e2SPeter Wemm errno = db->close(db, 0);
248306f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2484c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN
2485c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
248606f25ae9SGregory Neil Shapiro (void) close(map->map_lockfd);
24875b0945b5SGregory Neil Shapiro # endif
2488c2aa98e2SPeter Wemm errno = save_errno;
2489c2aa98e2SPeter Wemm syserr("db_map_open(%s): file changed after open", buf);
249040266059SGregory Neil Shapiro return false;
2491c2aa98e2SPeter Wemm }
2492c2aa98e2SPeter Wemm
2493c2aa98e2SPeter Wemm if (mode == O_RDWR)
2494c2aa98e2SPeter Wemm map->map_mflags |= MF_LOCKED;
2495c2aa98e2SPeter Wemm # if LOCK_ON_OPEN
2496c2aa98e2SPeter Wemm if (fd >= 0 && mode == O_RDONLY)
2497c2aa98e2SPeter Wemm (void) lockfile(fd, buf, NULL, LOCK_UN);
2498*d39bd2c1SGregory Neil Shapiro # endif
2499c2aa98e2SPeter Wemm
2500c2aa98e2SPeter Wemm /* try to make sure that at least the database header is on disk */
2501c2aa98e2SPeter Wemm if (mode == O_RDWR)
2502c2aa98e2SPeter Wemm {
2503c2aa98e2SPeter Wemm (void) db->sync(db, 0);
2504*d39bd2c1SGregory Neil Shapiro mapchown(map->map_file, fd, -1, buf);
2505c2aa98e2SPeter Wemm }
2506c2aa98e2SPeter Wemm
250706f25ae9SGregory Neil Shapiro map->map_db2 = (ARBPTR_T) db;
250806f25ae9SGregory Neil Shapiro
250906f25ae9SGregory Neil Shapiro /*
251006f25ae9SGregory Neil Shapiro ** Need to set map_mtime before the call to aliaswait()
251106f25ae9SGregory Neil Shapiro ** as aliaswait() will call map_lookup() which requires
251206f25ae9SGregory Neil Shapiro ** map_mtime to be set
251306f25ae9SGregory Neil Shapiro */
251406f25ae9SGregory Neil Shapiro
2515c2aa98e2SPeter Wemm if (fd >= 0 && fstat(fd, &st) >= 0)
2516c2aa98e2SPeter Wemm map->map_mtime = st.st_mtime;
2517c2aa98e2SPeter Wemm
2518*d39bd2c1SGregory Neil Shapiro # if _FFR_TESTS
2519*d39bd2c1SGregory Neil Shapiro if (tTd(68, 101) && fd >= 0 && mode == O_RDONLY)
2520*d39bd2c1SGregory Neil Shapiro {
2521*d39bd2c1SGregory Neil Shapiro int sl;
2522*d39bd2c1SGregory Neil Shapiro
2523*d39bd2c1SGregory Neil Shapiro sl = tTdlevel(68) - 100;
2524*d39bd2c1SGregory Neil Shapiro /* XXX test checks for map type!!! */
2525*d39bd2c1SGregory Neil Shapiro sm_dprintf("hash_map_open: sleep=%d\n", sl);
2526*d39bd2c1SGregory Neil Shapiro sleep(sl);
2527*d39bd2c1SGregory Neil Shapiro }
2528*d39bd2c1SGregory Neil Shapiro # endif
2529*d39bd2c1SGregory Neil Shapiro
2530c2aa98e2SPeter Wemm if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
253140266059SGregory Neil Shapiro !aliaswait(map, ".db", true))
253240266059SGregory Neil Shapiro return false;
253340266059SGregory Neil Shapiro return true;
2534c2aa98e2SPeter Wemm }
2535c2aa98e2SPeter Wemm
2536c2aa98e2SPeter Wemm
2537c2aa98e2SPeter Wemm /*
2538c2aa98e2SPeter Wemm ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map
2539c2aa98e2SPeter Wemm */
2540c2aa98e2SPeter Wemm
2541c2aa98e2SPeter Wemm char *
db_map_lookup(map,name,av,statp)2542c2aa98e2SPeter Wemm db_map_lookup(map, name, av, statp)
2543c2aa98e2SPeter Wemm MAP *map;
2544c2aa98e2SPeter Wemm char *name;
2545c2aa98e2SPeter Wemm char **av;
2546c2aa98e2SPeter Wemm int *statp;
2547c2aa98e2SPeter Wemm {
2548c2aa98e2SPeter Wemm DBT key, val;
2549c2aa98e2SPeter Wemm register DB *db = (DB *) map->map_db2;
2550c2aa98e2SPeter Wemm int st;
255106f25ae9SGregory Neil Shapiro int save_errno;
2552c2aa98e2SPeter Wemm int fd;
25532fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
255494c01205SGregory Neil Shapiro char buf[MAXPATHLEN];
2555c2aa98e2SPeter Wemm
2556d0cef73dSGregory Neil Shapiro memset(&key, '\0', sizeof(key));
2557d0cef73dSGregory Neil Shapiro memset(&val, '\0', sizeof(val));
2558c2aa98e2SPeter Wemm
2559c2aa98e2SPeter Wemm if (tTd(38, 20))
256040266059SGregory Neil Shapiro sm_dprintf("db_map_lookup(%s, %s)\n",
2561c2aa98e2SPeter Wemm map->map_mname, name);
2562*d39bd2c1SGregory Neil Shapiro if (!smdb_add_extension(buf, sizeof(buf), map->map_file, "db"))
256394c01205SGregory Neil Shapiro {
256494c01205SGregory Neil Shapiro errno = 0;
256594c01205SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
2566*d39bd2c1SGregory Neil Shapiro syserr("db map \"%s\": map file %s name too long",
256794c01205SGregory Neil Shapiro map->map_mname, map->map_file);
256894c01205SGregory Neil Shapiro return NULL;
256994c01205SGregory Neil Shapiro }
2570c2aa98e2SPeter Wemm
2571c2aa98e2SPeter Wemm key.size = strlen(name);
2572d0cef73dSGregory Neil Shapiro if (key.size > sizeof(keybuf) - 1)
2573d0cef73dSGregory Neil Shapiro key.size = sizeof(keybuf) - 1;
2574c2aa98e2SPeter Wemm key.data = keybuf;
257506f25ae9SGregory Neil Shapiro memmove(keybuf, name, key.size);
2576c2aa98e2SPeter Wemm keybuf[key.size] = '\0';
2577c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
25782fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
2579c2aa98e2SPeter Wemm lockdb:
2580c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2581c2aa98e2SPeter Wemm fd = db->fd(db);
25825b0945b5SGregory Neil Shapiro # else
2583c2aa98e2SPeter Wemm fd = -1;
2584c2aa98e2SPeter Wemm errno = db->fd(db, &fd);
258506f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2586c2aa98e2SPeter Wemm if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
2587*d39bd2c1SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_SH);
2588*d39bd2c1SGregory Neil Shapiro if (map_has_chged(map, buf, fd))
2589c2aa98e2SPeter Wemm {
2590c2aa98e2SPeter Wemm /* Reopen the database to sync the cache */
2591c2aa98e2SPeter Wemm int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
2592c2aa98e2SPeter Wemm : O_RDONLY;
2593c2aa98e2SPeter Wemm
259406f25ae9SGregory Neil Shapiro if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
2595*d39bd2c1SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_UN);
25968774250cSGregory Neil Shapiro map->map_mflags |= MF_CLOSING;
2597c2aa98e2SPeter Wemm map->map_class->map_close(map);
25988774250cSGregory Neil Shapiro map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
2599c2aa98e2SPeter Wemm if (map->map_class->map_open(map, omode))
2600c2aa98e2SPeter Wemm {
2601c2aa98e2SPeter Wemm map->map_mflags |= MF_OPEN;
260240266059SGregory Neil Shapiro map->map_pid = CurrentPid;
26039bd497b8SGregory Neil Shapiro if ((omode & O_ACCMODE) == O_RDWR)
2604c2aa98e2SPeter Wemm map->map_mflags |= MF_WRITABLE;
2605c2aa98e2SPeter Wemm db = (DB *) map->map_db2;
2606c2aa98e2SPeter Wemm goto lockdb;
2607c2aa98e2SPeter Wemm }
2608c2aa98e2SPeter Wemm else
2609c2aa98e2SPeter Wemm {
2610c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
2611c2aa98e2SPeter Wemm {
2612c2aa98e2SPeter Wemm extern MAPCLASS BogusMapClass;
2613c2aa98e2SPeter Wemm
2614c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
261540266059SGregory Neil Shapiro map->map_orgclass = map->map_class;
2616c2aa98e2SPeter Wemm map->map_class = &BogusMapClass;
2617c2aa98e2SPeter Wemm map->map_mflags |= MF_OPEN;
261840266059SGregory Neil Shapiro map->map_pid = CurrentPid;
2619c2aa98e2SPeter Wemm syserr("Cannot reopen DB database %s",
2620c2aa98e2SPeter Wemm map->map_file);
2621c2aa98e2SPeter Wemm }
2622c2aa98e2SPeter Wemm return NULL;
2623c2aa98e2SPeter Wemm }
2624c2aa98e2SPeter Wemm }
2625c2aa98e2SPeter Wemm
2626c2aa98e2SPeter Wemm st = 1;
2627c2aa98e2SPeter Wemm if (bitset(MF_TRY0NULL, map->map_mflags))
2628c2aa98e2SPeter Wemm {
2629c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2630c2aa98e2SPeter Wemm st = db->get(db, &key, &val, 0);
263106f25ae9SGregory Neil Shapiro # else /* DB_VERSION_MAJOR < 2 */
2632c2aa98e2SPeter Wemm errno = db->get(db, NULL, &key, &val, 0);
2633c2aa98e2SPeter Wemm switch (errno)
2634c2aa98e2SPeter Wemm {
2635c2aa98e2SPeter Wemm case DB_NOTFOUND:
2636c2aa98e2SPeter Wemm case DB_KEYEMPTY:
2637c2aa98e2SPeter Wemm st = 1;
2638c2aa98e2SPeter Wemm break;
2639c2aa98e2SPeter Wemm
2640c2aa98e2SPeter Wemm case 0:
2641c2aa98e2SPeter Wemm st = 0;
2642c2aa98e2SPeter Wemm break;
2643c2aa98e2SPeter Wemm
2644c2aa98e2SPeter Wemm default:
2645c2aa98e2SPeter Wemm st = -1;
2646c2aa98e2SPeter Wemm break;
2647c2aa98e2SPeter Wemm }
264806f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2649c2aa98e2SPeter Wemm if (st == 0)
2650c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY1NULL;
2651c2aa98e2SPeter Wemm }
2652c2aa98e2SPeter Wemm if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags))
2653c2aa98e2SPeter Wemm {
2654c2aa98e2SPeter Wemm key.size++;
2655c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2656c2aa98e2SPeter Wemm st = db->get(db, &key, &val, 0);
265706f25ae9SGregory Neil Shapiro # else /* DB_VERSION_MAJOR < 2 */
2658c2aa98e2SPeter Wemm errno = db->get(db, NULL, &key, &val, 0);
2659c2aa98e2SPeter Wemm switch (errno)
2660c2aa98e2SPeter Wemm {
2661c2aa98e2SPeter Wemm case DB_NOTFOUND:
2662c2aa98e2SPeter Wemm case DB_KEYEMPTY:
2663c2aa98e2SPeter Wemm st = 1;
2664c2aa98e2SPeter Wemm break;
2665c2aa98e2SPeter Wemm
2666c2aa98e2SPeter Wemm case 0:
2667c2aa98e2SPeter Wemm st = 0;
2668c2aa98e2SPeter Wemm break;
2669c2aa98e2SPeter Wemm
2670c2aa98e2SPeter Wemm default:
2671c2aa98e2SPeter Wemm st = -1;
2672c2aa98e2SPeter Wemm break;
2673c2aa98e2SPeter Wemm }
267406f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2675c2aa98e2SPeter Wemm if (st == 0)
2676c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY0NULL;
2677c2aa98e2SPeter Wemm }
267806f25ae9SGregory Neil Shapiro save_errno = errno;
2679c2aa98e2SPeter Wemm if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
2680*d39bd2c1SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_UN);
2681c2aa98e2SPeter Wemm if (st != 0)
2682c2aa98e2SPeter Wemm {
268306f25ae9SGregory Neil Shapiro errno = save_errno;
2684c2aa98e2SPeter Wemm if (st < 0)
2685c2aa98e2SPeter Wemm syserr("db_map_lookup: get (%s)", name);
2686c2aa98e2SPeter Wemm return NULL;
2687c2aa98e2SPeter Wemm }
2688c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
2689c2aa98e2SPeter Wemm return map_rewrite(map, name, strlen(name), NULL);
2690c2aa98e2SPeter Wemm else
2691c2aa98e2SPeter Wemm return map_rewrite(map, val.data, val.size, av);
2692c2aa98e2SPeter Wemm }
2693c2aa98e2SPeter Wemm
2694c2aa98e2SPeter Wemm
2695c2aa98e2SPeter Wemm /*
2696c2aa98e2SPeter Wemm ** DB_MAP_STORE -- store a datum in the NEWDB database
2697c2aa98e2SPeter Wemm */
2698c2aa98e2SPeter Wemm
2699c2aa98e2SPeter Wemm void
db_map_store(map,lhs,rhs)2700c2aa98e2SPeter Wemm db_map_store(map, lhs, rhs)
2701c2aa98e2SPeter Wemm register MAP *map;
2702c2aa98e2SPeter Wemm char *lhs;
2703c2aa98e2SPeter Wemm char *rhs;
2704c2aa98e2SPeter Wemm {
270506f25ae9SGregory Neil Shapiro int status;
2706c2aa98e2SPeter Wemm DBT key;
2707c2aa98e2SPeter Wemm DBT data;
2708c2aa98e2SPeter Wemm register DB *db = map->map_db2;
27092fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
2710c2aa98e2SPeter Wemm
2711d0cef73dSGregory Neil Shapiro memset(&key, '\0', sizeof(key));
2712d0cef73dSGregory Neil Shapiro memset(&data, '\0', sizeof(data));
2713c2aa98e2SPeter Wemm
2714c2aa98e2SPeter Wemm if (tTd(38, 12))
271540266059SGregory Neil Shapiro sm_dprintf("db_map_store(%s, %s, %s)\n",
2716c2aa98e2SPeter Wemm map->map_mname, lhs, rhs);
2717c2aa98e2SPeter Wemm
2718c2aa98e2SPeter Wemm key.size = strlen(lhs);
2719c2aa98e2SPeter Wemm key.data = lhs;
2720c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
2721c2aa98e2SPeter Wemm {
2722d0cef73dSGregory Neil Shapiro if (key.size > sizeof(keybuf) - 1)
2723d0cef73dSGregory Neil Shapiro key.size = sizeof(keybuf) - 1;
272406f25ae9SGregory Neil Shapiro memmove(keybuf, key.data, key.size);
2725c2aa98e2SPeter Wemm keybuf[key.size] = '\0';
27262fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
2727c2aa98e2SPeter Wemm key.data = keybuf;
2728c2aa98e2SPeter Wemm }
2729c2aa98e2SPeter Wemm
2730c2aa98e2SPeter Wemm data.size = strlen(rhs);
2731c2aa98e2SPeter Wemm data.data = rhs;
2732c2aa98e2SPeter Wemm
2733c2aa98e2SPeter Wemm if (bitset(MF_INCLNULL, map->map_mflags))
2734c2aa98e2SPeter Wemm {
2735c2aa98e2SPeter Wemm key.size++;
2736c2aa98e2SPeter Wemm data.size++;
2737c2aa98e2SPeter Wemm }
2738c2aa98e2SPeter Wemm
2739c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
274006f25ae9SGregory Neil Shapiro status = db->put(db, &key, &data, R_NOOVERWRITE);
274106f25ae9SGregory Neil Shapiro # else /* DB_VERSION_MAJOR < 2 */
2742c2aa98e2SPeter Wemm errno = db->put(db, NULL, &key, &data, DB_NOOVERWRITE);
2743c2aa98e2SPeter Wemm switch (errno)
2744c2aa98e2SPeter Wemm {
2745c2aa98e2SPeter Wemm case DB_KEYEXIST:
274606f25ae9SGregory Neil Shapiro status = 1;
2747c2aa98e2SPeter Wemm break;
2748c2aa98e2SPeter Wemm
2749c2aa98e2SPeter Wemm case 0:
275006f25ae9SGregory Neil Shapiro status = 0;
2751c2aa98e2SPeter Wemm break;
2752c2aa98e2SPeter Wemm
2753c2aa98e2SPeter Wemm default:
275406f25ae9SGregory Neil Shapiro status = -1;
2755c2aa98e2SPeter Wemm break;
2756c2aa98e2SPeter Wemm }
275706f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
275806f25ae9SGregory Neil Shapiro if (status > 0)
2759c2aa98e2SPeter Wemm {
2760c2aa98e2SPeter Wemm if (!bitset(MF_APPEND, map->map_mflags))
2761c2aa98e2SPeter Wemm message("050 Warning: duplicate alias name %s", lhs);
2762c2aa98e2SPeter Wemm else
2763c2aa98e2SPeter Wemm {
2764c2aa98e2SPeter Wemm static char *buf = NULL;
2765c2aa98e2SPeter Wemm static int bufsiz = 0;
2766c2aa98e2SPeter Wemm DBT old;
2767c2aa98e2SPeter Wemm
2768d0cef73dSGregory Neil Shapiro memset(&old, '\0', sizeof(old));
2769c2aa98e2SPeter Wemm
2770c2aa98e2SPeter Wemm old.data = db_map_lookup(map, key.data,
277106f25ae9SGregory Neil Shapiro (char **) NULL, &status);
2772c2aa98e2SPeter Wemm if (old.data != NULL)
2773c2aa98e2SPeter Wemm {
2774c2aa98e2SPeter Wemm old.size = strlen(old.data);
277506f25ae9SGregory Neil Shapiro if (data.size + old.size + 2 > (size_t) bufsiz)
2776c2aa98e2SPeter Wemm {
27772fb4f839SGregory Neil Shapiro SM_FREE(buf);
2778c2aa98e2SPeter Wemm bufsiz = data.size + old.size + 2;
277940266059SGregory Neil Shapiro buf = sm_pmalloc_x(bufsiz);
2780c2aa98e2SPeter Wemm }
278140266059SGregory Neil Shapiro (void) sm_strlcpyn(buf, bufsiz, 3,
278240266059SGregory Neil Shapiro (char *) data.data, ",",
278340266059SGregory Neil Shapiro (char *) old.data);
2784c2aa98e2SPeter Wemm data.size = data.size + old.size + 1;
2785c2aa98e2SPeter Wemm data.data = buf;
2786c2aa98e2SPeter Wemm if (tTd(38, 9))
278740266059SGregory Neil Shapiro sm_dprintf("db_map_store append=%s\n",
2788c2aa98e2SPeter Wemm (char *) data.data);
2789c2aa98e2SPeter Wemm }
2790c2aa98e2SPeter Wemm }
2791c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
279206f25ae9SGregory Neil Shapiro status = db->put(db, &key, &data, 0);
27935b0945b5SGregory Neil Shapiro # else
279406f25ae9SGregory Neil Shapiro status = errno = db->put(db, NULL, &key, &data, 0);
279506f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2796c2aa98e2SPeter Wemm }
279706f25ae9SGregory Neil Shapiro if (status != 0)
2798c2aa98e2SPeter Wemm syserr("readaliases: db put (%s)", lhs);
2799c2aa98e2SPeter Wemm }
2800c2aa98e2SPeter Wemm
2801c2aa98e2SPeter Wemm
2802c2aa98e2SPeter Wemm /*
2803c2aa98e2SPeter Wemm ** DB_MAP_CLOSE -- add distinguished entries and close the database
2804c2aa98e2SPeter Wemm */
2805c2aa98e2SPeter Wemm
2806c2aa98e2SPeter Wemm void
db_map_close(map)2807c2aa98e2SPeter Wemm db_map_close(map)
2808c2aa98e2SPeter Wemm MAP *map;
2809c2aa98e2SPeter Wemm {
2810c2aa98e2SPeter Wemm register DB *db = map->map_db2;
2811c2aa98e2SPeter Wemm
2812c2aa98e2SPeter Wemm if (tTd(38, 9))
281340266059SGregory Neil Shapiro sm_dprintf("db_map_close(%s, %s, %lx)\n",
2814c2aa98e2SPeter Wemm map->map_mname, map->map_file, map->map_mflags);
2815c2aa98e2SPeter Wemm
2816c2aa98e2SPeter Wemm if (bitset(MF_WRITABLE, map->map_mflags))
2817c2aa98e2SPeter Wemm {
2818c2aa98e2SPeter Wemm /* write out the distinguished alias */
2819c2aa98e2SPeter Wemm db_map_store(map, "@", "@");
2820c2aa98e2SPeter Wemm }
2821c2aa98e2SPeter Wemm
2822c2aa98e2SPeter Wemm (void) db->sync(db, 0);
2823c2aa98e2SPeter Wemm
2824c2aa98e2SPeter Wemm # if !LOCK_ON_OPEN
2825c2aa98e2SPeter Wemm if (map->map_lockfd >= 0)
2826c2aa98e2SPeter Wemm (void) close(map->map_lockfd);
282706f25ae9SGregory Neil Shapiro # endif /* !LOCK_ON_OPEN */
2828c2aa98e2SPeter Wemm
2829c2aa98e2SPeter Wemm # if DB_VERSION_MAJOR < 2
2830c2aa98e2SPeter Wemm if (db->close(db) != 0)
283106f25ae9SGregory Neil Shapiro # else /* DB_VERSION_MAJOR < 2 */
2832065a643dSPeter Wemm /*
2833065a643dSPeter Wemm ** Berkeley DB can use internal shared memory
2834065a643dSPeter Wemm ** locking for its memory pool. Closing a map
2835065a643dSPeter Wemm ** opened by another process will interfere
2836065a643dSPeter Wemm ** with the shared memory and locks of the parent
2837065a643dSPeter Wemm ** process leaving things in a bad state.
28382e43090eSPeter Wemm */
28392e43090eSPeter Wemm
28402e43090eSPeter Wemm /*
2841065a643dSPeter Wemm ** If this map was not opened by the current
28422e43090eSPeter Wemm ** process, do not close the map but recover
2843065a643dSPeter Wemm ** the file descriptor.
2844065a643dSPeter Wemm */
284540266059SGregory Neil Shapiro
284640266059SGregory Neil Shapiro if (map->map_pid != CurrentPid)
2847065a643dSPeter Wemm {
2848065a643dSPeter Wemm int fd = -1;
2849065a643dSPeter Wemm
2850065a643dSPeter Wemm errno = db->fd(db, &fd);
2851065a643dSPeter Wemm if (fd >= 0)
2852065a643dSPeter Wemm (void) close(fd);
2853065a643dSPeter Wemm return;
2854065a643dSPeter Wemm }
2855065a643dSPeter Wemm
2856c2aa98e2SPeter Wemm if ((errno = db->close(db, 0)) != 0)
285706f25ae9SGregory Neil Shapiro # endif /* DB_VERSION_MAJOR < 2 */
2858065a643dSPeter Wemm syserr("db_map_close(%s, %s, %lx): db close failure",
2859065a643dSPeter Wemm map->map_mname, map->map_file, map->map_mflags);
2860c2aa98e2SPeter Wemm }
286106f25ae9SGregory Neil Shapiro #endif /* NEWDB */
28625b0945b5SGregory Neil Shapiro
28635b0945b5SGregory Neil Shapiro #if CDB
28645b0945b5SGregory Neil Shapiro /*
28655b0945b5SGregory Neil Shapiro ** CDB Modules
28665b0945b5SGregory Neil Shapiro */
28675b0945b5SGregory Neil Shapiro
28685b0945b5SGregory Neil Shapiro bool
cdb_map_open(map,mode)28695b0945b5SGregory Neil Shapiro cdb_map_open(map, mode)
28705b0945b5SGregory Neil Shapiro MAP *map;
28715b0945b5SGregory Neil Shapiro int mode;
28725b0945b5SGregory Neil Shapiro {
28735b0945b5SGregory Neil Shapiro int fd, status, omode, smode;
28745b0945b5SGregory Neil Shapiro long sff;
28755b0945b5SGregory Neil Shapiro struct stat st;
28762fb4f839SGregory Neil Shapiro struct cdb *cdbp;
28775b0945b5SGregory Neil Shapiro char buf[MAXPATHLEN];
28785b0945b5SGregory Neil Shapiro
28795b0945b5SGregory Neil Shapiro if (tTd(38, 2))
2880*d39bd2c1SGregory Neil Shapiro sm_dprintf("cdb_map_open(%s, %s, %s)\n",
2881*d39bd2c1SGregory Neil Shapiro map->map_mname, map->map_file,
2882*d39bd2c1SGregory Neil Shapiro O_RDWR == (mode & O_ACCMODE) ? "rdwr" : "rdonly");
28835b0945b5SGregory Neil Shapiro map->map_db1 = (ARBPTR_T)NULL;
28845b0945b5SGregory Neil Shapiro map->map_db2 = (ARBPTR_T)NULL;
28855b0945b5SGregory Neil Shapiro
28865b0945b5SGregory Neil Shapiro mode &= O_ACCMODE;
28875b0945b5SGregory Neil Shapiro omode = mode;
28885b0945b5SGregory Neil Shapiro
28895b0945b5SGregory Neil Shapiro /*
28902fb4f839SGregory Neil Shapiro ** Note:
28915b0945b5SGregory Neil Shapiro ** The code to add the extension and to set up safefile()
28925b0945b5SGregory Neil Shapiro ** and open() should be in a common function
28935b0945b5SGregory Neil Shapiro ** (it would be nice to re-use libsmdb?)
28945b0945b5SGregory Neil Shapiro */
28955b0945b5SGregory Neil Shapiro
28965b0945b5SGregory Neil Shapiro if (!smdb_add_extension(buf, sizeof(buf), map->map_file, CDBext))
28975b0945b5SGregory Neil Shapiro {
28985b0945b5SGregory Neil Shapiro errno = 0;
28995b0945b5SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
29005b0945b5SGregory Neil Shapiro syserr("cdb map \"%s\": map file %s name too long",
29015b0945b5SGregory Neil Shapiro map->map_mname, map->map_file);
29025b0945b5SGregory Neil Shapiro return false;
29035b0945b5SGregory Neil Shapiro }
29045b0945b5SGregory Neil Shapiro
29055b0945b5SGregory Neil Shapiro sff = SFF_ROOTOK|SFF_REGONLY;
29065b0945b5SGregory Neil Shapiro if (mode == O_RDWR)
29075b0945b5SGregory Neil Shapiro {
29085b0945b5SGregory Neil Shapiro sff |= SFF_CREAT;
29095b0945b5SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
29105b0945b5SGregory Neil Shapiro sff |= SFF_NOSLINK;
29115b0945b5SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
29125b0945b5SGregory Neil Shapiro sff |= SFF_NOHLINK;
29135b0945b5SGregory Neil Shapiro smode = S_IWRITE;
29142fb4f839SGregory Neil Shapiro map->map_mflags |= MF_LOCKED;
29155b0945b5SGregory Neil Shapiro }
29165b0945b5SGregory Neil Shapiro else
29175b0945b5SGregory Neil Shapiro {
29185b0945b5SGregory Neil Shapiro smode = S_IREAD;
29195b0945b5SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
29205b0945b5SGregory Neil Shapiro sff |= SFF_NOWLINK;
29215b0945b5SGregory Neil Shapiro }
29225b0945b5SGregory Neil Shapiro if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
29235b0945b5SGregory Neil Shapiro sff |= SFF_SAFEDIRPATH;
29245b0945b5SGregory Neil Shapiro status = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st);
29255b0945b5SGregory Neil Shapiro if (status != 0)
29265b0945b5SGregory Neil Shapiro {
29275b0945b5SGregory Neil Shapiro char *prob = "unsafe";
29285b0945b5SGregory Neil Shapiro
29295b0945b5SGregory Neil Shapiro /* cannot open this map */
29305b0945b5SGregory Neil Shapiro if (status == ENOENT)
29315b0945b5SGregory Neil Shapiro prob = "missing";
29325b0945b5SGregory Neil Shapiro errno = status;
29335b0945b5SGregory Neil Shapiro if (tTd(38, 2))
29345b0945b5SGregory Neil Shapiro sm_dprintf("\t%s map file: %s\n", prob, sm_errstring(status));
29355b0945b5SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
29365b0945b5SGregory Neil Shapiro syserr("%s map \"%s\": %s map file %s",
29375b0945b5SGregory Neil Shapiro map->map_mname, prob, buf, sm_errstring(status));
29385b0945b5SGregory Neil Shapiro return false;
29395b0945b5SGregory Neil Shapiro }
29405b0945b5SGregory Neil Shapiro
29415b0945b5SGregory Neil Shapiro if (st.st_mode == ST_MODE_NOFILE)
29425b0945b5SGregory Neil Shapiro omode |= O_CREAT|O_EXCL;
29435b0945b5SGregory Neil Shapiro # if LOCK_ON_OPEN
29445b0945b5SGregory Neil Shapiro if (mode == O_RDWR)
29455b0945b5SGregory Neil Shapiro omode |= O_TRUNC|O_EXLOCK;
29465b0945b5SGregory Neil Shapiro else
29475b0945b5SGregory Neil Shapiro omode |= O_SHLOCK;
29485b0945b5SGregory Neil Shapiro # else
29495b0945b5SGregory Neil Shapiro if (mode == O_RDWR)
29505b0945b5SGregory Neil Shapiro omode |= O_TRUNC;
29515b0945b5SGregory Neil Shapiro # endif /* LOCK_ON_OPEN */
29525b0945b5SGregory Neil Shapiro
29535b0945b5SGregory Neil Shapiro fd = open(buf, omode, DBMMODE);
29545b0945b5SGregory Neil Shapiro if (fd < 0)
29555b0945b5SGregory Neil Shapiro {
29565b0945b5SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
29575b0945b5SGregory Neil Shapiro syserr("cdb_map_open: cannot open database %s", buf);
29585b0945b5SGregory Neil Shapiro return false;
29595b0945b5SGregory Neil Shapiro }
29605b0945b5SGregory Neil Shapiro
29615b0945b5SGregory Neil Shapiro # if !LOCK_ON_OPEN
29625b0945b5SGregory Neil Shapiro /* make sure no baddies slipped in just before the open... */
29635b0945b5SGregory Neil Shapiro if (filechanged(buf, fd, &st))
29645b0945b5SGregory Neil Shapiro {
29655b0945b5SGregory Neil Shapiro int save_errno;
29665b0945b5SGregory Neil Shapiro
29675b0945b5SGregory Neil Shapiro save_errno = errno;
29685b0945b5SGregory Neil Shapiro (void) close(fd);
29695b0945b5SGregory Neil Shapiro errno = save_errno;
29705b0945b5SGregory Neil Shapiro syserr("cdb_map_open(%s): file changed after open", buf);
29715b0945b5SGregory Neil Shapiro return false;
29725b0945b5SGregory Neil Shapiro }
29735b0945b5SGregory Neil Shapiro
29745b0945b5SGregory Neil Shapiro /* actually lock the opened file */
29755b0945b5SGregory Neil Shapiro if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
29765b0945b5SGregory Neil Shapiro syserr("cdb_map_open: cannot lock %s", buf);
2977*d39bd2c1SGregory Neil Shapiro # else /* !LOCK_ON_OPEN */
2978*d39bd2c1SGregory Neil Shapiro if (tTd(55, 60))
2979*d39bd2c1SGregory Neil Shapiro sm_dprintf("lockopen(%s, fd=%d, action=nb, type=%s): SUCCESS\n",
2980*d39bd2c1SGregory Neil Shapiro buf, fd, mode == O_RDONLY ? "rd" : "wr");
29815b0945b5SGregory Neil Shapiro # endif /* !LOCK_ON_OPEN */
29825b0945b5SGregory Neil Shapiro
29832fb4f839SGregory Neil Shapiro map->map_lockfd = fd;
29842fb4f839SGregory Neil Shapiro
29852fb4f839SGregory Neil Shapiro if (fd >= 0 && fstat(fd, &st) >= 0)
29862fb4f839SGregory Neil Shapiro map->map_mtime = st.st_mtime;
29872fb4f839SGregory Neil Shapiro
29885b0945b5SGregory Neil Shapiro /* only for aliases! */
29895b0945b5SGregory Neil Shapiro if (mode == O_RDWR)
29905b0945b5SGregory Neil Shapiro {
29915b0945b5SGregory Neil Shapiro struct cdb_make *cdbmp;
29925b0945b5SGregory Neil Shapiro
29935b0945b5SGregory Neil Shapiro cdbmp = (struct cdb_make *) xalloc(sizeof(*cdbmp));
29945b0945b5SGregory Neil Shapiro status = cdb_make_start(cdbmp, fd);
29955b0945b5SGregory Neil Shapiro if (status != 0)
29965b0945b5SGregory Neil Shapiro {
29975b0945b5SGregory Neil Shapiro close(fd);
29985b0945b5SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
29995b0945b5SGregory Neil Shapiro syserr("initialization of cdb map (make) failed");
30005b0945b5SGregory Neil Shapiro return false;
30015b0945b5SGregory Neil Shapiro }
30025b0945b5SGregory Neil Shapiro
30035b0945b5SGregory Neil Shapiro map->map_db2 = (ARBPTR_T)cdbmp;
3004*d39bd2c1SGregory Neil Shapiro mapchown(map->map_file, fd, -1, buf);
30055b0945b5SGregory Neil Shapiro return true;
30065b0945b5SGregory Neil Shapiro }
3007*d39bd2c1SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_UN);
3008*d39bd2c1SGregory Neil Shapiro # if _FFR_TESTS
3009*d39bd2c1SGregory Neil Shapiro if (tTd(68, 101))
3010*d39bd2c1SGregory Neil Shapiro {
3011*d39bd2c1SGregory Neil Shapiro int sl;
3012*d39bd2c1SGregory Neil Shapiro
3013*d39bd2c1SGregory Neil Shapiro sl = tTdlevel(68) - 100;
3014*d39bd2c1SGregory Neil Shapiro sm_dprintf("cdb_map_open: sleep=%d\n", sl);
3015*d39bd2c1SGregory Neil Shapiro sleep(sl);
3016*d39bd2c1SGregory Neil Shapiro }
3017*d39bd2c1SGregory Neil Shapiro # endif
30185b0945b5SGregory Neil Shapiro
30195b0945b5SGregory Neil Shapiro cdbp = (struct cdb *) xalloc(sizeof(*cdbp));
30205b0945b5SGregory Neil Shapiro status = cdb_init(cdbp, fd);
30215b0945b5SGregory Neil Shapiro if (status != 0)
30225b0945b5SGregory Neil Shapiro {
30235b0945b5SGregory Neil Shapiro close(fd);
30245b0945b5SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
30255b0945b5SGregory Neil Shapiro syserr("initialization of cdb map failed");
30265b0945b5SGregory Neil Shapiro return false;
30275b0945b5SGregory Neil Shapiro }
3028*d39bd2c1SGregory Neil Shapiro
30295b0945b5SGregory Neil Shapiro map->map_db1 = (ARBPTR_T)cdbp;
3030*d39bd2c1SGregory Neil Shapiro if (bitset(MF_ALIAS, map->map_mflags) && !aliaswait(map, CDBEXT, true))
3031*d39bd2c1SGregory Neil Shapiro {
3032*d39bd2c1SGregory Neil Shapiro close(fd); /* XXX more error handling needed? */
3033*d39bd2c1SGregory Neil Shapiro return false;
3034*d39bd2c1SGregory Neil Shapiro }
30355b0945b5SGregory Neil Shapiro return true;
30365b0945b5SGregory Neil Shapiro }
30375b0945b5SGregory Neil Shapiro
30385b0945b5SGregory Neil Shapiro char *
cdb_map_lookup(map,name,av,statp)30395b0945b5SGregory Neil Shapiro cdb_map_lookup(map, name, av, statp)
30405b0945b5SGregory Neil Shapiro MAP *map;
30415b0945b5SGregory Neil Shapiro char *name;
30425b0945b5SGregory Neil Shapiro char **av;
30435b0945b5SGregory Neil Shapiro int *statp;
30445b0945b5SGregory Neil Shapiro {
30455b0945b5SGregory Neil Shapiro char *data;
30465b0945b5SGregory Neil Shapiro struct cdb *cdbmap;
30475b0945b5SGregory Neil Shapiro unsigned int klen, dlen;
30482fb4f839SGregory Neil Shapiro int st, fd;
30492fb4f839SGregory Neil Shapiro char key[MAXNAME + 1]; /* EAI:ok */
30502fb4f839SGregory Neil Shapiro char buf[MAXPATHLEN];
30515b0945b5SGregory Neil Shapiro
30525b0945b5SGregory Neil Shapiro data = NULL;
30535b0945b5SGregory Neil Shapiro cdbmap = map->map_db1;
30545b0945b5SGregory Neil Shapiro if (tTd(38, 20))
30555b0945b5SGregory Neil Shapiro sm_dprintf("cdb_map_lookup(%s, %s)\n", map->map_mname, name);
30565b0945b5SGregory Neil Shapiro
30572fb4f839SGregory Neil Shapiro if (!smdb_add_extension(buf, sizeof(buf), map->map_file, CDBext))
30582fb4f839SGregory Neil Shapiro {
30592fb4f839SGregory Neil Shapiro errno = 0;
30602fb4f839SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
30612fb4f839SGregory Neil Shapiro syserr("cdb map \"%s\": map file %s name too long",
30622fb4f839SGregory Neil Shapiro map->map_mname, map->map_file);
3063*d39bd2c1SGregory Neil Shapiro return NULL;
30642fb4f839SGregory Neil Shapiro }
30652fb4f839SGregory Neil Shapiro
30665b0945b5SGregory Neil Shapiro klen = strlen(name);
30675b0945b5SGregory Neil Shapiro if (klen > sizeof(key) - 1)
30685b0945b5SGregory Neil Shapiro klen = sizeof(key) - 1;
30695b0945b5SGregory Neil Shapiro memmove(key, name, klen);
30705b0945b5SGregory Neil Shapiro key[klen] = '\0';
30715b0945b5SGregory Neil Shapiro
30725b0945b5SGregory Neil Shapiro if (!bitset(MF_NOFOLDCASE, map->map_mflags))
30732fb4f839SGregory Neil Shapiro makelower_buf(key, key, sizeof(key));
30742fb4f839SGregory Neil Shapiro
30752fb4f839SGregory Neil Shapiro lockdb:
30762fb4f839SGregory Neil Shapiro fd = map->map_lockfd;
30772fb4f839SGregory Neil Shapiro if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
30782fb4f839SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_SH);
3079*d39bd2c1SGregory Neil Shapiro if (map_has_chged(map, buf, fd))
30802fb4f839SGregory Neil Shapiro {
30812fb4f839SGregory Neil Shapiro /* Reopen the database to sync the cache */
30822fb4f839SGregory Neil Shapiro int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
30832fb4f839SGregory Neil Shapiro : O_RDONLY;
30842fb4f839SGregory Neil Shapiro
30852fb4f839SGregory Neil Shapiro if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
30862fb4f839SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_UN);
30872fb4f839SGregory Neil Shapiro map->map_mflags |= MF_CLOSING;
30882fb4f839SGregory Neil Shapiro map->map_class->map_close(map);
30892fb4f839SGregory Neil Shapiro map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
30902fb4f839SGregory Neil Shapiro if (map->map_class->map_open(map, omode))
30912fb4f839SGregory Neil Shapiro {
30922fb4f839SGregory Neil Shapiro map->map_mflags |= MF_OPEN;
30932fb4f839SGregory Neil Shapiro if ((omode & O_ACCMODE) == O_RDWR)
30942fb4f839SGregory Neil Shapiro map->map_mflags |= MF_WRITABLE;
30952fb4f839SGregory Neil Shapiro cdbmap = map->map_db1;
30962fb4f839SGregory Neil Shapiro goto lockdb;
30972fb4f839SGregory Neil Shapiro }
30982fb4f839SGregory Neil Shapiro else
30992fb4f839SGregory Neil Shapiro {
31002fb4f839SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
31012fb4f839SGregory Neil Shapiro {
31022fb4f839SGregory Neil Shapiro extern MAPCLASS BogusMapClass;
31032fb4f839SGregory Neil Shapiro
31042fb4f839SGregory Neil Shapiro *statp = EX_TEMPFAIL;
31052fb4f839SGregory Neil Shapiro map->map_orgclass = map->map_class;
31062fb4f839SGregory Neil Shapiro map->map_class = &BogusMapClass;
31072fb4f839SGregory Neil Shapiro map->map_mflags |= MF_OPEN;
31082fb4f839SGregory Neil Shapiro syserr("Cannot reopen CDB database %s",
31092fb4f839SGregory Neil Shapiro map->map_file);
31102fb4f839SGregory Neil Shapiro }
31112fb4f839SGregory Neil Shapiro return NULL;
31122fb4f839SGregory Neil Shapiro }
31132fb4f839SGregory Neil Shapiro }
31145b0945b5SGregory Neil Shapiro
31155b0945b5SGregory Neil Shapiro st = 0;
31165b0945b5SGregory Neil Shapiro if (bitset(MF_TRY0NULL, map->map_mflags))
31175b0945b5SGregory Neil Shapiro {
31185b0945b5SGregory Neil Shapiro st = cdb_find(cdbmap, key, klen);
31195b0945b5SGregory Neil Shapiro if (st == 1)
31205b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_TRY1NULL;
31215b0945b5SGregory Neil Shapiro }
31225b0945b5SGregory Neil Shapiro if (st != 1 && bitset(MF_TRY1NULL, map->map_mflags))
31235b0945b5SGregory Neil Shapiro {
31245b0945b5SGregory Neil Shapiro st = cdb_find(cdbmap, key, klen + 1);
31255b0945b5SGregory Neil Shapiro if (st == 1)
31265b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_TRY0NULL;
31275b0945b5SGregory Neil Shapiro }
31282fb4f839SGregory Neil Shapiro if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
31292fb4f839SGregory Neil Shapiro (void) lockfile(fd, buf, NULL, LOCK_UN);
31305b0945b5SGregory Neil Shapiro if (st != 1)
31315b0945b5SGregory Neil Shapiro {
31325b0945b5SGregory Neil Shapiro if (st < 0)
31335b0945b5SGregory Neil Shapiro syserr("cdb_map_lookup: get (%s)", name);
31345b0945b5SGregory Neil Shapiro return NULL;
31355b0945b5SGregory Neil Shapiro }
31365b0945b5SGregory Neil Shapiro else
31375b0945b5SGregory Neil Shapiro {
31385b0945b5SGregory Neil Shapiro dlen = cdb_datalen(cdbmap);
31395b0945b5SGregory Neil Shapiro data = malloc(dlen + 1);
31405b0945b5SGregory Neil Shapiro cdb_read(cdbmap, data, dlen, cdb_datapos(cdbmap));
31415b0945b5SGregory Neil Shapiro data[dlen] = '\0';
31425b0945b5SGregory Neil Shapiro }
31435b0945b5SGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
31445b0945b5SGregory Neil Shapiro return map_rewrite(map, name, strlen(name), NULL);
31455b0945b5SGregory Neil Shapiro else
31465b0945b5SGregory Neil Shapiro return map_rewrite(map, data, dlen, av);
31475b0945b5SGregory Neil Shapiro }
31485b0945b5SGregory Neil Shapiro
31495b0945b5SGregory Neil Shapiro /*
31505b0945b5SGregory Neil Shapiro ** CDB_MAP_STORE -- store a datum in the CDB database
31515b0945b5SGregory Neil Shapiro */
31525b0945b5SGregory Neil Shapiro
31535b0945b5SGregory Neil Shapiro void
cdb_map_store(map,lhs,rhs)31545b0945b5SGregory Neil Shapiro cdb_map_store(map, lhs, rhs)
31555b0945b5SGregory Neil Shapiro MAP *map;
31565b0945b5SGregory Neil Shapiro char *lhs;
31575b0945b5SGregory Neil Shapiro char *rhs;
31585b0945b5SGregory Neil Shapiro {
31595b0945b5SGregory Neil Shapiro struct cdb_make *cdbmp;
31605b0945b5SGregory Neil Shapiro size_t klen;
31615b0945b5SGregory Neil Shapiro size_t vlen;
31625b0945b5SGregory Neil Shapiro int status;
31632fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
31645b0945b5SGregory Neil Shapiro
31655b0945b5SGregory Neil Shapiro cdbmp = map->map_db2;
31665b0945b5SGregory Neil Shapiro if (cdbmp == NULL)
31675b0945b5SGregory Neil Shapiro return; /* XXX */
31685b0945b5SGregory Neil Shapiro
31695b0945b5SGregory Neil Shapiro klen = strlen(lhs);
31705b0945b5SGregory Neil Shapiro vlen = strlen(rhs);
31715b0945b5SGregory Neil Shapiro if (!bitset(MF_NOFOLDCASE, map->map_mflags))
31725b0945b5SGregory Neil Shapiro {
31735b0945b5SGregory Neil Shapiro if (klen > sizeof(keybuf) - 1)
31745b0945b5SGregory Neil Shapiro klen = sizeof(keybuf) - 1;
31755b0945b5SGregory Neil Shapiro memmove(keybuf, lhs, klen);
31765b0945b5SGregory Neil Shapiro keybuf[klen] = '\0';
31772fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
31785b0945b5SGregory Neil Shapiro lhs = keybuf;
31795b0945b5SGregory Neil Shapiro }
31805b0945b5SGregory Neil Shapiro
31815b0945b5SGregory Neil Shapiro if (bitset(MF_INCLNULL, map->map_mflags))
31825b0945b5SGregory Neil Shapiro {
31835b0945b5SGregory Neil Shapiro klen++;
31845b0945b5SGregory Neil Shapiro vlen++;
31855b0945b5SGregory Neil Shapiro }
31865b0945b5SGregory Neil Shapiro
31875b0945b5SGregory Neil Shapiro /* flags? */
31885b0945b5SGregory Neil Shapiro status = cdb_make_put(cdbmp, lhs, klen, rhs, vlen, 0);
31895b0945b5SGregory Neil Shapiro /* and now? */
31905b0945b5SGregory Neil Shapiro }
31915b0945b5SGregory Neil Shapiro
31925b0945b5SGregory Neil Shapiro void
cdb_map_close(map)31935b0945b5SGregory Neil Shapiro cdb_map_close(map)
31945b0945b5SGregory Neil Shapiro MAP * map;
31955b0945b5SGregory Neil Shapiro {
31965b0945b5SGregory Neil Shapiro struct cdb *cdbp;
31975b0945b5SGregory Neil Shapiro struct cdb_make *cdbmp;
31985b0945b5SGregory Neil Shapiro int fd;
31995b0945b5SGregory Neil Shapiro
32005b0945b5SGregory Neil Shapiro fd = -1;
32015b0945b5SGregory Neil Shapiro cdbp = map->map_db1;
32025b0945b5SGregory Neil Shapiro if (cdbp != NULL)
32035b0945b5SGregory Neil Shapiro {
32045b0945b5SGregory Neil Shapiro if (tTd(38, 20))
32052fb4f839SGregory Neil Shapiro sm_dprintf("cdb_map_close(%p): cdbp\n", (void *)cdbp);
32065b0945b5SGregory Neil Shapiro fd = cdb_fileno(cdbp);
32075b0945b5SGregory Neil Shapiro cdb_free(cdbp);
32082fb4f839SGregory Neil Shapiro SM_FREE(cdbp);
32095b0945b5SGregory Neil Shapiro }
32105b0945b5SGregory Neil Shapiro cdbmp = map->map_db2;
32115b0945b5SGregory Neil Shapiro if (cdbmp != NULL)
32125b0945b5SGregory Neil Shapiro {
32135b0945b5SGregory Neil Shapiro if (tTd(38, 20))
32142fb4f839SGregory Neil Shapiro sm_dprintf("cdb_map_close(%p): cdmbp\n", (void *)cdbmp);
32155b0945b5SGregory Neil Shapiro fd = cdb_fileno(cdbmp);
32165b0945b5SGregory Neil Shapiro
32175b0945b5SGregory Neil Shapiro /* write out the distinguished alias */
32185b0945b5SGregory Neil Shapiro /* XXX Why isn't this in a common place? */
32195b0945b5SGregory Neil Shapiro cdb_map_store(map, "@", "@");
32205b0945b5SGregory Neil Shapiro
32215b0945b5SGregory Neil Shapiro if (cdb_make_finish(cdbmp) != 0)
32222fb4f839SGregory Neil Shapiro syserr("cdb: cdb_make_finish(%s) failed",
32232fb4f839SGregory Neil Shapiro map->map_file);
32245b0945b5SGregory Neil Shapiro if (fd >= 0)
32255b0945b5SGregory Neil Shapiro {
32265b0945b5SGregory Neil Shapiro if (fsync(fd) == -1)
32275b0945b5SGregory Neil Shapiro syserr("cdb: fsync(%s) failed", map->map_file);
32285b0945b5SGregory Neil Shapiro if (close(fd) == -1)
32295b0945b5SGregory Neil Shapiro syserr("cdb: close(%s) failed", map->map_file);
32302fb4f839SGregory Neil Shapiro fd = -1;
32315b0945b5SGregory Neil Shapiro }
32322fb4f839SGregory Neil Shapiro SM_FREE(cdbmp);
32335b0945b5SGregory Neil Shapiro }
32345b0945b5SGregory Neil Shapiro if (fd >=0)
32355b0945b5SGregory Neil Shapiro close(fd);
32365b0945b5SGregory Neil Shapiro }
32375b0945b5SGregory Neil Shapiro #endif /* CDB */
32385b0945b5SGregory Neil Shapiro
323940266059SGregory Neil Shapiro /*
3240c2aa98e2SPeter Wemm ** NIS Modules
3241c2aa98e2SPeter Wemm */
3242c2aa98e2SPeter Wemm
324340266059SGregory Neil Shapiro #if NIS
3244c2aa98e2SPeter Wemm
3245c2aa98e2SPeter Wemm # ifndef YPERR_BUSY
3246c2aa98e2SPeter Wemm # define YPERR_BUSY 16
32475b0945b5SGregory Neil Shapiro # endif
3248c2aa98e2SPeter Wemm
3249c2aa98e2SPeter Wemm /*
3250*d39bd2c1SGregory Neil Shapiro ** NIS_MAP_OPEN -- open NIS map
3251c2aa98e2SPeter Wemm */
3252c2aa98e2SPeter Wemm
3253c2aa98e2SPeter Wemm bool
nis_map_open(map,mode)3254c2aa98e2SPeter Wemm nis_map_open(map, mode)
3255c2aa98e2SPeter Wemm MAP *map;
3256c2aa98e2SPeter Wemm int mode;
3257c2aa98e2SPeter Wemm {
3258c2aa98e2SPeter Wemm int yperr;
3259c2aa98e2SPeter Wemm register char *p;
3260c2aa98e2SPeter Wemm auto char *vp;
3261c2aa98e2SPeter Wemm auto int vsize;
3262c2aa98e2SPeter Wemm
3263c2aa98e2SPeter Wemm if (tTd(38, 2))
326440266059SGregory Neil Shapiro sm_dprintf("nis_map_open(%s, %s, %d)\n",
3265c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
3266c2aa98e2SPeter Wemm
3267c2aa98e2SPeter Wemm mode &= O_ACCMODE;
3268c2aa98e2SPeter Wemm if (mode != O_RDONLY)
3269c2aa98e2SPeter Wemm {
3270c2aa98e2SPeter Wemm /* issue a pseudo-error message */
327140266059SGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
327240266059SGregory Neil Shapiro return false;
3273c2aa98e2SPeter Wemm }
3274c2aa98e2SPeter Wemm
3275c2aa98e2SPeter Wemm p = strchr(map->map_file, '@');
3276c2aa98e2SPeter Wemm if (p != NULL)
3277c2aa98e2SPeter Wemm {
3278c2aa98e2SPeter Wemm *p++ = '\0';
3279c2aa98e2SPeter Wemm if (*p != '\0')
3280c2aa98e2SPeter Wemm map->map_domain = p;
3281c2aa98e2SPeter Wemm }
3282c2aa98e2SPeter Wemm
3283c2aa98e2SPeter Wemm if (*map->map_file == '\0')
3284c2aa98e2SPeter Wemm map->map_file = "mail.aliases";
3285c2aa98e2SPeter Wemm
3286c2aa98e2SPeter Wemm if (map->map_domain == NULL)
3287c2aa98e2SPeter Wemm {
3288c2aa98e2SPeter Wemm yperr = yp_get_default_domain(&map->map_domain);
3289c2aa98e2SPeter Wemm if (yperr != 0)
3290c2aa98e2SPeter Wemm {
3291c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
3292605302a5SGregory Neil Shapiro syserr("451 4.3.5 NIS map %s specified, but NIS not running",
3293c2aa98e2SPeter Wemm map->map_file);
329440266059SGregory Neil Shapiro return false;
3295c2aa98e2SPeter Wemm }
3296c2aa98e2SPeter Wemm }
3297c2aa98e2SPeter Wemm
3298c2aa98e2SPeter Wemm /* check to see if this map actually exists */
329906f25ae9SGregory Neil Shapiro vp = NULL;
3300c2aa98e2SPeter Wemm yperr = yp_match(map->map_domain, map->map_file, "@", 1,
3301c2aa98e2SPeter Wemm &vp, &vsize);
3302c2aa98e2SPeter Wemm if (tTd(38, 10))
330340266059SGregory Neil Shapiro sm_dprintf("nis_map_open: yp_match(@, %s, %s) => %s\n",
3304c2aa98e2SPeter Wemm map->map_domain, map->map_file, yperr_string(yperr));
33052fb4f839SGregory Neil Shapiro SM_FREE(vp);
330606f25ae9SGregory Neil Shapiro
3307c2aa98e2SPeter Wemm if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
3308c2aa98e2SPeter Wemm {
3309c2aa98e2SPeter Wemm /*
3310c2aa98e2SPeter Wemm ** We ought to be calling aliaswait() here if this is an
3311c2aa98e2SPeter Wemm ** alias file, but powerful HP-UX NIS servers apparently
3312c2aa98e2SPeter Wemm ** don't insert the @:@ token into the alias map when it
3313c2aa98e2SPeter Wemm ** is rebuilt, so aliaswait() just hangs. I hate HP-UX.
3314c2aa98e2SPeter Wemm */
3315c2aa98e2SPeter Wemm
3316c2aa98e2SPeter Wemm # if 0
3317c2aa98e2SPeter Wemm if (!bitset(MF_ALIAS, map->map_mflags) ||
331840266059SGregory Neil Shapiro aliaswait(map, NULL, true))
33195b0945b5SGregory Neil Shapiro # endif
332040266059SGregory Neil Shapiro return true;
3321c2aa98e2SPeter Wemm }
3322c2aa98e2SPeter Wemm
3323c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
3324c2aa98e2SPeter Wemm {
3325605302a5SGregory Neil Shapiro syserr("451 4.3.5 Cannot bind to map %s in domain %s: %s",
3326c2aa98e2SPeter Wemm map->map_file, map->map_domain, yperr_string(yperr));
3327c2aa98e2SPeter Wemm }
3328c2aa98e2SPeter Wemm
332940266059SGregory Neil Shapiro return false;
3330c2aa98e2SPeter Wemm }
3331c2aa98e2SPeter Wemm
3332c2aa98e2SPeter Wemm
3333c2aa98e2SPeter Wemm /*
3334c2aa98e2SPeter Wemm ** NIS_MAP_LOOKUP -- look up a datum in a NIS map
3335c2aa98e2SPeter Wemm */
3336c2aa98e2SPeter Wemm
3337c2aa98e2SPeter Wemm /* ARGSUSED3 */
3338c2aa98e2SPeter Wemm char *
nis_map_lookup(map,name,av,statp)3339c2aa98e2SPeter Wemm nis_map_lookup(map, name, av, statp)
3340c2aa98e2SPeter Wemm MAP *map;
3341c2aa98e2SPeter Wemm char *name;
3342c2aa98e2SPeter Wemm char **av;
3343c2aa98e2SPeter Wemm int *statp;
3344c2aa98e2SPeter Wemm {
3345c2aa98e2SPeter Wemm char *vp;
3346c2aa98e2SPeter Wemm auto int vsize;
3347c2aa98e2SPeter Wemm int buflen;
3348c2aa98e2SPeter Wemm int yperr;
33492fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
335040266059SGregory Neil Shapiro char *SM_NONVOLATILE result = NULL;
3351c2aa98e2SPeter Wemm
3352c2aa98e2SPeter Wemm if (tTd(38, 20))
335340266059SGregory Neil Shapiro sm_dprintf("nis_map_lookup(%s, %s)\n",
3354c2aa98e2SPeter Wemm map->map_mname, name);
3355c2aa98e2SPeter Wemm
3356c2aa98e2SPeter Wemm buflen = strlen(name);
3357d0cef73dSGregory Neil Shapiro if (buflen > sizeof(keybuf) - 1)
3358d0cef73dSGregory Neil Shapiro buflen = sizeof(keybuf) - 1;
335906f25ae9SGregory Neil Shapiro memmove(keybuf, name, buflen);
3360c2aa98e2SPeter Wemm keybuf[buflen] = '\0';
3361c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
33622fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
3363c2aa98e2SPeter Wemm yperr = YPERR_KEY;
336406f25ae9SGregory Neil Shapiro vp = NULL;
3365c2aa98e2SPeter Wemm if (bitset(MF_TRY0NULL, map->map_mflags))
3366c2aa98e2SPeter Wemm {
3367c2aa98e2SPeter Wemm yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
3368c2aa98e2SPeter Wemm &vp, &vsize);
3369c2aa98e2SPeter Wemm if (yperr == 0)
3370c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY1NULL;
3371c2aa98e2SPeter Wemm }
3372c2aa98e2SPeter Wemm if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
3373c2aa98e2SPeter Wemm {
33745b0945b5SGregory Neil Shapiro SM_FREE(vp);
3375c2aa98e2SPeter Wemm buflen++;
3376c2aa98e2SPeter Wemm yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
3377c2aa98e2SPeter Wemm &vp, &vsize);
3378c2aa98e2SPeter Wemm if (yperr == 0)
3379c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY0NULL;
3380c2aa98e2SPeter Wemm }
3381c2aa98e2SPeter Wemm if (yperr != 0)
3382c2aa98e2SPeter Wemm {
3383c2aa98e2SPeter Wemm if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
3384c2aa98e2SPeter Wemm map->map_mflags &= ~(MF_VALID|MF_OPEN);
33852fb4f839SGregory Neil Shapiro SM_FREE(vp);
3386c2aa98e2SPeter Wemm return NULL;
3387c2aa98e2SPeter Wemm }
338840266059SGregory Neil Shapiro SM_TRY
3389c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
339040266059SGregory Neil Shapiro result = map_rewrite(map, name, strlen(name), NULL);
3391c2aa98e2SPeter Wemm else
339240266059SGregory Neil Shapiro result = map_rewrite(map, vp, vsize, av);
339340266059SGregory Neil Shapiro SM_FINALLY
33942fb4f839SGregory Neil Shapiro SM_FREE(vp);
339540266059SGregory Neil Shapiro SM_END_TRY
339640266059SGregory Neil Shapiro return result;
3397c2aa98e2SPeter Wemm }
3398c2aa98e2SPeter Wemm
3399c2aa98e2SPeter Wemm
3400c2aa98e2SPeter Wemm /*
3401c2aa98e2SPeter Wemm ** NIS_GETCANONNAME -- look up canonical name in NIS
3402c2aa98e2SPeter Wemm */
3403c2aa98e2SPeter Wemm
340406f25ae9SGregory Neil Shapiro static bool
nis_getcanonname(name,hbsize,statp)3405c2aa98e2SPeter Wemm nis_getcanonname(name, hbsize, statp)
3406c2aa98e2SPeter Wemm char *name;
3407c2aa98e2SPeter Wemm int hbsize;
3408c2aa98e2SPeter Wemm int *statp;
3409c2aa98e2SPeter Wemm {
3410c2aa98e2SPeter Wemm char *vp;
3411c2aa98e2SPeter Wemm auto int vsize;
3412c2aa98e2SPeter Wemm int keylen;
3413c2aa98e2SPeter Wemm int yperr;
341440266059SGregory Neil Shapiro static bool try0null = true;
341540266059SGregory Neil Shapiro static bool try1null = true;
3416c2aa98e2SPeter Wemm static char *yp_domain = NULL;
3417c2aa98e2SPeter Wemm char host_record[MAXLINE];
34182fb4f839SGregory Neil Shapiro char cbuf[MAXNAME]; /* EAI:hostname */
34192fb4f839SGregory Neil Shapiro char nbuf[MAXNAME + 1]; /* EAI:hostname */
3420c2aa98e2SPeter Wemm
3421c2aa98e2SPeter Wemm if (tTd(38, 20))
342240266059SGregory Neil Shapiro sm_dprintf("nis_getcanonname(%s)\n", name);
3423c2aa98e2SPeter Wemm
3424d0cef73dSGregory Neil Shapiro if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
3425c2aa98e2SPeter Wemm {
3426c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
342740266059SGregory Neil Shapiro return false;
3428c2aa98e2SPeter Wemm }
3429602a2b1bSGregory Neil Shapiro (void) shorten_hostname(nbuf);
3430c2aa98e2SPeter Wemm keylen = strlen(nbuf);
3431c2aa98e2SPeter Wemm
3432c2aa98e2SPeter Wemm if (yp_domain == NULL)
343306f25ae9SGregory Neil Shapiro (void) yp_get_default_domain(&yp_domain);
34342fb4f839SGregory Neil Shapiro makelower_buf(nbuf, nbuf, sizeof(nbuf));
3435c2aa98e2SPeter Wemm yperr = YPERR_KEY;
343606f25ae9SGregory Neil Shapiro vp = NULL;
3437c2aa98e2SPeter Wemm if (try0null)
3438c2aa98e2SPeter Wemm {
3439c2aa98e2SPeter Wemm yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
3440c2aa98e2SPeter Wemm &vp, &vsize);
3441c2aa98e2SPeter Wemm if (yperr == 0)
344240266059SGregory Neil Shapiro try1null = false;
3443c2aa98e2SPeter Wemm }
3444c2aa98e2SPeter Wemm if (yperr == YPERR_KEY && try1null)
3445c2aa98e2SPeter Wemm {
34465b0945b5SGregory Neil Shapiro SM_FREE(vp);
3447c2aa98e2SPeter Wemm keylen++;
3448c2aa98e2SPeter Wemm yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
3449c2aa98e2SPeter Wemm &vp, &vsize);
3450c2aa98e2SPeter Wemm if (yperr == 0)
345140266059SGregory Neil Shapiro try0null = false;
3452c2aa98e2SPeter Wemm }
3453c2aa98e2SPeter Wemm if (yperr != 0)
3454c2aa98e2SPeter Wemm {
3455c2aa98e2SPeter Wemm if (yperr == YPERR_KEY)
3456c2aa98e2SPeter Wemm *statp = EX_NOHOST;
3457c2aa98e2SPeter Wemm else if (yperr == YPERR_BUSY)
3458c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
3459c2aa98e2SPeter Wemm else
3460c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
34612fb4f839SGregory Neil Shapiro SM_FREE(vp);
346240266059SGregory Neil Shapiro return false;
3463c2aa98e2SPeter Wemm }
3464d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(host_record, vp, sizeof(host_record));
34658774250cSGregory Neil Shapiro sm_free(vp);
3466c2aa98e2SPeter Wemm if (tTd(38, 44))
346740266059SGregory Neil Shapiro sm_dprintf("got record `%s'\n", host_record);
346840266059SGregory Neil Shapiro vp = strpbrk(host_record, "#\n");
346940266059SGregory Neil Shapiro if (vp != NULL)
347040266059SGregory Neil Shapiro *vp = '\0';
3471d0cef73dSGregory Neil Shapiro if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof(cbuf)))
3472c2aa98e2SPeter Wemm {
3473c2aa98e2SPeter Wemm /* this should not happen, but.... */
3474c2aa98e2SPeter Wemm *statp = EX_NOHOST;
347540266059SGregory Neil Shapiro return false;
3476c2aa98e2SPeter Wemm }
347740266059SGregory Neil Shapiro if (sm_strlcpy(name, cbuf, hbsize) >= hbsize)
3478c2aa98e2SPeter Wemm {
3479c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
348040266059SGregory Neil Shapiro return false;
3481c2aa98e2SPeter Wemm }
3482c2aa98e2SPeter Wemm *statp = EX_OK;
348340266059SGregory Neil Shapiro return true;
3484c2aa98e2SPeter Wemm }
3485c2aa98e2SPeter Wemm
348606f25ae9SGregory Neil Shapiro #endif /* NIS */
348740266059SGregory Neil Shapiro /*
3488c2aa98e2SPeter Wemm ** NISPLUS Modules
3489c2aa98e2SPeter Wemm **
3490c2aa98e2SPeter Wemm ** This code donated by Sun Microsystems.
3491c2aa98e2SPeter Wemm */
3492c2aa98e2SPeter Wemm
349340266059SGregory Neil Shapiro #if NISPLUS
3494c2aa98e2SPeter Wemm
3495c2aa98e2SPeter Wemm # undef NIS /* symbol conflict in nis.h */
3496c2aa98e2SPeter Wemm # undef T_UNSPEC /* symbol conflict in nis.h -> ... -> sys/tiuser.h */
3497c2aa98e2SPeter Wemm # include <rpcsvc/nis.h>
3498c2aa98e2SPeter Wemm # include <rpcsvc/nislib.h>
3499552d4955SGregory Neil Shapiro # ifndef NIS_TABLE_OBJ
3500552d4955SGregory Neil Shapiro # define NIS_TABLE_OBJ TABLE_OBJ
35015b0945b5SGregory Neil Shapiro # endif
3502c2aa98e2SPeter Wemm
3503c2aa98e2SPeter Wemm # define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val
3504c2aa98e2SPeter Wemm # define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name
3505c2aa98e2SPeter Wemm # define COL_MAX(res) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len)
3506c2aa98e2SPeter Wemm # define PARTIAL_NAME(x) ((x)[strlen(x) - 1] != '.')
3507c2aa98e2SPeter Wemm
3508c2aa98e2SPeter Wemm /*
3509c2aa98e2SPeter Wemm ** NISPLUS_MAP_OPEN -- open nisplus table
3510c2aa98e2SPeter Wemm */
3511c2aa98e2SPeter Wemm
3512c2aa98e2SPeter Wemm bool
nisplus_map_open(map,mode)3513c2aa98e2SPeter Wemm nisplus_map_open(map, mode)
3514c2aa98e2SPeter Wemm MAP *map;
3515c2aa98e2SPeter Wemm int mode;
3516c2aa98e2SPeter Wemm {
3517c2aa98e2SPeter Wemm nis_result *res = NULL;
3518c2aa98e2SPeter Wemm int retry_cnt, max_col, i;
3519c2aa98e2SPeter Wemm char qbuf[MAXLINE + NIS_MAXNAMELEN];
3520c2aa98e2SPeter Wemm
3521c2aa98e2SPeter Wemm if (tTd(38, 2))
352240266059SGregory Neil Shapiro sm_dprintf("nisplus_map_open(%s, %s, %d)\n",
3523c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
3524c2aa98e2SPeter Wemm
3525c2aa98e2SPeter Wemm mode &= O_ACCMODE;
3526c2aa98e2SPeter Wemm if (mode != O_RDONLY)
3527c2aa98e2SPeter Wemm {
3528c2aa98e2SPeter Wemm errno = EPERM;
352940266059SGregory Neil Shapiro return false;
3530c2aa98e2SPeter Wemm }
3531c2aa98e2SPeter Wemm
3532c2aa98e2SPeter Wemm if (*map->map_file == '\0')
3533c2aa98e2SPeter Wemm map->map_file = "mail_aliases.org_dir";
3534c2aa98e2SPeter Wemm
3535c2aa98e2SPeter Wemm if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL)
3536c2aa98e2SPeter Wemm {
3537c2aa98e2SPeter Wemm /* set default NISPLUS Domain to $m */
3538c2aa98e2SPeter Wemm map->map_domain = newstr(nisplus_default_domain());
3539c2aa98e2SPeter Wemm if (tTd(38, 2))
354040266059SGregory Neil Shapiro sm_dprintf("nisplus_map_open(%s): using domain %s\n",
3541c2aa98e2SPeter Wemm map->map_file, map->map_domain);
3542c2aa98e2SPeter Wemm }
3543c2aa98e2SPeter Wemm if (!PARTIAL_NAME(map->map_file))
3544c2aa98e2SPeter Wemm {
3545c2aa98e2SPeter Wemm map->map_domain = newstr("");
3546d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(qbuf, map->map_file, sizeof(qbuf));
3547c2aa98e2SPeter Wemm }
3548c2aa98e2SPeter Wemm else
3549c2aa98e2SPeter Wemm {
3550c2aa98e2SPeter Wemm /* check to see if this map actually exists */
3551d0cef73dSGregory Neil Shapiro (void) sm_strlcpyn(qbuf, sizeof(qbuf), 3,
355240266059SGregory Neil Shapiro map->map_file, ".", map->map_domain);
3553c2aa98e2SPeter Wemm }
3554c2aa98e2SPeter Wemm
3555c2aa98e2SPeter Wemm retry_cnt = 0;
3556c2aa98e2SPeter Wemm while (res == NULL || res->status != NIS_SUCCESS)
3557c2aa98e2SPeter Wemm {
3558c2aa98e2SPeter Wemm res = nis_lookup(qbuf, FOLLOW_LINKS);
3559c2aa98e2SPeter Wemm switch (res->status)
3560c2aa98e2SPeter Wemm {
3561c2aa98e2SPeter Wemm case NIS_SUCCESS:
3562c2aa98e2SPeter Wemm break;
3563c2aa98e2SPeter Wemm
3564c2aa98e2SPeter Wemm case NIS_TRYAGAIN:
3565c2aa98e2SPeter Wemm case NIS_RPCERROR:
3566c2aa98e2SPeter Wemm case NIS_NAMEUNREACHABLE:
3567c2aa98e2SPeter Wemm if (retry_cnt++ > 4)
3568c2aa98e2SPeter Wemm {
3569c2aa98e2SPeter Wemm errno = EAGAIN;
357040266059SGregory Neil Shapiro return false;
3571c2aa98e2SPeter Wemm }
3572c2aa98e2SPeter Wemm /* try not to overwhelm hosed server */
3573c2aa98e2SPeter Wemm sleep(2);
3574c2aa98e2SPeter Wemm break;
3575c2aa98e2SPeter Wemm
3576c2aa98e2SPeter Wemm default: /* all other nisplus errors */
3577c2aa98e2SPeter Wemm # if 0
3578c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
3579605302a5SGregory Neil Shapiro syserr("451 4.3.5 Cannot find table %s.%s: %s",
3580c2aa98e2SPeter Wemm map->map_file, map->map_domain,
3581c2aa98e2SPeter Wemm nis_sperrno(res->status));
358206f25ae9SGregory Neil Shapiro # endif /* 0 */
3583c2aa98e2SPeter Wemm errno = EAGAIN;
358440266059SGregory Neil Shapiro return false;
3585c2aa98e2SPeter Wemm }
3586c2aa98e2SPeter Wemm }
3587c2aa98e2SPeter Wemm
3588c2aa98e2SPeter Wemm if (NIS_RES_NUMOBJ(res) != 1 ||
3589552d4955SGregory Neil Shapiro (NIS_RES_OBJECT(res)->zo_data.zo_type != NIS_TABLE_OBJ))
3590c2aa98e2SPeter Wemm {
3591c2aa98e2SPeter Wemm if (tTd(38, 10))
359240266059SGregory Neil Shapiro sm_dprintf("nisplus_map_open: %s is not a table\n", qbuf);
3593c2aa98e2SPeter Wemm # if 0
3594c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
3595605302a5SGregory Neil Shapiro syserr("451 4.3.5 %s.%s: %s is not a table",
3596c2aa98e2SPeter Wemm map->map_file, map->map_domain,
3597c2aa98e2SPeter Wemm nis_sperrno(res->status));
359806f25ae9SGregory Neil Shapiro # endif /* 0 */
3599c2aa98e2SPeter Wemm errno = EBADF;
360040266059SGregory Neil Shapiro return false;
3601c2aa98e2SPeter Wemm }
3602c2aa98e2SPeter Wemm /* default key column is column 0 */
3603c2aa98e2SPeter Wemm if (map->map_keycolnm == NULL)
3604c2aa98e2SPeter Wemm map->map_keycolnm = newstr(COL_NAME(res,0));
3605c2aa98e2SPeter Wemm
3606c2aa98e2SPeter Wemm max_col = COL_MAX(res);
3607c2aa98e2SPeter Wemm
3608c2aa98e2SPeter Wemm /* verify the key column exist */
3609c2aa98e2SPeter Wemm for (i = 0; i < max_col; i++)
3610c2aa98e2SPeter Wemm {
361106f25ae9SGregory Neil Shapiro if (strcmp(map->map_keycolnm, COL_NAME(res,i)) == 0)
3612c2aa98e2SPeter Wemm break;
3613c2aa98e2SPeter Wemm }
3614c2aa98e2SPeter Wemm if (i == max_col)
3615c2aa98e2SPeter Wemm {
3616c2aa98e2SPeter Wemm if (tTd(38, 2))
361740266059SGregory Neil Shapiro sm_dprintf("nisplus_map_open(%s): can not find key column %s\n",
3618c2aa98e2SPeter Wemm map->map_file, map->map_keycolnm);
3619c2aa98e2SPeter Wemm errno = ENOENT;
362040266059SGregory Neil Shapiro return false;
3621c2aa98e2SPeter Wemm }
3622c2aa98e2SPeter Wemm
3623c2aa98e2SPeter Wemm /* default value column is the last column */
3624c2aa98e2SPeter Wemm if (map->map_valcolnm == NULL)
3625c2aa98e2SPeter Wemm {
3626c2aa98e2SPeter Wemm map->map_valcolno = max_col - 1;
362740266059SGregory Neil Shapiro return true;
3628c2aa98e2SPeter Wemm }
3629c2aa98e2SPeter Wemm
3630c2aa98e2SPeter Wemm for (i = 0; i< max_col; i++)
3631c2aa98e2SPeter Wemm {
3632c2aa98e2SPeter Wemm if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0)
3633c2aa98e2SPeter Wemm {
3634c2aa98e2SPeter Wemm map->map_valcolno = i;
363540266059SGregory Neil Shapiro return true;
3636c2aa98e2SPeter Wemm }
3637c2aa98e2SPeter Wemm }
3638c2aa98e2SPeter Wemm
3639c2aa98e2SPeter Wemm if (tTd(38, 2))
364040266059SGregory Neil Shapiro sm_dprintf("nisplus_map_open(%s): can not find column %s\n",
3641c2aa98e2SPeter Wemm map->map_file, map->map_keycolnm);
3642c2aa98e2SPeter Wemm errno = ENOENT;
364340266059SGregory Neil Shapiro return false;
3644c2aa98e2SPeter Wemm }
3645c2aa98e2SPeter Wemm
3646c2aa98e2SPeter Wemm
3647c2aa98e2SPeter Wemm /*
3648c2aa98e2SPeter Wemm ** NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table
3649c2aa98e2SPeter Wemm */
3650c2aa98e2SPeter Wemm
3651c2aa98e2SPeter Wemm char *
nisplus_map_lookup(map,name,av,statp)3652c2aa98e2SPeter Wemm nisplus_map_lookup(map, name, av, statp)
3653c2aa98e2SPeter Wemm MAP *map;
3654c2aa98e2SPeter Wemm char *name;
3655c2aa98e2SPeter Wemm char **av;
3656c2aa98e2SPeter Wemm int *statp;
3657c2aa98e2SPeter Wemm {
3658c2aa98e2SPeter Wemm char *p;
3659c2aa98e2SPeter Wemm auto int vsize;
3660c2aa98e2SPeter Wemm char *skp;
3661c2aa98e2SPeter Wemm int skleft;
36622fb4f839SGregory Neil Shapiro char search_key[MAXNAME + 4]; /* EAI:ok */
3663c2aa98e2SPeter Wemm char qbuf[MAXLINE + NIS_MAXNAMELEN];
3664c2aa98e2SPeter Wemm nis_result *result;
3665c2aa98e2SPeter Wemm
3666c2aa98e2SPeter Wemm if (tTd(38, 20))
366740266059SGregory Neil Shapiro sm_dprintf("nisplus_map_lookup(%s, %s)\n",
3668c2aa98e2SPeter Wemm map->map_mname, name);
3669c2aa98e2SPeter Wemm
3670c2aa98e2SPeter Wemm if (!bitset(MF_OPEN, map->map_mflags))
3671c2aa98e2SPeter Wemm {
3672c2aa98e2SPeter Wemm if (nisplus_map_open(map, O_RDONLY))
3673065a643dSPeter Wemm {
3674c2aa98e2SPeter Wemm map->map_mflags |= MF_OPEN;
367540266059SGregory Neil Shapiro map->map_pid = CurrentPid;
3676065a643dSPeter Wemm }
3677c2aa98e2SPeter Wemm else
3678c2aa98e2SPeter Wemm {
3679c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
3680c2aa98e2SPeter Wemm return NULL;
3681c2aa98e2SPeter Wemm }
3682c2aa98e2SPeter Wemm }
3683c2aa98e2SPeter Wemm
3684c2aa98e2SPeter Wemm /*
3685c2aa98e2SPeter Wemm ** Copy the name to the key buffer, escaping double quote characters
3686c2aa98e2SPeter Wemm ** by doubling them and quoting "]" and "," to avoid having the
3687c2aa98e2SPeter Wemm ** NIS+ parser choke on them.
3688c2aa98e2SPeter Wemm */
3689c2aa98e2SPeter Wemm
3690d0cef73dSGregory Neil Shapiro skleft = sizeof(search_key) - 4;
3691c2aa98e2SPeter Wemm skp = search_key;
3692c2aa98e2SPeter Wemm for (p = name; *p != '\0' && skleft > 0; p++)
3693c2aa98e2SPeter Wemm {
3694c2aa98e2SPeter Wemm switch (*p)
3695c2aa98e2SPeter Wemm {
3696c2aa98e2SPeter Wemm case ']':
3697c2aa98e2SPeter Wemm case ',':
3698c2aa98e2SPeter Wemm /* quote the character */
3699c2aa98e2SPeter Wemm *skp++ = '"';
3700c2aa98e2SPeter Wemm *skp++ = *p;
3701c2aa98e2SPeter Wemm *skp++ = '"';
3702c2aa98e2SPeter Wemm skleft -= 3;
3703c2aa98e2SPeter Wemm break;
3704c2aa98e2SPeter Wemm
3705c2aa98e2SPeter Wemm case '"':
3706c2aa98e2SPeter Wemm /* double the quote */
3707c2aa98e2SPeter Wemm *skp++ = '"';
3708c2aa98e2SPeter Wemm skleft--;
370906f25ae9SGregory Neil Shapiro /* FALLTHROUGH */
3710c2aa98e2SPeter Wemm
3711c2aa98e2SPeter Wemm default:
3712c2aa98e2SPeter Wemm *skp++ = *p;
3713c2aa98e2SPeter Wemm skleft--;
3714c2aa98e2SPeter Wemm break;
3715c2aa98e2SPeter Wemm }
3716c2aa98e2SPeter Wemm }
3717c2aa98e2SPeter Wemm *skp = '\0';
3718c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
37192fb4f839SGregory Neil Shapiro makelower_buf(search_key, search_key, sizeof(search_key));
3720c2aa98e2SPeter Wemm
3721c2aa98e2SPeter Wemm /* construct the query */
3722c2aa98e2SPeter Wemm if (PARTIAL_NAME(map->map_file))
3723d0cef73dSGregory Neil Shapiro (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s.%s",
3724c2aa98e2SPeter Wemm map->map_keycolnm, search_key, map->map_file,
3725c2aa98e2SPeter Wemm map->map_domain);
3726c2aa98e2SPeter Wemm else
3727d0cef73dSGregory Neil Shapiro (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s",
3728c2aa98e2SPeter Wemm map->map_keycolnm, search_key, map->map_file);
3729c2aa98e2SPeter Wemm
3730c2aa98e2SPeter Wemm if (tTd(38, 20))
373140266059SGregory Neil Shapiro sm_dprintf("qbuf=%s\n", qbuf);
3732c2aa98e2SPeter Wemm result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
3733c2aa98e2SPeter Wemm if (result->status == NIS_SUCCESS)
3734c2aa98e2SPeter Wemm {
3735c2aa98e2SPeter Wemm int count;
3736c2aa98e2SPeter Wemm char *str;
3737c2aa98e2SPeter Wemm
3738c2aa98e2SPeter Wemm if ((count = NIS_RES_NUMOBJ(result)) != 1)
3739c2aa98e2SPeter Wemm {
3740c2aa98e2SPeter Wemm if (LogLevel > 10)
3741c2aa98e2SPeter Wemm sm_syslog(LOG_WARNING, CurEnv->e_id,
3742c2aa98e2SPeter Wemm "%s: lookup error, expected 1 entry, got %d",
3743c2aa98e2SPeter Wemm map->map_file, count);
3744c2aa98e2SPeter Wemm
3745c2aa98e2SPeter Wemm /* ignore second entry */
3746c2aa98e2SPeter Wemm if (tTd(38, 20))
374740266059SGregory Neil Shapiro sm_dprintf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n",
3748c2aa98e2SPeter Wemm name, count);
3749c2aa98e2SPeter Wemm }
3750c2aa98e2SPeter Wemm
3751c2aa98e2SPeter Wemm p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno));
3752c2aa98e2SPeter Wemm /* set the length of the result */
3753c2aa98e2SPeter Wemm if (p == NULL)
3754c2aa98e2SPeter Wemm p = "";
3755c2aa98e2SPeter Wemm vsize = strlen(p);
3756c2aa98e2SPeter Wemm if (tTd(38, 20))
375740266059SGregory Neil Shapiro sm_dprintf("nisplus_map_lookup(%s), found %s\n",
3758c2aa98e2SPeter Wemm name, p);
3759c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
3760c2aa98e2SPeter Wemm str = map_rewrite(map, name, strlen(name), NULL);
3761c2aa98e2SPeter Wemm else
3762c2aa98e2SPeter Wemm str = map_rewrite(map, p, vsize, av);
3763c2aa98e2SPeter Wemm nis_freeresult(result);
3764c2aa98e2SPeter Wemm *statp = EX_OK;
3765c2aa98e2SPeter Wemm return str;
3766c2aa98e2SPeter Wemm }
3767c2aa98e2SPeter Wemm else
3768c2aa98e2SPeter Wemm {
3769c2aa98e2SPeter Wemm if (result->status == NIS_NOTFOUND)
3770c2aa98e2SPeter Wemm *statp = EX_NOTFOUND;
3771c2aa98e2SPeter Wemm else if (result->status == NIS_TRYAGAIN)
3772c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
3773c2aa98e2SPeter Wemm else
3774c2aa98e2SPeter Wemm {
3775c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
3776c2aa98e2SPeter Wemm map->map_mflags &= ~(MF_VALID|MF_OPEN);
3777c2aa98e2SPeter Wemm }
3778c2aa98e2SPeter Wemm }
3779c2aa98e2SPeter Wemm if (tTd(38, 20))
378040266059SGregory Neil Shapiro sm_dprintf("nisplus_map_lookup(%s), failed\n", name);
3781c2aa98e2SPeter Wemm nis_freeresult(result);
3782c2aa98e2SPeter Wemm return NULL;
3783c2aa98e2SPeter Wemm }
3784c2aa98e2SPeter Wemm
3785c2aa98e2SPeter Wemm
3786c2aa98e2SPeter Wemm
3787c2aa98e2SPeter Wemm /*
3788c2aa98e2SPeter Wemm ** NISPLUS_GETCANONNAME -- look up canonical name in NIS+
3789c2aa98e2SPeter Wemm */
3790c2aa98e2SPeter Wemm
379106f25ae9SGregory Neil Shapiro static bool
nisplus_getcanonname(name,hbsize,statp)3792c2aa98e2SPeter Wemm nisplus_getcanonname(name, hbsize, statp)
3793c2aa98e2SPeter Wemm char *name;
3794c2aa98e2SPeter Wemm int hbsize;
3795c2aa98e2SPeter Wemm int *statp;
3796c2aa98e2SPeter Wemm {
3797c2aa98e2SPeter Wemm char *vp;
3798c2aa98e2SPeter Wemm auto int vsize;
3799c2aa98e2SPeter Wemm nis_result *result;
3800c2aa98e2SPeter Wemm char *p;
38012fb4f839SGregory Neil Shapiro char nbuf[MAXNAME + 1]; /* EAI:hostname */
38022fb4f839SGregory Neil Shapiro char qbuf[MAXLINE + NIS_MAXNAMELEN]; /* EAI:hostname */
3803c2aa98e2SPeter Wemm
3804d0cef73dSGregory Neil Shapiro if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
3805c2aa98e2SPeter Wemm {
3806c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
380740266059SGregory Neil Shapiro return false;
3808c2aa98e2SPeter Wemm }
3809602a2b1bSGregory Neil Shapiro (void) shorten_hostname(nbuf);
3810c2aa98e2SPeter Wemm
3811c2aa98e2SPeter Wemm p = strchr(nbuf, '.');
3812c2aa98e2SPeter Wemm if (p == NULL)
3813c2aa98e2SPeter Wemm {
3814c2aa98e2SPeter Wemm /* single token */
3815d0cef73dSGregory Neil Shapiro (void) sm_snprintf(qbuf, sizeof(qbuf),
381640266059SGregory Neil Shapiro "[name=%s],hosts.org_dir", nbuf);
3817c2aa98e2SPeter Wemm }
3818c2aa98e2SPeter Wemm else if (p[1] != '\0')
3819c2aa98e2SPeter Wemm {
3820c2aa98e2SPeter Wemm /* multi token -- take only first token in nbuf */
3821c2aa98e2SPeter Wemm *p = '\0';
3822d0cef73dSGregory Neil Shapiro (void) sm_snprintf(qbuf, sizeof(qbuf),
382340266059SGregory Neil Shapiro "[name=%s],hosts.org_dir.%s", nbuf, &p[1]);
3824c2aa98e2SPeter Wemm }
3825c2aa98e2SPeter Wemm else
3826c2aa98e2SPeter Wemm {
3827c2aa98e2SPeter Wemm *statp = EX_NOHOST;
382840266059SGregory Neil Shapiro return false;
3829c2aa98e2SPeter Wemm }
3830c2aa98e2SPeter Wemm
3831c2aa98e2SPeter Wemm if (tTd(38, 20))
3832605302a5SGregory Neil Shapiro sm_dprintf("\nnisplus_getcanonname(%s), qbuf=%s\n",
3833c2aa98e2SPeter Wemm name, qbuf);
3834c2aa98e2SPeter Wemm
3835c2aa98e2SPeter Wemm result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH,
3836c2aa98e2SPeter Wemm NULL, NULL);
3837c2aa98e2SPeter Wemm
3838c2aa98e2SPeter Wemm if (result->status == NIS_SUCCESS)
3839c2aa98e2SPeter Wemm {
3840c2aa98e2SPeter Wemm int count;
3841c2aa98e2SPeter Wemm char *domain;
3842c2aa98e2SPeter Wemm
3843c2aa98e2SPeter Wemm if ((count = NIS_RES_NUMOBJ(result)) != 1)
3844c2aa98e2SPeter Wemm {
3845c2aa98e2SPeter Wemm if (LogLevel > 10)
3846c2aa98e2SPeter Wemm sm_syslog(LOG_WARNING, CurEnv->e_id,
3847c2aa98e2SPeter Wemm "nisplus_getcanonname: lookup error, expected 1 entry, got %d",
3848c2aa98e2SPeter Wemm count);
3849c2aa98e2SPeter Wemm
3850c2aa98e2SPeter Wemm /* ignore second entry */
3851c2aa98e2SPeter Wemm if (tTd(38, 20))
3852605302a5SGregory Neil Shapiro sm_dprintf("nisplus_getcanonname(%s), got %d entries, all but first ignored\n",
3853c2aa98e2SPeter Wemm name, count);
3854c2aa98e2SPeter Wemm }
3855c2aa98e2SPeter Wemm
3856c2aa98e2SPeter Wemm if (tTd(38, 20))
3857605302a5SGregory Neil Shapiro sm_dprintf("nisplus_getcanonname(%s), found in directory \"%s\"\n",
3858c2aa98e2SPeter Wemm name, (NIS_RES_OBJECT(result))->zo_domain);
3859c2aa98e2SPeter Wemm
3860c2aa98e2SPeter Wemm
3861c2aa98e2SPeter Wemm vp = ((NIS_RES_OBJECT(result))->EN_col(0));
3862c2aa98e2SPeter Wemm vsize = strlen(vp);
3863c2aa98e2SPeter Wemm if (tTd(38, 20))
386440266059SGregory Neil Shapiro sm_dprintf("nisplus_getcanonname(%s), found %s\n",
3865c2aa98e2SPeter Wemm name, vp);
3866c2aa98e2SPeter Wemm if (strchr(vp, '.') != NULL)
3867c2aa98e2SPeter Wemm {
3868c2aa98e2SPeter Wemm domain = "";
3869c2aa98e2SPeter Wemm }
3870c2aa98e2SPeter Wemm else
3871c2aa98e2SPeter Wemm {
3872c2aa98e2SPeter Wemm domain = macvalue('m', CurEnv);
3873c2aa98e2SPeter Wemm if (domain == NULL)
3874c2aa98e2SPeter Wemm domain = "";
3875c2aa98e2SPeter Wemm }
3876c2aa98e2SPeter Wemm if (hbsize > vsize + (int) strlen(domain) + 1)
3877c2aa98e2SPeter Wemm {
3878c2aa98e2SPeter Wemm if (domain[0] == '\0')
387940266059SGregory Neil Shapiro (void) sm_strlcpy(name, vp, hbsize);
3880c2aa98e2SPeter Wemm else
388140266059SGregory Neil Shapiro (void) sm_snprintf(name, hbsize,
388240266059SGregory Neil Shapiro "%s.%s", vp, domain);
3883c2aa98e2SPeter Wemm *statp = EX_OK;
3884c2aa98e2SPeter Wemm }
3885c2aa98e2SPeter Wemm else
3886c2aa98e2SPeter Wemm *statp = EX_NOHOST;
3887c2aa98e2SPeter Wemm nis_freeresult(result);
388840266059SGregory Neil Shapiro return true;
3889c2aa98e2SPeter Wemm }
3890c2aa98e2SPeter Wemm else
3891c2aa98e2SPeter Wemm {
3892c2aa98e2SPeter Wemm if (result->status == NIS_NOTFOUND)
3893c2aa98e2SPeter Wemm *statp = EX_NOHOST;
3894c2aa98e2SPeter Wemm else if (result->status == NIS_TRYAGAIN)
3895c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
3896c2aa98e2SPeter Wemm else
3897c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
3898c2aa98e2SPeter Wemm }
3899c2aa98e2SPeter Wemm if (tTd(38, 20))
390040266059SGregory Neil Shapiro sm_dprintf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n",
3901c2aa98e2SPeter Wemm name, result->status, *statp);
3902c2aa98e2SPeter Wemm nis_freeresult(result);
390340266059SGregory Neil Shapiro return false;
3904c2aa98e2SPeter Wemm }
3905c2aa98e2SPeter Wemm
3906c2aa98e2SPeter Wemm char *
nisplus_default_domain()3907c2aa98e2SPeter Wemm nisplus_default_domain()
3908c2aa98e2SPeter Wemm {
39092fb4f839SGregory Neil Shapiro static char default_domain[MAXNAME + 1] = ""; /* EAI:hostname */
3910c2aa98e2SPeter Wemm char *p;
3911c2aa98e2SPeter Wemm
3912c2aa98e2SPeter Wemm if (default_domain[0] != '\0')
391306f25ae9SGregory Neil Shapiro return default_domain;
3914c2aa98e2SPeter Wemm
3915c2aa98e2SPeter Wemm p = nis_local_directory();
3916d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(default_domain, p, sizeof(default_domain));
3917c2aa98e2SPeter Wemm return default_domain;
3918c2aa98e2SPeter Wemm }
3919c2aa98e2SPeter Wemm
3920c2aa98e2SPeter Wemm #endif /* NISPLUS */
392140266059SGregory Neil Shapiro /*
3922c2aa98e2SPeter Wemm ** LDAP Modules
3923c2aa98e2SPeter Wemm */
3924c2aa98e2SPeter Wemm
392506f25ae9SGregory Neil Shapiro /*
392606f25ae9SGregory Neil Shapiro ** LDAPMAP_DEQUOTE - helper routine for ldapmap_parseargs
392706f25ae9SGregory Neil Shapiro */
392806f25ae9SGregory Neil Shapiro
392906f25ae9SGregory Neil Shapiro #if defined(LDAPMAP) || defined(PH_MAP)
393006f25ae9SGregory Neil Shapiro
393140266059SGregory Neil Shapiro # if PH_MAP
393206f25ae9SGregory Neil Shapiro # define ph_map_dequote ldapmap_dequote
39335b0945b5SGregory Neil Shapiro # endif
393406f25ae9SGregory Neil Shapiro
393540266059SGregory Neil Shapiro static char *ldapmap_dequote __P((char *));
393640266059SGregory Neil Shapiro
393740266059SGregory Neil Shapiro static char *
ldapmap_dequote(str)393806f25ae9SGregory Neil Shapiro ldapmap_dequote(str)
393906f25ae9SGregory Neil Shapiro char *str;
394006f25ae9SGregory Neil Shapiro {
394106f25ae9SGregory Neil Shapiro char *p;
394206f25ae9SGregory Neil Shapiro char *start;
394306f25ae9SGregory Neil Shapiro
394406f25ae9SGregory Neil Shapiro if (str == NULL)
394506f25ae9SGregory Neil Shapiro return NULL;
394606f25ae9SGregory Neil Shapiro
394706f25ae9SGregory Neil Shapiro p = str;
394806f25ae9SGregory Neil Shapiro if (*p == '"')
394906f25ae9SGregory Neil Shapiro {
395006f25ae9SGregory Neil Shapiro /* Should probably swallow initial whitespace here */
395106f25ae9SGregory Neil Shapiro start = ++p;
395206f25ae9SGregory Neil Shapiro }
395306f25ae9SGregory Neil Shapiro else
395406f25ae9SGregory Neil Shapiro return str;
395506f25ae9SGregory Neil Shapiro while (*p != '"' && *p != '\0')
395606f25ae9SGregory Neil Shapiro p++;
395706f25ae9SGregory Neil Shapiro if (*p != '\0')
395806f25ae9SGregory Neil Shapiro *p = '\0';
395906f25ae9SGregory Neil Shapiro return start;
396006f25ae9SGregory Neil Shapiro }
396106f25ae9SGregory Neil Shapiro #endif /* defined(LDAPMAP) || defined(PH_MAP) */
396206f25ae9SGregory Neil Shapiro
396340266059SGregory Neil Shapiro #if LDAPMAP
3964c2aa98e2SPeter Wemm
396540266059SGregory Neil Shapiro static SM_LDAP_STRUCT *LDAPDefaults = NULL;
3966c2aa98e2SPeter Wemm
3967c2aa98e2SPeter Wemm /*
396806f25ae9SGregory Neil Shapiro ** LDAPMAP_OPEN -- open LDAP map
3969c2aa98e2SPeter Wemm **
397006f25ae9SGregory Neil Shapiro ** Connect to the LDAP server. Re-use existing connections since a
397106f25ae9SGregory Neil Shapiro ** single server connection to a host (with the same host, port,
397206f25ae9SGregory Neil Shapiro ** bind DN, and secret) can answer queries for multiple maps.
3973c2aa98e2SPeter Wemm */
3974c2aa98e2SPeter Wemm
3975c2aa98e2SPeter Wemm bool
ldapmap_open(map,mode)397606f25ae9SGregory Neil Shapiro ldapmap_open(map, mode)
3977c2aa98e2SPeter Wemm MAP *map;
3978c2aa98e2SPeter Wemm int mode;
3979c2aa98e2SPeter Wemm {
398040266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap;
398106f25ae9SGregory Neil Shapiro STAB *s;
3982e92d3f3fSGregory Neil Shapiro char *id;
398306f25ae9SGregory Neil Shapiro
3984c2aa98e2SPeter Wemm if (tTd(38, 2))
398540266059SGregory Neil Shapiro sm_dprintf("ldapmap_open(%s, %d): ", map->map_mname, mode);
3986c2aa98e2SPeter Wemm
3987d0cef73dSGregory Neil Shapiro # if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \
3988d0cef73dSGregory Neil Shapiro HASLDAPGETALIASBYNAME
3989d0cef73dSGregory Neil Shapiro if (VendorCode == VENDOR_SUN &&
3990d0cef73dSGregory Neil Shapiro strcmp(map->map_mname, "aliases.ldap") == 0)
3991d0cef73dSGregory Neil Shapiro {
3992d0cef73dSGregory Neil Shapiro return true;
3993d0cef73dSGregory Neil Shapiro }
3994d0cef73dSGregory Neil Shapiro # endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */
3995d0cef73dSGregory Neil Shapiro
3996c2aa98e2SPeter Wemm mode &= O_ACCMODE;
399706f25ae9SGregory Neil Shapiro
399806f25ae9SGregory Neil Shapiro /* sendmail doesn't have the ability to write to LDAP (yet) */
3999c2aa98e2SPeter Wemm if (mode != O_RDONLY)
4000c2aa98e2SPeter Wemm {
4001c2aa98e2SPeter Wemm /* issue a pseudo-error message */
400240266059SGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
400340266059SGregory Neil Shapiro return false;
4004c2aa98e2SPeter Wemm }
400506f25ae9SGregory Neil Shapiro
400640266059SGregory Neil Shapiro lmap = (SM_LDAP_STRUCT *) map->map_db1;
400706f25ae9SGregory Neil Shapiro
400806f25ae9SGregory Neil Shapiro s = ldapmap_findconn(lmap);
40098774250cSGregory Neil Shapiro if (s->s_lmap != NULL)
401006f25ae9SGregory Neil Shapiro {
401106f25ae9SGregory Neil Shapiro /* Already have a connection open to this LDAP server */
401240266059SGregory Neil Shapiro lmap->ldap_ld = ((SM_LDAP_STRUCT *)s->s_lmap->map_db1)->ldap_ld;
401340266059SGregory Neil Shapiro lmap->ldap_pid = ((SM_LDAP_STRUCT *)s->s_lmap->map_db1)->ldap_pid;
40148774250cSGregory Neil Shapiro
40158774250cSGregory Neil Shapiro /* Add this map as head of linked list */
40168774250cSGregory Neil Shapiro lmap->ldap_next = s->s_lmap;
40178774250cSGregory Neil Shapiro s->s_lmap = map;
40188774250cSGregory Neil Shapiro
401942e5d165SGregory Neil Shapiro if (tTd(38, 2))
402040266059SGregory Neil Shapiro sm_dprintf("using cached connection\n");
402140266059SGregory Neil Shapiro return true;
4022c2aa98e2SPeter Wemm }
4023c2aa98e2SPeter Wemm
402442e5d165SGregory Neil Shapiro if (tTd(38, 2))
402540266059SGregory Neil Shapiro sm_dprintf("opening new connection\n");
402642e5d165SGregory Neil Shapiro
4027e92d3f3fSGregory Neil Shapiro if (lmap->ldap_host != NULL)
4028e92d3f3fSGregory Neil Shapiro id = lmap->ldap_host;
4029e92d3f3fSGregory Neil Shapiro else if (lmap->ldap_uri != NULL)
4030e92d3f3fSGregory Neil Shapiro id = lmap->ldap_uri;
4031e92d3f3fSGregory Neil Shapiro else
4032e92d3f3fSGregory Neil Shapiro id = "localhost";
4033e92d3f3fSGregory Neil Shapiro
40349bd497b8SGregory Neil Shapiro if (tTd(74, 104))
40359bd497b8SGregory Neil Shapiro {
40369bd497b8SGregory Neil Shapiro extern MAPCLASS NullMapClass;
40379bd497b8SGregory Neil Shapiro
40389bd497b8SGregory Neil Shapiro /* debug mode: don't actually open an LDAP connection */
40399bd497b8SGregory Neil Shapiro map->map_orgclass = map->map_class;
40409bd497b8SGregory Neil Shapiro map->map_class = &NullMapClass;
40419bd497b8SGregory Neil Shapiro map->map_mflags |= MF_OPEN;
40429bd497b8SGregory Neil Shapiro map->map_pid = CurrentPid;
40439bd497b8SGregory Neil Shapiro return true;
40449bd497b8SGregory Neil Shapiro }
40459bd497b8SGregory Neil Shapiro
404606f25ae9SGregory Neil Shapiro /* No connection yet, connect */
404740266059SGregory Neil Shapiro if (!sm_ldap_start(map->map_mname, lmap))
404806f25ae9SGregory Neil Shapiro {
404940266059SGregory Neil Shapiro if (errno == ETIMEDOUT)
405006f25ae9SGregory Neil Shapiro {
405106f25ae9SGregory Neil Shapiro if (LogLevel > 1)
405206f25ae9SGregory Neil Shapiro sm_syslog(LOG_NOTICE, CurEnv->e_id,
4053ba00ec3dSGregory Neil Shapiro "timeout connecting to LDAP server %.100s",
4054e92d3f3fSGregory Neil Shapiro id);
405506f25ae9SGregory Neil Shapiro }
405606f25ae9SGregory Neil Shapiro
405706f25ae9SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
405806f25ae9SGregory Neil Shapiro {
405906f25ae9SGregory Neil Shapiro if (bitset(MF_NODEFER, map->map_mflags))
4060e92d3f3fSGregory Neil Shapiro {
406106f25ae9SGregory Neil Shapiro syserr("%s failed to %s in map %s",
406206f25ae9SGregory Neil Shapiro # if USE_LDAP_INIT
406340266059SGregory Neil Shapiro "ldap_init/ldap_bind",
40645b0945b5SGregory Neil Shapiro # else
406506f25ae9SGregory Neil Shapiro "ldap_open",
40665b0945b5SGregory Neil Shapiro # endif
4067e92d3f3fSGregory Neil Shapiro id, map->map_mname);
4068e92d3f3fSGregory Neil Shapiro }
406906f25ae9SGregory Neil Shapiro else
4070e92d3f3fSGregory Neil Shapiro {
4071605302a5SGregory Neil Shapiro syserr("451 4.3.5 %s failed to %s in map %s",
407206f25ae9SGregory Neil Shapiro # if USE_LDAP_INIT
407340266059SGregory Neil Shapiro "ldap_init/ldap_bind",
40745b0945b5SGregory Neil Shapiro # else
407506f25ae9SGregory Neil Shapiro "ldap_open",
40765b0945b5SGregory Neil Shapiro # endif
4077e92d3f3fSGregory Neil Shapiro id, map->map_mname);
4078e92d3f3fSGregory Neil Shapiro }
407906f25ae9SGregory Neil Shapiro }
408040266059SGregory Neil Shapiro return false;
408106f25ae9SGregory Neil Shapiro }
408206f25ae9SGregory Neil Shapiro
408340266059SGregory Neil Shapiro /* Save connection for reuse */
408440266059SGregory Neil Shapiro s->s_lmap = map;
408540266059SGregory Neil Shapiro return true;
4086c2aa98e2SPeter Wemm }
4087c2aa98e2SPeter Wemm
408806f25ae9SGregory Neil Shapiro /*
408906f25ae9SGregory Neil Shapiro ** LDAPMAP_CLOSE -- close ldap map
409006f25ae9SGregory Neil Shapiro */
409106f25ae9SGregory Neil Shapiro
409206f25ae9SGregory Neil Shapiro void
ldapmap_close(map)409306f25ae9SGregory Neil Shapiro ldapmap_close(map)
4094c2aa98e2SPeter Wemm MAP *map;
4095c2aa98e2SPeter Wemm {
409640266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap;
409706f25ae9SGregory Neil Shapiro STAB *s;
4098c2aa98e2SPeter Wemm
4099c2aa98e2SPeter Wemm if (tTd(38, 2))
410040266059SGregory Neil Shapiro sm_dprintf("ldapmap_close(%s)\n", map->map_mname);
4101c2aa98e2SPeter Wemm
410240266059SGregory Neil Shapiro lmap = (SM_LDAP_STRUCT *) map->map_db1;
4103c2aa98e2SPeter Wemm
410406f25ae9SGregory Neil Shapiro /* Check if already closed */
410506f25ae9SGregory Neil Shapiro if (lmap->ldap_ld == NULL)
410606f25ae9SGregory Neil Shapiro return;
4107c2aa98e2SPeter Wemm
41088774250cSGregory Neil Shapiro /* Close the LDAP connection */
410940266059SGregory Neil Shapiro sm_ldap_close(lmap);
41108774250cSGregory Neil Shapiro
41118774250cSGregory Neil Shapiro /* Mark all the maps that share the connection as closed */
411206f25ae9SGregory Neil Shapiro s = ldapmap_findconn(lmap);
4113c2aa98e2SPeter Wemm
41148774250cSGregory Neil Shapiro while (s->s_lmap != NULL)
4115c2aa98e2SPeter Wemm {
41168774250cSGregory Neil Shapiro MAP *smap = s->s_lmap;
41178774250cSGregory Neil Shapiro
41188774250cSGregory Neil Shapiro if (tTd(38, 2) && smap != map)
411940266059SGregory Neil Shapiro sm_dprintf("ldapmap_close(%s): closed %s (shared LDAP connection)\n",
41208774250cSGregory Neil Shapiro map->map_mname, smap->map_mname);
41218774250cSGregory Neil Shapiro smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
412240266059SGregory Neil Shapiro lmap = (SM_LDAP_STRUCT *) smap->map_db1;
412306f25ae9SGregory Neil Shapiro lmap->ldap_ld = NULL;
41248774250cSGregory Neil Shapiro s->s_lmap = lmap->ldap_next;
41258774250cSGregory Neil Shapiro lmap->ldap_next = NULL;
4126c2aa98e2SPeter Wemm }
4127c2aa98e2SPeter Wemm }
4128c2aa98e2SPeter Wemm
4129c2aa98e2SPeter Wemm # ifdef SUNET_ID
4130c2aa98e2SPeter Wemm /*
413140266059SGregory Neil Shapiro ** SUNET_ID_HASH -- Convert a string to its Sunet_id canonical form
4132c2aa98e2SPeter Wemm ** This only makes sense at Stanford University.
4133c2aa98e2SPeter Wemm */
4134c2aa98e2SPeter Wemm
413540266059SGregory Neil Shapiro static char *
sunet_id_hash(str)4136c2aa98e2SPeter Wemm sunet_id_hash(str)
4137c2aa98e2SPeter Wemm char *str;
4138c2aa98e2SPeter Wemm {
4139c2aa98e2SPeter Wemm char *p, *p_last;
4140c2aa98e2SPeter Wemm
4141c2aa98e2SPeter Wemm p = str;
4142c2aa98e2SPeter Wemm p_last = p;
4143c2aa98e2SPeter Wemm while (*p != '\0')
4144c2aa98e2SPeter Wemm {
41459bd497b8SGregory Neil Shapiro if (isascii(*p) && (islower(*p) || isdigit(*p)))
4146c2aa98e2SPeter Wemm {
4147c2aa98e2SPeter Wemm *p_last = *p;
4148c2aa98e2SPeter Wemm p_last++;
4149c2aa98e2SPeter Wemm }
41509bd497b8SGregory Neil Shapiro else if (isascii(*p) && isupper(*p))
4151c2aa98e2SPeter Wemm {
4152c2aa98e2SPeter Wemm *p_last = tolower(*p);
4153c2aa98e2SPeter Wemm p_last++;
4154c2aa98e2SPeter Wemm }
4155c2aa98e2SPeter Wemm ++p;
4156c2aa98e2SPeter Wemm }
4157c2aa98e2SPeter Wemm if (*p_last != '\0')
4158c2aa98e2SPeter Wemm *p_last = '\0';
415906f25ae9SGregory Neil Shapiro return str;
4160c2aa98e2SPeter Wemm }
4161d0cef73dSGregory Neil Shapiro # define SM_CONVERT_ID(str) sunet_id_hash(str)
4162d0cef73dSGregory Neil Shapiro # else /* SUNET_ID */
4163d0cef73dSGregory Neil Shapiro # define SM_CONVERT_ID(str) makelower(str)
4164c2aa98e2SPeter Wemm # endif /* SUNET_ID */
416506f25ae9SGregory Neil Shapiro
4166c2aa98e2SPeter Wemm /*
416706f25ae9SGregory Neil Shapiro ** LDAPMAP_LOOKUP -- look up a datum in a LDAP map
4168c2aa98e2SPeter Wemm */
4169c2aa98e2SPeter Wemm
4170c2aa98e2SPeter Wemm char *
ldapmap_lookup(map,name,av,statp)417106f25ae9SGregory Neil Shapiro ldapmap_lookup(map, name, av, statp)
4172c2aa98e2SPeter Wemm MAP *map;
4173c2aa98e2SPeter Wemm char *name;
4174c2aa98e2SPeter Wemm char **av;
4175c2aa98e2SPeter Wemm int *statp;
4176c2aa98e2SPeter Wemm {
4177e92d3f3fSGregory Neil Shapiro int flags;
4178d0cef73dSGregory Neil Shapiro int i;
4179605302a5SGregory Neil Shapiro int plen = 0;
4180605302a5SGregory Neil Shapiro int psize = 0;
4181605302a5SGregory Neil Shapiro int msgid;
4182605302a5SGregory Neil Shapiro int save_errno;
418340266059SGregory Neil Shapiro char *vp, *p;
418406f25ae9SGregory Neil Shapiro char *result = NULL;
4185e92d3f3fSGregory Neil Shapiro SM_RPOOL_T *rpool;
418640266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap = NULL;
4187d0cef73dSGregory Neil Shapiro char *argv[SM_LDAP_ARGS];
41884e4196cbSGregory Neil Shapiro char keybuf[MAXKEY];
4189d0cef73dSGregory Neil Shapiro # if SM_LDAP_ARGS != MAX_MAP_ARGS
4190*d39bd2c1SGregory Neil Shapiro # error "SM_LDAP_ARGS must be the same as MAX_MAP_ARGS"
41912fb4f839SGregory Neil Shapiro # endif
41922fb4f839SGregory Neil Shapiro
41932fb4f839SGregory Neil Shapiro # define AV_FREE(av) \
41942fb4f839SGregory Neil Shapiro do \
41952fb4f839SGregory Neil Shapiro { \
41962fb4f839SGregory Neil Shapiro int ai; \
41972fb4f839SGregory Neil Shapiro for (ai = 0; ai < SM_LDAP_ARGS && av[ai] != NULL; ai++) \
41982fb4f839SGregory Neil Shapiro SM_FREE(av[ai]); \
41992fb4f839SGregory Neil Shapiro } while (0)
42002fb4f839SGregory Neil Shapiro
42012fb4f839SGregory Neil Shapiro # if USE_EAI
42022fb4f839SGregory Neil Shapiro bool allascii;
42032fb4f839SGregory Neil Shapiro char *largv[SM_LDAP_ARGS];
42042fb4f839SGregory Neil Shapiro char **largs;
42052fb4f839SGregory Neil Shapiro
42062fb4f839SGregory Neil Shapiro # define LARGV_FREE AV_FREE(largv)
42072fb4f839SGregory Neil Shapiro # else
42082fb4f839SGregory Neil Shapiro # define largs av
42092fb4f839SGregory Neil Shapiro # define LARGV_FREE
42105b0945b5SGregory Neil Shapiro # endif
4211c2aa98e2SPeter Wemm
4212d0cef73dSGregory Neil Shapiro # if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \
4213d0cef73dSGregory Neil Shapiro HASLDAPGETALIASBYNAME
4214d0cef73dSGregory Neil Shapiro if (VendorCode == VENDOR_SUN &&
4215d0cef73dSGregory Neil Shapiro strcmp(map->map_mname, "aliases.ldap") == 0)
4216d0cef73dSGregory Neil Shapiro {
4217d0cef73dSGregory Neil Shapiro int rc;
4218ffb83623SGregory Neil Shapiro # if defined(GETLDAPALIASBYNAME_VERSION) && (GETLDAPALIASBYNAME_VERSION >= 2)
4219ffb83623SGregory Neil Shapiro extern char *__getldapaliasbyname();
4220ffb83623SGregory Neil Shapiro char *answer;
4221ffb83623SGregory Neil Shapiro
4222ffb83623SGregory Neil Shapiro answer = __getldapaliasbyname(name, &rc);
4223ffb83623SGregory Neil Shapiro # else
42242fb4f839SGregory Neil Shapiro char answer[MAXNAME + 1]; /* EAI:Sun only, ignore */
4225d0cef73dSGregory Neil Shapiro
4226d0cef73dSGregory Neil Shapiro rc = __getldapaliasbyname(name, answer, sizeof(answer));
4227ffb83623SGregory Neil Shapiro # endif
4228d0cef73dSGregory Neil Shapiro if (rc != 0)
4229d0cef73dSGregory Neil Shapiro {
4230c2aa98e2SPeter Wemm if (tTd(38, 20))
4231d0cef73dSGregory Neil Shapiro sm_dprintf("getldapaliasbyname(%.100s) failed, errno=%d\n",
4232d0cef73dSGregory Neil Shapiro name, errno);
4233d0cef73dSGregory Neil Shapiro *statp = EX_NOTFOUND;
4234d0cef73dSGregory Neil Shapiro return NULL;
4235d0cef73dSGregory Neil Shapiro }
4236d0cef73dSGregory Neil Shapiro *statp = EX_OK;
4237d0cef73dSGregory Neil Shapiro if (tTd(38, 20))
4238d0cef73dSGregory Neil Shapiro sm_dprintf("getldapaliasbyname(%.100s) => %s\n", name,
4239d0cef73dSGregory Neil Shapiro answer);
4240d0cef73dSGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
4241d0cef73dSGregory Neil Shapiro result = map_rewrite(map, name, strlen(name), NULL);
4242d0cef73dSGregory Neil Shapiro else
4243d0cef73dSGregory Neil Shapiro result = map_rewrite(map, answer, strlen(answer), av);
4244ffb83623SGregory Neil Shapiro # if defined(GETLDAPALIASBYNAME_VERSION) && (GETLDAPALIASBYNAME_VERSION >= 2)
4245ffb83623SGregory Neil Shapiro free(answer);
4246ffb83623SGregory Neil Shapiro # endif
4247d0cef73dSGregory Neil Shapiro return result;
4248d0cef73dSGregory Neil Shapiro }
4249d0cef73dSGregory Neil Shapiro # endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */
4250c2aa98e2SPeter Wemm
4251c2aa98e2SPeter Wemm /* Get ldap struct pointer from map */
425240266059SGregory Neil Shapiro lmap = (SM_LDAP_STRUCT *) map->map_db1;
425340266059SGregory Neil Shapiro sm_ldap_setopts(lmap->ldap_ld, lmap);
4254c2aa98e2SPeter Wemm
42552fb4f839SGregory Neil Shapiro /* initialize first element so AV_FREE can work */
42562fb4f839SGregory Neil Shapiro argv[0] = NULL;
42572fb4f839SGregory Neil Shapiro # if USE_EAI
42582fb4f839SGregory Neil Shapiro largv[0] = NULL;
42592fb4f839SGregory Neil Shapiro # endif
42602fb4f839SGregory Neil Shapiro
4261d0cef73dSGregory Neil Shapiro if (lmap->ldap_multi_args)
426206f25ae9SGregory Neil Shapiro {
4263d0cef73dSGregory Neil Shapiro SM_REQUIRE(av != NULL);
4264d0cef73dSGregory Neil Shapiro memset(argv, '\0', sizeof(argv));
42652fb4f839SGregory Neil Shapiro # if USE_EAI
42662fb4f839SGregory Neil Shapiro largs = av;
42672fb4f839SGregory Neil Shapiro memset(largv, '\0', sizeof(largv));
42682fb4f839SGregory Neil Shapiro
42692fb4f839SGregory Neil Shapiro /* this is ugly - can we merge it with the next loop? */
42702fb4f839SGregory Neil Shapiro allascii = true;
42712fb4f839SGregory Neil Shapiro if (!bitset(MF_MATCHONLY, map->map_mflags))
42722fb4f839SGregory Neil Shapiro {
42732fb4f839SGregory Neil Shapiro for (i = 0, allascii = true;
42742fb4f839SGregory Neil Shapiro i < SM_LDAP_ARGS && av[i] != NULL;
42752fb4f839SGregory Neil Shapiro i++)
42762fb4f839SGregory Neil Shapiro {
42772fb4f839SGregory Neil Shapiro if (!addr_is_ascii(av[i]))
42782fb4f839SGregory Neil Shapiro {
42792fb4f839SGregory Neil Shapiro allascii = false;
42802fb4f839SGregory Neil Shapiro largs = largv;
42812fb4f839SGregory Neil Shapiro break;
42822fb4f839SGregory Neil Shapiro }
42832fb4f839SGregory Neil Shapiro }
42842fb4f839SGregory Neil Shapiro }
42852fb4f839SGregory Neil Shapiro # endif /* USE_EAI */
4286d0cef73dSGregory Neil Shapiro for (i = 0; i < SM_LDAP_ARGS && av[i] != NULL; i++)
4287d0cef73dSGregory Neil Shapiro {
4288d0cef73dSGregory Neil Shapiro argv[i] = sm_strdup(av[i]);
4289d0cef73dSGregory Neil Shapiro if (argv[i] == NULL)
4290d0cef73dSGregory Neil Shapiro {
4291d0cef73dSGregory Neil Shapiro *statp = EX_TEMPFAIL;
42922fb4f839SGregory Neil Shapiro goto none;
429306f25ae9SGregory Neil Shapiro }
4294c2aa98e2SPeter Wemm
4295d0cef73dSGregory Neil Shapiro if (!bitset(MF_NOFOLDCASE, map->map_mflags))
42962fb4f839SGregory Neil Shapiro /* && !bitset(MF_MATCHONLY, map->map_mflags)) */
42972fb4f839SGregory Neil Shapiro /* see below: av[]/largs onluy used if !MF_MATCHONLY !? */
42982fb4f839SGregory Neil Shapiro {
42992fb4f839SGregory Neil Shapiro # if USE_EAI
43002fb4f839SGregory Neil Shapiro if (!allascii)
43012fb4f839SGregory Neil Shapiro {
43022fb4f839SGregory Neil Shapiro char *lower;
43032fb4f839SGregory Neil Shapiro
43042fb4f839SGregory Neil Shapiro lower = makelower(av[i]);
43052fb4f839SGregory Neil Shapiro largv[i] = sm_strdup(lower);
43062fb4f839SGregory Neil Shapiro if (largv[i] == NULL)
43072fb4f839SGregory Neil Shapiro {
43082fb4f839SGregory Neil Shapiro *statp = EX_TEMPFAIL;
43092fb4f839SGregory Neil Shapiro goto none;
43102fb4f839SGregory Neil Shapiro }
43112fb4f839SGregory Neil Shapiro }
43122fb4f839SGregory Neil Shapiro else
43132fb4f839SGregory Neil Shapiro # endif /* USE_EAI */
43142fb4f839SGregory Neil Shapiro /* NOTE: see else above! */
4315d0cef73dSGregory Neil Shapiro SM_CONVERT_ID(av[i]);
4316d0cef73dSGregory Neil Shapiro }
4317d0cef73dSGregory Neil Shapiro }
43182fb4f839SGregory Neil Shapiro }
4319d0cef73dSGregory Neil Shapiro else
4320d0cef73dSGregory Neil Shapiro {
4321d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(keybuf, name, sizeof(keybuf));
4322d0cef73dSGregory Neil Shapiro
4323d0cef73dSGregory Neil Shapiro if (!bitset(MF_NOFOLDCASE, map->map_mflags))
4324d0cef73dSGregory Neil Shapiro SM_CONVERT_ID(keybuf);
4325d0cef73dSGregory Neil Shapiro }
4326d0cef73dSGregory Neil Shapiro
4327d0cef73dSGregory Neil Shapiro if (tTd(38, 20))
4328d0cef73dSGregory Neil Shapiro {
4329d0cef73dSGregory Neil Shapiro if (lmap->ldap_multi_args)
4330d0cef73dSGregory Neil Shapiro {
4331d0cef73dSGregory Neil Shapiro sm_dprintf("ldapmap_lookup(%s, argv)\n",
4332d0cef73dSGregory Neil Shapiro map->map_mname);
4333d0cef73dSGregory Neil Shapiro for (i = 0; i < SM_LDAP_ARGS; i++)
4334d0cef73dSGregory Neil Shapiro {
4335d0cef73dSGregory Neil Shapiro sm_dprintf(" argv[%d] = %s\n", i,
4336d0cef73dSGregory Neil Shapiro argv[i] == NULL ? "NULL" : argv[i]);
4337d0cef73dSGregory Neil Shapiro }
4338d0cef73dSGregory Neil Shapiro }
4339d0cef73dSGregory Neil Shapiro else
4340d0cef73dSGregory Neil Shapiro {
4341d0cef73dSGregory Neil Shapiro sm_dprintf("ldapmap_lookup(%s, %s)\n",
4342d0cef73dSGregory Neil Shapiro map->map_mname, name);
4343d0cef73dSGregory Neil Shapiro }
4344d0cef73dSGregory Neil Shapiro }
4345d0cef73dSGregory Neil Shapiro
4346d0cef73dSGregory Neil Shapiro if (lmap->ldap_multi_args)
4347d0cef73dSGregory Neil Shapiro {
4348d0cef73dSGregory Neil Shapiro msgid = sm_ldap_search_m(lmap, argv);
4349d0cef73dSGregory Neil Shapiro
4350d0cef73dSGregory Neil Shapiro /* free the argv array and its content, no longer needed */
43512fb4f839SGregory Neil Shapiro AV_FREE(argv);
4352d0cef73dSGregory Neil Shapiro }
4353d0cef73dSGregory Neil Shapiro else
435440266059SGregory Neil Shapiro msgid = sm_ldap_search(lmap, keybuf);
4355d0cef73dSGregory Neil Shapiro if (msgid == SM_LDAP_ERR)
4356c2aa98e2SPeter Wemm {
435740266059SGregory Neil Shapiro errno = sm_ldap_geterrno(lmap->ldap_ld) + E_LDAPBASE;
43588774250cSGregory Neil Shapiro save_errno = errno;
4359c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
4360c2aa98e2SPeter Wemm {
4361d0cef73dSGregory Neil Shapiro /*
4362d0cef73dSGregory Neil Shapiro ** Do not include keybuf as this error may be shown
4363d0cef73dSGregory Neil Shapiro ** to outsiders.
4364d0cef73dSGregory Neil Shapiro */
4365d0cef73dSGregory Neil Shapiro
436606f25ae9SGregory Neil Shapiro if (bitset(MF_NODEFER, map->map_mflags))
4367d0cef73dSGregory Neil Shapiro syserr("Error in ldap_search in map %s",
4368d0cef73dSGregory Neil Shapiro map->map_mname);
436906f25ae9SGregory Neil Shapiro else
4370d0cef73dSGregory Neil Shapiro syserr("451 4.3.5 Error in ldap_search in map %s",
4371d0cef73dSGregory Neil Shapiro map->map_mname);
4372c2aa98e2SPeter Wemm }
4373c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
437440266059SGregory Neil Shapiro switch (save_errno - E_LDAPBASE)
43758774250cSGregory Neil Shapiro {
437640266059SGregory Neil Shapiro # ifdef LDAP_SERVER_DOWN
437740266059SGregory Neil Shapiro case LDAP_SERVER_DOWN:
43785b0945b5SGregory Neil Shapiro # endif
437940266059SGregory Neil Shapiro case LDAP_TIMEOUT:
438040266059SGregory Neil Shapiro case LDAP_UNAVAILABLE:
43818774250cSGregory Neil Shapiro /* server disappeared, try reopen on next search */
43828774250cSGregory Neil Shapiro ldapmap_close(map);
438340266059SGregory Neil Shapiro break;
438442e5d165SGregory Neil Shapiro }
43858774250cSGregory Neil Shapiro errno = save_errno;
43862fb4f839SGregory Neil Shapiro goto none;
438706f25ae9SGregory Neil Shapiro }
4388d0cef73dSGregory Neil Shapiro # if SM_LDAP_ERROR_ON_MISSING_ARGS
4389d0cef73dSGregory Neil Shapiro else if (msgid == SM_LDAP_ERR_ARG_MISS)
4390d0cef73dSGregory Neil Shapiro {
4391d0cef73dSGregory Neil Shapiro if (bitset(MF_NODEFER, map->map_mflags))
4392d0cef73dSGregory Neil Shapiro syserr("Error in ldap_search in map %s, too few arguments",
4393d0cef73dSGregory Neil Shapiro map->map_mname);
4394d0cef73dSGregory Neil Shapiro else
4395d0cef73dSGregory Neil Shapiro syserr("554 5.3.5 Error in ldap_search in map %s, too few arguments",
4396d0cef73dSGregory Neil Shapiro map->map_mname);
4397d0cef73dSGregory Neil Shapiro *statp = EX_CONFIG;
43982fb4f839SGregory Neil Shapiro goto none;
4399d0cef73dSGregory Neil Shapiro }
4400d0cef73dSGregory Neil Shapiro # endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */
440106f25ae9SGregory Neil Shapiro
440206f25ae9SGregory Neil Shapiro *statp = EX_NOTFOUND;
440306f25ae9SGregory Neil Shapiro vp = NULL;
440406f25ae9SGregory Neil Shapiro
440540266059SGregory Neil Shapiro flags = 0;
440640266059SGregory Neil Shapiro if (bitset(MF_SINGLEMATCH, map->map_mflags))
440740266059SGregory Neil Shapiro flags |= SM_LDAP_SINGLEMATCH;
440840266059SGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
440940266059SGregory Neil Shapiro flags |= SM_LDAP_MATCHONLY;
44104e4196cbSGregory Neil Shapiro # if _FFR_LDAP_SINGLEDN
44114e4196cbSGregory Neil Shapiro if (bitset(MF_SINGLEDN, map->map_mflags))
44124e4196cbSGregory Neil Shapiro flags |= SM_LDAP_SINGLEDN;
44135b0945b5SGregory Neil Shapiro # endif
441440266059SGregory Neil Shapiro
441540266059SGregory Neil Shapiro /* Create an rpool for search related memory usage */
441640266059SGregory Neil Shapiro rpool = sm_rpool_new_x(NULL);
441740266059SGregory Neil Shapiro
441840266059SGregory Neil Shapiro p = NULL;
441940266059SGregory Neil Shapiro *statp = sm_ldap_results(lmap, msgid, flags, map->map_coldelim,
4420605302a5SGregory Neil Shapiro rpool, &p, &plen, &psize, NULL);
442140266059SGregory Neil Shapiro save_errno = errno;
442240266059SGregory Neil Shapiro
442340266059SGregory Neil Shapiro /* Copy result so rpool can be freed */
442440266059SGregory Neil Shapiro if (*statp == EX_OK && p != NULL)
442540266059SGregory Neil Shapiro vp = newstr(p);
442640266059SGregory Neil Shapiro sm_rpool_free(rpool);
442740266059SGregory Neil Shapiro
442840266059SGregory Neil Shapiro /* need to restart LDAP connection? */
442940266059SGregory Neil Shapiro if (*statp == EX_RESTART)
443040266059SGregory Neil Shapiro {
443140266059SGregory Neil Shapiro *statp = EX_TEMPFAIL;
443240266059SGregory Neil Shapiro ldapmap_close(map);
443340266059SGregory Neil Shapiro }
443440266059SGregory Neil Shapiro
443540266059SGregory Neil Shapiro errno = save_errno;
443640266059SGregory Neil Shapiro if (*statp != EX_OK && *statp != EX_NOTFOUND)
443740266059SGregory Neil Shapiro {
443840266059SGregory Neil Shapiro if (!bitset(MF_OPTIONAL, map->map_mflags))
443940266059SGregory Neil Shapiro {
444040266059SGregory Neil Shapiro if (bitset(MF_NODEFER, map->map_mflags))
4441ba00ec3dSGregory Neil Shapiro syserr("Error getting LDAP results, map=%s, name=%s",
4442ba00ec3dSGregory Neil Shapiro map->map_mname, name);
444340266059SGregory Neil Shapiro else
4444ba00ec3dSGregory Neil Shapiro syserr("451 4.3.5 Error getting LDAP results, map=%s, name=%s",
4445ba00ec3dSGregory Neil Shapiro map->map_mname, name);
444640266059SGregory Neil Shapiro }
444740266059SGregory Neil Shapiro errno = save_errno;
44482fb4f839SGregory Neil Shapiro goto none;
444940266059SGregory Neil Shapiro }
445040266059SGregory Neil Shapiro
445106f25ae9SGregory Neil Shapiro /* Did we match anything? */
4452193538b7SGregory Neil Shapiro if (vp == NULL && !bitset(MF_MATCHONLY, map->map_mflags))
44532fb4f839SGregory Neil Shapiro goto none;
445406f25ae9SGregory Neil Shapiro
445506f25ae9SGregory Neil Shapiro if (*statp == EX_OK)
445606f25ae9SGregory Neil Shapiro {
4457c2aa98e2SPeter Wemm if (LogLevel > 9)
4458c2aa98e2SPeter Wemm sm_syslog(LOG_INFO, CurEnv->e_id,
4459ba00ec3dSGregory Neil Shapiro "ldap=%s, %.100s=>%s", map->map_mname, name,
4460193538b7SGregory Neil Shapiro vp == NULL ? "<NULL>" : vp);
4461c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
4462c2aa98e2SPeter Wemm result = map_rewrite(map, name, strlen(name), NULL);
4463c2aa98e2SPeter Wemm else
4464193538b7SGregory Neil Shapiro {
4465193538b7SGregory Neil Shapiro /* vp != NULL according to test above */
44662fb4f839SGregory Neil Shapiro result = map_rewrite(map, vp, strlen(vp), largs);
4467193538b7SGregory Neil Shapiro }
44682fb4f839SGregory Neil Shapiro SM_FREE(vp); /* XXX */
446906f25ae9SGregory Neil Shapiro }
44702fb4f839SGregory Neil Shapiro LARGV_FREE;
4471c2aa98e2SPeter Wemm return result;
44722fb4f839SGregory Neil Shapiro
44732fb4f839SGregory Neil Shapiro none:
44742fb4f839SGregory Neil Shapiro /* other cleanup? */
44752fb4f839SGregory Neil Shapiro save_errno = errno;
44762fb4f839SGregory Neil Shapiro AV_FREE(argv);
44772fb4f839SGregory Neil Shapiro LARGV_FREE;
44782fb4f839SGregory Neil Shapiro errno = save_errno;
44792fb4f839SGregory Neil Shapiro return NULL;
4480c2aa98e2SPeter Wemm }
4481c2aa98e2SPeter Wemm
4482c2aa98e2SPeter Wemm /*
448306f25ae9SGregory Neil Shapiro ** LDAPMAP_FINDCONN -- find an LDAP connection to the server
448406f25ae9SGregory Neil Shapiro **
448506f25ae9SGregory Neil Shapiro ** Cache LDAP connections based on the host, port, bind DN,
448642e5d165SGregory Neil Shapiro ** secret, and PID so we don't have multiple connections open to
448742e5d165SGregory Neil Shapiro ** the same server for different maps. Need a separate connection
448842e5d165SGregory Neil Shapiro ** per PID since a parent process may close the map before the
448942e5d165SGregory Neil Shapiro ** child is done with it.
449006f25ae9SGregory Neil Shapiro **
449106f25ae9SGregory Neil Shapiro ** Parameters:
449206f25ae9SGregory Neil Shapiro ** lmap -- LDAP map information
449306f25ae9SGregory Neil Shapiro **
449406f25ae9SGregory Neil Shapiro ** Returns:
449506f25ae9SGregory Neil Shapiro ** Symbol table entry for the LDAP connection.
4496c2aa98e2SPeter Wemm */
4497c2aa98e2SPeter Wemm
449806f25ae9SGregory Neil Shapiro static STAB *
ldapmap_findconn(lmap)449906f25ae9SGregory Neil Shapiro ldapmap_findconn(lmap)
450040266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap;
4501c2aa98e2SPeter Wemm {
4502605302a5SGregory Neil Shapiro char *format;
450306f25ae9SGregory Neil Shapiro char *nbuf;
4504e92d3f3fSGregory Neil Shapiro char *id;
450540266059SGregory Neil Shapiro STAB *SM_NONVOLATILE s = NULL;
4506c2aa98e2SPeter Wemm
4507e92d3f3fSGregory Neil Shapiro if (lmap->ldap_host != NULL)
4508e92d3f3fSGregory Neil Shapiro id = lmap->ldap_host;
4509e92d3f3fSGregory Neil Shapiro else if (lmap->ldap_uri != NULL)
4510e92d3f3fSGregory Neil Shapiro id = lmap->ldap_uri;
4511e92d3f3fSGregory Neil Shapiro else
4512e92d3f3fSGregory Neil Shapiro id = "localhost";
4513e92d3f3fSGregory Neil Shapiro
4514605302a5SGregory Neil Shapiro format = "%s%c%d%c%d%c%s%c%s%d";
4515605302a5SGregory Neil Shapiro nbuf = sm_stringf_x(format,
4516e92d3f3fSGregory Neil Shapiro id,
451706f25ae9SGregory Neil Shapiro CONDELSE,
451806f25ae9SGregory Neil Shapiro lmap->ldap_port,
451906f25ae9SGregory Neil Shapiro CONDELSE,
4520605302a5SGregory Neil Shapiro lmap->ldap_version,
4521605302a5SGregory Neil Shapiro CONDELSE,
452240266059SGregory Neil Shapiro (lmap->ldap_binddn == NULL ? ""
452340266059SGregory Neil Shapiro : lmap->ldap_binddn),
452406f25ae9SGregory Neil Shapiro CONDELSE,
452540266059SGregory Neil Shapiro (lmap->ldap_secret == NULL ? ""
452640266059SGregory Neil Shapiro : lmap->ldap_secret),
452740266059SGregory Neil Shapiro (int) CurrentPid);
452840266059SGregory Neil Shapiro SM_TRY
45298774250cSGregory Neil Shapiro s = stab(nbuf, ST_LMAP, ST_ENTER);
453040266059SGregory Neil Shapiro SM_FINALLY
45318774250cSGregory Neil Shapiro sm_free(nbuf);
453240266059SGregory Neil Shapiro SM_END_TRY
453306f25ae9SGregory Neil Shapiro return s;
4534c2aa98e2SPeter Wemm }
453506f25ae9SGregory Neil Shapiro /*
453606f25ae9SGregory Neil Shapiro ** LDAPMAP_PARSEARGS -- parse ldap map definition args.
453706f25ae9SGregory Neil Shapiro */
453806f25ae9SGregory Neil Shapiro
453940266059SGregory Neil Shapiro static struct lamvalues LDAPAuthMethods[] =
454006f25ae9SGregory Neil Shapiro {
454106f25ae9SGregory Neil Shapiro { "none", LDAP_AUTH_NONE },
454206f25ae9SGregory Neil Shapiro { "simple", LDAP_AUTH_SIMPLE },
454306f25ae9SGregory Neil Shapiro # ifdef LDAP_AUTH_KRBV4
454406f25ae9SGregory Neil Shapiro { "krbv4", LDAP_AUTH_KRBV4 },
45455b0945b5SGregory Neil Shapiro # endif
454606f25ae9SGregory Neil Shapiro { NULL, 0 }
454706f25ae9SGregory Neil Shapiro };
454806f25ae9SGregory Neil Shapiro
454940266059SGregory Neil Shapiro static struct ladvalues LDAPAliasDereference[] =
455006f25ae9SGregory Neil Shapiro {
455106f25ae9SGregory Neil Shapiro { "never", LDAP_DEREF_NEVER },
455206f25ae9SGregory Neil Shapiro { "always", LDAP_DEREF_ALWAYS },
455306f25ae9SGregory Neil Shapiro { "search", LDAP_DEREF_SEARCHING },
455406f25ae9SGregory Neil Shapiro { "find", LDAP_DEREF_FINDING },
455506f25ae9SGregory Neil Shapiro { NULL, 0 }
455606f25ae9SGregory Neil Shapiro };
455706f25ae9SGregory Neil Shapiro
455840266059SGregory Neil Shapiro static struct lssvalues LDAPSearchScope[] =
455906f25ae9SGregory Neil Shapiro {
456006f25ae9SGregory Neil Shapiro { "base", LDAP_SCOPE_BASE },
456106f25ae9SGregory Neil Shapiro { "one", LDAP_SCOPE_ONELEVEL },
456206f25ae9SGregory Neil Shapiro { "sub", LDAP_SCOPE_SUBTREE },
456306f25ae9SGregory Neil Shapiro { NULL, 0 }
456406f25ae9SGregory Neil Shapiro };
456506f25ae9SGregory Neil Shapiro
456606f25ae9SGregory Neil Shapiro bool
ldapmap_parseargs(map,args)456706f25ae9SGregory Neil Shapiro ldapmap_parseargs(map, args)
456806f25ae9SGregory Neil Shapiro MAP *map;
456906f25ae9SGregory Neil Shapiro char *args;
457006f25ae9SGregory Neil Shapiro {
457140266059SGregory Neil Shapiro bool secretread = true;
4572e92d3f3fSGregory Neil Shapiro bool attrssetup = false;
457306f25ae9SGregory Neil Shapiro int i;
4574c2aa98e2SPeter Wemm register char *p = args;
457540266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap;
45762fb4f839SGregory Neil Shapiro SM_LDAP_STRUCT *lmap_alloc;
457706f25ae9SGregory Neil Shapiro struct lamvalues *lam;
457806f25ae9SGregory Neil Shapiro struct ladvalues *lad;
457906f25ae9SGregory Neil Shapiro struct lssvalues *lss;
458040266059SGregory Neil Shapiro char ldapfilt[MAXLINE];
458106f25ae9SGregory Neil Shapiro char m_tmp[MAXPATHLEN + LDAPMAP_MAX_PASSWD];
458206f25ae9SGregory Neil Shapiro
458306f25ae9SGregory Neil Shapiro /* Get ldap struct pointer from map */
458440266059SGregory Neil Shapiro lmap = (SM_LDAP_STRUCT *) map->map_db1;
458506f25ae9SGregory Neil Shapiro
458606f25ae9SGregory Neil Shapiro /* Check if setting the initial LDAP defaults */
458706f25ae9SGregory Neil Shapiro if (lmap == NULL || lmap != LDAPDefaults)
458806f25ae9SGregory Neil Shapiro {
458940266059SGregory Neil Shapiro /* We need to alloc an SM_LDAP_STRUCT struct */
45902fb4f839SGregory Neil Shapiro lmap_alloc = lmap = (SM_LDAP_STRUCT *) xalloc(sizeof(*lmap));
459106f25ae9SGregory Neil Shapiro if (LDAPDefaults == NULL)
459240266059SGregory Neil Shapiro sm_ldap_clear(lmap);
459306f25ae9SGregory Neil Shapiro else
459406f25ae9SGregory Neil Shapiro STRUCTCOPY(*LDAPDefaults, *lmap);
459506f25ae9SGregory Neil Shapiro }
45962fb4f839SGregory Neil Shapiro else
45972fb4f839SGregory Neil Shapiro lmap_alloc = NULL;
459806f25ae9SGregory Neil Shapiro
459906f25ae9SGregory Neil Shapiro /* there is no check whether there is really an argument */
460006f25ae9SGregory Neil Shapiro map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
460106f25ae9SGregory Neil Shapiro map->map_spacesub = SpaceSub; /* default value */
460240266059SGregory Neil Shapiro
460340266059SGregory Neil Shapiro /* Check if setting up an alias or file class LDAP map */
460440266059SGregory Neil Shapiro if (bitset(MF_ALIAS, map->map_mflags))
460540266059SGregory Neil Shapiro {
460640266059SGregory Neil Shapiro /* Comma separate if used as an alias file */
460740266059SGregory Neil Shapiro map->map_coldelim = ',';
460840266059SGregory Neil Shapiro if (*args == '\0')
460940266059SGregory Neil Shapiro {
461040266059SGregory Neil Shapiro int n;
461140266059SGregory Neil Shapiro char *lc;
461240266059SGregory Neil Shapiro char jbuf[MAXHOSTNAMELEN];
461340266059SGregory Neil Shapiro char lcbuf[MAXLINE];
461440266059SGregory Neil Shapiro
461540266059SGregory Neil Shapiro /* Get $j */
4616d0cef73dSGregory Neil Shapiro expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope);
461740266059SGregory Neil Shapiro if (jbuf[0] == '\0')
461840266059SGregory Neil Shapiro {
461940266059SGregory Neil Shapiro (void) sm_strlcpy(jbuf, "localhost",
4620d0cef73dSGregory Neil Shapiro sizeof(jbuf));
462140266059SGregory Neil Shapiro }
462240266059SGregory Neil Shapiro
462340266059SGregory Neil Shapiro lc = macvalue(macid("{sendmailMTACluster}"), CurEnv);
462440266059SGregory Neil Shapiro if (lc == NULL)
462540266059SGregory Neil Shapiro lc = "";
462640266059SGregory Neil Shapiro else
462740266059SGregory Neil Shapiro {
4628d0cef73dSGregory Neil Shapiro expand(lc, lcbuf, sizeof(lcbuf), CurEnv);
462940266059SGregory Neil Shapiro lc = lcbuf;
463040266059SGregory Neil Shapiro }
463140266059SGregory Neil Shapiro
4632d0cef73dSGregory Neil Shapiro n = sm_snprintf(ldapfilt, sizeof(ldapfilt),
463340266059SGregory Neil Shapiro "(&(objectClass=sendmailMTAAliasObject)(sendmailMTAAliasGrouping=aliases)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))(sendmailMTAKey=%%0))",
463440266059SGregory Neil Shapiro lc, jbuf);
4635d0cef73dSGregory Neil Shapiro if (n >= sizeof(ldapfilt))
463640266059SGregory Neil Shapiro {
463740266059SGregory Neil Shapiro syserr("%s: Default LDAP string too long",
463840266059SGregory Neil Shapiro map->map_mname);
46392fb4f839SGregory Neil Shapiro goto fail;
464040266059SGregory Neil Shapiro }
464140266059SGregory Neil Shapiro
464240266059SGregory Neil Shapiro /* default args for an alias LDAP entry */
464340266059SGregory Neil Shapiro lmap->ldap_filter = ldapfilt;
4644e92d3f3fSGregory Neil Shapiro lmap->ldap_attr[0] = "objectClass";
4645e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_type[0] = SM_LDAP_ATTR_OBJCLASS;
4646e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_needobjclass[0] = NULL;
4647e92d3f3fSGregory Neil Shapiro lmap->ldap_attr[1] = "sendmailMTAAliasValue";
4648e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_type[1] = SM_LDAP_ATTR_NORMAL;
4649e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_needobjclass[1] = NULL;
4650e92d3f3fSGregory Neil Shapiro lmap->ldap_attr[2] = "sendmailMTAAliasSearch";
4651e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_type[2] = SM_LDAP_ATTR_FILTER;
4652e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_needobjclass[2] = "sendmailMTAMapObject";
4653e92d3f3fSGregory Neil Shapiro lmap->ldap_attr[3] = "sendmailMTAAliasURL";
4654e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_type[3] = SM_LDAP_ATTR_URL;
4655e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_needobjclass[3] = "sendmailMTAMapObject";
4656e92d3f3fSGregory Neil Shapiro lmap->ldap_attr[4] = NULL;
4657e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_type[4] = SM_LDAP_ATTR_NONE;
4658e92d3f3fSGregory Neil Shapiro lmap->ldap_attr_needobjclass[4] = NULL;
4659e92d3f3fSGregory Neil Shapiro attrssetup = true;
466040266059SGregory Neil Shapiro }
466140266059SGregory Neil Shapiro }
466240266059SGregory Neil Shapiro else if (bitset(MF_FILECLASS, map->map_mflags))
466340266059SGregory Neil Shapiro {
466440266059SGregory Neil Shapiro /* Space separate if used as a file class file */
466540266059SGregory Neil Shapiro map->map_coldelim = ' ';
466640266059SGregory Neil Shapiro }
466740266059SGregory Neil Shapiro
46685b0945b5SGregory Neil Shapiro # if LDAP_NETWORK_TIMEOUT
46695b0945b5SGregory Neil Shapiro if (0 == lmap->ldap_networktmo)
46705b0945b5SGregory Neil Shapiro lmap->ldap_networktmo = (LDAP_NETWORK_TIMEOUT > 1)
46715b0945b5SGregory Neil Shapiro ? LDAP_NETWORK_TIMEOUT : 60;
46725b0945b5SGregory Neil Shapiro # endif
46739bd497b8SGregory Neil Shapiro
467406f25ae9SGregory Neil Shapiro for (;;)
467506f25ae9SGregory Neil Shapiro {
46765b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
467706f25ae9SGregory Neil Shapiro p++;
467806f25ae9SGregory Neil Shapiro if (*p != '-')
467906f25ae9SGregory Neil Shapiro break;
468006f25ae9SGregory Neil Shapiro switch (*++p)
468106f25ae9SGregory Neil Shapiro {
4682ffb83623SGregory Neil Shapiro case 'A':
4683ffb83623SGregory Neil Shapiro map->map_mflags |= MF_APPEND;
4684ffb83623SGregory Neil Shapiro break;
4685ffb83623SGregory Neil Shapiro
4686ffb83623SGregory Neil Shapiro case 'a':
4687ffb83623SGregory Neil Shapiro map->map_app = ++p;
4688ffb83623SGregory Neil Shapiro break;
4689ffb83623SGregory Neil Shapiro
4690ffb83623SGregory Neil Shapiro case 'D':
4691ffb83623SGregory Neil Shapiro map->map_mflags |= MF_DEFER;
4692ffb83623SGregory Neil Shapiro break;
4693ffb83623SGregory Neil Shapiro
4694ffb83623SGregory Neil Shapiro case 'f':
4695ffb83623SGregory Neil Shapiro map->map_mflags |= MF_NOFOLDCASE;
4696ffb83623SGregory Neil Shapiro break;
4697ffb83623SGregory Neil Shapiro
4698ffb83623SGregory Neil Shapiro case 'm':
4699ffb83623SGregory Neil Shapiro map->map_mflags |= MF_MATCHONLY;
4700ffb83623SGregory Neil Shapiro break;
4701ffb83623SGregory Neil Shapiro
470206f25ae9SGregory Neil Shapiro case 'N':
470306f25ae9SGregory Neil Shapiro map->map_mflags |= MF_INCLNULL;
470406f25ae9SGregory Neil Shapiro map->map_mflags &= ~MF_TRY0NULL;
470506f25ae9SGregory Neil Shapiro break;
470606f25ae9SGregory Neil Shapiro
470706f25ae9SGregory Neil Shapiro case 'O':
470806f25ae9SGregory Neil Shapiro map->map_mflags &= ~MF_TRY1NULL;
470906f25ae9SGregory Neil Shapiro break;
471006f25ae9SGregory Neil Shapiro
471106f25ae9SGregory Neil Shapiro case 'o':
471206f25ae9SGregory Neil Shapiro map->map_mflags |= MF_OPTIONAL;
471306f25ae9SGregory Neil Shapiro break;
471406f25ae9SGregory Neil Shapiro
471506f25ae9SGregory Neil Shapiro case 'q':
471606f25ae9SGregory Neil Shapiro map->map_mflags |= MF_KEEPQUOTES;
471706f25ae9SGregory Neil Shapiro break;
471806f25ae9SGregory Neil Shapiro
4719ffb83623SGregory Neil Shapiro case 'S':
4720ffb83623SGregory Neil Shapiro map->map_spacesub = *++p;
472106f25ae9SGregory Neil Shapiro break;
472206f25ae9SGregory Neil Shapiro
472306f25ae9SGregory Neil Shapiro case 'T':
472406f25ae9SGregory Neil Shapiro map->map_tapp = ++p;
472506f25ae9SGregory Neil Shapiro break;
472606f25ae9SGregory Neil Shapiro
472706f25ae9SGregory Neil Shapiro case 't':
472806f25ae9SGregory Neil Shapiro map->map_mflags |= MF_NODEFER;
472906f25ae9SGregory Neil Shapiro break;
473006f25ae9SGregory Neil Shapiro
473106f25ae9SGregory Neil Shapiro case 'z':
473206f25ae9SGregory Neil Shapiro if (*++p != '\\')
473306f25ae9SGregory Neil Shapiro map->map_coldelim = *p;
473406f25ae9SGregory Neil Shapiro else
473506f25ae9SGregory Neil Shapiro {
473606f25ae9SGregory Neil Shapiro switch (*++p)
473706f25ae9SGregory Neil Shapiro {
473806f25ae9SGregory Neil Shapiro case 'n':
473906f25ae9SGregory Neil Shapiro map->map_coldelim = '\n';
474006f25ae9SGregory Neil Shapiro break;
474106f25ae9SGregory Neil Shapiro
474206f25ae9SGregory Neil Shapiro case 't':
474306f25ae9SGregory Neil Shapiro map->map_coldelim = '\t';
474406f25ae9SGregory Neil Shapiro break;
474506f25ae9SGregory Neil Shapiro
474606f25ae9SGregory Neil Shapiro default:
474706f25ae9SGregory Neil Shapiro map->map_coldelim = '\\';
474806f25ae9SGregory Neil Shapiro }
474906f25ae9SGregory Neil Shapiro }
475006f25ae9SGregory Neil Shapiro break;
475106f25ae9SGregory Neil Shapiro
475206f25ae9SGregory Neil Shapiro /* Start of ldapmap specific args */
475306f25ae9SGregory Neil Shapiro case '1':
475406f25ae9SGregory Neil Shapiro map->map_mflags |= MF_SINGLEMATCH;
475506f25ae9SGregory Neil Shapiro break;
475606f25ae9SGregory Neil Shapiro
47574e4196cbSGregory Neil Shapiro # if _FFR_LDAP_SINGLEDN
47584e4196cbSGregory Neil Shapiro case '2':
47594e4196cbSGregory Neil Shapiro map->map_mflags |= MF_SINGLEDN;
47604e4196cbSGregory Neil Shapiro break;
47614e4196cbSGregory Neil Shapiro # endif /* _FFR_LDAP_SINGLEDN */
47624e4196cbSGregory Neil Shapiro
4763ffb83623SGregory Neil Shapiro case 'b': /* search base */
4764ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4765ffb83623SGregory Neil Shapiro continue;
4766ffb83623SGregory Neil Shapiro lmap->ldap_base = p;
4767ffb83623SGregory Neil Shapiro break;
4768ffb83623SGregory Neil Shapiro
47695b0945b5SGregory Neil Shapiro # if LDAP_NETWORK_TIMEOUT
4770ffb83623SGregory Neil Shapiro case 'c': /* network (connect) timeout */
4771ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4772ffb83623SGregory Neil Shapiro continue;
47739bd497b8SGregory Neil Shapiro lmap->ldap_networktmo = atoi(p);
4774ffb83623SGregory Neil Shapiro break;
47755b0945b5SGregory Neil Shapiro # endif /* LDAP_NETWORK_TIMEOUT */
4776ffb83623SGregory Neil Shapiro
4777ffb83623SGregory Neil Shapiro case 'd': /* Dn to bind to server as */
4778ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4779ffb83623SGregory Neil Shapiro continue;
4780ffb83623SGregory Neil Shapiro lmap->ldap_binddn = p;
4781ffb83623SGregory Neil Shapiro break;
4782ffb83623SGregory Neil Shapiro
4783ffb83623SGregory Neil Shapiro case 'H': /* Use LDAP URI */
4784ffb83623SGregory Neil Shapiro # if !USE_LDAP_INIT
4785ffb83623SGregory Neil Shapiro syserr("Must compile with -DUSE_LDAP_INIT to use LDAP URIs (-H) in map %s",
4786ffb83623SGregory Neil Shapiro map->map_mname);
47872fb4f839SGregory Neil Shapiro goto fail;
4788ffb83623SGregory Neil Shapiro # else /* !USE_LDAP_INIT */
4789ffb83623SGregory Neil Shapiro if (lmap->ldap_host != NULL)
4790ffb83623SGregory Neil Shapiro {
4791ffb83623SGregory Neil Shapiro syserr("Can not specify both an LDAP host and an LDAP URI in map %s",
4792ffb83623SGregory Neil Shapiro map->map_mname);
47932fb4f839SGregory Neil Shapiro goto fail;
4794ffb83623SGregory Neil Shapiro }
4795ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4796ffb83623SGregory Neil Shapiro continue;
4797ffb83623SGregory Neil Shapiro lmap->ldap_uri = p;
4798ffb83623SGregory Neil Shapiro break;
4799ffb83623SGregory Neil Shapiro # endif /* !USE_LDAP_INIT */
4800ffb83623SGregory Neil Shapiro
4801ffb83623SGregory Neil Shapiro case 'h': /* ldap host */
4802ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4803ffb83623SGregory Neil Shapiro continue;
4804ffb83623SGregory Neil Shapiro if (lmap->ldap_uri != NULL)
4805ffb83623SGregory Neil Shapiro {
4806ffb83623SGregory Neil Shapiro syserr("Can not specify both an LDAP host and an LDAP URI in map %s",
4807ffb83623SGregory Neil Shapiro map->map_mname);
48082fb4f839SGregory Neil Shapiro goto fail;
4809ffb83623SGregory Neil Shapiro }
4810ffb83623SGregory Neil Shapiro lmap->ldap_host = p;
4811ffb83623SGregory Neil Shapiro break;
4812ffb83623SGregory Neil Shapiro
4813ffb83623SGregory Neil Shapiro case 'K':
4814ffb83623SGregory Neil Shapiro lmap->ldap_multi_args = true;
4815ffb83623SGregory Neil Shapiro break;
4816ffb83623SGregory Neil Shapiro
4817ffb83623SGregory Neil Shapiro case 'k': /* search field */
4818ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4819ffb83623SGregory Neil Shapiro continue;
4820ffb83623SGregory Neil Shapiro lmap->ldap_filter = p;
4821ffb83623SGregory Neil Shapiro break;
4822ffb83623SGregory Neil Shapiro
4823ffb83623SGregory Neil Shapiro case 'l': /* time limit */
4824ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4825ffb83623SGregory Neil Shapiro continue;
4826ffb83623SGregory Neil Shapiro lmap->ldap_timelimit = atoi(p);
4827ffb83623SGregory Neil Shapiro lmap->ldap_timeout.tv_sec = lmap->ldap_timelimit;
4828ffb83623SGregory Neil Shapiro break;
4829ffb83623SGregory Neil Shapiro
4830ffb83623SGregory Neil Shapiro case 'M': /* Method for binding */
4831ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4832ffb83623SGregory Neil Shapiro continue;
4833ffb83623SGregory Neil Shapiro
4834ffb83623SGregory Neil Shapiro if (sm_strncasecmp(p, "LDAP_AUTH_", 10) == 0)
4835ffb83623SGregory Neil Shapiro p += 10;
4836ffb83623SGregory Neil Shapiro
4837ffb83623SGregory Neil Shapiro for (lam = LDAPAuthMethods;
4838ffb83623SGregory Neil Shapiro lam != NULL && lam->lam_name != NULL; lam++)
4839ffb83623SGregory Neil Shapiro {
4840ffb83623SGregory Neil Shapiro if (sm_strncasecmp(p, lam->lam_name,
4841ffb83623SGregory Neil Shapiro strlen(lam->lam_name)) == 0)
4842ffb83623SGregory Neil Shapiro break;
4843ffb83623SGregory Neil Shapiro }
4844ffb83623SGregory Neil Shapiro if (lam->lam_name != NULL)
4845ffb83623SGregory Neil Shapiro lmap->ldap_method = lam->lam_code;
4846ffb83623SGregory Neil Shapiro else
4847ffb83623SGregory Neil Shapiro {
4848ffb83623SGregory Neil Shapiro /* bad config line */
4849ffb83623SGregory Neil Shapiro if (!bitset(MCF_OPTFILE,
4850ffb83623SGregory Neil Shapiro map->map_class->map_cflags))
4851ffb83623SGregory Neil Shapiro {
4852ffb83623SGregory Neil Shapiro char *ptr;
4853ffb83623SGregory Neil Shapiro
4854ffb83623SGregory Neil Shapiro if ((ptr = strchr(p, ' ')) != NULL)
4855ffb83623SGregory Neil Shapiro *ptr = '\0';
4856ffb83623SGregory Neil Shapiro syserr("Method for binding must be [none|simple|krbv4] (not %s) in map %s",
4857ffb83623SGregory Neil Shapiro p, map->map_mname);
4858ffb83623SGregory Neil Shapiro if (ptr != NULL)
4859ffb83623SGregory Neil Shapiro *ptr = ' ';
48602fb4f839SGregory Neil Shapiro goto fail;
4861ffb83623SGregory Neil Shapiro }
4862ffb83623SGregory Neil Shapiro }
4863ffb83623SGregory Neil Shapiro break;
4864ffb83623SGregory Neil Shapiro
4865ffb83623SGregory Neil Shapiro case 'n': /* retrieve attribute names only */
4866ffb83623SGregory Neil Shapiro lmap->ldap_attrsonly = LDAPMAP_TRUE;
4867ffb83623SGregory Neil Shapiro break;
4868ffb83623SGregory Neil Shapiro
4869ffb83623SGregory Neil Shapiro /*
4870ffb83623SGregory Neil Shapiro ** This is a string that is dependent on the
4871ffb83623SGregory Neil Shapiro ** method used defined by 'M'.
4872ffb83623SGregory Neil Shapiro */
4873ffb83623SGregory Neil Shapiro
4874ffb83623SGregory Neil Shapiro case 'P': /* Secret password for binding */
4875ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4876ffb83623SGregory Neil Shapiro continue;
4877ffb83623SGregory Neil Shapiro lmap->ldap_secret = p;
4878ffb83623SGregory Neil Shapiro secretread = false;
4879ffb83623SGregory Neil Shapiro break;
4880ffb83623SGregory Neil Shapiro
4881ffb83623SGregory Neil Shapiro case 'p': /* ldap port */
4882ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4883ffb83623SGregory Neil Shapiro continue;
4884ffb83623SGregory Neil Shapiro lmap->ldap_port = atoi(p);
4885ffb83623SGregory Neil Shapiro break;
4886ffb83623SGregory Neil Shapiro
488706f25ae9SGregory Neil Shapiro /* args stolen from ldapsearch.c */
488806f25ae9SGregory Neil Shapiro case 'R': /* don't auto chase referrals */
488906f25ae9SGregory Neil Shapiro # ifdef LDAP_REFERRALS
489006f25ae9SGregory Neil Shapiro lmap->ldap_options &= ~LDAP_OPT_REFERRALS;
48915b0945b5SGregory Neil Shapiro # else
489240266059SGregory Neil Shapiro syserr("compile with -DLDAP_REFERRALS for referral support");
489306f25ae9SGregory Neil Shapiro # endif /* LDAP_REFERRALS */
489406f25ae9SGregory Neil Shapiro break;
489506f25ae9SGregory Neil Shapiro
489606f25ae9SGregory Neil Shapiro case 'r': /* alias dereferencing */
489706f25ae9SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
489806f25ae9SGregory Neil Shapiro continue;
489906f25ae9SGregory Neil Shapiro
490040266059SGregory Neil Shapiro if (sm_strncasecmp(p, "LDAP_DEREF_", 11) == 0)
490106f25ae9SGregory Neil Shapiro p += 11;
490206f25ae9SGregory Neil Shapiro
490306f25ae9SGregory Neil Shapiro for (lad = LDAPAliasDereference;
490406f25ae9SGregory Neil Shapiro lad != NULL && lad->lad_name != NULL; lad++)
490506f25ae9SGregory Neil Shapiro {
490640266059SGregory Neil Shapiro if (sm_strncasecmp(p, lad->lad_name,
490706f25ae9SGregory Neil Shapiro strlen(lad->lad_name)) == 0)
490806f25ae9SGregory Neil Shapiro break;
490906f25ae9SGregory Neil Shapiro }
491006f25ae9SGregory Neil Shapiro if (lad->lad_name != NULL)
491106f25ae9SGregory Neil Shapiro lmap->ldap_deref = lad->lad_code;
491206f25ae9SGregory Neil Shapiro else
491306f25ae9SGregory Neil Shapiro {
491406f25ae9SGregory Neil Shapiro /* bad config line */
491506f25ae9SGregory Neil Shapiro if (!bitset(MCF_OPTFILE,
491606f25ae9SGregory Neil Shapiro map->map_class->map_cflags))
491706f25ae9SGregory Neil Shapiro {
491806f25ae9SGregory Neil Shapiro char *ptr;
491906f25ae9SGregory Neil Shapiro
492006f25ae9SGregory Neil Shapiro if ((ptr = strchr(p, ' ')) != NULL)
492106f25ae9SGregory Neil Shapiro *ptr = '\0';
4922602a2b1bSGregory Neil Shapiro syserr("Deref must be [never|always|search|find] (not %s) in map %s",
492306f25ae9SGregory Neil Shapiro p, map->map_mname);
492406f25ae9SGregory Neil Shapiro if (ptr != NULL)
492506f25ae9SGregory Neil Shapiro *ptr = ' ';
49262fb4f839SGregory Neil Shapiro goto fail;
492706f25ae9SGregory Neil Shapiro }
492806f25ae9SGregory Neil Shapiro }
492906f25ae9SGregory Neil Shapiro break;
493006f25ae9SGregory Neil Shapiro
493106f25ae9SGregory Neil Shapiro case 's': /* search scope */
493206f25ae9SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
493306f25ae9SGregory Neil Shapiro continue;
493406f25ae9SGregory Neil Shapiro
493540266059SGregory Neil Shapiro if (sm_strncasecmp(p, "LDAP_SCOPE_", 11) == 0)
493606f25ae9SGregory Neil Shapiro p += 11;
493706f25ae9SGregory Neil Shapiro
493806f25ae9SGregory Neil Shapiro for (lss = LDAPSearchScope;
493906f25ae9SGregory Neil Shapiro lss != NULL && lss->lss_name != NULL; lss++)
494006f25ae9SGregory Neil Shapiro {
494140266059SGregory Neil Shapiro if (sm_strncasecmp(p, lss->lss_name,
494206f25ae9SGregory Neil Shapiro strlen(lss->lss_name)) == 0)
494306f25ae9SGregory Neil Shapiro break;
494406f25ae9SGregory Neil Shapiro }
494506f25ae9SGregory Neil Shapiro if (lss->lss_name != NULL)
494606f25ae9SGregory Neil Shapiro lmap->ldap_scope = lss->lss_code;
494706f25ae9SGregory Neil Shapiro else
494806f25ae9SGregory Neil Shapiro {
494906f25ae9SGregory Neil Shapiro /* bad config line */
495006f25ae9SGregory Neil Shapiro if (!bitset(MCF_OPTFILE,
495106f25ae9SGregory Neil Shapiro map->map_class->map_cflags))
495206f25ae9SGregory Neil Shapiro {
495306f25ae9SGregory Neil Shapiro char *ptr;
495406f25ae9SGregory Neil Shapiro
495506f25ae9SGregory Neil Shapiro if ((ptr = strchr(p, ' ')) != NULL)
495606f25ae9SGregory Neil Shapiro *ptr = '\0';
4957602a2b1bSGregory Neil Shapiro syserr("Scope must be [base|one|sub] (not %s) in map %s",
495806f25ae9SGregory Neil Shapiro p, map->map_mname);
495906f25ae9SGregory Neil Shapiro if (ptr != NULL)
496006f25ae9SGregory Neil Shapiro *ptr = ' ';
49612fb4f839SGregory Neil Shapiro goto fail;
496206f25ae9SGregory Neil Shapiro }
496306f25ae9SGregory Neil Shapiro }
496406f25ae9SGregory Neil Shapiro break;
496506f25ae9SGregory Neil Shapiro
4966ffb83623SGregory Neil Shapiro case 'V':
4967ffb83623SGregory Neil Shapiro if (*++p != '\\')
4968ffb83623SGregory Neil Shapiro lmap->ldap_attrsep = *p;
496906f25ae9SGregory Neil Shapiro else
497006f25ae9SGregory Neil Shapiro {
4971ffb83623SGregory Neil Shapiro switch (*++p)
497206f25ae9SGregory Neil Shapiro {
4973ffb83623SGregory Neil Shapiro case 'n':
4974ffb83623SGregory Neil Shapiro lmap->ldap_attrsep = '\n';
497506f25ae9SGregory Neil Shapiro break;
497606f25ae9SGregory Neil Shapiro
4977ffb83623SGregory Neil Shapiro case 't':
4978ffb83623SGregory Neil Shapiro lmap->ldap_attrsep = '\t';
4979ffb83623SGregory Neil Shapiro break;
498006f25ae9SGregory Neil Shapiro
4981ffb83623SGregory Neil Shapiro default:
4982ffb83623SGregory Neil Shapiro lmap->ldap_attrsep = '\\';
4983ffb83623SGregory Neil Shapiro }
4984ffb83623SGregory Neil Shapiro }
4985ffb83623SGregory Neil Shapiro break;
4986ffb83623SGregory Neil Shapiro
4987ffb83623SGregory Neil Shapiro case 'v': /* attr to return */
498806f25ae9SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
498906f25ae9SGregory Neil Shapiro continue;
4990ffb83623SGregory Neil Shapiro lmap->ldap_attr[0] = p;
4991ffb83623SGregory Neil Shapiro lmap->ldap_attr[1] = NULL;
499206f25ae9SGregory Neil Shapiro break;
499306f25ae9SGregory Neil Shapiro
4994605302a5SGregory Neil Shapiro case 'w':
4995605302a5SGregory Neil Shapiro /* -w should be for passwd, -P should be for version */
4996605302a5SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
4997605302a5SGregory Neil Shapiro continue;
4998605302a5SGregory Neil Shapiro lmap->ldap_version = atoi(p);
4999605302a5SGregory Neil Shapiro # ifdef LDAP_VERSION_MAX
5000605302a5SGregory Neil Shapiro if (lmap->ldap_version > LDAP_VERSION_MAX)
5001605302a5SGregory Neil Shapiro {
5002605302a5SGregory Neil Shapiro syserr("LDAP version %d exceeds max of %d in map %s",
5003605302a5SGregory Neil Shapiro lmap->ldap_version, LDAP_VERSION_MAX,
5004605302a5SGregory Neil Shapiro map->map_mname);
50052fb4f839SGregory Neil Shapiro goto fail;
5006605302a5SGregory Neil Shapiro }
5007605302a5SGregory Neil Shapiro # endif /* LDAP_VERSION_MAX */
5008605302a5SGregory Neil Shapiro # ifdef LDAP_VERSION_MIN
5009605302a5SGregory Neil Shapiro if (lmap->ldap_version < LDAP_VERSION_MIN)
5010605302a5SGregory Neil Shapiro {
5011605302a5SGregory Neil Shapiro syserr("LDAP version %d is lower than min of %d in map %s",
5012605302a5SGregory Neil Shapiro lmap->ldap_version, LDAP_VERSION_MIN,
5013605302a5SGregory Neil Shapiro map->map_mname);
50142fb4f839SGregory Neil Shapiro goto fail;
5015605302a5SGregory Neil Shapiro }
5016605302a5SGregory Neil Shapiro # endif /* LDAP_VERSION_MIN */
5017605302a5SGregory Neil Shapiro break;
5018605302a5SGregory Neil Shapiro
50195b0945b5SGregory Neil Shapiro case 'x':
50205b0945b5SGregory Neil Shapiro # if _FFR_SM_LDAP_DBG
50215b0945b5SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
50225b0945b5SGregory Neil Shapiro continue;
50235b0945b5SGregory Neil Shapiro lmap->ldap_debug = atoi(p);
50245b0945b5SGregory Neil Shapiro # endif
50255b0945b5SGregory Neil Shapiro break;
50265b0945b5SGregory Neil Shapiro
5027ffb83623SGregory Neil Shapiro case 'Z':
5028ffb83623SGregory Neil Shapiro while (isascii(*++p) && isspace(*p))
5029ffb83623SGregory Neil Shapiro continue;
5030ffb83623SGregory Neil Shapiro lmap->ldap_sizelimit = atoi(p);
5031d0cef73dSGregory Neil Shapiro break;
5032d0cef73dSGregory Neil Shapiro
503306f25ae9SGregory Neil Shapiro default:
503406f25ae9SGregory Neil Shapiro syserr("Illegal option %c map %s", *p, map->map_mname);
503506f25ae9SGregory Neil Shapiro break;
503606f25ae9SGregory Neil Shapiro }
503706f25ae9SGregory Neil Shapiro
503806f25ae9SGregory Neil Shapiro /* need to account for quoted strings here */
50395b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
504006f25ae9SGregory Neil Shapiro {
504106f25ae9SGregory Neil Shapiro if (*p == '"')
504206f25ae9SGregory Neil Shapiro {
504306f25ae9SGregory Neil Shapiro while (*++p != '"' && *p != '\0')
504406f25ae9SGregory Neil Shapiro continue;
504506f25ae9SGregory Neil Shapiro if (*p != '\0')
504606f25ae9SGregory Neil Shapiro p++;
504706f25ae9SGregory Neil Shapiro }
504806f25ae9SGregory Neil Shapiro else
504906f25ae9SGregory Neil Shapiro p++;
505006f25ae9SGregory Neil Shapiro }
505106f25ae9SGregory Neil Shapiro
505206f25ae9SGregory Neil Shapiro if (*p != '\0')
505306f25ae9SGregory Neil Shapiro *p++ = '\0';
505406f25ae9SGregory Neil Shapiro }
505506f25ae9SGregory Neil Shapiro
505606f25ae9SGregory Neil Shapiro if (map->map_app != NULL)
505706f25ae9SGregory Neil Shapiro map->map_app = newstr(ldapmap_dequote(map->map_app));
505806f25ae9SGregory Neil Shapiro if (map->map_tapp != NULL)
505906f25ae9SGregory Neil Shapiro map->map_tapp = newstr(ldapmap_dequote(map->map_tapp));
506006f25ae9SGregory Neil Shapiro
506106f25ae9SGregory Neil Shapiro /*
506206f25ae9SGregory Neil Shapiro ** We need to swallow up all the stuff into a struct
506306f25ae9SGregory Neil Shapiro ** and dump it into map->map_dbptr1
506406f25ae9SGregory Neil Shapiro */
506506f25ae9SGregory Neil Shapiro
5066e92d3f3fSGregory Neil Shapiro if (lmap->ldap_host != NULL &&
506706f25ae9SGregory Neil Shapiro (LDAPDefaults == NULL ||
506806f25ae9SGregory Neil Shapiro LDAPDefaults == lmap ||
5069e92d3f3fSGregory Neil Shapiro LDAPDefaults->ldap_host != lmap->ldap_host))
5070e92d3f3fSGregory Neil Shapiro lmap->ldap_host = newstr(ldapmap_dequote(lmap->ldap_host));
5071e92d3f3fSGregory Neil Shapiro map->map_domain = lmap->ldap_host;
5072e92d3f3fSGregory Neil Shapiro
5073e92d3f3fSGregory Neil Shapiro if (lmap->ldap_uri != NULL &&
5074e92d3f3fSGregory Neil Shapiro (LDAPDefaults == NULL ||
5075e92d3f3fSGregory Neil Shapiro LDAPDefaults == lmap ||
5076e92d3f3fSGregory Neil Shapiro LDAPDefaults->ldap_uri != lmap->ldap_uri))
5077e92d3f3fSGregory Neil Shapiro lmap->ldap_uri = newstr(ldapmap_dequote(lmap->ldap_uri));
5078e92d3f3fSGregory Neil Shapiro map->map_domain = lmap->ldap_uri;
507906f25ae9SGregory Neil Shapiro
508006f25ae9SGregory Neil Shapiro if (lmap->ldap_binddn != NULL &&
508106f25ae9SGregory Neil Shapiro (LDAPDefaults == NULL ||
508206f25ae9SGregory Neil Shapiro LDAPDefaults == lmap ||
508306f25ae9SGregory Neil Shapiro LDAPDefaults->ldap_binddn != lmap->ldap_binddn))
508406f25ae9SGregory Neil Shapiro lmap->ldap_binddn = newstr(ldapmap_dequote(lmap->ldap_binddn));
508506f25ae9SGregory Neil Shapiro
508606f25ae9SGregory Neil Shapiro if (lmap->ldap_secret != NULL &&
508706f25ae9SGregory Neil Shapiro (LDAPDefaults == NULL ||
508806f25ae9SGregory Neil Shapiro LDAPDefaults == lmap ||
508906f25ae9SGregory Neil Shapiro LDAPDefaults->ldap_secret != lmap->ldap_secret))
509006f25ae9SGregory Neil Shapiro {
509140266059SGregory Neil Shapiro SM_FILE_T *sfd;
509206f25ae9SGregory Neil Shapiro long sff = SFF_OPENASROOT|SFF_ROOTOK|SFF_NOWLINK|SFF_NOWWFILES|SFF_NOGWFILES;
509306f25ae9SGregory Neil Shapiro
509406f25ae9SGregory Neil Shapiro if (DontLockReadFiles)
509506f25ae9SGregory Neil Shapiro sff |= SFF_NOLOCK;
509606f25ae9SGregory Neil Shapiro
509706f25ae9SGregory Neil Shapiro /* need to use method to map secret to passwd string */
509806f25ae9SGregory Neil Shapiro switch (lmap->ldap_method)
509906f25ae9SGregory Neil Shapiro {
510006f25ae9SGregory Neil Shapiro case LDAP_AUTH_NONE:
510106f25ae9SGregory Neil Shapiro /* Do nothing */
510206f25ae9SGregory Neil Shapiro break;
510306f25ae9SGregory Neil Shapiro
510406f25ae9SGregory Neil Shapiro case LDAP_AUTH_SIMPLE:
510506f25ae9SGregory Neil Shapiro
510606f25ae9SGregory Neil Shapiro /*
510706f25ae9SGregory Neil Shapiro ** Secret is the name of a file with
510806f25ae9SGregory Neil Shapiro ** the first line as the password.
510906f25ae9SGregory Neil Shapiro */
511006f25ae9SGregory Neil Shapiro
511106f25ae9SGregory Neil Shapiro /* Already read in the secret? */
511206f25ae9SGregory Neil Shapiro if (secretread)
511306f25ae9SGregory Neil Shapiro break;
511406f25ae9SGregory Neil Shapiro
511506f25ae9SGregory Neil Shapiro sfd = safefopen(ldapmap_dequote(lmap->ldap_secret),
511606f25ae9SGregory Neil Shapiro O_RDONLY, 0, sff);
511706f25ae9SGregory Neil Shapiro if (sfd == NULL)
511806f25ae9SGregory Neil Shapiro {
511906f25ae9SGregory Neil Shapiro syserr("LDAP map: cannot open secret %s",
512006f25ae9SGregory Neil Shapiro ldapmap_dequote(lmap->ldap_secret));
51212fb4f839SGregory Neil Shapiro goto fail;
512206f25ae9SGregory Neil Shapiro }
5123d0cef73dSGregory Neil Shapiro lmap->ldap_secret = sfgets(m_tmp, sizeof(m_tmp),
512442e5d165SGregory Neil Shapiro sfd, TimeOuts.to_fileopen,
512542e5d165SGregory Neil Shapiro "ldapmap_parseargs");
512640266059SGregory Neil Shapiro (void) sm_io_close(sfd, SM_TIME_DEFAULT);
512794c01205SGregory Neil Shapiro if (strlen(m_tmp) > LDAPMAP_MAX_PASSWD)
512894c01205SGregory Neil Shapiro {
512994c01205SGregory Neil Shapiro syserr("LDAP map: secret in %s too long",
513094c01205SGregory Neil Shapiro ldapmap_dequote(lmap->ldap_secret));
51312fb4f839SGregory Neil Shapiro goto fail;
513294c01205SGregory Neil Shapiro }
513306f25ae9SGregory Neil Shapiro if (lmap->ldap_secret != NULL &&
513406f25ae9SGregory Neil Shapiro strlen(m_tmp) > 0)
513506f25ae9SGregory Neil Shapiro {
513606f25ae9SGregory Neil Shapiro /* chomp newline */
513706f25ae9SGregory Neil Shapiro if (m_tmp[strlen(m_tmp) - 1] == '\n')
513806f25ae9SGregory Neil Shapiro m_tmp[strlen(m_tmp) - 1] = '\0';
513906f25ae9SGregory Neil Shapiro
514006f25ae9SGregory Neil Shapiro lmap->ldap_secret = m_tmp;
514106f25ae9SGregory Neil Shapiro }
514206f25ae9SGregory Neil Shapiro break;
514306f25ae9SGregory Neil Shapiro
514406f25ae9SGregory Neil Shapiro # ifdef LDAP_AUTH_KRBV4
514506f25ae9SGregory Neil Shapiro case LDAP_AUTH_KRBV4:
514606f25ae9SGregory Neil Shapiro
514706f25ae9SGregory Neil Shapiro /*
514806f25ae9SGregory Neil Shapiro ** Secret is where the ticket file is
514906f25ae9SGregory Neil Shapiro ** stashed
515006f25ae9SGregory Neil Shapiro */
515106f25ae9SGregory Neil Shapiro
5152d0cef73dSGregory Neil Shapiro (void) sm_snprintf(m_tmp, sizeof(m_tmp),
515306f25ae9SGregory Neil Shapiro "KRBTKFILE=%s",
515406f25ae9SGregory Neil Shapiro ldapmap_dequote(lmap->ldap_secret));
515506f25ae9SGregory Neil Shapiro lmap->ldap_secret = m_tmp;
515606f25ae9SGregory Neil Shapiro break;
515706f25ae9SGregory Neil Shapiro # endif /* LDAP_AUTH_KRBV4 */
515806f25ae9SGregory Neil Shapiro
515906f25ae9SGregory Neil Shapiro default: /* Should NEVER get here */
516006f25ae9SGregory Neil Shapiro syserr("LDAP map: Illegal value in lmap method");
51612fb4f839SGregory Neil Shapiro goto fail;
516240266059SGregory Neil Shapiro /* NOTREACHED */
516306f25ae9SGregory Neil Shapiro break;
516406f25ae9SGregory Neil Shapiro }
516506f25ae9SGregory Neil Shapiro }
516606f25ae9SGregory Neil Shapiro
516706f25ae9SGregory Neil Shapiro if (lmap->ldap_secret != NULL &&
516806f25ae9SGregory Neil Shapiro (LDAPDefaults == NULL ||
516906f25ae9SGregory Neil Shapiro LDAPDefaults == lmap ||
517006f25ae9SGregory Neil Shapiro LDAPDefaults->ldap_secret != lmap->ldap_secret))
517106f25ae9SGregory Neil Shapiro lmap->ldap_secret = newstr(ldapmap_dequote(lmap->ldap_secret));
517206f25ae9SGregory Neil Shapiro
517306f25ae9SGregory Neil Shapiro if (lmap->ldap_base != NULL &&
517406f25ae9SGregory Neil Shapiro (LDAPDefaults == NULL ||
517506f25ae9SGregory Neil Shapiro LDAPDefaults == lmap ||
517606f25ae9SGregory Neil Shapiro LDAPDefaults->ldap_base != lmap->ldap_base))
517706f25ae9SGregory Neil Shapiro lmap->ldap_base = newstr(ldapmap_dequote(lmap->ldap_base));
517806f25ae9SGregory Neil Shapiro
517906f25ae9SGregory Neil Shapiro /*
518006f25ae9SGregory Neil Shapiro ** Save the server from extra work. If request is for a single
518106f25ae9SGregory Neil Shapiro ** match, tell the server to only return enough records to
518206f25ae9SGregory Neil Shapiro ** determine if there is a single match or not. This can not
518306f25ae9SGregory Neil Shapiro ** be one since the server would only return one and we wouldn't
518406f25ae9SGregory Neil Shapiro ** know if there were others available.
518506f25ae9SGregory Neil Shapiro */
518606f25ae9SGregory Neil Shapiro
518706f25ae9SGregory Neil Shapiro if (bitset(MF_SINGLEMATCH, map->map_mflags))
518806f25ae9SGregory Neil Shapiro lmap->ldap_sizelimit = 2;
518906f25ae9SGregory Neil Shapiro
519006f25ae9SGregory Neil Shapiro /* If setting defaults, don't process ldap_filter and ldap_attr */
519106f25ae9SGregory Neil Shapiro if (lmap == LDAPDefaults)
519240266059SGregory Neil Shapiro return true;
519306f25ae9SGregory Neil Shapiro
519406f25ae9SGregory Neil Shapiro if (lmap->ldap_filter != NULL)
519506f25ae9SGregory Neil Shapiro lmap->ldap_filter = newstr(ldapmap_dequote(lmap->ldap_filter));
519606f25ae9SGregory Neil Shapiro else
519706f25ae9SGregory Neil Shapiro {
519806f25ae9SGregory Neil Shapiro if (!bitset(MCF_OPTFILE, map->map_class->map_cflags))
519906f25ae9SGregory Neil Shapiro {
520006f25ae9SGregory Neil Shapiro syserr("No filter given in map %s", map->map_mname);
52012fb4f839SGregory Neil Shapiro goto fail;
520206f25ae9SGregory Neil Shapiro }
520306f25ae9SGregory Neil Shapiro }
520406f25ae9SGregory Neil Shapiro
5205e92d3f3fSGregory Neil Shapiro if (!attrssetup && lmap->ldap_attr[0] != NULL)
520606f25ae9SGregory Neil Shapiro {
520740266059SGregory Neil Shapiro bool recurse = false;
5208605302a5SGregory Neil Shapiro bool normalseen = false;
520940266059SGregory Neil Shapiro
521006f25ae9SGregory Neil Shapiro i = 0;
521106f25ae9SGregory Neil Shapiro p = ldapmap_dequote(lmap->ldap_attr[0]);
521206f25ae9SGregory Neil Shapiro lmap->ldap_attr[0] = NULL;
521306f25ae9SGregory Neil Shapiro
5214605302a5SGregory Neil Shapiro /* Prime the attr list with the objectClass attribute */
5215605302a5SGregory Neil Shapiro lmap->ldap_attr[i] = "objectClass";
5216605302a5SGregory Neil Shapiro lmap->ldap_attr_type[i] = SM_LDAP_ATTR_OBJCLASS;
5217605302a5SGregory Neil Shapiro lmap->ldap_attr_needobjclass[i] = NULL;
5218605302a5SGregory Neil Shapiro i++;
5219605302a5SGregory Neil Shapiro
522006f25ae9SGregory Neil Shapiro while (p != NULL)
522106f25ae9SGregory Neil Shapiro {
522206f25ae9SGregory Neil Shapiro char *v;
522306f25ae9SGregory Neil Shapiro
52245b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
522506f25ae9SGregory Neil Shapiro p++;
522606f25ae9SGregory Neil Shapiro if (*p == '\0')
522706f25ae9SGregory Neil Shapiro break;
522806f25ae9SGregory Neil Shapiro v = p;
522906f25ae9SGregory Neil Shapiro p = strchr(v, ',');
523006f25ae9SGregory Neil Shapiro if (p != NULL)
523106f25ae9SGregory Neil Shapiro *p++ = '\0';
523206f25ae9SGregory Neil Shapiro
5233193538b7SGregory Neil Shapiro if (i >= LDAPMAP_MAX_ATTR)
523406f25ae9SGregory Neil Shapiro {
523506f25ae9SGregory Neil Shapiro syserr("Too many return attributes in %s (max %d)",
523606f25ae9SGregory Neil Shapiro map->map_mname, LDAPMAP_MAX_ATTR);
52372fb4f839SGregory Neil Shapiro goto fail;
523806f25ae9SGregory Neil Shapiro }
523906f25ae9SGregory Neil Shapiro if (*v != '\0')
524040266059SGregory Neil Shapiro {
5241605302a5SGregory Neil Shapiro int j;
5242605302a5SGregory Neil Shapiro int use;
524340266059SGregory Neil Shapiro char *type;
5244605302a5SGregory Neil Shapiro char *needobjclass;
524540266059SGregory Neil Shapiro
524640266059SGregory Neil Shapiro type = strchr(v, ':');
524740266059SGregory Neil Shapiro if (type != NULL)
5248605302a5SGregory Neil Shapiro {
524940266059SGregory Neil Shapiro *type++ = '\0';
5250605302a5SGregory Neil Shapiro needobjclass = strchr(type, ':');
5251605302a5SGregory Neil Shapiro if (needobjclass != NULL)
5252605302a5SGregory Neil Shapiro *needobjclass++ = '\0';
525340266059SGregory Neil Shapiro }
5254605302a5SGregory Neil Shapiro else
5255605302a5SGregory Neil Shapiro {
5256605302a5SGregory Neil Shapiro needobjclass = NULL;
5257605302a5SGregory Neil Shapiro }
5258605302a5SGregory Neil Shapiro
5259605302a5SGregory Neil Shapiro use = i;
5260605302a5SGregory Neil Shapiro
5261605302a5SGregory Neil Shapiro /* allow override on "objectClass" type */
52622fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ(v, "objectClass") &&
5263605302a5SGregory Neil Shapiro lmap->ldap_attr_type[0] == SM_LDAP_ATTR_OBJCLASS)
5264605302a5SGregory Neil Shapiro {
5265605302a5SGregory Neil Shapiro use = 0;
5266605302a5SGregory Neil Shapiro }
5267605302a5SGregory Neil Shapiro else
5268605302a5SGregory Neil Shapiro {
5269605302a5SGregory Neil Shapiro /*
5270605302a5SGregory Neil Shapiro ** Don't add something to attribute
5271605302a5SGregory Neil Shapiro ** list twice.
5272605302a5SGregory Neil Shapiro */
5273605302a5SGregory Neil Shapiro
5274605302a5SGregory Neil Shapiro for (j = 1; j < i; j++)
5275605302a5SGregory Neil Shapiro {
52762fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ(v, lmap->ldap_attr[j]))
5277605302a5SGregory Neil Shapiro {
5278605302a5SGregory Neil Shapiro syserr("Duplicate attribute (%s) in %s",
5279605302a5SGregory Neil Shapiro v, map->map_mname);
52802fb4f839SGregory Neil Shapiro goto fail;
5281605302a5SGregory Neil Shapiro }
5282605302a5SGregory Neil Shapiro }
5283605302a5SGregory Neil Shapiro
5284605302a5SGregory Neil Shapiro lmap->ldap_attr[use] = newstr(v);
5285605302a5SGregory Neil Shapiro if (needobjclass != NULL &&
5286605302a5SGregory Neil Shapiro *needobjclass != '\0' &&
5287605302a5SGregory Neil Shapiro *needobjclass != '*')
5288605302a5SGregory Neil Shapiro {
5289605302a5SGregory Neil Shapiro lmap->ldap_attr_needobjclass[use] = newstr(needobjclass);
5290605302a5SGregory Neil Shapiro }
5291605302a5SGregory Neil Shapiro else
5292605302a5SGregory Neil Shapiro {
5293605302a5SGregory Neil Shapiro lmap->ldap_attr_needobjclass[use] = NULL;
5294605302a5SGregory Neil Shapiro }
5295605302a5SGregory Neil Shapiro
5296605302a5SGregory Neil Shapiro }
5297605302a5SGregory Neil Shapiro
5298605302a5SGregory Neil Shapiro if (type != NULL && *type != '\0')
5299605302a5SGregory Neil Shapiro {
53002fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ(type, "dn"))
530140266059SGregory Neil Shapiro {
530240266059SGregory Neil Shapiro recurse = true;
5303605302a5SGregory Neil Shapiro lmap->ldap_attr_type[use] = SM_LDAP_ATTR_DN;
530440266059SGregory Neil Shapiro }
53052fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(type, "filter"))
530640266059SGregory Neil Shapiro {
530740266059SGregory Neil Shapiro recurse = true;
5308605302a5SGregory Neil Shapiro lmap->ldap_attr_type[use] = SM_LDAP_ATTR_FILTER;
530940266059SGregory Neil Shapiro }
53102fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(type, "url"))
531140266059SGregory Neil Shapiro {
531240266059SGregory Neil Shapiro recurse = true;
5313605302a5SGregory Neil Shapiro lmap->ldap_attr_type[use] = SM_LDAP_ATTR_URL;
531440266059SGregory Neil Shapiro }
53152fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(type, "normal"))
531640266059SGregory Neil Shapiro {
5317605302a5SGregory Neil Shapiro lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL;
5318605302a5SGregory Neil Shapiro normalseen = true;
531940266059SGregory Neil Shapiro }
532040266059SGregory Neil Shapiro else
532140266059SGregory Neil Shapiro {
532240266059SGregory Neil Shapiro syserr("Unknown attribute type (%s) in %s",
532340266059SGregory Neil Shapiro type, map->map_mname);
53242fb4f839SGregory Neil Shapiro goto fail;
532540266059SGregory Neil Shapiro }
532640266059SGregory Neil Shapiro }
532740266059SGregory Neil Shapiro else
5328605302a5SGregory Neil Shapiro {
5329605302a5SGregory Neil Shapiro lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL;
5330605302a5SGregory Neil Shapiro normalseen = true;
5331605302a5SGregory Neil Shapiro }
533240266059SGregory Neil Shapiro i++;
533340266059SGregory Neil Shapiro }
533406f25ae9SGregory Neil Shapiro }
533506f25ae9SGregory Neil Shapiro lmap->ldap_attr[i] = NULL;
5336b6bacd31SGregory Neil Shapiro
5337b6bacd31SGregory Neil Shapiro /* Set in case needed in future code */
5338e92d3f3fSGregory Neil Shapiro attrssetup = true;
5339b6bacd31SGregory Neil Shapiro
5340605302a5SGregory Neil Shapiro if (recurse && !normalseen)
534140266059SGregory Neil Shapiro {
5342605302a5SGregory Neil Shapiro syserr("LDAP recursion requested in %s but no returnable attribute given",
534340266059SGregory Neil Shapiro map->map_mname);
53442fb4f839SGregory Neil Shapiro goto fail;
534506f25ae9SGregory Neil Shapiro }
534640266059SGregory Neil Shapiro if (recurse && lmap->ldap_attrsonly == LDAPMAP_TRUE)
534740266059SGregory Neil Shapiro {
534840266059SGregory Neil Shapiro syserr("LDAP recursion requested in %s can not be used with -n",
534940266059SGregory Neil Shapiro map->map_mname);
53502fb4f839SGregory Neil Shapiro goto fail;
535140266059SGregory Neil Shapiro }
535240266059SGregory Neil Shapiro }
535306f25ae9SGregory Neil Shapiro map->map_db1 = (ARBPTR_T) lmap;
535440266059SGregory Neil Shapiro return true;
53552fb4f839SGregory Neil Shapiro fail:
53562fb4f839SGregory Neil Shapiro SM_FREE(lmap_alloc);
53572fb4f839SGregory Neil Shapiro return false;
535806f25ae9SGregory Neil Shapiro }
535906f25ae9SGregory Neil Shapiro
536006f25ae9SGregory Neil Shapiro /*
536106f25ae9SGregory Neil Shapiro ** LDAPMAP_SET_DEFAULTS -- Read default map spec from LDAPDefaults in .cf
536206f25ae9SGregory Neil Shapiro **
536306f25ae9SGregory Neil Shapiro ** Parameters:
536406f25ae9SGregory Neil Shapiro ** spec -- map argument string from LDAPDefaults option
536506f25ae9SGregory Neil Shapiro **
536606f25ae9SGregory Neil Shapiro ** Returns:
536706f25ae9SGregory Neil Shapiro ** None.
536806f25ae9SGregory Neil Shapiro */
536906f25ae9SGregory Neil Shapiro
537006f25ae9SGregory Neil Shapiro void
ldapmap_set_defaults(spec)537106f25ae9SGregory Neil Shapiro ldapmap_set_defaults(spec)
537206f25ae9SGregory Neil Shapiro char *spec;
537306f25ae9SGregory Neil Shapiro {
5374602a2b1bSGregory Neil Shapiro STAB *class;
537506f25ae9SGregory Neil Shapiro MAP map;
537606f25ae9SGregory Neil Shapiro
537706f25ae9SGregory Neil Shapiro /* Allocate and set the default values */
537806f25ae9SGregory Neil Shapiro if (LDAPDefaults == NULL)
5379d0cef73dSGregory Neil Shapiro LDAPDefaults = (SM_LDAP_STRUCT *) xalloc(sizeof(*LDAPDefaults));
538040266059SGregory Neil Shapiro sm_ldap_clear(LDAPDefaults);
538106f25ae9SGregory Neil Shapiro
5382d0cef73dSGregory Neil Shapiro memset(&map, '\0', sizeof(map));
5383602a2b1bSGregory Neil Shapiro
5384602a2b1bSGregory Neil Shapiro /* look up the class */
5385602a2b1bSGregory Neil Shapiro class = stab("ldap", ST_MAPCLASS, ST_FIND);
5386602a2b1bSGregory Neil Shapiro if (class == NULL)
5387602a2b1bSGregory Neil Shapiro {
5388602a2b1bSGregory Neil Shapiro syserr("readcf: LDAPDefaultSpec: class ldap not available");
5389602a2b1bSGregory Neil Shapiro return;
5390602a2b1bSGregory Neil Shapiro }
5391602a2b1bSGregory Neil Shapiro map.map_class = &class->s_mapclass;
539206f25ae9SGregory Neil Shapiro map.map_db1 = (ARBPTR_T) LDAPDefaults;
5393602a2b1bSGregory Neil Shapiro map.map_mname = "O LDAPDefaultSpec";
539406f25ae9SGregory Neil Shapiro
539506f25ae9SGregory Neil Shapiro (void) ldapmap_parseargs(&map, spec);
539606f25ae9SGregory Neil Shapiro
539706f25ae9SGregory Neil Shapiro /* These should never be set in LDAPDefaults */
539806f25ae9SGregory Neil Shapiro if (map.map_mflags != (MF_TRY0NULL|MF_TRY1NULL) ||
539906f25ae9SGregory Neil Shapiro map.map_spacesub != SpaceSub ||
540006f25ae9SGregory Neil Shapiro map.map_app != NULL ||
540106f25ae9SGregory Neil Shapiro map.map_tapp != NULL)
540206f25ae9SGregory Neil Shapiro {
540306f25ae9SGregory Neil Shapiro syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags");
54045b0945b5SGregory Neil Shapiro SM_FREE(map.map_app);
54055b0945b5SGregory Neil Shapiro SM_FREE(map.map_tapp);
540606f25ae9SGregory Neil Shapiro }
540706f25ae9SGregory Neil Shapiro
540806f25ae9SGregory Neil Shapiro if (LDAPDefaults->ldap_filter != NULL)
540906f25ae9SGregory Neil Shapiro {
541006f25ae9SGregory Neil Shapiro syserr("readcf: option LDAPDefaultSpec: Do not set the LDAP search filter");
5411605302a5SGregory Neil Shapiro
541206f25ae9SGregory Neil Shapiro /* don't free, it isn't malloc'ed in parseargs */
541306f25ae9SGregory Neil Shapiro LDAPDefaults->ldap_filter = NULL;
541406f25ae9SGregory Neil Shapiro }
541506f25ae9SGregory Neil Shapiro
541606f25ae9SGregory Neil Shapiro if (LDAPDefaults->ldap_attr[0] != NULL)
541706f25ae9SGregory Neil Shapiro {
541806f25ae9SGregory Neil Shapiro syserr("readcf: option LDAPDefaultSpec: Do not set the requested LDAP attributes");
541906f25ae9SGregory Neil Shapiro /* don't free, they aren't malloc'ed in parseargs */
542006f25ae9SGregory Neil Shapiro LDAPDefaults->ldap_attr[0] = NULL;
542106f25ae9SGregory Neil Shapiro }
542206f25ae9SGregory Neil Shapiro }
542306f25ae9SGregory Neil Shapiro #endif /* LDAPMAP */
542440266059SGregory Neil Shapiro /*
542506f25ae9SGregory Neil Shapiro ** PH map
542606f25ae9SGregory Neil Shapiro */
542706f25ae9SGregory Neil Shapiro
542840266059SGregory Neil Shapiro #if PH_MAP
542906f25ae9SGregory Neil Shapiro
543006f25ae9SGregory Neil Shapiro /*
543106f25ae9SGregory Neil Shapiro ** Support for the CCSO Nameserver (ph/qi).
543206f25ae9SGregory Neil Shapiro ** This code is intended to replace the so-called "ph mailer".
5433d0cef73dSGregory Neil Shapiro ** Contributed by Mark D. Roth. Contact him for support.
543406f25ae9SGregory Neil Shapiro */
543506f25ae9SGregory Neil Shapiro
543640266059SGregory Neil Shapiro /* what version of the ph map code we're running */
543713bd1963SGregory Neil Shapiro static char phmap_id[128];
543840266059SGregory Neil Shapiro
543940266059SGregory Neil Shapiro /* sendmail version for phmap id string */
544040266059SGregory Neil Shapiro extern const char Version[];
544106f25ae9SGregory Neil Shapiro
5442e92d3f3fSGregory Neil Shapiro /* assume we're using nph-1.2.x if not specified */
544313bd1963SGregory Neil Shapiro # ifndef NPH_VERSION
5444e92d3f3fSGregory Neil Shapiro # define NPH_VERSION 10200
544513bd1963SGregory Neil Shapiro # endif
544613bd1963SGregory Neil Shapiro
544713bd1963SGregory Neil Shapiro /* compatibility for versions older than nph-1.2.0 */
544813bd1963SGregory Neil Shapiro # if NPH_VERSION < 10200
544913bd1963SGregory Neil Shapiro # define PH_OPEN_ROUNDROBIN PH_ROUNDROBIN
545013bd1963SGregory Neil Shapiro # define PH_OPEN_DONTID PH_DONTID
545113bd1963SGregory Neil Shapiro # define PH_CLOSE_FAST PH_FASTCLOSE
545213bd1963SGregory Neil Shapiro # define PH_ERR_DATAERR PH_DATAERR
545313bd1963SGregory Neil Shapiro # define PH_ERR_NOMATCH PH_NOMATCH
545413bd1963SGregory Neil Shapiro # endif /* NPH_VERSION < 10200 */
545513bd1963SGregory Neil Shapiro
545606f25ae9SGregory Neil Shapiro /*
545706f25ae9SGregory Neil Shapiro ** PH_MAP_PARSEARGS -- parse ph map definition args.
545806f25ae9SGregory Neil Shapiro */
545906f25ae9SGregory Neil Shapiro
546006f25ae9SGregory Neil Shapiro bool
ph_map_parseargs(map,args)546106f25ae9SGregory Neil Shapiro ph_map_parseargs(map, args)
546206f25ae9SGregory Neil Shapiro MAP *map;
546306f25ae9SGregory Neil Shapiro char *args;
546406f25ae9SGregory Neil Shapiro {
546540266059SGregory Neil Shapiro register bool done;
546606f25ae9SGregory Neil Shapiro register char *p = args;
546740266059SGregory Neil Shapiro PH_MAP_STRUCT *pmap = NULL;
546840266059SGregory Neil Shapiro
546940266059SGregory Neil Shapiro /* initialize version string */
5470d0cef73dSGregory Neil Shapiro (void) sm_snprintf(phmap_id, sizeof(phmap_id),
547140266059SGregory Neil Shapiro "sendmail-%s phmap-20010529 libphclient-%s",
547240266059SGregory Neil Shapiro Version, libphclient_version);
5473c2aa98e2SPeter Wemm
5474d0cef73dSGregory Neil Shapiro pmap = (PH_MAP_STRUCT *) xalloc(sizeof(*pmap));
5475c2aa98e2SPeter Wemm
547606f25ae9SGregory Neil Shapiro /* defaults */
547706f25ae9SGregory Neil Shapiro pmap->ph_servers = NULL;
547806f25ae9SGregory Neil Shapiro pmap->ph_field_list = NULL;
547940266059SGregory Neil Shapiro pmap->ph = NULL;
548006f25ae9SGregory Neil Shapiro pmap->ph_timeout = 0;
548140266059SGregory Neil Shapiro pmap->ph_fastclose = 0;
5482c2aa98e2SPeter Wemm
5483c2aa98e2SPeter Wemm map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
5484c2aa98e2SPeter Wemm for (;;)
5485c2aa98e2SPeter Wemm {
54865b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
5487c2aa98e2SPeter Wemm p++;
5488c2aa98e2SPeter Wemm if (*p != '-')
5489c2aa98e2SPeter Wemm break;
5490c2aa98e2SPeter Wemm switch (*++p)
5491c2aa98e2SPeter Wemm {
5492c2aa98e2SPeter Wemm case 'N':
5493c2aa98e2SPeter Wemm map->map_mflags |= MF_INCLNULL;
5494c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY0NULL;
5495c2aa98e2SPeter Wemm break;
5496c2aa98e2SPeter Wemm
5497c2aa98e2SPeter Wemm case 'O':
5498c2aa98e2SPeter Wemm map->map_mflags &= ~MF_TRY1NULL;
5499c2aa98e2SPeter Wemm break;
5500c2aa98e2SPeter Wemm
5501c2aa98e2SPeter Wemm case 'o':
5502c2aa98e2SPeter Wemm map->map_mflags |= MF_OPTIONAL;
5503c2aa98e2SPeter Wemm break;
5504c2aa98e2SPeter Wemm
5505c2aa98e2SPeter Wemm case 'f':
5506c2aa98e2SPeter Wemm map->map_mflags |= MF_NOFOLDCASE;
5507c2aa98e2SPeter Wemm break;
5508c2aa98e2SPeter Wemm
5509c2aa98e2SPeter Wemm case 'm':
5510c2aa98e2SPeter Wemm map->map_mflags |= MF_MATCHONLY;
5511c2aa98e2SPeter Wemm break;
5512c2aa98e2SPeter Wemm
5513c2aa98e2SPeter Wemm case 'A':
5514c2aa98e2SPeter Wemm map->map_mflags |= MF_APPEND;
5515c2aa98e2SPeter Wemm break;
5516c2aa98e2SPeter Wemm
5517c2aa98e2SPeter Wemm case 'q':
5518c2aa98e2SPeter Wemm map->map_mflags |= MF_KEEPQUOTES;
5519c2aa98e2SPeter Wemm break;
5520c2aa98e2SPeter Wemm
5521c2aa98e2SPeter Wemm case 't':
5522c2aa98e2SPeter Wemm map->map_mflags |= MF_NODEFER;
5523c2aa98e2SPeter Wemm break;
5524c2aa98e2SPeter Wemm
5525c2aa98e2SPeter Wemm case 'a':
5526c2aa98e2SPeter Wemm map->map_app = ++p;
5527c2aa98e2SPeter Wemm break;
5528c2aa98e2SPeter Wemm
5529c2aa98e2SPeter Wemm case 'T':
5530c2aa98e2SPeter Wemm map->map_tapp = ++p;
5531c2aa98e2SPeter Wemm break;
5532c2aa98e2SPeter Wemm
553306f25ae9SGregory Neil Shapiro case 'l':
5534c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p))
5535c2aa98e2SPeter Wemm continue;
553606f25ae9SGregory Neil Shapiro pmap->ph_timeout = atoi(p);
553706f25ae9SGregory Neil Shapiro break;
553806f25ae9SGregory Neil Shapiro
553906f25ae9SGregory Neil Shapiro case 'S':
554006f25ae9SGregory Neil Shapiro map->map_spacesub = *++p;
5541c2aa98e2SPeter Wemm break;
5542c2aa98e2SPeter Wemm
554306f25ae9SGregory Neil Shapiro case 'D':
554406f25ae9SGregory Neil Shapiro map->map_mflags |= MF_DEFER;
554506f25ae9SGregory Neil Shapiro break;
554606f25ae9SGregory Neil Shapiro
554706f25ae9SGregory Neil Shapiro case 'h': /* PH server list */
5548c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p))
5549c2aa98e2SPeter Wemm continue;
555006f25ae9SGregory Neil Shapiro pmap->ph_servers = p;
5551c2aa98e2SPeter Wemm break;
5552c2aa98e2SPeter Wemm
555340266059SGregory Neil Shapiro case 'k': /* fields to search for */
5554c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p))
5555c2aa98e2SPeter Wemm continue;
555606f25ae9SGregory Neil Shapiro pmap->ph_field_list = p;
5557c2aa98e2SPeter Wemm break;
5558c2aa98e2SPeter Wemm
555906f25ae9SGregory Neil Shapiro default:
556040266059SGregory Neil Shapiro syserr("ph_map_parseargs: unknown option -%c", *p);
5561c2aa98e2SPeter Wemm }
5562c2aa98e2SPeter Wemm
556306f25ae9SGregory Neil Shapiro /* try to account for quoted strings */
55645b0945b5SGregory Neil Shapiro done = SM_ISSPACE(*p);
5565c2aa98e2SPeter Wemm while (*p != '\0' && !done)
5566c2aa98e2SPeter Wemm {
5567c2aa98e2SPeter Wemm if (*p == '"')
5568c2aa98e2SPeter Wemm {
5569c2aa98e2SPeter Wemm while (*++p != '"' && *p != '\0')
5570c2aa98e2SPeter Wemm continue;
5571c2aa98e2SPeter Wemm if (*p != '\0')
5572c2aa98e2SPeter Wemm p++;
5573c2aa98e2SPeter Wemm }
5574c2aa98e2SPeter Wemm else
5575c2aa98e2SPeter Wemm p++;
55765b0945b5SGregory Neil Shapiro done = SM_ISSPACE(*p);
5577c2aa98e2SPeter Wemm }
5578c2aa98e2SPeter Wemm
5579c2aa98e2SPeter Wemm if (*p != '\0')
5580c2aa98e2SPeter Wemm *p++ = '\0';
5581c2aa98e2SPeter Wemm }
5582c2aa98e2SPeter Wemm
5583c2aa98e2SPeter Wemm if (map->map_app != NULL)
558406f25ae9SGregory Neil Shapiro map->map_app = newstr(ph_map_dequote(map->map_app));
5585c2aa98e2SPeter Wemm if (map->map_tapp != NULL)
558606f25ae9SGregory Neil Shapiro map->map_tapp = newstr(ph_map_dequote(map->map_tapp));
5587c2aa98e2SPeter Wemm
558806f25ae9SGregory Neil Shapiro if (pmap->ph_field_list != NULL)
558906f25ae9SGregory Neil Shapiro pmap->ph_field_list = newstr(ph_map_dequote(pmap->ph_field_list));
5590c2aa98e2SPeter Wemm
559106f25ae9SGregory Neil Shapiro if (pmap->ph_servers != NULL)
559206f25ae9SGregory Neil Shapiro pmap->ph_servers = newstr(ph_map_dequote(pmap->ph_servers));
5593c2aa98e2SPeter Wemm else
5594c2aa98e2SPeter Wemm {
559506f25ae9SGregory Neil Shapiro syserr("ph_map_parseargs: -h flag is required");
559640266059SGregory Neil Shapiro return false;
5597c2aa98e2SPeter Wemm }
5598c2aa98e2SPeter Wemm
559906f25ae9SGregory Neil Shapiro map->map_db1 = (ARBPTR_T) pmap;
560040266059SGregory Neil Shapiro return true;
5601c2aa98e2SPeter Wemm }
5602c2aa98e2SPeter Wemm
560306f25ae9SGregory Neil Shapiro /*
560406f25ae9SGregory Neil Shapiro ** PH_MAP_CLOSE -- close the connection to the ph server
560506f25ae9SGregory Neil Shapiro */
560606f25ae9SGregory Neil Shapiro
560706f25ae9SGregory Neil Shapiro void
ph_map_close(map)560806f25ae9SGregory Neil Shapiro ph_map_close(map)
560906f25ae9SGregory Neil Shapiro MAP *map;
561006f25ae9SGregory Neil Shapiro {
561106f25ae9SGregory Neil Shapiro PH_MAP_STRUCT *pmap;
561206f25ae9SGregory Neil Shapiro
561306f25ae9SGregory Neil Shapiro pmap = (PH_MAP_STRUCT *)map->map_db1;
561440266059SGregory Neil Shapiro if (tTd(38, 9))
5615605302a5SGregory Neil Shapiro sm_dprintf("ph_map_close(%s): pmap->ph_fastclose=%d\n",
561640266059SGregory Neil Shapiro map->map_mname, pmap->ph_fastclose);
561740266059SGregory Neil Shapiro
561840266059SGregory Neil Shapiro
561940266059SGregory Neil Shapiro if (pmap->ph != NULL)
562040266059SGregory Neil Shapiro {
562140266059SGregory Neil Shapiro ph_set_sendhook(pmap->ph, NULL);
562240266059SGregory Neil Shapiro ph_set_recvhook(pmap->ph, NULL);
562340266059SGregory Neil Shapiro ph_close(pmap->ph, pmap->ph_fastclose);
562440266059SGregory Neil Shapiro }
562540266059SGregory Neil Shapiro
562640266059SGregory Neil Shapiro map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
562706f25ae9SGregory Neil Shapiro }
562806f25ae9SGregory Neil Shapiro
562906f25ae9SGregory Neil Shapiro static jmp_buf PHTimeout;
563006f25ae9SGregory Neil Shapiro
563106f25ae9SGregory Neil Shapiro /* ARGSUSED */
563206f25ae9SGregory Neil Shapiro static void
ph_timeout(unused)563340266059SGregory Neil Shapiro ph_timeout(unused)
563440266059SGregory Neil Shapiro int unused;
563506f25ae9SGregory Neil Shapiro {
56368774250cSGregory Neil Shapiro /*
56378774250cSGregory Neil Shapiro ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
56388774250cSGregory Neil Shapiro ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
56398774250cSGregory Neil Shapiro ** DOING.
56408774250cSGregory Neil Shapiro */
56418774250cSGregory Neil Shapiro
56428774250cSGregory Neil Shapiro errno = ETIMEDOUT;
564306f25ae9SGregory Neil Shapiro longjmp(PHTimeout, 1);
564406f25ae9SGregory Neil Shapiro }
564506f25ae9SGregory Neil Shapiro
564640266059SGregory Neil Shapiro static void
564713bd1963SGregory Neil Shapiro # if NPH_VERSION >= 10200
ph_map_send_debug(appdata,text)564813bd1963SGregory Neil Shapiro ph_map_send_debug(appdata, text)
564913bd1963SGregory Neil Shapiro void *appdata;
565013bd1963SGregory Neil Shapiro # else
565140266059SGregory Neil Shapiro ph_map_send_debug(text)
565213bd1963SGregory Neil Shapiro # endif
565340266059SGregory Neil Shapiro char *text;
565406f25ae9SGregory Neil Shapiro {
565540266059SGregory Neil Shapiro if (LogLevel > 9)
565640266059SGregory Neil Shapiro sm_syslog(LOG_NOTICE, CurEnv->e_id,
565740266059SGregory Neil Shapiro "ph_map_send_debug: ==> %s", text);
565840266059SGregory Neil Shapiro if (tTd(38, 20))
565940266059SGregory Neil Shapiro sm_dprintf("ph_map_send_debug: ==> %s\n", text);
566006f25ae9SGregory Neil Shapiro }
566106f25ae9SGregory Neil Shapiro
566240266059SGregory Neil Shapiro static void
566313bd1963SGregory Neil Shapiro # if NPH_VERSION >= 10200
ph_map_recv_debug(appdata,text)566413bd1963SGregory Neil Shapiro ph_map_recv_debug(appdata, text)
566513bd1963SGregory Neil Shapiro void *appdata;
566613bd1963SGregory Neil Shapiro # else
566740266059SGregory Neil Shapiro ph_map_recv_debug(text)
566813bd1963SGregory Neil Shapiro # endif
566940266059SGregory Neil Shapiro char *text;
567040266059SGregory Neil Shapiro {
567140266059SGregory Neil Shapiro if (LogLevel > 10)
567240266059SGregory Neil Shapiro sm_syslog(LOG_NOTICE, CurEnv->e_id,
567340266059SGregory Neil Shapiro "ph_map_recv_debug: <== %s", text);
567440266059SGregory Neil Shapiro if (tTd(38, 21))
567540266059SGregory Neil Shapiro sm_dprintf("ph_map_recv_debug: <== %s\n", text);
567640266059SGregory Neil Shapiro }
567740266059SGregory Neil Shapiro
567840266059SGregory Neil Shapiro /*
567906f25ae9SGregory Neil Shapiro ** PH_MAP_OPEN -- sub for opening PH map
568006f25ae9SGregory Neil Shapiro */
568106f25ae9SGregory Neil Shapiro bool
ph_map_open(map,mode)568206f25ae9SGregory Neil Shapiro ph_map_open(map, mode)
568306f25ae9SGregory Neil Shapiro MAP *map;
568406f25ae9SGregory Neil Shapiro int mode;
568506f25ae9SGregory Neil Shapiro {
568606f25ae9SGregory Neil Shapiro PH_MAP_STRUCT *pmap;
568740266059SGregory Neil Shapiro register SM_EVENT *ev = NULL;
568840266059SGregory Neil Shapiro int save_errno = 0;
568940266059SGregory Neil Shapiro char *hostlist, *host;
569006f25ae9SGregory Neil Shapiro
569106f25ae9SGregory Neil Shapiro if (tTd(38, 2))
569240266059SGregory Neil Shapiro sm_dprintf("ph_map_open(%s)\n", map->map_mname);
569306f25ae9SGregory Neil Shapiro
569406f25ae9SGregory Neil Shapiro mode &= O_ACCMODE;
569506f25ae9SGregory Neil Shapiro if (mode != O_RDONLY)
569606f25ae9SGregory Neil Shapiro {
569706f25ae9SGregory Neil Shapiro /* issue a pseudo-error message */
569840266059SGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
569940266059SGregory Neil Shapiro return false;
570006f25ae9SGregory Neil Shapiro }
570106f25ae9SGregory Neil Shapiro
570242e5d165SGregory Neil Shapiro if (CurEnv != NULL && CurEnv->e_sendmode == SM_DEFER &&
570342e5d165SGregory Neil Shapiro bitset(MF_DEFER, map->map_mflags))
570442e5d165SGregory Neil Shapiro {
570542e5d165SGregory Neil Shapiro if (tTd(9, 1))
570640266059SGregory Neil Shapiro sm_dprintf("ph_map_open(%s) => DEFERRED\n",
570742e5d165SGregory Neil Shapiro map->map_mname);
570842e5d165SGregory Neil Shapiro
570942e5d165SGregory Neil Shapiro /*
571042e5d165SGregory Neil Shapiro ** Unset MF_DEFER here so that map_lookup() returns
571142e5d165SGregory Neil Shapiro ** a temporary failure using the bogus map and
571242e5d165SGregory Neil Shapiro ** map->map_tapp instead of the default permanent error.
571342e5d165SGregory Neil Shapiro */
571442e5d165SGregory Neil Shapiro
571542e5d165SGregory Neil Shapiro map->map_mflags &= ~MF_DEFER;
571640266059SGregory Neil Shapiro return false;
571742e5d165SGregory Neil Shapiro }
571842e5d165SGregory Neil Shapiro
571906f25ae9SGregory Neil Shapiro pmap = (PH_MAP_STRUCT *)map->map_db1;
572040266059SGregory Neil Shapiro pmap->ph_fastclose = 0; /* refresh field for reopen */
572106f25ae9SGregory Neil Shapiro
572240266059SGregory Neil Shapiro /* try each host in the list */
572306f25ae9SGregory Neil Shapiro hostlist = newstr(pmap->ph_servers);
572440266059SGregory Neil Shapiro for (host = strtok(hostlist, " ");
572540266059SGregory Neil Shapiro host != NULL;
572640266059SGregory Neil Shapiro host = strtok(NULL, " "))
572706f25ae9SGregory Neil Shapiro {
572840266059SGregory Neil Shapiro /* set timeout */
572906f25ae9SGregory Neil Shapiro if (pmap->ph_timeout != 0)
573006f25ae9SGregory Neil Shapiro {
573106f25ae9SGregory Neil Shapiro if (setjmp(PHTimeout) != 0)
573206f25ae9SGregory Neil Shapiro {
573306f25ae9SGregory Neil Shapiro ev = NULL;
573406f25ae9SGregory Neil Shapiro if (LogLevel > 1)
573506f25ae9SGregory Neil Shapiro sm_syslog(LOG_NOTICE, CurEnv->e_id,
573606f25ae9SGregory Neil Shapiro "timeout connecting to PH server %.100s",
573740266059SGregory Neil Shapiro host);
573806f25ae9SGregory Neil Shapiro errno = ETIMEDOUT;
573906f25ae9SGregory Neil Shapiro goto ph_map_open_abort;
574006f25ae9SGregory Neil Shapiro }
574140266059SGregory Neil Shapiro ev = sm_setevent(pmap->ph_timeout, ph_timeout, 0);
574206f25ae9SGregory Neil Shapiro }
574306f25ae9SGregory Neil Shapiro
574440266059SGregory Neil Shapiro /* open connection to server */
574513bd1963SGregory Neil Shapiro if (ph_open(&(pmap->ph), host,
574613bd1963SGregory Neil Shapiro PH_OPEN_ROUNDROBIN|PH_OPEN_DONTID,
574713bd1963SGregory Neil Shapiro ph_map_send_debug, ph_map_recv_debug
574813bd1963SGregory Neil Shapiro # if NPH_VERSION >= 10200
574913bd1963SGregory Neil Shapiro , NULL
575013bd1963SGregory Neil Shapiro # endif
575113bd1963SGregory Neil Shapiro ) == 0
575213bd1963SGregory Neil Shapiro && ph_id(pmap->ph, phmap_id) == 0)
575340266059SGregory Neil Shapiro {
575440266059SGregory Neil Shapiro if (ev != NULL)
575540266059SGregory Neil Shapiro sm_clrevent(ev);
575640266059SGregory Neil Shapiro sm_free(hostlist); /* XXX */
575740266059SGregory Neil Shapiro return true;
575840266059SGregory Neil Shapiro }
575940266059SGregory Neil Shapiro
576040266059SGregory Neil Shapiro ph_map_open_abort:
576140266059SGregory Neil Shapiro save_errno = errno;
576240266059SGregory Neil Shapiro if (ev != NULL)
576340266059SGregory Neil Shapiro sm_clrevent(ev);
576413bd1963SGregory Neil Shapiro pmap->ph_fastclose = PH_CLOSE_FAST;
576540266059SGregory Neil Shapiro ph_map_close(map);
576606f25ae9SGregory Neil Shapiro errno = save_errno;
576740266059SGregory Neil Shapiro }
576840266059SGregory Neil Shapiro
576942e5d165SGregory Neil Shapiro if (bitset(MF_NODEFER, map->map_mflags))
577006f25ae9SGregory Neil Shapiro {
577142e5d165SGregory Neil Shapiro if (errno == 0)
577206f25ae9SGregory Neil Shapiro errno = EAGAIN;
577342e5d165SGregory Neil Shapiro syserr("ph_map_open: %s: cannot connect to PH server",
577442e5d165SGregory Neil Shapiro map->map_mname);
577506f25ae9SGregory Neil Shapiro }
577642e5d165SGregory Neil Shapiro else if (!bitset(MF_OPTIONAL, map->map_mflags) && LogLevel > 1)
577706f25ae9SGregory Neil Shapiro sm_syslog(LOG_NOTICE, CurEnv->e_id,
577842e5d165SGregory Neil Shapiro "ph_map_open: %s: cannot connect to PH server",
577942e5d165SGregory Neil Shapiro map->map_mname);
578040266059SGregory Neil Shapiro sm_free(hostlist); /* XXX */
578140266059SGregory Neil Shapiro return false;
578206f25ae9SGregory Neil Shapiro }
578306f25ae9SGregory Neil Shapiro
578406f25ae9SGregory Neil Shapiro /*
578506f25ae9SGregory Neil Shapiro ** PH_MAP_LOOKUP -- look up key from ph server
578606f25ae9SGregory Neil Shapiro */
578706f25ae9SGregory Neil Shapiro
578806f25ae9SGregory Neil Shapiro char *
ph_map_lookup(map,key,args,pstat)578906f25ae9SGregory Neil Shapiro ph_map_lookup(map, key, args, pstat)
579006f25ae9SGregory Neil Shapiro MAP *map;
579106f25ae9SGregory Neil Shapiro char *key;
579206f25ae9SGregory Neil Shapiro char **args;
579306f25ae9SGregory Neil Shapiro int *pstat;
579406f25ae9SGregory Neil Shapiro {
579540266059SGregory Neil Shapiro int i, save_errno = 0;
579640266059SGregory Neil Shapiro register SM_EVENT *ev = NULL;
579706f25ae9SGregory Neil Shapiro PH_MAP_STRUCT *pmap;
579840266059SGregory Neil Shapiro char *value = NULL;
579906f25ae9SGregory Neil Shapiro
580006f25ae9SGregory Neil Shapiro pmap = (PH_MAP_STRUCT *)map->map_db1;
580106f25ae9SGregory Neil Shapiro
580206f25ae9SGregory Neil Shapiro *pstat = EX_OK;
580306f25ae9SGregory Neil Shapiro
580440266059SGregory Neil Shapiro /* set timeout */
580506f25ae9SGregory Neil Shapiro if (pmap->ph_timeout != 0)
580606f25ae9SGregory Neil Shapiro {
580706f25ae9SGregory Neil Shapiro if (setjmp(PHTimeout) != 0)
580806f25ae9SGregory Neil Shapiro {
580906f25ae9SGregory Neil Shapiro ev = NULL;
581006f25ae9SGregory Neil Shapiro if (LogLevel > 1)
581106f25ae9SGregory Neil Shapiro sm_syslog(LOG_NOTICE, CurEnv->e_id,
581206f25ae9SGregory Neil Shapiro "timeout during PH lookup of %.100s",
581306f25ae9SGregory Neil Shapiro key);
581406f25ae9SGregory Neil Shapiro errno = ETIMEDOUT;
581506f25ae9SGregory Neil Shapiro *pstat = EX_TEMPFAIL;
581606f25ae9SGregory Neil Shapiro goto ph_map_lookup_abort;
581706f25ae9SGregory Neil Shapiro }
581840266059SGregory Neil Shapiro ev = sm_setevent(pmap->ph_timeout, ph_timeout, 0);
581906f25ae9SGregory Neil Shapiro }
582006f25ae9SGregory Neil Shapiro
582140266059SGregory Neil Shapiro /* perform lookup */
582240266059SGregory Neil Shapiro i = ph_email_resolve(pmap->ph, key, pmap->ph_field_list, &value);
582340266059SGregory Neil Shapiro if (i == -1)
582406f25ae9SGregory Neil Shapiro *pstat = EX_TEMPFAIL;
582513bd1963SGregory Neil Shapiro else if (i == PH_ERR_NOMATCH || i == PH_ERR_DATAERR)
582640266059SGregory Neil Shapiro *pstat = EX_UNAVAILABLE;
582706f25ae9SGregory Neil Shapiro
582806f25ae9SGregory Neil Shapiro ph_map_lookup_abort:
582906f25ae9SGregory Neil Shapiro if (ev != NULL)
583040266059SGregory Neil Shapiro sm_clrevent(ev);
583106f25ae9SGregory Neil Shapiro
583206f25ae9SGregory Neil Shapiro /*
583340266059SGregory Neil Shapiro ** Close the connection if the timer popped
583406f25ae9SGregory Neil Shapiro ** or we got a temporary PH error
583506f25ae9SGregory Neil Shapiro */
583606f25ae9SGregory Neil Shapiro
583706f25ae9SGregory Neil Shapiro if (*pstat == EX_TEMPFAIL)
583806f25ae9SGregory Neil Shapiro {
583940266059SGregory Neil Shapiro save_errno = errno;
584013bd1963SGregory Neil Shapiro pmap->ph_fastclose = PH_CLOSE_FAST;
584140266059SGregory Neil Shapiro ph_map_close(map);
584240266059SGregory Neil Shapiro errno = save_errno;
584306f25ae9SGregory Neil Shapiro }
584406f25ae9SGregory Neil Shapiro
584506f25ae9SGregory Neil Shapiro if (*pstat == EX_OK)
584606f25ae9SGregory Neil Shapiro {
584706f25ae9SGregory Neil Shapiro if (tTd(38,20))
584840266059SGregory Neil Shapiro sm_dprintf("ph_map_lookup: %s => %s\n", key, value);
584906f25ae9SGregory Neil Shapiro
585006f25ae9SGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
585140266059SGregory Neil Shapiro return map_rewrite(map, key, strlen(key), NULL);
585206f25ae9SGregory Neil Shapiro else
585340266059SGregory Neil Shapiro return map_rewrite(map, value, strlen(value), args);
585406f25ae9SGregory Neil Shapiro }
585540266059SGregory Neil Shapiro
585640266059SGregory Neil Shapiro return NULL;
585706f25ae9SGregory Neil Shapiro }
585806f25ae9SGregory Neil Shapiro #endif /* PH_MAP */
5859d0cef73dSGregory Neil Shapiro
586040266059SGregory Neil Shapiro /*
5861c2aa98e2SPeter Wemm ** syslog map
5862c2aa98e2SPeter Wemm */
5863c2aa98e2SPeter Wemm
5864c2aa98e2SPeter Wemm #define map_prio map_lockfd /* overload field */
5865c2aa98e2SPeter Wemm
5866c2aa98e2SPeter Wemm /*
5867c2aa98e2SPeter Wemm ** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages.
5868c2aa98e2SPeter Wemm */
5869c2aa98e2SPeter Wemm
5870c2aa98e2SPeter Wemm bool
syslog_map_parseargs(map,args)5871c2aa98e2SPeter Wemm syslog_map_parseargs(map, args)
5872c2aa98e2SPeter Wemm MAP *map;
5873c2aa98e2SPeter Wemm char *args;
5874c2aa98e2SPeter Wemm {
5875c2aa98e2SPeter Wemm char *p = args;
5876c2aa98e2SPeter Wemm char *priority = NULL;
5877c2aa98e2SPeter Wemm
587806f25ae9SGregory Neil Shapiro /* there is no check whether there is really an argument */
587906f25ae9SGregory Neil Shapiro while (*p != '\0')
5880c2aa98e2SPeter Wemm {
58815b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
5882c2aa98e2SPeter Wemm p++;
5883c2aa98e2SPeter Wemm if (*p != '-')
5884c2aa98e2SPeter Wemm break;
588506f25ae9SGregory Neil Shapiro ++p;
588606f25ae9SGregory Neil Shapiro if (*p == 'D')
588706f25ae9SGregory Neil Shapiro {
588806f25ae9SGregory Neil Shapiro map->map_mflags |= MF_DEFER;
588906f25ae9SGregory Neil Shapiro ++p;
589006f25ae9SGregory Neil Shapiro }
589106f25ae9SGregory Neil Shapiro else if (*p == 'S')
589206f25ae9SGregory Neil Shapiro {
589306f25ae9SGregory Neil Shapiro map->map_spacesub = *++p;
589406f25ae9SGregory Neil Shapiro if (*p != '\0')
589506f25ae9SGregory Neil Shapiro p++;
589606f25ae9SGregory Neil Shapiro }
589706f25ae9SGregory Neil Shapiro else if (*p == 'L')
589806f25ae9SGregory Neil Shapiro {
58995b0945b5SGregory Neil Shapiro while (*++p != '\0' && SM_ISSPACE(*p))
590006f25ae9SGregory Neil Shapiro continue;
590106f25ae9SGregory Neil Shapiro if (*p == '\0')
590206f25ae9SGregory Neil Shapiro break;
590306f25ae9SGregory Neil Shapiro priority = p;
59045b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
5905c2aa98e2SPeter Wemm p++;
5906c2aa98e2SPeter Wemm if (*p != '\0')
5907c2aa98e2SPeter Wemm *p++ = '\0';
5908c2aa98e2SPeter Wemm }
590906f25ae9SGregory Neil Shapiro else
591006f25ae9SGregory Neil Shapiro {
591106f25ae9SGregory Neil Shapiro syserr("Illegal option %c map syslog", *p);
591206f25ae9SGregory Neil Shapiro ++p;
591306f25ae9SGregory Neil Shapiro }
591406f25ae9SGregory Neil Shapiro }
5915c2aa98e2SPeter Wemm
5916c2aa98e2SPeter Wemm if (priority == NULL)
5917c2aa98e2SPeter Wemm map->map_prio = LOG_INFO;
5918c2aa98e2SPeter Wemm else
5919c2aa98e2SPeter Wemm {
592040266059SGregory Neil Shapiro if (sm_strncasecmp("LOG_", priority, 4) == 0)
5921c2aa98e2SPeter Wemm priority += 4;
5922c2aa98e2SPeter Wemm
5923c2aa98e2SPeter Wemm #ifdef LOG_EMERG
59242fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("EMERG", priority))
5925c2aa98e2SPeter Wemm map->map_prio = LOG_EMERG;
5926c2aa98e2SPeter Wemm else
59272fb4f839SGregory Neil Shapiro #endif
5928c2aa98e2SPeter Wemm #ifdef LOG_ALERT
59292fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("ALERT", priority))
5930c2aa98e2SPeter Wemm map->map_prio = LOG_ALERT;
5931c2aa98e2SPeter Wemm else
59322fb4f839SGregory Neil Shapiro #endif
5933c2aa98e2SPeter Wemm #ifdef LOG_CRIT
59342fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("CRIT", priority))
5935c2aa98e2SPeter Wemm map->map_prio = LOG_CRIT;
5936c2aa98e2SPeter Wemm else
59372fb4f839SGregory Neil Shapiro #endif
5938c2aa98e2SPeter Wemm #ifdef LOG_ERR
59392fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("ERR", priority))
5940c2aa98e2SPeter Wemm map->map_prio = LOG_ERR;
5941c2aa98e2SPeter Wemm else
59422fb4f839SGregory Neil Shapiro #endif
5943c2aa98e2SPeter Wemm #ifdef LOG_WARNING
59442fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("WARNING", priority))
5945c2aa98e2SPeter Wemm map->map_prio = LOG_WARNING;
5946c2aa98e2SPeter Wemm else
59472fb4f839SGregory Neil Shapiro #endif
5948c2aa98e2SPeter Wemm #ifdef LOG_NOTICE
59492fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("NOTICE", priority))
5950c2aa98e2SPeter Wemm map->map_prio = LOG_NOTICE;
5951c2aa98e2SPeter Wemm else
59522fb4f839SGregory Neil Shapiro #endif
5953c2aa98e2SPeter Wemm #ifdef LOG_INFO
59542fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("INFO", priority))
5955c2aa98e2SPeter Wemm map->map_prio = LOG_INFO;
5956c2aa98e2SPeter Wemm else
59572fb4f839SGregory Neil Shapiro #endif
5958c2aa98e2SPeter Wemm #ifdef LOG_DEBUG
59592fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ("DEBUG", priority))
5960c2aa98e2SPeter Wemm map->map_prio = LOG_DEBUG;
5961c2aa98e2SPeter Wemm else
59622fb4f839SGregory Neil Shapiro #endif
5963c2aa98e2SPeter Wemm {
596440266059SGregory Neil Shapiro syserr("syslog_map_parseargs: Unknown priority %s",
5965c2aa98e2SPeter Wemm priority);
596640266059SGregory Neil Shapiro return false;
5967c2aa98e2SPeter Wemm }
5968c2aa98e2SPeter Wemm }
59692fb4f839SGregory Neil Shapiro #if _FFR_8BITENVADDR
59702fb4f839SGregory Neil Shapiro map->map_mflags |= MF_KEEPXFMT;
59712fb4f839SGregory Neil Shapiro #endif
597240266059SGregory Neil Shapiro return true;
5973c2aa98e2SPeter Wemm }
5974c2aa98e2SPeter Wemm
5975c2aa98e2SPeter Wemm /*
5976c2aa98e2SPeter Wemm ** SYSLOG_MAP_LOOKUP -- rewrite and syslog message. Always return empty string
5977c2aa98e2SPeter Wemm */
5978c2aa98e2SPeter Wemm
5979c2aa98e2SPeter Wemm char *
syslog_map_lookup(map,string,args,statp)5980c2aa98e2SPeter Wemm syslog_map_lookup(map, string, args, statp)
5981c2aa98e2SPeter Wemm MAP *map;
5982c2aa98e2SPeter Wemm char *string;
5983c2aa98e2SPeter Wemm char **args;
5984c2aa98e2SPeter Wemm int *statp;
5985c2aa98e2SPeter Wemm {
5986c2aa98e2SPeter Wemm char *ptr = map_rewrite(map, string, strlen(string), args);
5987c2aa98e2SPeter Wemm
5988c2aa98e2SPeter Wemm if (ptr != NULL)
5989c2aa98e2SPeter Wemm {
5990c2aa98e2SPeter Wemm if (tTd(38, 20))
599140266059SGregory Neil Shapiro sm_dprintf("syslog_map_lookup(%s (priority %d): %s\n",
5992c2aa98e2SPeter Wemm map->map_mname, map->map_prio, ptr);
5993c2aa98e2SPeter Wemm
5994c2aa98e2SPeter Wemm sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr);
5995c2aa98e2SPeter Wemm }
5996c2aa98e2SPeter Wemm
5997c2aa98e2SPeter Wemm *statp = EX_OK;
5998c2aa98e2SPeter Wemm return "";
5999c2aa98e2SPeter Wemm }
6000c2aa98e2SPeter Wemm
6001d0cef73dSGregory Neil Shapiro #if _FFR_DPRINTF_MAP
6002d0cef73dSGregory Neil Shapiro /*
6003d0cef73dSGregory Neil Shapiro ** dprintf map
6004d0cef73dSGregory Neil Shapiro */
6005d0cef73dSGregory Neil Shapiro
6006d0cef73dSGregory Neil Shapiro #define map_dbg_level map_lockfd /* overload field */
6007d0cef73dSGregory Neil Shapiro
6008d0cef73dSGregory Neil Shapiro /*
6009d0cef73dSGregory Neil Shapiro ** DPRINTF_MAP_PARSEARGS -- check for priority level to dprintf messages.
6010d0cef73dSGregory Neil Shapiro */
6011d0cef73dSGregory Neil Shapiro
6012d0cef73dSGregory Neil Shapiro bool
dprintf_map_parseargs(map,args)6013d0cef73dSGregory Neil Shapiro dprintf_map_parseargs(map, args)
6014d0cef73dSGregory Neil Shapiro MAP *map;
6015d0cef73dSGregory Neil Shapiro char *args;
6016d0cef73dSGregory Neil Shapiro {
6017d0cef73dSGregory Neil Shapiro char *p = args;
6018d0cef73dSGregory Neil Shapiro char *dbg_level = NULL;
6019d0cef73dSGregory Neil Shapiro
6020d0cef73dSGregory Neil Shapiro /* there is no check whether there is really an argument */
6021d0cef73dSGregory Neil Shapiro while (*p != '\0')
6022d0cef73dSGregory Neil Shapiro {
60235b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
6024d0cef73dSGregory Neil Shapiro p++;
6025d0cef73dSGregory Neil Shapiro if (*p != '-')
6026d0cef73dSGregory Neil Shapiro break;
6027d0cef73dSGregory Neil Shapiro ++p;
6028d0cef73dSGregory Neil Shapiro if (*p == 'D')
6029d0cef73dSGregory Neil Shapiro {
6030d0cef73dSGregory Neil Shapiro map->map_mflags |= MF_DEFER;
6031d0cef73dSGregory Neil Shapiro ++p;
6032d0cef73dSGregory Neil Shapiro }
6033d0cef73dSGregory Neil Shapiro else if (*p == 'S')
6034d0cef73dSGregory Neil Shapiro {
6035d0cef73dSGregory Neil Shapiro map->map_spacesub = *++p;
6036d0cef73dSGregory Neil Shapiro if (*p != '\0')
6037d0cef73dSGregory Neil Shapiro p++;
6038d0cef73dSGregory Neil Shapiro }
6039d0cef73dSGregory Neil Shapiro else if (*p == 'd')
6040d0cef73dSGregory Neil Shapiro {
60415b0945b5SGregory Neil Shapiro while (*++p != '\0' && SM_ISSPACE(*p))
6042d0cef73dSGregory Neil Shapiro continue;
6043d0cef73dSGregory Neil Shapiro if (*p == '\0')
6044d0cef73dSGregory Neil Shapiro break;
6045d0cef73dSGregory Neil Shapiro dbg_level = p;
60465b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
6047d0cef73dSGregory Neil Shapiro p++;
6048d0cef73dSGregory Neil Shapiro if (*p != '\0')
6049d0cef73dSGregory Neil Shapiro *p++ = '\0';
6050d0cef73dSGregory Neil Shapiro }
6051d0cef73dSGregory Neil Shapiro else
6052d0cef73dSGregory Neil Shapiro {
6053d0cef73dSGregory Neil Shapiro syserr("Illegal option %c map dprintf", *p);
6054d0cef73dSGregory Neil Shapiro ++p;
6055d0cef73dSGregory Neil Shapiro }
6056d0cef73dSGregory Neil Shapiro }
6057d0cef73dSGregory Neil Shapiro
6058d0cef73dSGregory Neil Shapiro if (dbg_level == NULL)
6059d0cef73dSGregory Neil Shapiro map->map_dbg_level = 0;
6060d0cef73dSGregory Neil Shapiro else
6061d0cef73dSGregory Neil Shapiro {
6062d0cef73dSGregory Neil Shapiro if (!(isascii(*dbg_level) && isdigit(*dbg_level)))
6063d0cef73dSGregory Neil Shapiro {
6064d0cef73dSGregory Neil Shapiro syserr("dprintf map \"%s\", file %s: -d should specify a number, not %s",
6065d0cef73dSGregory Neil Shapiro map->map_mname, map->map_file,
6066d0cef73dSGregory Neil Shapiro dbg_level);
6067d0cef73dSGregory Neil Shapiro return false;
6068d0cef73dSGregory Neil Shapiro }
6069d0cef73dSGregory Neil Shapiro map->map_dbg_level = atoi(dbg_level);
6070d0cef73dSGregory Neil Shapiro }
60712fb4f839SGregory Neil Shapiro # if _FFR_8BITENVADDR
60722fb4f839SGregory Neil Shapiro map->map_mflags |= MF_KEEPXFMT;
60732fb4f839SGregory Neil Shapiro # endif
6074d0cef73dSGregory Neil Shapiro return true;
6075d0cef73dSGregory Neil Shapiro }
6076d0cef73dSGregory Neil Shapiro
6077d0cef73dSGregory Neil Shapiro /*
6078d0cef73dSGregory Neil Shapiro ** DPRINTF_MAP_LOOKUP -- rewrite and print message. Always return empty string
6079d0cef73dSGregory Neil Shapiro */
6080d0cef73dSGregory Neil Shapiro
6081d0cef73dSGregory Neil Shapiro char *
dprintf_map_lookup(map,string,args,statp)6082d0cef73dSGregory Neil Shapiro dprintf_map_lookup(map, string, args, statp)
6083d0cef73dSGregory Neil Shapiro MAP *map;
6084d0cef73dSGregory Neil Shapiro char *string;
6085d0cef73dSGregory Neil Shapiro char **args;
6086d0cef73dSGregory Neil Shapiro int *statp;
6087d0cef73dSGregory Neil Shapiro {
6088d0cef73dSGregory Neil Shapiro char *ptr = map_rewrite(map, string, strlen(string), args);
6089d0cef73dSGregory Neil Shapiro
6090d0cef73dSGregory Neil Shapiro if (ptr != NULL && tTd(85, map->map_dbg_level))
6091d0cef73dSGregory Neil Shapiro sm_dprintf("%s\n", ptr);
6092d0cef73dSGregory Neil Shapiro *statp = EX_OK;
6093d0cef73dSGregory Neil Shapiro return "";
6094d0cef73dSGregory Neil Shapiro }
6095d0cef73dSGregory Neil Shapiro #endif /* _FFR_DPRINTF_MAP */
6096d0cef73dSGregory Neil Shapiro
609740266059SGregory Neil Shapiro /*
6098c2aa98e2SPeter Wemm ** HESIOD Modules
6099c2aa98e2SPeter Wemm */
6100c2aa98e2SPeter Wemm
610140266059SGregory Neil Shapiro #if HESIOD
6102c2aa98e2SPeter Wemm
6103c2aa98e2SPeter Wemm bool
hes_map_open(map,mode)6104c2aa98e2SPeter Wemm hes_map_open(map, mode)
6105c2aa98e2SPeter Wemm MAP *map;
6106c2aa98e2SPeter Wemm int mode;
6107c2aa98e2SPeter Wemm {
6108c2aa98e2SPeter Wemm if (tTd(38, 2))
610940266059SGregory Neil Shapiro sm_dprintf("hes_map_open(%s, %s, %d)\n",
6110c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
6111c2aa98e2SPeter Wemm
6112c2aa98e2SPeter Wemm if (mode != O_RDONLY)
6113c2aa98e2SPeter Wemm {
6114c2aa98e2SPeter Wemm /* issue a pseudo-error message */
611540266059SGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
611640266059SGregory Neil Shapiro return false;
6117c2aa98e2SPeter Wemm }
6118c2aa98e2SPeter Wemm
6119c2aa98e2SPeter Wemm # ifdef HESIOD_INIT
6120c2aa98e2SPeter Wemm if (HesiodContext != NULL || hesiod_init(&HesiodContext) == 0)
612140266059SGregory Neil Shapiro return true;
6122c2aa98e2SPeter Wemm
6123c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
6124605302a5SGregory Neil Shapiro syserr("451 4.3.5 cannot initialize Hesiod map (%s)",
612540266059SGregory Neil Shapiro sm_errstring(errno));
612640266059SGregory Neil Shapiro return false;
612706f25ae9SGregory Neil Shapiro # else /* HESIOD_INIT */
6128c2aa98e2SPeter Wemm if (hes_error() == HES_ER_UNINIT)
6129c2aa98e2SPeter Wemm hes_init();
6130c2aa98e2SPeter Wemm switch (hes_error())
6131c2aa98e2SPeter Wemm {
6132c2aa98e2SPeter Wemm case HES_ER_OK:
6133c2aa98e2SPeter Wemm case HES_ER_NOTFOUND:
613440266059SGregory Neil Shapiro return true;
6135c2aa98e2SPeter Wemm }
6136c2aa98e2SPeter Wemm
6137c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
6138605302a5SGregory Neil Shapiro syserr("451 4.3.5 cannot initialize Hesiod map (%d)", hes_error());
6139c2aa98e2SPeter Wemm
614040266059SGregory Neil Shapiro return false;
6141c2aa98e2SPeter Wemm # endif /* HESIOD_INIT */
6142c2aa98e2SPeter Wemm }
6143c2aa98e2SPeter Wemm
6144c2aa98e2SPeter Wemm char *
hes_map_lookup(map,name,av,statp)6145c2aa98e2SPeter Wemm hes_map_lookup(map, name, av, statp)
6146c2aa98e2SPeter Wemm MAP *map;
6147c2aa98e2SPeter Wemm char *name;
6148c2aa98e2SPeter Wemm char **av;
6149c2aa98e2SPeter Wemm int *statp;
6150c2aa98e2SPeter Wemm {
6151c2aa98e2SPeter Wemm char **hp;
6152c2aa98e2SPeter Wemm
6153c2aa98e2SPeter Wemm if (tTd(38, 20))
615440266059SGregory Neil Shapiro sm_dprintf("hes_map_lookup(%s, %s)\n", map->map_file, name);
6155c2aa98e2SPeter Wemm
6156c2aa98e2SPeter Wemm if (name[0] == '\\')
6157c2aa98e2SPeter Wemm {
6158c2aa98e2SPeter Wemm char *np;
6159c2aa98e2SPeter Wemm int nl;
61608774250cSGregory Neil Shapiro int save_errno;
61612fb4f839SGregory Neil Shapiro char nbuf[MAXNAME]; /* EAI:ok - larger buffer used if needed */
6162c2aa98e2SPeter Wemm
6163c2aa98e2SPeter Wemm nl = strlen(name);
6164d0cef73dSGregory Neil Shapiro if (nl < sizeof(nbuf) - 1)
6165c2aa98e2SPeter Wemm np = nbuf;
6166c2aa98e2SPeter Wemm else
61672fb4f839SGregory Neil Shapiro np = xalloc(nl + 2);
6168c2aa98e2SPeter Wemm np[0] = '\\';
61692fb4f839SGregory Neil Shapiro (void) sm_strlcpy(&np[1], name, sizeof(nbuf) - 1);
6170c2aa98e2SPeter Wemm # ifdef HESIOD_INIT
6171c2aa98e2SPeter Wemm hp = hesiod_resolve(HesiodContext, np, map->map_file);
61725b0945b5SGregory Neil Shapiro # else
6173c2aa98e2SPeter Wemm hp = hes_resolve(np, map->map_file);
61742fb4f839SGregory Neil Shapiro # endif
61758774250cSGregory Neil Shapiro save_errno = errno;
6176c2aa98e2SPeter Wemm if (np != nbuf)
61772fb4f839SGregory Neil Shapiro SM_FREE(np); /* XXX */
61788774250cSGregory Neil Shapiro errno = save_errno;
6179c2aa98e2SPeter Wemm }
6180c2aa98e2SPeter Wemm else
6181c2aa98e2SPeter Wemm {
6182c2aa98e2SPeter Wemm # ifdef HESIOD_INIT
6183c2aa98e2SPeter Wemm hp = hesiod_resolve(HesiodContext, name, map->map_file);
61845b0945b5SGregory Neil Shapiro # else
6185c2aa98e2SPeter Wemm hp = hes_resolve(name, map->map_file);
6186c2aa98e2SPeter Wemm # endif /* HESIOD_INIT */
6187c2aa98e2SPeter Wemm }
6188c2aa98e2SPeter Wemm # ifdef HESIOD_INIT
61898774250cSGregory Neil Shapiro if (hp == NULL || *hp == NULL)
6190c2aa98e2SPeter Wemm {
6191c2aa98e2SPeter Wemm switch (errno)
6192c2aa98e2SPeter Wemm {
6193c2aa98e2SPeter Wemm case ENOENT:
6194c2aa98e2SPeter Wemm *statp = EX_NOTFOUND;
6195c2aa98e2SPeter Wemm break;
6196c2aa98e2SPeter Wemm case ECONNREFUSED:
6197c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
6198c2aa98e2SPeter Wemm break;
619940266059SGregory Neil Shapiro case EMSGSIZE:
6200c2aa98e2SPeter Wemm case ENOMEM:
6201c2aa98e2SPeter Wemm default:
6202c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
6203c2aa98e2SPeter Wemm break;
6204c2aa98e2SPeter Wemm }
6205c86d5965SGregory Neil Shapiro if (hp != NULL)
62068774250cSGregory Neil Shapiro hesiod_free_list(HesiodContext, hp);
6207c2aa98e2SPeter Wemm return NULL;
6208c2aa98e2SPeter Wemm }
620906f25ae9SGregory Neil Shapiro # else /* HESIOD_INIT */
6210c2aa98e2SPeter Wemm if (hp == NULL || hp[0] == NULL)
6211c2aa98e2SPeter Wemm {
6212c2aa98e2SPeter Wemm switch (hes_error())
6213c2aa98e2SPeter Wemm {
6214c2aa98e2SPeter Wemm case HES_ER_OK:
6215c2aa98e2SPeter Wemm *statp = EX_OK;
6216c2aa98e2SPeter Wemm break;
6217c2aa98e2SPeter Wemm
6218c2aa98e2SPeter Wemm case HES_ER_NOTFOUND:
6219c2aa98e2SPeter Wemm *statp = EX_NOTFOUND;
6220c2aa98e2SPeter Wemm break;
6221c2aa98e2SPeter Wemm
6222c2aa98e2SPeter Wemm case HES_ER_CONFIG:
6223c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
6224c2aa98e2SPeter Wemm break;
6225c2aa98e2SPeter Wemm
6226c2aa98e2SPeter Wemm case HES_ER_NET:
6227c2aa98e2SPeter Wemm *statp = EX_TEMPFAIL;
6228c2aa98e2SPeter Wemm break;
6229c2aa98e2SPeter Wemm }
6230c2aa98e2SPeter Wemm return NULL;
6231c2aa98e2SPeter Wemm }
6232c2aa98e2SPeter Wemm # endif /* HESIOD_INIT */
6233c2aa98e2SPeter Wemm
6234c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
6235c2aa98e2SPeter Wemm return map_rewrite(map, name, strlen(name), NULL);
6236c2aa98e2SPeter Wemm else
6237c2aa98e2SPeter Wemm return map_rewrite(map, hp[0], strlen(hp[0]), av);
6238c2aa98e2SPeter Wemm }
6239c2aa98e2SPeter Wemm
624040266059SGregory Neil Shapiro /*
624140266059SGregory Neil Shapiro ** HES_MAP_CLOSE -- free the Hesiod context
624240266059SGregory Neil Shapiro */
624340266059SGregory Neil Shapiro
624440266059SGregory Neil Shapiro void
hes_map_close(map)624540266059SGregory Neil Shapiro hes_map_close(map)
624640266059SGregory Neil Shapiro MAP *map;
624740266059SGregory Neil Shapiro {
624840266059SGregory Neil Shapiro if (tTd(38, 20))
624940266059SGregory Neil Shapiro sm_dprintf("hes_map_close(%s)\n", map->map_file);
625040266059SGregory Neil Shapiro
625140266059SGregory Neil Shapiro # ifdef HESIOD_INIT
625240266059SGregory Neil Shapiro /* Free the hesiod context */
625340266059SGregory Neil Shapiro if (HesiodContext != NULL)
625440266059SGregory Neil Shapiro {
625540266059SGregory Neil Shapiro hesiod_end(HesiodContext);
625640266059SGregory Neil Shapiro HesiodContext = NULL;
625740266059SGregory Neil Shapiro }
625840266059SGregory Neil Shapiro # endif /* HESIOD_INIT */
625940266059SGregory Neil Shapiro }
626040266059SGregory Neil Shapiro
626106f25ae9SGregory Neil Shapiro #endif /* HESIOD */
626240266059SGregory Neil Shapiro /*
6263c2aa98e2SPeter Wemm ** NeXT NETINFO Modules
6264c2aa98e2SPeter Wemm */
6265c2aa98e2SPeter Wemm
6266c2aa98e2SPeter Wemm #if NETINFO
6267c2aa98e2SPeter Wemm
6268c2aa98e2SPeter Wemm # define NETINFO_DEFAULT_DIR "/aliases"
6269c2aa98e2SPeter Wemm # define NETINFO_DEFAULT_PROPERTY "members"
6270c2aa98e2SPeter Wemm
6271c2aa98e2SPeter Wemm /*
6272c2aa98e2SPeter Wemm ** NI_MAP_OPEN -- open NetInfo Aliases
6273c2aa98e2SPeter Wemm */
6274c2aa98e2SPeter Wemm
6275c2aa98e2SPeter Wemm bool
ni_map_open(map,mode)6276c2aa98e2SPeter Wemm ni_map_open(map, mode)
6277c2aa98e2SPeter Wemm MAP *map;
6278c2aa98e2SPeter Wemm int mode;
6279c2aa98e2SPeter Wemm {
6280c2aa98e2SPeter Wemm if (tTd(38, 2))
628140266059SGregory Neil Shapiro sm_dprintf("ni_map_open(%s, %s, %d)\n",
6282c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
6283c2aa98e2SPeter Wemm mode &= O_ACCMODE;
6284c2aa98e2SPeter Wemm
6285c2aa98e2SPeter Wemm if (*map->map_file == '\0')
6286c2aa98e2SPeter Wemm map->map_file = NETINFO_DEFAULT_DIR;
6287c2aa98e2SPeter Wemm
6288c2aa98e2SPeter Wemm if (map->map_valcolnm == NULL)
6289c2aa98e2SPeter Wemm map->map_valcolnm = NETINFO_DEFAULT_PROPERTY;
6290c2aa98e2SPeter Wemm
629140266059SGregory Neil Shapiro if (map->map_coldelim == '\0')
629240266059SGregory Neil Shapiro {
629340266059SGregory Neil Shapiro if (bitset(MF_ALIAS, map->map_mflags))
6294c2aa98e2SPeter Wemm map->map_coldelim = ',';
629540266059SGregory Neil Shapiro else if (bitset(MF_FILECLASS, map->map_mflags))
629640266059SGregory Neil Shapiro map->map_coldelim = ' ';
629740266059SGregory Neil Shapiro }
629840266059SGregory Neil Shapiro return true;
6299c2aa98e2SPeter Wemm }
6300c2aa98e2SPeter Wemm
6301c2aa98e2SPeter Wemm
6302c2aa98e2SPeter Wemm /*
6303c2aa98e2SPeter Wemm ** NI_MAP_LOOKUP -- look up a datum in NetInfo
6304c2aa98e2SPeter Wemm */
6305c2aa98e2SPeter Wemm
6306c2aa98e2SPeter Wemm char *
ni_map_lookup(map,name,av,statp)6307c2aa98e2SPeter Wemm ni_map_lookup(map, name, av, statp)
6308c2aa98e2SPeter Wemm MAP *map;
6309c2aa98e2SPeter Wemm char *name;
6310c2aa98e2SPeter Wemm char **av;
6311c2aa98e2SPeter Wemm int *statp;
6312c2aa98e2SPeter Wemm {
6313c2aa98e2SPeter Wemm char *res;
6314c2aa98e2SPeter Wemm char *propval;
6315c2aa98e2SPeter Wemm
6316c2aa98e2SPeter Wemm if (tTd(38, 20))
631740266059SGregory Neil Shapiro sm_dprintf("ni_map_lookup(%s, %s)\n", map->map_mname, name);
6318c2aa98e2SPeter Wemm
6319c2aa98e2SPeter Wemm propval = ni_propval(map->map_file, map->map_keycolnm, name,
6320c2aa98e2SPeter Wemm map->map_valcolnm, map->map_coldelim);
6321c2aa98e2SPeter Wemm
6322c2aa98e2SPeter Wemm if (propval == NULL)
6323c2aa98e2SPeter Wemm return NULL;
6324c2aa98e2SPeter Wemm
632540266059SGregory Neil Shapiro SM_TRY
6326c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
6327c2aa98e2SPeter Wemm res = map_rewrite(map, name, strlen(name), NULL);
6328c2aa98e2SPeter Wemm else
6329c2aa98e2SPeter Wemm res = map_rewrite(map, propval, strlen(propval), av);
633040266059SGregory Neil Shapiro SM_FINALLY
63318774250cSGregory Neil Shapiro sm_free(propval);
633240266059SGregory Neil Shapiro SM_END_TRY
6333c2aa98e2SPeter Wemm return res;
6334c2aa98e2SPeter Wemm }
6335c2aa98e2SPeter Wemm
6336c2aa98e2SPeter Wemm
633706f25ae9SGregory Neil Shapiro static bool
ni_getcanonname(name,hbsize,statp)6338c2aa98e2SPeter Wemm ni_getcanonname(name, hbsize, statp)
6339c2aa98e2SPeter Wemm char *name;
6340c2aa98e2SPeter Wemm int hbsize;
6341c2aa98e2SPeter Wemm int *statp;
6342c2aa98e2SPeter Wemm {
6343c2aa98e2SPeter Wemm char *vptr;
6344c2aa98e2SPeter Wemm char *ptr;
63452fb4f839SGregory Neil Shapiro char nbuf[MAXNAME + 1]; /* EAI:hostname */
6346c2aa98e2SPeter Wemm
6347c2aa98e2SPeter Wemm if (tTd(38, 20))
634840266059SGregory Neil Shapiro sm_dprintf("ni_getcanonname(%s)\n", name);
6349c2aa98e2SPeter Wemm
6350d0cef73dSGregory Neil Shapiro if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
6351c2aa98e2SPeter Wemm {
6352c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
635340266059SGregory Neil Shapiro return false;
6354c2aa98e2SPeter Wemm }
6355602a2b1bSGregory Neil Shapiro (void) shorten_hostname(nbuf);
6356c2aa98e2SPeter Wemm
6357c2aa98e2SPeter Wemm /* we only accept single token search key */
6358c2aa98e2SPeter Wemm if (strchr(nbuf, '.'))
6359c2aa98e2SPeter Wemm {
6360c2aa98e2SPeter Wemm *statp = EX_NOHOST;
636140266059SGregory Neil Shapiro return false;
6362c2aa98e2SPeter Wemm }
6363c2aa98e2SPeter Wemm
6364c2aa98e2SPeter Wemm /* Do the search */
6365c2aa98e2SPeter Wemm vptr = ni_propval("/machines", NULL, nbuf, "name", '\n');
6366c2aa98e2SPeter Wemm
6367c2aa98e2SPeter Wemm if (vptr == NULL)
6368c2aa98e2SPeter Wemm {
6369c2aa98e2SPeter Wemm *statp = EX_NOHOST;
637040266059SGregory Neil Shapiro return false;
6371c2aa98e2SPeter Wemm }
6372c2aa98e2SPeter Wemm
6373c2aa98e2SPeter Wemm /* Only want the first machine name */
6374c2aa98e2SPeter Wemm if ((ptr = strchr(vptr, '\n')) != NULL)
6375c2aa98e2SPeter Wemm *ptr = '\0';
6376c2aa98e2SPeter Wemm
637740266059SGregory Neil Shapiro if (sm_strlcpy(name, vptr, hbsize) >= hbsize)
6378c2aa98e2SPeter Wemm {
637940266059SGregory Neil Shapiro sm_free(vptr);
638040266059SGregory Neil Shapiro *statp = EX_UNAVAILABLE;
638140266059SGregory Neil Shapiro return true;
638240266059SGregory Neil Shapiro }
63838774250cSGregory Neil Shapiro sm_free(vptr);
6384c2aa98e2SPeter Wemm *statp = EX_OK;
638540266059SGregory Neil Shapiro return false;
6386c2aa98e2SPeter Wemm }
6387065a643dSPeter Wemm #endif /* NETINFO */
638840266059SGregory Neil Shapiro /*
6389c2aa98e2SPeter Wemm ** TEXT (unindexed text file) Modules
6390c2aa98e2SPeter Wemm **
6391c2aa98e2SPeter Wemm ** This code donated by Sun Microsystems.
6392c2aa98e2SPeter Wemm */
6393c2aa98e2SPeter Wemm
6394c2aa98e2SPeter Wemm #define map_sff map_lockfd /* overload field */
6395c2aa98e2SPeter Wemm
6396c2aa98e2SPeter Wemm
6397c2aa98e2SPeter Wemm /*
6398c2aa98e2SPeter Wemm ** TEXT_MAP_OPEN -- open text table
6399c2aa98e2SPeter Wemm */
6400c2aa98e2SPeter Wemm
6401c2aa98e2SPeter Wemm bool
text_map_open(map,mode)6402c2aa98e2SPeter Wemm text_map_open(map, mode)
6403c2aa98e2SPeter Wemm MAP *map;
6404c2aa98e2SPeter Wemm int mode;
6405c2aa98e2SPeter Wemm {
640606f25ae9SGregory Neil Shapiro long sff;
6407c2aa98e2SPeter Wemm int i;
6408c2aa98e2SPeter Wemm
6409c2aa98e2SPeter Wemm if (tTd(38, 2))
641040266059SGregory Neil Shapiro sm_dprintf("text_map_open(%s, %s, %d)\n",
6411c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
6412c2aa98e2SPeter Wemm
6413c2aa98e2SPeter Wemm mode &= O_ACCMODE;
6414c2aa98e2SPeter Wemm if (mode != O_RDONLY)
6415c2aa98e2SPeter Wemm {
6416c2aa98e2SPeter Wemm errno = EPERM;
641740266059SGregory Neil Shapiro return false;
6418c2aa98e2SPeter Wemm }
6419c2aa98e2SPeter Wemm
6420c2aa98e2SPeter Wemm if (*map->map_file == '\0')
6421c2aa98e2SPeter Wemm {
6422c2aa98e2SPeter Wemm syserr("text map \"%s\": file name required",
6423c2aa98e2SPeter Wemm map->map_mname);
642440266059SGregory Neil Shapiro return false;
6425c2aa98e2SPeter Wemm }
6426c2aa98e2SPeter Wemm
6427c2aa98e2SPeter Wemm if (map->map_file[0] != '/')
6428c2aa98e2SPeter Wemm {
6429c2aa98e2SPeter Wemm syserr("text map \"%s\": file name must be fully qualified",
6430c2aa98e2SPeter Wemm map->map_mname);
643140266059SGregory Neil Shapiro return false;
6432c2aa98e2SPeter Wemm }
6433c2aa98e2SPeter Wemm
6434c2aa98e2SPeter Wemm sff = SFF_ROOTOK|SFF_REGONLY;
643506f25ae9SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
6436c2aa98e2SPeter Wemm sff |= SFF_NOWLINK;
643706f25ae9SGregory Neil Shapiro if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
6438c2aa98e2SPeter Wemm sff |= SFF_SAFEDIRPATH;
6439c2aa98e2SPeter Wemm if ((i = safefile(map->map_file, RunAsUid, RunAsGid, RunAsUserName,
6440c2aa98e2SPeter Wemm sff, S_IRUSR, NULL)) != 0)
6441c2aa98e2SPeter Wemm {
644206f25ae9SGregory Neil Shapiro int save_errno = errno;
644306f25ae9SGregory Neil Shapiro
6444c2aa98e2SPeter Wemm /* cannot open this map */
6445c2aa98e2SPeter Wemm if (tTd(38, 2))
644640266059SGregory Neil Shapiro sm_dprintf("\tunsafe map file: %d\n", i);
644706f25ae9SGregory Neil Shapiro errno = save_errno;
6448c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
6449c2aa98e2SPeter Wemm syserr("text map \"%s\": unsafe map file %s",
6450c2aa98e2SPeter Wemm map->map_mname, map->map_file);
645140266059SGregory Neil Shapiro return false;
6452c2aa98e2SPeter Wemm }
6453c2aa98e2SPeter Wemm
6454c2aa98e2SPeter Wemm if (map->map_keycolnm == NULL)
6455c2aa98e2SPeter Wemm map->map_keycolno = 0;
6456c2aa98e2SPeter Wemm else
6457c2aa98e2SPeter Wemm {
6458c2aa98e2SPeter Wemm if (!(isascii(*map->map_keycolnm) && isdigit(*map->map_keycolnm)))
6459c2aa98e2SPeter Wemm {
6460c2aa98e2SPeter Wemm syserr("text map \"%s\", file %s: -k should specify a number, not %s",
6461c2aa98e2SPeter Wemm map->map_mname, map->map_file,
6462c2aa98e2SPeter Wemm map->map_keycolnm);
646340266059SGregory Neil Shapiro return false;
6464c2aa98e2SPeter Wemm }
6465c2aa98e2SPeter Wemm map->map_keycolno = atoi(map->map_keycolnm);
6466c2aa98e2SPeter Wemm }
6467c2aa98e2SPeter Wemm
6468c2aa98e2SPeter Wemm if (map->map_valcolnm == NULL)
6469c2aa98e2SPeter Wemm map->map_valcolno = 0;
6470c2aa98e2SPeter Wemm else
6471c2aa98e2SPeter Wemm {
6472c2aa98e2SPeter Wemm if (!(isascii(*map->map_valcolnm) && isdigit(*map->map_valcolnm)))
6473c2aa98e2SPeter Wemm {
6474c2aa98e2SPeter Wemm syserr("text map \"%s\", file %s: -v should specify a number, not %s",
6475c2aa98e2SPeter Wemm map->map_mname, map->map_file,
6476c2aa98e2SPeter Wemm map->map_valcolnm);
647740266059SGregory Neil Shapiro return false;
6478c2aa98e2SPeter Wemm }
6479c2aa98e2SPeter Wemm map->map_valcolno = atoi(map->map_valcolnm);
6480c2aa98e2SPeter Wemm }
6481c2aa98e2SPeter Wemm
6482c2aa98e2SPeter Wemm if (tTd(38, 2))
6483c2aa98e2SPeter Wemm {
648440266059SGregory Neil Shapiro sm_dprintf("text_map_open(%s, %s): delimiter = ",
6485c2aa98e2SPeter Wemm map->map_mname, map->map_file);
6486c2aa98e2SPeter Wemm if (map->map_coldelim == '\0')
648740266059SGregory Neil Shapiro sm_dprintf("(white space)\n");
6488c2aa98e2SPeter Wemm else
648940266059SGregory Neil Shapiro sm_dprintf("%c\n", map->map_coldelim);
6490c2aa98e2SPeter Wemm }
6491c2aa98e2SPeter Wemm
6492c2aa98e2SPeter Wemm map->map_sff = sff;
649340266059SGregory Neil Shapiro return true;
6494c2aa98e2SPeter Wemm }
6495c2aa98e2SPeter Wemm
6496c2aa98e2SPeter Wemm
6497c2aa98e2SPeter Wemm /*
6498c2aa98e2SPeter Wemm ** TEXT_MAP_LOOKUP -- look up a datum in a TEXT table
6499c2aa98e2SPeter Wemm */
6500c2aa98e2SPeter Wemm
6501c2aa98e2SPeter Wemm char *
text_map_lookup(map,name,av,statp)6502c2aa98e2SPeter Wemm text_map_lookup(map, name, av, statp)
6503c2aa98e2SPeter Wemm MAP *map;
6504c2aa98e2SPeter Wemm char *name;
6505c2aa98e2SPeter Wemm char **av;
6506c2aa98e2SPeter Wemm int *statp;
6507c2aa98e2SPeter Wemm {
6508c2aa98e2SPeter Wemm char *vp;
6509c2aa98e2SPeter Wemm auto int vsize;
6510c2aa98e2SPeter Wemm int buflen;
651140266059SGregory Neil Shapiro SM_FILE_T *f;
6512c2aa98e2SPeter Wemm char delim;
6513c2aa98e2SPeter Wemm int key_idx;
6514c2aa98e2SPeter Wemm bool found_it;
651506f25ae9SGregory Neil Shapiro long sff = map->map_sff;
65162fb4f839SGregory Neil Shapiro char search_key[MAXNAME + 1]; /* EAI:ok */
6517c2aa98e2SPeter Wemm char linebuf[MAXLINE];
65182fb4f839SGregory Neil Shapiro char buf[MAXNAME + 1]; /* EAI:ok */
6519c2aa98e2SPeter Wemm
652040266059SGregory Neil Shapiro found_it = false;
6521c2aa98e2SPeter Wemm if (tTd(38, 20))
652240266059SGregory Neil Shapiro sm_dprintf("text_map_lookup(%s, %s)\n", map->map_mname, name);
6523c2aa98e2SPeter Wemm
6524c2aa98e2SPeter Wemm buflen = strlen(name);
6525d0cef73dSGregory Neil Shapiro if (buflen > sizeof(search_key) - 1)
6526d0cef73dSGregory Neil Shapiro buflen = sizeof(search_key) - 1; /* XXX just cut if off? */
652706f25ae9SGregory Neil Shapiro memmove(search_key, name, buflen);
6528c2aa98e2SPeter Wemm search_key[buflen] = '\0';
6529c2aa98e2SPeter Wemm if (!bitset(MF_NOFOLDCASE, map->map_mflags))
65302fb4f839SGregory Neil Shapiro makelower_buf(search_key, search_key, sizeof(search_key));
6531c2aa98e2SPeter Wemm
6532c2aa98e2SPeter Wemm f = safefopen(map->map_file, O_RDONLY, FileMode, sff);
6533c2aa98e2SPeter Wemm if (f == NULL)
6534c2aa98e2SPeter Wemm {
6535c2aa98e2SPeter Wemm map->map_mflags &= ~(MF_VALID|MF_OPEN);
6536c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
6537c2aa98e2SPeter Wemm return NULL;
6538c2aa98e2SPeter Wemm }
6539c2aa98e2SPeter Wemm key_idx = map->map_keycolno;
6540c2aa98e2SPeter Wemm delim = map->map_coldelim;
654194c01205SGregory Neil Shapiro while (sm_io_fgets(f, SM_TIME_DEFAULT,
6542552d4955SGregory Neil Shapiro linebuf, sizeof(linebuf)) >= 0)
6543c2aa98e2SPeter Wemm {
6544c2aa98e2SPeter Wemm char *p;
6545c2aa98e2SPeter Wemm
6546c2aa98e2SPeter Wemm /* skip comment line */
6547c2aa98e2SPeter Wemm if (linebuf[0] == '#')
6548c2aa98e2SPeter Wemm continue;
6549c2aa98e2SPeter Wemm p = strchr(linebuf, '\n');
6550c2aa98e2SPeter Wemm if (p != NULL)
6551c2aa98e2SPeter Wemm *p = '\0';
6552d0cef73dSGregory Neil Shapiro p = get_column(linebuf, key_idx, delim, buf, sizeof(buf));
65532fb4f839SGregory Neil Shapiro if (p != NULL && SM_STRCASEEQ(search_key, p))
6554c2aa98e2SPeter Wemm {
655540266059SGregory Neil Shapiro found_it = true;
6556c2aa98e2SPeter Wemm break;
6557c2aa98e2SPeter Wemm }
6558c2aa98e2SPeter Wemm }
655940266059SGregory Neil Shapiro (void) sm_io_close(f, SM_TIME_DEFAULT);
6560c2aa98e2SPeter Wemm if (!found_it)
6561c2aa98e2SPeter Wemm {
6562c2aa98e2SPeter Wemm *statp = EX_NOTFOUND;
6563c2aa98e2SPeter Wemm return NULL;
6564c2aa98e2SPeter Wemm }
6565d0cef73dSGregory Neil Shapiro vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof(buf));
6566065a643dSPeter Wemm if (vp == NULL)
6567065a643dSPeter Wemm {
6568065a643dSPeter Wemm *statp = EX_NOTFOUND;
6569065a643dSPeter Wemm return NULL;
6570065a643dSPeter Wemm }
6571c2aa98e2SPeter Wemm vsize = strlen(vp);
6572c2aa98e2SPeter Wemm *statp = EX_OK;
6573c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
6574c2aa98e2SPeter Wemm return map_rewrite(map, name, strlen(name), NULL);
6575c2aa98e2SPeter Wemm else
6576c2aa98e2SPeter Wemm return map_rewrite(map, vp, vsize, av);
6577c2aa98e2SPeter Wemm }
6578c2aa98e2SPeter Wemm
6579c2aa98e2SPeter Wemm /*
6580c2aa98e2SPeter Wemm ** TEXT_GETCANONNAME -- look up canonical name in hosts file
6581c2aa98e2SPeter Wemm */
6582c2aa98e2SPeter Wemm
658306f25ae9SGregory Neil Shapiro static bool
text_getcanonname(name,hbsize,statp)6584c2aa98e2SPeter Wemm text_getcanonname(name, hbsize, statp)
6585c2aa98e2SPeter Wemm char *name;
6586c2aa98e2SPeter Wemm int hbsize;
6587c2aa98e2SPeter Wemm int *statp;
6588c2aa98e2SPeter Wemm {
6589c2aa98e2SPeter Wemm bool found;
6590602a2b1bSGregory Neil Shapiro char *dot;
659140266059SGregory Neil Shapiro SM_FILE_T *f;
6592c2aa98e2SPeter Wemm char linebuf[MAXLINE];
65932fb4f839SGregory Neil Shapiro char cbuf[MAXNAME + 1]; /* EAI:hostname */
65942fb4f839SGregory Neil Shapiro char nbuf[MAXNAME + 1]; /* EAI:hostname */
6595c2aa98e2SPeter Wemm
6596c2aa98e2SPeter Wemm if (tTd(38, 20))
659740266059SGregory Neil Shapiro sm_dprintf("text_getcanonname(%s)\n", name);
6598c2aa98e2SPeter Wemm
6599d0cef73dSGregory Neil Shapiro if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
6600c2aa98e2SPeter Wemm {
6601c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
660240266059SGregory Neil Shapiro return false;
6603c2aa98e2SPeter Wemm }
6604602a2b1bSGregory Neil Shapiro dot = shorten_hostname(nbuf);
6605c2aa98e2SPeter Wemm
660640266059SGregory Neil Shapiro f = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, HostsFile, SM_IO_RDONLY,
660740266059SGregory Neil Shapiro NULL);
6608c2aa98e2SPeter Wemm if (f == NULL)
6609c2aa98e2SPeter Wemm {
6610c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
661140266059SGregory Neil Shapiro return false;
6612c2aa98e2SPeter Wemm }
661340266059SGregory Neil Shapiro found = false;
661440266059SGregory Neil Shapiro while (!found &&
661594c01205SGregory Neil Shapiro sm_io_fgets(f, SM_TIME_DEFAULT,
6616552d4955SGregory Neil Shapiro linebuf, sizeof(linebuf)) >= 0)
6617c2aa98e2SPeter Wemm {
6618c2aa98e2SPeter Wemm char *p = strpbrk(linebuf, "#\n");
6619c2aa98e2SPeter Wemm
6620c2aa98e2SPeter Wemm if (p != NULL)
6621c2aa98e2SPeter Wemm *p = '\0';
6622c2aa98e2SPeter Wemm if (linebuf[0] != '\0')
6623602a2b1bSGregory Neil Shapiro found = extract_canonname(nbuf, dot, linebuf,
6624d0cef73dSGregory Neil Shapiro cbuf, sizeof(cbuf));
6625c2aa98e2SPeter Wemm }
662640266059SGregory Neil Shapiro (void) sm_io_close(f, SM_TIME_DEFAULT);
6627c2aa98e2SPeter Wemm if (!found)
6628c2aa98e2SPeter Wemm {
6629c2aa98e2SPeter Wemm *statp = EX_NOHOST;
663040266059SGregory Neil Shapiro return false;
6631c2aa98e2SPeter Wemm }
6632c2aa98e2SPeter Wemm
663340266059SGregory Neil Shapiro if (sm_strlcpy(name, cbuf, hbsize) >= hbsize)
6634c2aa98e2SPeter Wemm {
6635c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
663640266059SGregory Neil Shapiro return false;
6637c2aa98e2SPeter Wemm }
663840266059SGregory Neil Shapiro *statp = EX_OK;
663940266059SGregory Neil Shapiro return true;
664040266059SGregory Neil Shapiro }
664140266059SGregory Neil Shapiro /*
6642c2aa98e2SPeter Wemm ** STAB (Symbol Table) Modules
6643c2aa98e2SPeter Wemm */
6644c2aa98e2SPeter Wemm
6645c2aa98e2SPeter Wemm
6646c2aa98e2SPeter Wemm /*
6647c2aa98e2SPeter Wemm ** STAB_MAP_LOOKUP -- look up alias in symbol table
6648c2aa98e2SPeter Wemm */
6649c2aa98e2SPeter Wemm
6650c2aa98e2SPeter Wemm /* ARGSUSED2 */
6651c2aa98e2SPeter Wemm char *
stab_map_lookup(map,name,av,pstat)6652c2aa98e2SPeter Wemm stab_map_lookup(map, name, av, pstat)
6653c2aa98e2SPeter Wemm register MAP *map;
6654c2aa98e2SPeter Wemm char *name;
6655c2aa98e2SPeter Wemm char **av;
6656c2aa98e2SPeter Wemm int *pstat;
6657c2aa98e2SPeter Wemm {
6658c2aa98e2SPeter Wemm register STAB *s;
6659c2aa98e2SPeter Wemm
6660c2aa98e2SPeter Wemm if (tTd(38, 20))
666140266059SGregory Neil Shapiro sm_dprintf("stab_lookup(%s, %s)\n",
6662c2aa98e2SPeter Wemm map->map_mname, name);
6663c2aa98e2SPeter Wemm
6664c2aa98e2SPeter Wemm s = stab(name, ST_ALIAS, ST_FIND);
666513d88268SGregory Neil Shapiro if (s == NULL)
666606f25ae9SGregory Neil Shapiro return NULL;
666713d88268SGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
666813d88268SGregory Neil Shapiro return map_rewrite(map, name, strlen(name), NULL);
666913d88268SGregory Neil Shapiro else
667013d88268SGregory Neil Shapiro return map_rewrite(map, s->s_alias, strlen(s->s_alias), av);
6671c2aa98e2SPeter Wemm }
6672c2aa98e2SPeter Wemm
6673c2aa98e2SPeter Wemm /*
6674c2aa98e2SPeter Wemm ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild)
6675c2aa98e2SPeter Wemm */
6676c2aa98e2SPeter Wemm
6677c2aa98e2SPeter Wemm void
stab_map_store(map,lhs,rhs)6678c2aa98e2SPeter Wemm stab_map_store(map, lhs, rhs)
6679c2aa98e2SPeter Wemm register MAP *map;
6680c2aa98e2SPeter Wemm char *lhs;
6681c2aa98e2SPeter Wemm char *rhs;
6682c2aa98e2SPeter Wemm {
6683c2aa98e2SPeter Wemm register STAB *s;
6684c2aa98e2SPeter Wemm
6685c2aa98e2SPeter Wemm s = stab(lhs, ST_ALIAS, ST_ENTER);
6686c2aa98e2SPeter Wemm s->s_alias = newstr(rhs);
6687c2aa98e2SPeter Wemm }
6688c2aa98e2SPeter Wemm
6689c2aa98e2SPeter Wemm
6690c2aa98e2SPeter Wemm /*
6691c2aa98e2SPeter Wemm ** STAB_MAP_OPEN -- initialize (reads data file)
6692c2aa98e2SPeter Wemm **
66936f9c8e5bSGregory Neil Shapiro ** This is a weird case -- it is only intended as a fallback for
6694c2aa98e2SPeter Wemm ** aliases. For this reason, opens for write (only during a
6695c2aa98e2SPeter Wemm ** "newaliases") always fails, and opens for read open the
6696c2aa98e2SPeter Wemm ** actual underlying text file instead of the database.
6697c2aa98e2SPeter Wemm */
6698c2aa98e2SPeter Wemm
6699c2aa98e2SPeter Wemm bool
stab_map_open(map,mode)6700c2aa98e2SPeter Wemm stab_map_open(map, mode)
6701c2aa98e2SPeter Wemm register MAP *map;
6702c2aa98e2SPeter Wemm int mode;
6703c2aa98e2SPeter Wemm {
670440266059SGregory Neil Shapiro SM_FILE_T *af;
670506f25ae9SGregory Neil Shapiro long sff;
6706c2aa98e2SPeter Wemm struct stat st;
6707c2aa98e2SPeter Wemm
6708c2aa98e2SPeter Wemm if (tTd(38, 2))
670940266059SGregory Neil Shapiro sm_dprintf("stab_map_open(%s, %s, %d)\n",
6710c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
6711c2aa98e2SPeter Wemm
6712c2aa98e2SPeter Wemm mode &= O_ACCMODE;
6713c2aa98e2SPeter Wemm if (mode != O_RDONLY)
6714c2aa98e2SPeter Wemm {
6715c2aa98e2SPeter Wemm errno = EPERM;
671640266059SGregory Neil Shapiro return false;
6717c2aa98e2SPeter Wemm }
6718c2aa98e2SPeter Wemm
6719c2aa98e2SPeter Wemm sff = SFF_ROOTOK|SFF_REGONLY;
672006f25ae9SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
6721c2aa98e2SPeter Wemm sff |= SFF_NOWLINK;
672206f25ae9SGregory Neil Shapiro if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
6723c2aa98e2SPeter Wemm sff |= SFF_SAFEDIRPATH;
6724c2aa98e2SPeter Wemm af = safefopen(map->map_file, O_RDONLY, 0444, sff);
6725c2aa98e2SPeter Wemm if (af == NULL)
672640266059SGregory Neil Shapiro return false;
672740266059SGregory Neil Shapiro readaliases(map, af, false, false);
6728c2aa98e2SPeter Wemm
672940266059SGregory Neil Shapiro if (fstat(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), &st) >= 0)
6730c2aa98e2SPeter Wemm map->map_mtime = st.st_mtime;
673140266059SGregory Neil Shapiro (void) sm_io_close(af, SM_TIME_DEFAULT);
6732c2aa98e2SPeter Wemm
673340266059SGregory Neil Shapiro return true;
6734c2aa98e2SPeter Wemm }
673540266059SGregory Neil Shapiro /*
6736c2aa98e2SPeter Wemm ** Implicit Modules
6737c2aa98e2SPeter Wemm **
6738c2aa98e2SPeter Wemm ** Tries several types. For back compatibility of aliases.
6739c2aa98e2SPeter Wemm */
6740c2aa98e2SPeter Wemm
6741c2aa98e2SPeter Wemm
6742c2aa98e2SPeter Wemm /*
6743c2aa98e2SPeter Wemm ** IMPL_MAP_LOOKUP -- lookup in best open database
6744c2aa98e2SPeter Wemm */
6745c2aa98e2SPeter Wemm
6746c2aa98e2SPeter Wemm char *
impl_map_lookup(map,name,av,pstat)6747c2aa98e2SPeter Wemm impl_map_lookup(map, name, av, pstat)
6748c2aa98e2SPeter Wemm MAP *map;
6749c2aa98e2SPeter Wemm char *name;
6750c2aa98e2SPeter Wemm char **av;
6751c2aa98e2SPeter Wemm int *pstat;
6752c2aa98e2SPeter Wemm {
6753c2aa98e2SPeter Wemm if (tTd(38, 20))
675440266059SGregory Neil Shapiro sm_dprintf("impl_map_lookup(%s, %s)\n",
6755c2aa98e2SPeter Wemm map->map_mname, name);
6756c2aa98e2SPeter Wemm
675740266059SGregory Neil Shapiro #if NEWDB
6758c2aa98e2SPeter Wemm if (bitset(MF_IMPL_HASH, map->map_mflags))
6759c2aa98e2SPeter Wemm return db_map_lookup(map, name, av, pstat);
67605b0945b5SGregory Neil Shapiro #endif
676140266059SGregory Neil Shapiro #if NDBM
6762c2aa98e2SPeter Wemm if (bitset(MF_IMPL_NDBM, map->map_mflags))
6763c2aa98e2SPeter Wemm return ndbm_map_lookup(map, name, av, pstat);
67645b0945b5SGregory Neil Shapiro #endif
67655b0945b5SGregory Neil Shapiro #if CDB
67665b0945b5SGregory Neil Shapiro if (bitset(MF_IMPL_CDB, map->map_mflags))
67675b0945b5SGregory Neil Shapiro return cdb_map_lookup(map, name, av, pstat);
67685b0945b5SGregory Neil Shapiro #endif
6769c2aa98e2SPeter Wemm return stab_map_lookup(map, name, av, pstat);
6770c2aa98e2SPeter Wemm }
6771c2aa98e2SPeter Wemm
6772c2aa98e2SPeter Wemm /*
6773c2aa98e2SPeter Wemm ** IMPL_MAP_STORE -- store in open databases
6774c2aa98e2SPeter Wemm */
6775c2aa98e2SPeter Wemm
6776c2aa98e2SPeter Wemm void
impl_map_store(map,lhs,rhs)6777c2aa98e2SPeter Wemm impl_map_store(map, lhs, rhs)
6778c2aa98e2SPeter Wemm MAP *map;
6779c2aa98e2SPeter Wemm char *lhs;
6780c2aa98e2SPeter Wemm char *rhs;
6781c2aa98e2SPeter Wemm {
6782c2aa98e2SPeter Wemm if (tTd(38, 12))
678340266059SGregory Neil Shapiro sm_dprintf("impl_map_store(%s, %s, %s)\n",
6784c2aa98e2SPeter Wemm map->map_mname, lhs, rhs);
678540266059SGregory Neil Shapiro #if NEWDB
6786c2aa98e2SPeter Wemm if (bitset(MF_IMPL_HASH, map->map_mflags))
6787c2aa98e2SPeter Wemm db_map_store(map, lhs, rhs);
67885b0945b5SGregory Neil Shapiro #endif
678940266059SGregory Neil Shapiro #if NDBM
6790c2aa98e2SPeter Wemm if (bitset(MF_IMPL_NDBM, map->map_mflags))
6791c2aa98e2SPeter Wemm ndbm_map_store(map, lhs, rhs);
67925b0945b5SGregory Neil Shapiro #endif
67935b0945b5SGregory Neil Shapiro #if CDB
67945b0945b5SGregory Neil Shapiro if (bitset(MF_IMPL_CDB, map->map_mflags))
67955b0945b5SGregory Neil Shapiro cdb_map_store(map, lhs, rhs);
67965b0945b5SGregory Neil Shapiro #endif
6797c2aa98e2SPeter Wemm stab_map_store(map, lhs, rhs);
6798c2aa98e2SPeter Wemm }
6799c2aa98e2SPeter Wemm
6800c2aa98e2SPeter Wemm /*
6801c2aa98e2SPeter Wemm ** IMPL_MAP_OPEN -- implicit database open
6802c2aa98e2SPeter Wemm */
6803c2aa98e2SPeter Wemm
6804c2aa98e2SPeter Wemm bool
impl_map_open(map,mode)6805c2aa98e2SPeter Wemm impl_map_open(map, mode)
6806c2aa98e2SPeter Wemm MAP *map;
6807c2aa98e2SPeter Wemm int mode;
6808c2aa98e2SPeter Wemm {
68095b0945b5SGregory Neil Shapiro bool wasopt;
68105b0945b5SGregory Neil Shapiro
6811c2aa98e2SPeter Wemm if (tTd(38, 2))
681240266059SGregory Neil Shapiro sm_dprintf("impl_map_open(%s, %s, %d)\n",
6813c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
6814c2aa98e2SPeter Wemm
6815c2aa98e2SPeter Wemm mode &= O_ACCMODE;
68165b0945b5SGregory Neil Shapiro wasopt = bitset(MF_OPTIONAL, map->map_mflags);
68175b0945b5SGregory Neil Shapiro
68185b0945b5SGregory Neil Shapiro /* suppress error msgs */
68195b0945b5SGregory Neil Shapiro map->map_mflags |= MF_OPTIONAL;
682040266059SGregory Neil Shapiro #if NEWDB
6821c2aa98e2SPeter Wemm map->map_mflags |= MF_IMPL_HASH;
6822c2aa98e2SPeter Wemm if (hash_map_open(map, mode))
6823c2aa98e2SPeter Wemm {
6824c2aa98e2SPeter Wemm # ifdef NDBM_YP_COMPAT
6825c2aa98e2SPeter Wemm if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL)
68265b0945b5SGregory Neil Shapiro # endif
68275b0945b5SGregory Neil Shapiro goto ok;
6828c2aa98e2SPeter Wemm }
6829c2aa98e2SPeter Wemm else
6830c2aa98e2SPeter Wemm map->map_mflags &= ~MF_IMPL_HASH;
683106f25ae9SGregory Neil Shapiro #endif /* NEWDB */
683240266059SGregory Neil Shapiro #if NDBM
6833c2aa98e2SPeter Wemm map->map_mflags |= MF_IMPL_NDBM;
6834c2aa98e2SPeter Wemm if (ndbm_map_open(map, mode))
68355b0945b5SGregory Neil Shapiro goto ok;
6836c2aa98e2SPeter Wemm else
6837c2aa98e2SPeter Wemm map->map_mflags &= ~MF_IMPL_NDBM;
683806f25ae9SGregory Neil Shapiro #endif /* NDBM */
6839c2aa98e2SPeter Wemm
68405b0945b5SGregory Neil Shapiro #if CDB
68415b0945b5SGregory Neil Shapiro map->map_mflags |= MF_IMPL_CDB;
68425b0945b5SGregory Neil Shapiro if (cdb_map_open(map, mode))
68435b0945b5SGregory Neil Shapiro goto ok;
68445b0945b5SGregory Neil Shapiro else
68455b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_IMPL_CDB;
68465b0945b5SGregory Neil Shapiro #endif /* CDB */
68475b0945b5SGregory Neil Shapiro
68485b0945b5SGregory Neil Shapiro if (!bitset(MF_ALIAS, map->map_mflags))
68495b0945b5SGregory Neil Shapiro goto fail;
68505b0945b5SGregory Neil Shapiro #if NEWDB || NDBM || CDB
6851c2aa98e2SPeter Wemm if (Verbose)
6852c2aa98e2SPeter Wemm message("WARNING: cannot open alias database %s%s",
6853c2aa98e2SPeter Wemm map->map_file,
6854c2aa98e2SPeter Wemm mode == O_RDONLY ? "; reading text version" : "");
68555b0945b5SGregory Neil Shapiro #else
6856c2aa98e2SPeter Wemm if (mode != O_RDONLY)
6857c2aa98e2SPeter Wemm usrerr("Cannot rebuild aliases: no database format defined");
68585b0945b5SGregory Neil Shapiro #endif
6859c2aa98e2SPeter Wemm
68605b0945b5SGregory Neil Shapiro if (mode == O_RDONLY && stab_map_open(map, mode))
68615b0945b5SGregory Neil Shapiro goto ok;
68625b0945b5SGregory Neil Shapiro
68635b0945b5SGregory Neil Shapiro fail:
68645b0945b5SGregory Neil Shapiro if (!wasopt)
68655b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_OPTIONAL;
686640266059SGregory Neil Shapiro return false;
68675b0945b5SGregory Neil Shapiro
68685b0945b5SGregory Neil Shapiro ok:
68695b0945b5SGregory Neil Shapiro if (!wasopt)
68705b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_OPTIONAL;
68715b0945b5SGregory Neil Shapiro return true;
6872c2aa98e2SPeter Wemm }
6873c2aa98e2SPeter Wemm
6874c2aa98e2SPeter Wemm
6875c2aa98e2SPeter Wemm /*
6876c2aa98e2SPeter Wemm ** IMPL_MAP_CLOSE -- close any open database(s)
6877c2aa98e2SPeter Wemm */
6878c2aa98e2SPeter Wemm
6879c2aa98e2SPeter Wemm void
impl_map_close(map)6880c2aa98e2SPeter Wemm impl_map_close(map)
6881c2aa98e2SPeter Wemm MAP *map;
6882c2aa98e2SPeter Wemm {
6883c2aa98e2SPeter Wemm if (tTd(38, 9))
688440266059SGregory Neil Shapiro sm_dprintf("impl_map_close(%s, %s, %lx)\n",
6885c2aa98e2SPeter Wemm map->map_mname, map->map_file, map->map_mflags);
688640266059SGregory Neil Shapiro #if NEWDB
6887c2aa98e2SPeter Wemm if (bitset(MF_IMPL_HASH, map->map_mflags))
6888c2aa98e2SPeter Wemm {
6889c2aa98e2SPeter Wemm db_map_close(map);
6890c2aa98e2SPeter Wemm map->map_mflags &= ~MF_IMPL_HASH;
6891c2aa98e2SPeter Wemm }
689206f25ae9SGregory Neil Shapiro #endif /* NEWDB */
6893c2aa98e2SPeter Wemm
689440266059SGregory Neil Shapiro #if NDBM
6895c2aa98e2SPeter Wemm if (bitset(MF_IMPL_NDBM, map->map_mflags))
6896c2aa98e2SPeter Wemm {
6897c2aa98e2SPeter Wemm ndbm_map_close(map);
6898c2aa98e2SPeter Wemm map->map_mflags &= ~MF_IMPL_NDBM;
6899c2aa98e2SPeter Wemm }
690006f25ae9SGregory Neil Shapiro #endif /* NDBM */
69015b0945b5SGregory Neil Shapiro #if CDB
69025b0945b5SGregory Neil Shapiro if (bitset(MF_IMPL_CDB, map->map_mflags))
69035b0945b5SGregory Neil Shapiro {
69045b0945b5SGregory Neil Shapiro cdb_map_close(map);
69055b0945b5SGregory Neil Shapiro map->map_mflags &= ~MF_IMPL_CDB;
6906c2aa98e2SPeter Wemm }
69075b0945b5SGregory Neil Shapiro #endif /* CDB */
69085b0945b5SGregory Neil Shapiro }
69095b0945b5SGregory Neil Shapiro
691040266059SGregory Neil Shapiro /*
6911c2aa98e2SPeter Wemm ** User map class.
6912c2aa98e2SPeter Wemm **
6913c2aa98e2SPeter Wemm ** Provides access to the system password file.
6914c2aa98e2SPeter Wemm */
6915c2aa98e2SPeter Wemm
6916c2aa98e2SPeter Wemm /*
6917c2aa98e2SPeter Wemm ** USER_MAP_OPEN -- open user map
6918c2aa98e2SPeter Wemm **
6919c2aa98e2SPeter Wemm ** Really just binds field names to field numbers.
6920c2aa98e2SPeter Wemm */
6921c2aa98e2SPeter Wemm
6922c2aa98e2SPeter Wemm bool
user_map_open(map,mode)6923c2aa98e2SPeter Wemm user_map_open(map, mode)
6924c2aa98e2SPeter Wemm MAP *map;
6925c2aa98e2SPeter Wemm int mode;
6926c2aa98e2SPeter Wemm {
6927c2aa98e2SPeter Wemm if (tTd(38, 2))
692840266059SGregory Neil Shapiro sm_dprintf("user_map_open(%s, %d)\n",
6929c2aa98e2SPeter Wemm map->map_mname, mode);
6930c2aa98e2SPeter Wemm
6931c2aa98e2SPeter Wemm mode &= O_ACCMODE;
6932c2aa98e2SPeter Wemm if (mode != O_RDONLY)
6933c2aa98e2SPeter Wemm {
6934c2aa98e2SPeter Wemm /* issue a pseudo-error message */
693540266059SGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
693640266059SGregory Neil Shapiro return false;
6937c2aa98e2SPeter Wemm }
6938c2aa98e2SPeter Wemm if (map->map_valcolnm == NULL)
693906f25ae9SGregory Neil Shapiro /* EMPTY */
6940c2aa98e2SPeter Wemm /* nothing */ ;
69412fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "name"))
6942c2aa98e2SPeter Wemm map->map_valcolno = 1;
69432fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "passwd"))
6944c2aa98e2SPeter Wemm map->map_valcolno = 2;
69452fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "uid"))
6946c2aa98e2SPeter Wemm map->map_valcolno = 3;
69472fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "gid"))
6948c2aa98e2SPeter Wemm map->map_valcolno = 4;
69492fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "gecos"))
6950c2aa98e2SPeter Wemm map->map_valcolno = 5;
69512fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "dir"))
6952c2aa98e2SPeter Wemm map->map_valcolno = 6;
69532fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(map->map_valcolnm, "shell"))
6954c2aa98e2SPeter Wemm map->map_valcolno = 7;
6955c2aa98e2SPeter Wemm else
6956c2aa98e2SPeter Wemm {
6957c2aa98e2SPeter Wemm syserr("User map %s: unknown column name %s",
6958c2aa98e2SPeter Wemm map->map_mname, map->map_valcolnm);
695940266059SGregory Neil Shapiro return false;
6960c2aa98e2SPeter Wemm }
696140266059SGregory Neil Shapiro return true;
6962c2aa98e2SPeter Wemm }
6963c2aa98e2SPeter Wemm
6964c2aa98e2SPeter Wemm
6965c2aa98e2SPeter Wemm /*
6966c2aa98e2SPeter Wemm ** USER_MAP_LOOKUP -- look up a user in the passwd file.
6967c2aa98e2SPeter Wemm */
6968c2aa98e2SPeter Wemm
6969c2aa98e2SPeter Wemm /* ARGSUSED3 */
6970c2aa98e2SPeter Wemm char *
user_map_lookup(map,key,av,statp)6971c2aa98e2SPeter Wemm user_map_lookup(map, key, av, statp)
6972c2aa98e2SPeter Wemm MAP *map;
6973c2aa98e2SPeter Wemm char *key;
6974c2aa98e2SPeter Wemm char **av;
6975c2aa98e2SPeter Wemm int *statp;
6976c2aa98e2SPeter Wemm {
6977c2aa98e2SPeter Wemm auto bool fuzzy;
697840266059SGregory Neil Shapiro SM_MBDB_T user;
6979c2aa98e2SPeter Wemm
6980c2aa98e2SPeter Wemm if (tTd(38, 20))
698140266059SGregory Neil Shapiro sm_dprintf("user_map_lookup(%s, %s)\n",
6982c2aa98e2SPeter Wemm map->map_mname, key);
6983c2aa98e2SPeter Wemm
698440266059SGregory Neil Shapiro *statp = finduser(key, &fuzzy, &user);
698540266059SGregory Neil Shapiro if (*statp != EX_OK)
6986c2aa98e2SPeter Wemm return NULL;
6987c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
6988c2aa98e2SPeter Wemm return map_rewrite(map, key, strlen(key), NULL);
6989c2aa98e2SPeter Wemm else
6990c2aa98e2SPeter Wemm {
6991c2aa98e2SPeter Wemm char *rwval = NULL;
6992c2aa98e2SPeter Wemm char buf[30];
6993c2aa98e2SPeter Wemm
6994c2aa98e2SPeter Wemm switch (map->map_valcolno)
6995c2aa98e2SPeter Wemm {
6996c2aa98e2SPeter Wemm case 0:
6997c2aa98e2SPeter Wemm case 1:
699840266059SGregory Neil Shapiro rwval = user.mbdb_name;
6999c2aa98e2SPeter Wemm break;
7000c2aa98e2SPeter Wemm
7001c2aa98e2SPeter Wemm case 2:
700240266059SGregory Neil Shapiro rwval = "x"; /* passwd no longer supported */
7003c2aa98e2SPeter Wemm break;
7004c2aa98e2SPeter Wemm
7005c2aa98e2SPeter Wemm case 3:
7006d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%d",
700740266059SGregory Neil Shapiro (int) user.mbdb_uid);
7008c2aa98e2SPeter Wemm rwval = buf;
7009c2aa98e2SPeter Wemm break;
7010c2aa98e2SPeter Wemm
7011c2aa98e2SPeter Wemm case 4:
7012d0cef73dSGregory Neil Shapiro (void) sm_snprintf(buf, sizeof(buf), "%d",
701340266059SGregory Neil Shapiro (int) user.mbdb_gid);
7014c2aa98e2SPeter Wemm rwval = buf;
7015c2aa98e2SPeter Wemm break;
7016c2aa98e2SPeter Wemm
7017c2aa98e2SPeter Wemm case 5:
701840266059SGregory Neil Shapiro rwval = user.mbdb_fullname;
7019c2aa98e2SPeter Wemm break;
7020c2aa98e2SPeter Wemm
7021c2aa98e2SPeter Wemm case 6:
702240266059SGregory Neil Shapiro rwval = user.mbdb_homedir;
7023c2aa98e2SPeter Wemm break;
7024c2aa98e2SPeter Wemm
7025c2aa98e2SPeter Wemm case 7:
702640266059SGregory Neil Shapiro rwval = user.mbdb_shell;
7027c2aa98e2SPeter Wemm break;
7028af9557fdSGregory Neil Shapiro default:
7029af9557fdSGregory Neil Shapiro syserr("user_map %s: bogus field %d",
7030af9557fdSGregory Neil Shapiro map->map_mname, map->map_valcolno);
7031af9557fdSGregory Neil Shapiro return NULL;
7032c2aa98e2SPeter Wemm }
7033c2aa98e2SPeter Wemm return map_rewrite(map, rwval, strlen(rwval), av);
7034c2aa98e2SPeter Wemm }
7035c2aa98e2SPeter Wemm }
703640266059SGregory Neil Shapiro /*
7037c2aa98e2SPeter Wemm ** Program map type.
7038c2aa98e2SPeter Wemm **
7039c2aa98e2SPeter Wemm ** This provides access to arbitrary programs. It should be used
7040c2aa98e2SPeter Wemm ** only very sparingly, since there is no way to bound the cost
7041c2aa98e2SPeter Wemm ** of invoking an arbitrary program.
7042c2aa98e2SPeter Wemm */
7043c2aa98e2SPeter Wemm
7044c2aa98e2SPeter Wemm char *
prog_map_lookup(map,name,av,statp)7045c2aa98e2SPeter Wemm prog_map_lookup(map, name, av, statp)
7046c2aa98e2SPeter Wemm MAP *map;
7047c2aa98e2SPeter Wemm char *name;
7048c2aa98e2SPeter Wemm char **av;
7049c2aa98e2SPeter Wemm int *statp;
7050c2aa98e2SPeter Wemm {
7051c2aa98e2SPeter Wemm int i;
705206f25ae9SGregory Neil Shapiro int save_errno;
7053c2aa98e2SPeter Wemm int fd;
705406f25ae9SGregory Neil Shapiro int status;
7055c2aa98e2SPeter Wemm auto pid_t pid;
705606f25ae9SGregory Neil Shapiro register char *p;
7057c2aa98e2SPeter Wemm char *rval;
7058c2aa98e2SPeter Wemm char *argv[MAXPV + 1];
7059c2aa98e2SPeter Wemm char buf[MAXLINE];
7060c2aa98e2SPeter Wemm
7061c2aa98e2SPeter Wemm if (tTd(38, 20))
706240266059SGregory Neil Shapiro sm_dprintf("prog_map_lookup(%s, %s) %s\n",
7063c2aa98e2SPeter Wemm map->map_mname, name, map->map_file);
7064c2aa98e2SPeter Wemm
7065c2aa98e2SPeter Wemm i = 0;
7066c2aa98e2SPeter Wemm argv[i++] = map->map_file;
7067c2aa98e2SPeter Wemm if (map->map_rebuild != NULL)
7068c2aa98e2SPeter Wemm {
7069d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(buf, map->map_rebuild, sizeof(buf));
7070c2aa98e2SPeter Wemm for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t"))
7071c2aa98e2SPeter Wemm {
7072c2aa98e2SPeter Wemm if (i >= MAXPV - 1)
7073c2aa98e2SPeter Wemm break;
7074c2aa98e2SPeter Wemm argv[i++] = p;
7075c2aa98e2SPeter Wemm }
7076c2aa98e2SPeter Wemm }
7077c2aa98e2SPeter Wemm argv[i++] = name;
7078c2aa98e2SPeter Wemm argv[i] = NULL;
7079c2aa98e2SPeter Wemm if (tTd(38, 21))
7080c2aa98e2SPeter Wemm {
708140266059SGregory Neil Shapiro sm_dprintf("prog_open:");
7082c2aa98e2SPeter Wemm for (i = 0; argv[i] != NULL; i++)
708340266059SGregory Neil Shapiro sm_dprintf(" %s", argv[i]);
708440266059SGregory Neil Shapiro sm_dprintf("\n");
7085c2aa98e2SPeter Wemm }
708640266059SGregory Neil Shapiro (void) sm_blocksignal(SIGCHLD);
7087c2aa98e2SPeter Wemm pid = prog_open(argv, &fd, CurEnv);
7088c2aa98e2SPeter Wemm if (pid < 0)
7089c2aa98e2SPeter Wemm {
7090c2aa98e2SPeter Wemm if (!bitset(MF_OPTIONAL, map->map_mflags))
7091c2aa98e2SPeter Wemm syserr("prog_map_lookup(%s) failed (%s) -- closing",
709240266059SGregory Neil Shapiro map->map_mname, sm_errstring(errno));
7093c2aa98e2SPeter Wemm else if (tTd(38, 9))
709440266059SGregory Neil Shapiro sm_dprintf("prog_map_lookup(%s) failed (%s) -- closing",
709540266059SGregory Neil Shapiro map->map_mname, sm_errstring(errno));
7096c2aa98e2SPeter Wemm map->map_mflags &= ~(MF_VALID|MF_OPEN);
7097c2aa98e2SPeter Wemm *statp = EX_OSFILE;
7098c2aa98e2SPeter Wemm return NULL;
7099c2aa98e2SPeter Wemm }
7100d0cef73dSGregory Neil Shapiro i = read(fd, buf, sizeof(buf) - 1);
7101c2aa98e2SPeter Wemm if (i < 0)
7102c2aa98e2SPeter Wemm {
710340266059SGregory Neil Shapiro syserr("prog_map_lookup(%s): read error %s",
710440266059SGregory Neil Shapiro map->map_mname, sm_errstring(errno));
7105c2aa98e2SPeter Wemm rval = NULL;
7106c2aa98e2SPeter Wemm }
7107c2aa98e2SPeter Wemm else if (i == 0)
7108c2aa98e2SPeter Wemm {
7109c2aa98e2SPeter Wemm if (tTd(38, 20))
711040266059SGregory Neil Shapiro sm_dprintf("prog_map_lookup(%s): empty answer\n",
7111c2aa98e2SPeter Wemm map->map_mname);
7112c2aa98e2SPeter Wemm rval = NULL;
7113c2aa98e2SPeter Wemm }
7114c2aa98e2SPeter Wemm else
7115c2aa98e2SPeter Wemm {
7116c2aa98e2SPeter Wemm buf[i] = '\0';
7117c2aa98e2SPeter Wemm p = strchr(buf, '\n');
7118c2aa98e2SPeter Wemm if (p != NULL)
7119c2aa98e2SPeter Wemm *p = '\0';
7120c2aa98e2SPeter Wemm
7121c2aa98e2SPeter Wemm /* collect the return value */
7122c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
7123c2aa98e2SPeter Wemm rval = map_rewrite(map, name, strlen(name), NULL);
7124c2aa98e2SPeter Wemm else
71258774250cSGregory Neil Shapiro rval = map_rewrite(map, buf, strlen(buf), av);
7126c2aa98e2SPeter Wemm
7127c2aa98e2SPeter Wemm /* now flush any additional output */
7128d0cef73dSGregory Neil Shapiro while ((i = read(fd, buf, sizeof(buf))) > 0)
7129c2aa98e2SPeter Wemm continue;
7130c2aa98e2SPeter Wemm }
7131c2aa98e2SPeter Wemm
7132c2aa98e2SPeter Wemm /* wait for the process to terminate */
713306f25ae9SGregory Neil Shapiro (void) close(fd);
713406f25ae9SGregory Neil Shapiro status = waitfor(pid);
713506f25ae9SGregory Neil Shapiro save_errno = errno;
713640266059SGregory Neil Shapiro (void) sm_releasesignal(SIGCHLD);
713706f25ae9SGregory Neil Shapiro errno = save_errno;
7138c2aa98e2SPeter Wemm
713906f25ae9SGregory Neil Shapiro if (status == -1)
7140c2aa98e2SPeter Wemm {
714140266059SGregory Neil Shapiro syserr("prog_map_lookup(%s): wait error %s",
714240266059SGregory Neil Shapiro map->map_mname, sm_errstring(errno));
7143c2aa98e2SPeter Wemm *statp = EX_SOFTWARE;
7144c2aa98e2SPeter Wemm rval = NULL;
7145c2aa98e2SPeter Wemm }
714606f25ae9SGregory Neil Shapiro else if (WIFEXITED(status))
7147c2aa98e2SPeter Wemm {
714806f25ae9SGregory Neil Shapiro if ((*statp = WEXITSTATUS(status)) != EX_OK)
7149c2aa98e2SPeter Wemm rval = NULL;
7150c2aa98e2SPeter Wemm }
7151c2aa98e2SPeter Wemm else
7152c2aa98e2SPeter Wemm {
7153c2aa98e2SPeter Wemm syserr("prog_map_lookup(%s): child died on signal %d",
715406f25ae9SGregory Neil Shapiro map->map_mname, status);
7155c2aa98e2SPeter Wemm *statp = EX_UNAVAILABLE;
7156c2aa98e2SPeter Wemm rval = NULL;
7157c2aa98e2SPeter Wemm }
7158c2aa98e2SPeter Wemm return rval;
7159c2aa98e2SPeter Wemm }
716040266059SGregory Neil Shapiro /*
7161c2aa98e2SPeter Wemm ** Sequenced map type.
7162c2aa98e2SPeter Wemm **
7163c2aa98e2SPeter Wemm ** Tries each map in order until something matches, much like
7164c2aa98e2SPeter Wemm ** implicit. Stores go to the first map in the list that can
7165c2aa98e2SPeter Wemm ** support storing.
7166c2aa98e2SPeter Wemm **
7167c2aa98e2SPeter Wemm ** This is slightly unusual in that there are two interfaces.
7168c2aa98e2SPeter Wemm ** The "sequence" interface lets you stack maps arbitrarily.
7169c2aa98e2SPeter Wemm ** The "switch" interface builds a sequence map by looking
7170c2aa98e2SPeter Wemm ** at a system-dependent configuration file such as
7171c2aa98e2SPeter Wemm ** /etc/nsswitch.conf on Solaris or /etc/svc.conf on Ultrix.
7172c2aa98e2SPeter Wemm **
7173c2aa98e2SPeter Wemm ** We don't need an explicit open, since all maps are
717440266059SGregory Neil Shapiro ** opened on demand.
7175c2aa98e2SPeter Wemm */
7176c2aa98e2SPeter Wemm
7177c2aa98e2SPeter Wemm /*
7178c2aa98e2SPeter Wemm ** SEQ_MAP_PARSE -- Sequenced map parsing
7179c2aa98e2SPeter Wemm */
7180c2aa98e2SPeter Wemm
7181c2aa98e2SPeter Wemm bool
seq_map_parse(map,ap)7182c2aa98e2SPeter Wemm seq_map_parse(map, ap)
7183c2aa98e2SPeter Wemm MAP *map;
7184c2aa98e2SPeter Wemm char *ap;
7185c2aa98e2SPeter Wemm {
7186c2aa98e2SPeter Wemm int maxmap;
7187c2aa98e2SPeter Wemm
7188c2aa98e2SPeter Wemm if (tTd(38, 2))
718940266059SGregory Neil Shapiro sm_dprintf("seq_map_parse(%s, %s)\n", map->map_mname, ap);
7190c2aa98e2SPeter Wemm maxmap = 0;
7191c2aa98e2SPeter Wemm while (*ap != '\0')
7192c2aa98e2SPeter Wemm {
7193c2aa98e2SPeter Wemm register char *p;
7194c2aa98e2SPeter Wemm STAB *s;
7195c2aa98e2SPeter Wemm
7196c2aa98e2SPeter Wemm /* find beginning of map name */
71975b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*ap))
7198c2aa98e2SPeter Wemm ap++;
719906f25ae9SGregory Neil Shapiro for (p = ap;
720006f25ae9SGregory Neil Shapiro (isascii(*p) && isalnum(*p)) || *p == '_' || *p == '.';
720106f25ae9SGregory Neil Shapiro p++)
7202c2aa98e2SPeter Wemm continue;
7203c2aa98e2SPeter Wemm if (*p != '\0')
7204c2aa98e2SPeter Wemm *p++ = '\0';
7205c2aa98e2SPeter Wemm while (*p != '\0' && (!isascii(*p) || !isalnum(*p)))
7206c2aa98e2SPeter Wemm p++;
7207c2aa98e2SPeter Wemm if (*ap == '\0')
7208c2aa98e2SPeter Wemm {
7209c2aa98e2SPeter Wemm ap = p;
7210c2aa98e2SPeter Wemm continue;
7211c2aa98e2SPeter Wemm }
7212c2aa98e2SPeter Wemm s = stab(ap, ST_MAP, ST_FIND);
7213c2aa98e2SPeter Wemm if (s == NULL)
7214c2aa98e2SPeter Wemm {
7215c2aa98e2SPeter Wemm syserr("Sequence map %s: unknown member map %s",
7216c2aa98e2SPeter Wemm map->map_mname, ap);
7217c2aa98e2SPeter Wemm }
721840266059SGregory Neil Shapiro else if (maxmap >= MAXMAPSTACK)
7219c2aa98e2SPeter Wemm {
7220c2aa98e2SPeter Wemm syserr("Sequence map %s: too many member maps (%d max)",
7221c2aa98e2SPeter Wemm map->map_mname, MAXMAPSTACK);
7222c2aa98e2SPeter Wemm maxmap++;
7223c2aa98e2SPeter Wemm }
7224c2aa98e2SPeter Wemm else if (maxmap < MAXMAPSTACK)
7225c2aa98e2SPeter Wemm {
7226c2aa98e2SPeter Wemm map->map_stack[maxmap++] = &s->s_map;
7227c2aa98e2SPeter Wemm }
7228c2aa98e2SPeter Wemm ap = p;
7229c2aa98e2SPeter Wemm }
723040266059SGregory Neil Shapiro return true;
7231c2aa98e2SPeter Wemm }
7232c2aa98e2SPeter Wemm
7233c2aa98e2SPeter Wemm /*
7234c2aa98e2SPeter Wemm ** SWITCH_MAP_OPEN -- open a switched map
7235c2aa98e2SPeter Wemm **
7236c2aa98e2SPeter Wemm ** This looks at the system-dependent configuration and builds
7237c2aa98e2SPeter Wemm ** a sequence map that does the same thing.
7238c2aa98e2SPeter Wemm **
7239c2aa98e2SPeter Wemm ** Every system must define a switch_map_find routine in conf.c
7240c2aa98e2SPeter Wemm ** that will return the list of service types associated with a
7241c2aa98e2SPeter Wemm ** given service class.
7242c2aa98e2SPeter Wemm */
7243c2aa98e2SPeter Wemm
7244c2aa98e2SPeter Wemm bool
switch_map_open(map,mode)7245c2aa98e2SPeter Wemm switch_map_open(map, mode)
7246c2aa98e2SPeter Wemm MAP *map;
7247c2aa98e2SPeter Wemm int mode;
7248c2aa98e2SPeter Wemm {
7249c2aa98e2SPeter Wemm int mapno;
7250c2aa98e2SPeter Wemm int nmaps;
7251c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK];
7252c2aa98e2SPeter Wemm
7253c2aa98e2SPeter Wemm if (tTd(38, 2))
725440266059SGregory Neil Shapiro sm_dprintf("switch_map_open(%s, %s, %d)\n",
7255c2aa98e2SPeter Wemm map->map_mname, map->map_file, mode);
7256c2aa98e2SPeter Wemm
7257c2aa98e2SPeter Wemm mode &= O_ACCMODE;
7258c2aa98e2SPeter Wemm nmaps = switch_map_find(map->map_file, maptype, map->map_return);
7259c2aa98e2SPeter Wemm if (tTd(38, 19))
7260c2aa98e2SPeter Wemm {
726140266059SGregory Neil Shapiro sm_dprintf("\tswitch_map_find => %d\n", nmaps);
7262c2aa98e2SPeter Wemm for (mapno = 0; mapno < nmaps; mapno++)
726340266059SGregory Neil Shapiro sm_dprintf("\t\t%s\n", maptype[mapno]);
7264c2aa98e2SPeter Wemm }
7265c2aa98e2SPeter Wemm if (nmaps <= 0 || nmaps > MAXMAPSTACK)
726640266059SGregory Neil Shapiro return false;
7267c2aa98e2SPeter Wemm
7268c2aa98e2SPeter Wemm for (mapno = 0; mapno < nmaps; mapno++)
7269c2aa98e2SPeter Wemm {
7270c2aa98e2SPeter Wemm register STAB *s;
72712fb4f839SGregory Neil Shapiro char nbuf[MAXNAME + 1]; /* EAI:not relevant (map name) */
7272c2aa98e2SPeter Wemm
7273c2aa98e2SPeter Wemm if (maptype[mapno] == NULL)
7274c2aa98e2SPeter Wemm continue;
7275d0cef73dSGregory Neil Shapiro (void) sm_strlcpyn(nbuf, sizeof(nbuf), 3,
727640266059SGregory Neil Shapiro map->map_mname, ".", maptype[mapno]);
7277c2aa98e2SPeter Wemm s = stab(nbuf, ST_MAP, ST_FIND);
7278c2aa98e2SPeter Wemm if (s == NULL)
7279c2aa98e2SPeter Wemm {
7280c2aa98e2SPeter Wemm syserr("Switch map %s: unknown member map %s",
7281c2aa98e2SPeter Wemm map->map_mname, nbuf);
7282c2aa98e2SPeter Wemm }
7283c2aa98e2SPeter Wemm else
7284c2aa98e2SPeter Wemm {
7285c2aa98e2SPeter Wemm map->map_stack[mapno] = &s->s_map;
7286c2aa98e2SPeter Wemm if (tTd(38, 4))
728740266059SGregory Neil Shapiro sm_dprintf("\tmap_stack[%d] = %s:%s\n",
728840266059SGregory Neil Shapiro mapno,
728940266059SGregory Neil Shapiro s->s_map.map_class->map_cname,
7290c2aa98e2SPeter Wemm nbuf);
7291c2aa98e2SPeter Wemm }
7292c2aa98e2SPeter Wemm }
729340266059SGregory Neil Shapiro return true;
7294c2aa98e2SPeter Wemm }
7295c2aa98e2SPeter Wemm
729640266059SGregory Neil Shapiro #if 0
7297c2aa98e2SPeter Wemm /*
7298c2aa98e2SPeter Wemm ** SEQ_MAP_CLOSE -- close all underlying maps
7299c2aa98e2SPeter Wemm */
7300c2aa98e2SPeter Wemm
7301c2aa98e2SPeter Wemm void
7302c2aa98e2SPeter Wemm seq_map_close(map)
7303c2aa98e2SPeter Wemm MAP *map;
7304c2aa98e2SPeter Wemm {
7305c2aa98e2SPeter Wemm int mapno;
7306c2aa98e2SPeter Wemm
7307c2aa98e2SPeter Wemm if (tTd(38, 9))
730840266059SGregory Neil Shapiro sm_dprintf("seq_map_close(%s)\n", map->map_mname);
7309c2aa98e2SPeter Wemm
7310c2aa98e2SPeter Wemm for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
7311c2aa98e2SPeter Wemm {
7312c2aa98e2SPeter Wemm MAP *mm = map->map_stack[mapno];
7313c2aa98e2SPeter Wemm
7314c2aa98e2SPeter Wemm if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags))
7315c2aa98e2SPeter Wemm continue;
73168774250cSGregory Neil Shapiro mm->map_mflags |= MF_CLOSING;
7317c2aa98e2SPeter Wemm mm->map_class->map_close(mm);
73188774250cSGregory Neil Shapiro mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
7319c2aa98e2SPeter Wemm }
7320c2aa98e2SPeter Wemm }
732140266059SGregory Neil Shapiro #endif /* 0 */
7322c2aa98e2SPeter Wemm
7323c2aa98e2SPeter Wemm /*
7324c2aa98e2SPeter Wemm ** SEQ_MAP_LOOKUP -- sequenced map lookup
7325c2aa98e2SPeter Wemm */
7326c2aa98e2SPeter Wemm
7327c2aa98e2SPeter Wemm char *
seq_map_lookup(map,key,args,pstat)7328c2aa98e2SPeter Wemm seq_map_lookup(map, key, args, pstat)
7329c2aa98e2SPeter Wemm MAP *map;
7330c2aa98e2SPeter Wemm char *key;
7331c2aa98e2SPeter Wemm char **args;
7332c2aa98e2SPeter Wemm int *pstat;
7333c2aa98e2SPeter Wemm {
7334c2aa98e2SPeter Wemm int mapno;
7335c2aa98e2SPeter Wemm int mapbit = 0x01;
733640266059SGregory Neil Shapiro bool tempfail = false;
7337c2aa98e2SPeter Wemm
7338c2aa98e2SPeter Wemm if (tTd(38, 20))
733940266059SGregory Neil Shapiro sm_dprintf("seq_map_lookup(%s, %s)\n", map->map_mname, key);
7340c2aa98e2SPeter Wemm
7341c2aa98e2SPeter Wemm for (mapno = 0; mapno < MAXMAPSTACK; mapbit <<= 1, mapno++)
7342c2aa98e2SPeter Wemm {
7343c2aa98e2SPeter Wemm MAP *mm = map->map_stack[mapno];
7344c2aa98e2SPeter Wemm char *rv;
7345c2aa98e2SPeter Wemm
7346c2aa98e2SPeter Wemm if (mm == NULL)
7347c2aa98e2SPeter Wemm continue;
734806f25ae9SGregory Neil Shapiro if (!bitset(MF_OPEN, mm->map_mflags) &&
734906f25ae9SGregory Neil Shapiro !openmap(mm))
7350c2aa98e2SPeter Wemm {
7351c2aa98e2SPeter Wemm if (bitset(mapbit, map->map_return[MA_UNAVAIL]))
7352c2aa98e2SPeter Wemm {
7353c2aa98e2SPeter Wemm *pstat = EX_UNAVAILABLE;
7354c2aa98e2SPeter Wemm return NULL;
7355c2aa98e2SPeter Wemm }
7356c2aa98e2SPeter Wemm continue;
7357c2aa98e2SPeter Wemm }
7358c2aa98e2SPeter Wemm *pstat = EX_OK;
7359c2aa98e2SPeter Wemm rv = mm->map_class->map_lookup(mm, key, args, pstat);
7360c2aa98e2SPeter Wemm if (rv != NULL)
7361c2aa98e2SPeter Wemm return rv;
7362c2aa98e2SPeter Wemm if (*pstat == EX_TEMPFAIL)
7363c2aa98e2SPeter Wemm {
7364c2aa98e2SPeter Wemm if (bitset(mapbit, map->map_return[MA_TRYAGAIN]))
7365c2aa98e2SPeter Wemm return NULL;
736640266059SGregory Neil Shapiro tempfail = true;
7367c2aa98e2SPeter Wemm }
7368c2aa98e2SPeter Wemm else if (bitset(mapbit, map->map_return[MA_NOTFOUND]))
7369c2aa98e2SPeter Wemm break;
7370c2aa98e2SPeter Wemm }
7371c2aa98e2SPeter Wemm if (tempfail)
7372c2aa98e2SPeter Wemm *pstat = EX_TEMPFAIL;
7373c2aa98e2SPeter Wemm else if (*pstat == EX_OK)
7374c2aa98e2SPeter Wemm *pstat = EX_NOTFOUND;
7375c2aa98e2SPeter Wemm return NULL;
7376c2aa98e2SPeter Wemm }
7377c2aa98e2SPeter Wemm
7378c2aa98e2SPeter Wemm /*
7379c2aa98e2SPeter Wemm ** SEQ_MAP_STORE -- sequenced map store
7380c2aa98e2SPeter Wemm */
7381c2aa98e2SPeter Wemm
7382c2aa98e2SPeter Wemm void
seq_map_store(map,key,val)7383c2aa98e2SPeter Wemm seq_map_store(map, key, val)
7384c2aa98e2SPeter Wemm MAP *map;
7385c2aa98e2SPeter Wemm char *key;
7386c2aa98e2SPeter Wemm char *val;
7387c2aa98e2SPeter Wemm {
7388c2aa98e2SPeter Wemm int mapno;
7389c2aa98e2SPeter Wemm
7390c2aa98e2SPeter Wemm if (tTd(38, 12))
739140266059SGregory Neil Shapiro sm_dprintf("seq_map_store(%s, %s, %s)\n",
7392c2aa98e2SPeter Wemm map->map_mname, key, val);
7393c2aa98e2SPeter Wemm
7394c2aa98e2SPeter Wemm for (mapno = 0; mapno < MAXMAPSTACK; mapno++)
7395c2aa98e2SPeter Wemm {
7396c2aa98e2SPeter Wemm MAP *mm = map->map_stack[mapno];
7397c2aa98e2SPeter Wemm
7398c2aa98e2SPeter Wemm if (mm == NULL || !bitset(MF_WRITABLE, mm->map_mflags))
7399c2aa98e2SPeter Wemm continue;
7400c2aa98e2SPeter Wemm
7401c2aa98e2SPeter Wemm mm->map_class->map_store(mm, key, val);
7402c2aa98e2SPeter Wemm return;
7403c2aa98e2SPeter Wemm }
7404c2aa98e2SPeter Wemm syserr("seq_map_store(%s, %s, %s): no writable map",
7405c2aa98e2SPeter Wemm map->map_mname, key, val);
7406c2aa98e2SPeter Wemm }
740740266059SGregory Neil Shapiro /*
7408c2aa98e2SPeter Wemm ** NULL stubs
7409c2aa98e2SPeter Wemm */
7410c2aa98e2SPeter Wemm
7411c2aa98e2SPeter Wemm /* ARGSUSED */
7412c2aa98e2SPeter Wemm bool
null_map_open(map,mode)7413c2aa98e2SPeter Wemm null_map_open(map, mode)
7414c2aa98e2SPeter Wemm MAP *map;
7415c2aa98e2SPeter Wemm int mode;
7416c2aa98e2SPeter Wemm {
741740266059SGregory Neil Shapiro return true;
7418c2aa98e2SPeter Wemm }
7419c2aa98e2SPeter Wemm
7420c2aa98e2SPeter Wemm /* ARGSUSED */
7421c2aa98e2SPeter Wemm void
null_map_close(map)7422c2aa98e2SPeter Wemm null_map_close(map)
7423c2aa98e2SPeter Wemm MAP *map;
7424c2aa98e2SPeter Wemm {
7425c2aa98e2SPeter Wemm return;
7426c2aa98e2SPeter Wemm }
7427c2aa98e2SPeter Wemm
7428c2aa98e2SPeter Wemm char *
null_map_lookup(map,key,args,pstat)7429c2aa98e2SPeter Wemm null_map_lookup(map, key, args, pstat)
7430c2aa98e2SPeter Wemm MAP *map;
7431c2aa98e2SPeter Wemm char *key;
7432c2aa98e2SPeter Wemm char **args;
7433c2aa98e2SPeter Wemm int *pstat;
7434c2aa98e2SPeter Wemm {
7435c2aa98e2SPeter Wemm *pstat = EX_NOTFOUND;
7436c2aa98e2SPeter Wemm return NULL;
7437c2aa98e2SPeter Wemm }
7438c2aa98e2SPeter Wemm
7439c2aa98e2SPeter Wemm /* ARGSUSED */
7440c2aa98e2SPeter Wemm void
null_map_store(map,key,val)7441c2aa98e2SPeter Wemm null_map_store(map, key, val)
7442c2aa98e2SPeter Wemm MAP *map;
7443c2aa98e2SPeter Wemm char *key;
7444c2aa98e2SPeter Wemm char *val;
7445c2aa98e2SPeter Wemm {
7446c2aa98e2SPeter Wemm return;
7447c2aa98e2SPeter Wemm }
7448c2aa98e2SPeter Wemm
74499bd497b8SGregory Neil Shapiro MAPCLASS NullMapClass =
74509bd497b8SGregory Neil Shapiro {
74519bd497b8SGregory Neil Shapiro "null-map", NULL, 0,
74529bd497b8SGregory Neil Shapiro NULL, null_map_lookup, null_map_store,
74539bd497b8SGregory Neil Shapiro null_map_open, null_map_close,
74549bd497b8SGregory Neil Shapiro };
74559bd497b8SGregory Neil Shapiro
7456c2aa98e2SPeter Wemm /*
7457c2aa98e2SPeter Wemm ** BOGUS stubs
7458c2aa98e2SPeter Wemm */
7459c2aa98e2SPeter Wemm
7460c2aa98e2SPeter Wemm char *
bogus_map_lookup(map,key,args,pstat)7461c2aa98e2SPeter Wemm bogus_map_lookup(map, key, args, pstat)
7462c2aa98e2SPeter Wemm MAP *map;
7463c2aa98e2SPeter Wemm char *key;
7464c2aa98e2SPeter Wemm char **args;
7465c2aa98e2SPeter Wemm int *pstat;
7466c2aa98e2SPeter Wemm {
7467c2aa98e2SPeter Wemm *pstat = EX_TEMPFAIL;
7468c2aa98e2SPeter Wemm return NULL;
7469c2aa98e2SPeter Wemm }
7470c2aa98e2SPeter Wemm
7471c2aa98e2SPeter Wemm MAPCLASS BogusMapClass =
7472c2aa98e2SPeter Wemm {
7473c2aa98e2SPeter Wemm "bogus-map", NULL, 0,
7474c2aa98e2SPeter Wemm NULL, bogus_map_lookup, null_map_store,
7475c2aa98e2SPeter Wemm null_map_open, null_map_close,
7476c2aa98e2SPeter Wemm };
747740266059SGregory Neil Shapiro /*
747806f25ae9SGregory Neil Shapiro ** MACRO modules
747906f25ae9SGregory Neil Shapiro */
748006f25ae9SGregory Neil Shapiro
748106f25ae9SGregory Neil Shapiro char *
macro_map_lookup(map,name,av,statp)748206f25ae9SGregory Neil Shapiro macro_map_lookup(map, name, av, statp)
748306f25ae9SGregory Neil Shapiro MAP *map;
748406f25ae9SGregory Neil Shapiro char *name;
748506f25ae9SGregory Neil Shapiro char **av;
748606f25ae9SGregory Neil Shapiro int *statp;
748706f25ae9SGregory Neil Shapiro {
748806f25ae9SGregory Neil Shapiro int mid;
748906f25ae9SGregory Neil Shapiro
749006f25ae9SGregory Neil Shapiro if (tTd(38, 20))
749140266059SGregory Neil Shapiro sm_dprintf("macro_map_lookup(%s, %s)\n", map->map_mname,
749206f25ae9SGregory Neil Shapiro name == NULL ? "NULL" : name);
749306f25ae9SGregory Neil Shapiro
749406f25ae9SGregory Neil Shapiro if (name == NULL ||
749506f25ae9SGregory Neil Shapiro *name == '\0' ||
749640266059SGregory Neil Shapiro (mid = macid(name)) == 0)
749706f25ae9SGregory Neil Shapiro {
749806f25ae9SGregory Neil Shapiro *statp = EX_CONFIG;
749906f25ae9SGregory Neil Shapiro return NULL;
750006f25ae9SGregory Neil Shapiro }
750106f25ae9SGregory Neil Shapiro
750206f25ae9SGregory Neil Shapiro if (av[1] == NULL)
750340266059SGregory Neil Shapiro macdefine(&CurEnv->e_macro, A_PERM, mid, NULL);
750406f25ae9SGregory Neil Shapiro else
750540266059SGregory Neil Shapiro macdefine(&CurEnv->e_macro, A_TEMP, mid, av[1]);
750606f25ae9SGregory Neil Shapiro
750706f25ae9SGregory Neil Shapiro *statp = EX_OK;
750806f25ae9SGregory Neil Shapiro return "";
750906f25ae9SGregory Neil Shapiro }
751040266059SGregory Neil Shapiro /*
7511c2aa98e2SPeter Wemm ** REGEX modules
7512c2aa98e2SPeter Wemm */
7513c2aa98e2SPeter Wemm
751440266059SGregory Neil Shapiro #if MAP_REGEX
7515c2aa98e2SPeter Wemm
7516c2aa98e2SPeter Wemm # include <regex.h>
7517c2aa98e2SPeter Wemm
7518c2aa98e2SPeter Wemm # define DEFAULT_DELIM CONDELSE
7519c2aa98e2SPeter Wemm # define END_OF_FIELDS -1
7520c2aa98e2SPeter Wemm # define ERRBUF_SIZE 80
7521c2aa98e2SPeter Wemm # define MAX_MATCH 32
7522c2aa98e2SPeter Wemm
752306f25ae9SGregory Neil Shapiro # define xnalloc(s) memset(xalloc(s), '\0', s);
7524c2aa98e2SPeter Wemm
7525c2aa98e2SPeter Wemm struct regex_map
7526c2aa98e2SPeter Wemm {
7527193538b7SGregory Neil Shapiro regex_t *regex_pattern_buf; /* xalloc it */
7528c2aa98e2SPeter Wemm int *regex_subfields; /* move to type MAP */
752906f25ae9SGregory Neil Shapiro char *regex_delim; /* move to type MAP */
7530c2aa98e2SPeter Wemm };
7531c2aa98e2SPeter Wemm
7532b6bacd31SGregory Neil Shapiro static int parse_fields __P((char *, int *, int, int));
7533b6bacd31SGregory Neil Shapiro static char *regex_map_rewrite __P((MAP *, const char*, size_t, char **));
7534b6bacd31SGregory Neil Shapiro
7535c2aa98e2SPeter Wemm static int
parse_fields(s,ibuf,blen,nr_substrings)7536c2aa98e2SPeter Wemm parse_fields(s, ibuf, blen, nr_substrings)
7537c2aa98e2SPeter Wemm char *s;
7538c2aa98e2SPeter Wemm int *ibuf; /* array */
7539c2aa98e2SPeter Wemm int blen; /* number of elements in ibuf */
7540c2aa98e2SPeter Wemm int nr_substrings; /* number of substrings in the pattern */
7541c2aa98e2SPeter Wemm {
7542c2aa98e2SPeter Wemm register char *cp;
7543c2aa98e2SPeter Wemm int i = 0;
754440266059SGregory Neil Shapiro bool lastone = false;
7545c2aa98e2SPeter Wemm
7546c2aa98e2SPeter Wemm blen--; /* for terminating END_OF_FIELDS */
7547c2aa98e2SPeter Wemm cp = s;
7548c2aa98e2SPeter Wemm do
7549c2aa98e2SPeter Wemm {
7550c2aa98e2SPeter Wemm for (;; cp++)
7551c2aa98e2SPeter Wemm {
7552c2aa98e2SPeter Wemm if (*cp == ',')
7553c2aa98e2SPeter Wemm {
7554c2aa98e2SPeter Wemm *cp = '\0';
7555c2aa98e2SPeter Wemm break;
7556c2aa98e2SPeter Wemm }
7557c2aa98e2SPeter Wemm if (*cp == '\0')
7558c2aa98e2SPeter Wemm {
755940266059SGregory Neil Shapiro lastone = true;
7560c2aa98e2SPeter Wemm break;
7561c2aa98e2SPeter Wemm }
7562c2aa98e2SPeter Wemm }
7563c2aa98e2SPeter Wemm if (i < blen)
7564c2aa98e2SPeter Wemm {
7565c2aa98e2SPeter Wemm int val = atoi(s);
7566c2aa98e2SPeter Wemm
7567c2aa98e2SPeter Wemm if (val < 0 || val >= nr_substrings)
7568c2aa98e2SPeter Wemm {
7569c2aa98e2SPeter Wemm syserr("field (%d) out of range, only %d substrings in pattern",
7570c2aa98e2SPeter Wemm val, nr_substrings);
7571c2aa98e2SPeter Wemm return -1;
7572c2aa98e2SPeter Wemm }
7573c2aa98e2SPeter Wemm ibuf[i++] = val;
7574c2aa98e2SPeter Wemm }
7575c2aa98e2SPeter Wemm else
7576c2aa98e2SPeter Wemm {
757740266059SGregory Neil Shapiro syserr("too many fields, %d max", blen);
7578c2aa98e2SPeter Wemm return -1;
7579c2aa98e2SPeter Wemm }
7580c2aa98e2SPeter Wemm s = ++cp;
7581c2aa98e2SPeter Wemm } while (!lastone);
7582c2aa98e2SPeter Wemm ibuf[i] = END_OF_FIELDS;
7583c2aa98e2SPeter Wemm return i;
7584c2aa98e2SPeter Wemm }
7585c2aa98e2SPeter Wemm
7586c2aa98e2SPeter Wemm bool
regex_map_init(map,ap)7587c2aa98e2SPeter Wemm regex_map_init(map, ap)
7588c2aa98e2SPeter Wemm MAP *map;
7589c2aa98e2SPeter Wemm char *ap;
7590c2aa98e2SPeter Wemm {
7591c2aa98e2SPeter Wemm int regerr;
7592c2aa98e2SPeter Wemm struct regex_map *map_p;
7593c2aa98e2SPeter Wemm register char *p;
7594c2aa98e2SPeter Wemm char *sub_param = NULL;
7595c2aa98e2SPeter Wemm int pflags;
7596c2aa98e2SPeter Wemm static char defdstr[] = { (char) DEFAULT_DELIM, '\0' };
7597c2aa98e2SPeter Wemm
7598c2aa98e2SPeter Wemm if (tTd(38, 2))
759940266059SGregory Neil Shapiro sm_dprintf("regex_map_init: mapname '%s', args '%s'\n",
7600c2aa98e2SPeter Wemm map->map_mname, ap);
7601c2aa98e2SPeter Wemm
7602c2aa98e2SPeter Wemm pflags = REG_ICASE | REG_EXTENDED | REG_NOSUB;
7603c2aa98e2SPeter Wemm p = ap;
7604d0cef73dSGregory Neil Shapiro map_p = (struct regex_map *) xnalloc(sizeof(*map_p));
7605193538b7SGregory Neil Shapiro map_p->regex_pattern_buf = (regex_t *)xnalloc(sizeof(regex_t));
7606c2aa98e2SPeter Wemm
7607c2aa98e2SPeter Wemm for (;;)
7608c2aa98e2SPeter Wemm {
76095b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p))
7610c2aa98e2SPeter Wemm p++;
7611c2aa98e2SPeter Wemm if (*p != '-')
7612c2aa98e2SPeter Wemm break;
7613c2aa98e2SPeter Wemm switch (*++p)
7614c2aa98e2SPeter Wemm {
7615c2aa98e2SPeter Wemm case 'n': /* not */
7616c2aa98e2SPeter Wemm map->map_mflags |= MF_REGEX_NOT;
7617c2aa98e2SPeter Wemm break;
7618c2aa98e2SPeter Wemm
7619c2aa98e2SPeter Wemm case 'f': /* case sensitive */
7620c2aa98e2SPeter Wemm map->map_mflags |= MF_NOFOLDCASE;
7621c2aa98e2SPeter Wemm pflags &= ~REG_ICASE;
7622c2aa98e2SPeter Wemm break;
7623c2aa98e2SPeter Wemm
7624c2aa98e2SPeter Wemm case 'b': /* basic regular expressions */
7625c2aa98e2SPeter Wemm pflags &= ~REG_EXTENDED;
7626c2aa98e2SPeter Wemm break;
7627c2aa98e2SPeter Wemm
7628c2aa98e2SPeter Wemm case 's': /* substring match () syntax */
7629c2aa98e2SPeter Wemm sub_param = ++p;
7630c2aa98e2SPeter Wemm pflags &= ~REG_NOSUB;
7631c2aa98e2SPeter Wemm break;
7632c2aa98e2SPeter Wemm
7633c2aa98e2SPeter Wemm case 'd': /* delimiter */
763406f25ae9SGregory Neil Shapiro map_p->regex_delim = ++p;
7635c2aa98e2SPeter Wemm break;
7636c2aa98e2SPeter Wemm
7637c2aa98e2SPeter Wemm case 'a': /* map append */
7638c2aa98e2SPeter Wemm map->map_app = ++p;
7639c2aa98e2SPeter Wemm break;
7640c2aa98e2SPeter Wemm
7641c2aa98e2SPeter Wemm case 'm': /* matchonly */
7642c2aa98e2SPeter Wemm map->map_mflags |= MF_MATCHONLY;
7643c2aa98e2SPeter Wemm break;
7644c2aa98e2SPeter Wemm
7645a7ec597cSGregory Neil Shapiro case 'q':
7646a7ec597cSGregory Neil Shapiro map->map_mflags |= MF_KEEPQUOTES;
7647a7ec597cSGregory Neil Shapiro break;
7648a7ec597cSGregory Neil Shapiro
764906f25ae9SGregory Neil Shapiro case 'S':
765006f25ae9SGregory Neil Shapiro map->map_spacesub = *++p;
765106f25ae9SGregory Neil Shapiro break;
765206f25ae9SGregory Neil Shapiro
765306f25ae9SGregory Neil Shapiro case 'D':
765406f25ae9SGregory Neil Shapiro map->map_mflags |= MF_DEFER;
765506f25ae9SGregory Neil Shapiro break;
765606f25ae9SGregory Neil Shapiro
7657c2aa98e2SPeter Wemm }
76585b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)))
7659c2aa98e2SPeter Wemm p++;
7660c2aa98e2SPeter Wemm if (*p != '\0')
7661c2aa98e2SPeter Wemm *p++ = '\0';
7662c2aa98e2SPeter Wemm }
76632fb4f839SGregory Neil Shapiro # if _FFR_8BITENVADDR
76642fb4f839SGregory Neil Shapiro (void) dequote_internal_chars(p, p, strlen(p) + 1);
76652fb4f839SGregory Neil Shapiro # endif
7666c2aa98e2SPeter Wemm if (tTd(38, 3))
766740266059SGregory Neil Shapiro sm_dprintf("regex_map_init: compile '%s' 0x%x\n", p, pflags);
7668c2aa98e2SPeter Wemm
7669193538b7SGregory Neil Shapiro if ((regerr = regcomp(map_p->regex_pattern_buf, p, pflags)) != 0)
7670c2aa98e2SPeter Wemm {
7671c2aa98e2SPeter Wemm /* Errorhandling */
7672c2aa98e2SPeter Wemm char errbuf[ERRBUF_SIZE];
7673c2aa98e2SPeter Wemm
7674193538b7SGregory Neil Shapiro (void) regerror(regerr, map_p->regex_pattern_buf,
7675d0cef73dSGregory Neil Shapiro errbuf, sizeof(errbuf));
767640266059SGregory Neil Shapiro syserr("pattern-compile-error: %s", errbuf);
767740266059SGregory Neil Shapiro sm_free(map_p->regex_pattern_buf); /* XXX */
767840266059SGregory Neil Shapiro sm_free(map_p); /* XXX */
767940266059SGregory Neil Shapiro return false;
7680c2aa98e2SPeter Wemm }
7681c2aa98e2SPeter Wemm
7682c2aa98e2SPeter Wemm if (map->map_app != NULL)
7683c2aa98e2SPeter Wemm map->map_app = newstr(map->map_app);
768406f25ae9SGregory Neil Shapiro if (map_p->regex_delim != NULL)
768506f25ae9SGregory Neil Shapiro map_p->regex_delim = newstr(map_p->regex_delim);
7686c2aa98e2SPeter Wemm else
768706f25ae9SGregory Neil Shapiro map_p->regex_delim = defdstr;
7688c2aa98e2SPeter Wemm
7689c2aa98e2SPeter Wemm if (!bitset(REG_NOSUB, pflags))
7690c2aa98e2SPeter Wemm {
7691c2aa98e2SPeter Wemm /* substring matching */
7692c2aa98e2SPeter Wemm int substrings;
7693c2aa98e2SPeter Wemm int *fields = (int *) xalloc(sizeof(int) * (MAX_MATCH + 1));
7694c2aa98e2SPeter Wemm
7695193538b7SGregory Neil Shapiro substrings = map_p->regex_pattern_buf->re_nsub + 1;
7696c2aa98e2SPeter Wemm
7697c2aa98e2SPeter Wemm if (tTd(38, 3))
769840266059SGregory Neil Shapiro sm_dprintf("regex_map_init: nr of substrings %d\n",
769906f25ae9SGregory Neil Shapiro substrings);
7700c2aa98e2SPeter Wemm
7701c2aa98e2SPeter Wemm if (substrings >= MAX_MATCH)
7702c2aa98e2SPeter Wemm {
770340266059SGregory Neil Shapiro syserr("too many substrings, %d max", MAX_MATCH);
77042fb4f839SGregory Neil Shapiro SM_FREE(map_p->regex_pattern_buf); /* XXX */
77052fb4f839SGregory Neil Shapiro SM_FREE(map_p); /* XXX */
77062fb4f839SGregory Neil Shapiro SM_FREE(fields);
770740266059SGregory Neil Shapiro return false;
7708c2aa98e2SPeter Wemm }
7709c2aa98e2SPeter Wemm if (sub_param != NULL && sub_param[0] != '\0')
7710c2aa98e2SPeter Wemm {
7711c2aa98e2SPeter Wemm /* optional parameter -sfields */
7712c2aa98e2SPeter Wemm if (parse_fields(sub_param, fields,
7713c2aa98e2SPeter Wemm MAX_MATCH + 1, substrings) == -1)
77142fb4f839SGregory Neil Shapiro {
77152fb4f839SGregory Neil Shapiro SM_FREE(map_p->regex_pattern_buf); /* XXX */
77162fb4f839SGregory Neil Shapiro SM_FREE(map_p); /* XXX */
77172fb4f839SGregory Neil Shapiro SM_FREE(fields);
771840266059SGregory Neil Shapiro return false;
7719c2aa98e2SPeter Wemm }
77202fb4f839SGregory Neil Shapiro }
7721c2aa98e2SPeter Wemm else
7722c2aa98e2SPeter Wemm {
7723c2aa98e2SPeter Wemm int i;
7724c2aa98e2SPeter Wemm
772540266059SGregory Neil Shapiro /* set default fields */
7726c2aa98e2SPeter Wemm for (i = 0; i < substrings; i++)
7727c2aa98e2SPeter Wemm fields[i] = i;
7728c2aa98e2SPeter Wemm fields[i] = END_OF_FIELDS;
7729c2aa98e2SPeter Wemm }
7730c2aa98e2SPeter Wemm map_p->regex_subfields = fields;
7731c2aa98e2SPeter Wemm if (tTd(38, 3))
7732c2aa98e2SPeter Wemm {
7733c2aa98e2SPeter Wemm int *ip;
7734c2aa98e2SPeter Wemm
773540266059SGregory Neil Shapiro sm_dprintf("regex_map_init: subfields");
7736c2aa98e2SPeter Wemm for (ip = fields; *ip != END_OF_FIELDS; ip++)
773740266059SGregory Neil Shapiro sm_dprintf(" %d", *ip);
773840266059SGregory Neil Shapiro sm_dprintf("\n");
7739c2aa98e2SPeter Wemm }
7740c2aa98e2SPeter Wemm }
7741c2aa98e2SPeter Wemm map->map_db1 = (ARBPTR_T) map_p; /* dirty hack */
774240266059SGregory Neil Shapiro return true;
7743c2aa98e2SPeter Wemm }
7744c2aa98e2SPeter Wemm
7745c2aa98e2SPeter Wemm static char *
regex_map_rewrite(map,s,slen,av)7746c2aa98e2SPeter Wemm regex_map_rewrite(map, s, slen, av)
7747c2aa98e2SPeter Wemm MAP *map;
7748c2aa98e2SPeter Wemm const char *s;
7749c2aa98e2SPeter Wemm size_t slen;
7750c2aa98e2SPeter Wemm char **av;
7751c2aa98e2SPeter Wemm {
7752c2aa98e2SPeter Wemm if (bitset(MF_MATCHONLY, map->map_mflags))
7753c2aa98e2SPeter Wemm return map_rewrite(map, av[0], strlen(av[0]), NULL);
7754c2aa98e2SPeter Wemm else
77558774250cSGregory Neil Shapiro return map_rewrite(map, s, slen, av);
7756c2aa98e2SPeter Wemm }
7757c2aa98e2SPeter Wemm
7758c2aa98e2SPeter Wemm char *
regex_map_lookup(map,name,av,statp)7759c2aa98e2SPeter Wemm regex_map_lookup(map, name, av, statp)
7760c2aa98e2SPeter Wemm MAP *map;
7761c2aa98e2SPeter Wemm char *name;
7762c2aa98e2SPeter Wemm char **av;
7763c2aa98e2SPeter Wemm int *statp;
7764c2aa98e2SPeter Wemm {
7765c2aa98e2SPeter Wemm int reg_res;
7766c2aa98e2SPeter Wemm struct regex_map *map_p;
7767c2aa98e2SPeter Wemm regmatch_t pmatch[MAX_MATCH];
7768c2aa98e2SPeter Wemm
7769c2aa98e2SPeter Wemm if (tTd(38, 20))
7770c2aa98e2SPeter Wemm {
7771c2aa98e2SPeter Wemm char **cpp;
7772c2aa98e2SPeter Wemm
77732fb4f839SGregory Neil Shapiro sm_dprintf("regex_map_lookup: name=%s, key='%s'\n",
77742fb4f839SGregory Neil Shapiro map->map_mname, name);
777506f25ae9SGregory Neil Shapiro for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
777640266059SGregory Neil Shapiro sm_dprintf("regex_map_lookup: arg '%s'\n", *cpp);
7777c2aa98e2SPeter Wemm }
7778c2aa98e2SPeter Wemm
7779c2aa98e2SPeter Wemm map_p = (struct regex_map *)(map->map_db1);
7780193538b7SGregory Neil Shapiro reg_res = regexec(map_p->regex_pattern_buf,
778106f25ae9SGregory Neil Shapiro name, MAX_MATCH, pmatch, 0);
7782c2aa98e2SPeter Wemm
7783c2aa98e2SPeter Wemm if (bitset(MF_REGEX_NOT, map->map_mflags))
7784c2aa98e2SPeter Wemm {
7785c2aa98e2SPeter Wemm /* option -n */
7786c2aa98e2SPeter Wemm if (reg_res == REG_NOMATCH)
7787c2aa98e2SPeter Wemm return regex_map_rewrite(map, "", (size_t) 0, av);
7788c2aa98e2SPeter Wemm else
7789c2aa98e2SPeter Wemm return NULL;
7790c2aa98e2SPeter Wemm }
7791c2aa98e2SPeter Wemm if (reg_res == REG_NOMATCH)
7792c2aa98e2SPeter Wemm return NULL;
7793c2aa98e2SPeter Wemm
7794c2aa98e2SPeter Wemm if (map_p->regex_subfields != NULL)
7795c2aa98e2SPeter Wemm {
7796c2aa98e2SPeter Wemm /* option -s */
77972fb4f839SGregory Neil Shapiro static char retbuf[MAXNAME]; /* EAI:not relevant */
7798c2aa98e2SPeter Wemm int fields[MAX_MATCH + 1];
779940266059SGregory Neil Shapiro bool first = true;
7800c2aa98e2SPeter Wemm int anglecnt = 0, cmntcnt = 0, spacecnt = 0;
780140266059SGregory Neil Shapiro bool quotemode = false, bslashmode = false;
7802c2aa98e2SPeter Wemm register char *dp, *sp;
7803c2aa98e2SPeter Wemm char *endp, *ldp;
7804c2aa98e2SPeter Wemm int *ip;
7805c2aa98e2SPeter Wemm
7806c2aa98e2SPeter Wemm dp = retbuf;
7807c2aa98e2SPeter Wemm ldp = retbuf + sizeof(retbuf) - 1;
7808c2aa98e2SPeter Wemm
7809c2aa98e2SPeter Wemm if (av[1] != NULL)
7810c2aa98e2SPeter Wemm {
7811c2aa98e2SPeter Wemm if (parse_fields(av[1], fields, MAX_MATCH + 1,
7812193538b7SGregory Neil Shapiro (int) map_p->regex_pattern_buf->re_nsub + 1) == -1)
7813c2aa98e2SPeter Wemm {
7814c2aa98e2SPeter Wemm *statp = EX_CONFIG;
7815c2aa98e2SPeter Wemm return NULL;
7816c2aa98e2SPeter Wemm }
7817c2aa98e2SPeter Wemm ip = fields;
7818c2aa98e2SPeter Wemm }
7819c2aa98e2SPeter Wemm else
7820c2aa98e2SPeter Wemm ip = map_p->regex_subfields;
7821c2aa98e2SPeter Wemm
7822c2aa98e2SPeter Wemm for ( ; *ip != END_OF_FIELDS; ip++)
7823c2aa98e2SPeter Wemm {
7824c2aa98e2SPeter Wemm if (!first)
7825c2aa98e2SPeter Wemm {
782606f25ae9SGregory Neil Shapiro for (sp = map_p->regex_delim; *sp; sp++)
7827c2aa98e2SPeter Wemm {
7828c2aa98e2SPeter Wemm if (dp < ldp)
7829c2aa98e2SPeter Wemm *dp++ = *sp;
7830c2aa98e2SPeter Wemm }
7831c2aa98e2SPeter Wemm }
7832c2aa98e2SPeter Wemm else
783340266059SGregory Neil Shapiro first = false;
7834c2aa98e2SPeter Wemm
7835193538b7SGregory Neil Shapiro if (*ip >= MAX_MATCH ||
7836193538b7SGregory Neil Shapiro pmatch[*ip].rm_so < 0 || pmatch[*ip].rm_eo < 0)
7837c2aa98e2SPeter Wemm continue;
7838c2aa98e2SPeter Wemm
7839c2aa98e2SPeter Wemm sp = name + pmatch[*ip].rm_so;
7840c2aa98e2SPeter Wemm endp = name + pmatch[*ip].rm_eo;
7841c2aa98e2SPeter Wemm for (; endp > sp; sp++)
7842c2aa98e2SPeter Wemm {
7843c2aa98e2SPeter Wemm if (dp < ldp)
7844c2aa98e2SPeter Wemm {
7845c2aa98e2SPeter Wemm if (bslashmode)
7846c2aa98e2SPeter Wemm {
7847c2aa98e2SPeter Wemm *dp++ = *sp;
784840266059SGregory Neil Shapiro bslashmode = false;
7849c2aa98e2SPeter Wemm }
7850c2aa98e2SPeter Wemm else if (quotemode && *sp != '"' &&
7851c2aa98e2SPeter Wemm *sp != '\\')
7852c2aa98e2SPeter Wemm {
7853c2aa98e2SPeter Wemm *dp++ = *sp;
7854c2aa98e2SPeter Wemm }
7855c2aa98e2SPeter Wemm else switch (*dp++ = *sp)
7856c2aa98e2SPeter Wemm {
7857c2aa98e2SPeter Wemm case '\\':
785840266059SGregory Neil Shapiro bslashmode = true;
7859c2aa98e2SPeter Wemm break;
7860c2aa98e2SPeter Wemm
7861c2aa98e2SPeter Wemm case '(':
7862c2aa98e2SPeter Wemm cmntcnt++;
7863c2aa98e2SPeter Wemm break;
7864c2aa98e2SPeter Wemm
7865c2aa98e2SPeter Wemm case ')':
7866c2aa98e2SPeter Wemm cmntcnt--;
7867c2aa98e2SPeter Wemm break;
7868c2aa98e2SPeter Wemm
7869c2aa98e2SPeter Wemm case '<':
7870c2aa98e2SPeter Wemm anglecnt++;
7871c2aa98e2SPeter Wemm break;
7872c2aa98e2SPeter Wemm
7873c2aa98e2SPeter Wemm case '>':
7874c2aa98e2SPeter Wemm anglecnt--;
7875c2aa98e2SPeter Wemm break;
7876c2aa98e2SPeter Wemm
7877c2aa98e2SPeter Wemm case ' ':
7878c2aa98e2SPeter Wemm spacecnt++;
7879c2aa98e2SPeter Wemm break;
7880c2aa98e2SPeter Wemm
7881c2aa98e2SPeter Wemm case '"':
7882c2aa98e2SPeter Wemm quotemode = !quotemode;
7883c2aa98e2SPeter Wemm break;
7884c2aa98e2SPeter Wemm }
7885c2aa98e2SPeter Wemm }
7886c2aa98e2SPeter Wemm }
7887c2aa98e2SPeter Wemm }
7888c2aa98e2SPeter Wemm if (anglecnt != 0 || cmntcnt != 0 || quotemode ||
7889c2aa98e2SPeter Wemm bslashmode || spacecnt != 0)
7890c2aa98e2SPeter Wemm {
7891c2aa98e2SPeter Wemm sm_syslog(LOG_WARNING, NOQID,
7892c2aa98e2SPeter Wemm "Warning: regex may cause prescan() failure map=%s lookup=%s",
7893c2aa98e2SPeter Wemm map->map_mname, name);
7894c2aa98e2SPeter Wemm return NULL;
7895c2aa98e2SPeter Wemm }
7896c2aa98e2SPeter Wemm *dp = '\0';
7897c2aa98e2SPeter Wemm return regex_map_rewrite(map, retbuf, strlen(retbuf), av);
7898c2aa98e2SPeter Wemm }
7899c2aa98e2SPeter Wemm return regex_map_rewrite(map, "", (size_t)0, av);
7900c2aa98e2SPeter Wemm }
7901c2aa98e2SPeter Wemm #endif /* MAP_REGEX */
790240266059SGregory Neil Shapiro /*
790306f25ae9SGregory Neil Shapiro ** NSD modules
790406f25ae9SGregory Neil Shapiro */
790540266059SGregory Neil Shapiro #if MAP_NSD
790606f25ae9SGregory Neil Shapiro
790706f25ae9SGregory Neil Shapiro # include <ndbm.h>
790806f25ae9SGregory Neil Shapiro # define _DATUM_DEFINED
790906f25ae9SGregory Neil Shapiro # include <ns_api.h>
791006f25ae9SGregory Neil Shapiro
791106f25ae9SGregory Neil Shapiro typedef struct ns_map_list
791206f25ae9SGregory Neil Shapiro {
791340266059SGregory Neil Shapiro ns_map_t *map; /* XXX ns_ ? */
791406f25ae9SGregory Neil Shapiro char *mapname;
791506f25ae9SGregory Neil Shapiro struct ns_map_list *next;
791606f25ae9SGregory Neil Shapiro } ns_map_list_t;
791706f25ae9SGregory Neil Shapiro
791806f25ae9SGregory Neil Shapiro static ns_map_t *
ns_map_t_find(mapname)791906f25ae9SGregory Neil Shapiro ns_map_t_find(mapname)
792006f25ae9SGregory Neil Shapiro char *mapname;
792106f25ae9SGregory Neil Shapiro {
792206f25ae9SGregory Neil Shapiro static ns_map_list_t *ns_maps = NULL;
792306f25ae9SGregory Neil Shapiro ns_map_list_t *ns_map;
792406f25ae9SGregory Neil Shapiro
792506f25ae9SGregory Neil Shapiro /* walk the list of maps looking for the correctly named map */
792606f25ae9SGregory Neil Shapiro for (ns_map = ns_maps; ns_map != NULL; ns_map = ns_map->next)
792706f25ae9SGregory Neil Shapiro {
792806f25ae9SGregory Neil Shapiro if (strcmp(ns_map->mapname, mapname) == 0)
792906f25ae9SGregory Neil Shapiro break;
793006f25ae9SGregory Neil Shapiro }
793106f25ae9SGregory Neil Shapiro
793206f25ae9SGregory Neil Shapiro /* if we are looking at a NULL ns_map_list_t, then create a new one */
793306f25ae9SGregory Neil Shapiro if (ns_map == NULL)
793406f25ae9SGregory Neil Shapiro {
7935d0cef73dSGregory Neil Shapiro ns_map = (ns_map_list_t *) xalloc(sizeof(*ns_map));
793606f25ae9SGregory Neil Shapiro ns_map->mapname = newstr(mapname);
7937d0cef73dSGregory Neil Shapiro ns_map->map = (ns_map_t *) xalloc(sizeof(*ns_map->map));
7938d0cef73dSGregory Neil Shapiro memset(ns_map->map, '\0', sizeof(*ns_map->map));
793906f25ae9SGregory Neil Shapiro ns_map->next = ns_maps;
794006f25ae9SGregory Neil Shapiro ns_maps = ns_map;
794106f25ae9SGregory Neil Shapiro }
794206f25ae9SGregory Neil Shapiro return ns_map->map;
794306f25ae9SGregory Neil Shapiro }
794406f25ae9SGregory Neil Shapiro
794506f25ae9SGregory Neil Shapiro char *
nsd_map_lookup(map,name,av,statp)794606f25ae9SGregory Neil Shapiro nsd_map_lookup(map, name, av, statp)
794706f25ae9SGregory Neil Shapiro MAP *map;
794806f25ae9SGregory Neil Shapiro char *name;
794906f25ae9SGregory Neil Shapiro char **av;
795006f25ae9SGregory Neil Shapiro int *statp;
795106f25ae9SGregory Neil Shapiro {
7952193538b7SGregory Neil Shapiro int buflen, r;
795306f25ae9SGregory Neil Shapiro char *p;
795406f25ae9SGregory Neil Shapiro ns_map_t *ns_map;
79552fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
795606f25ae9SGregory Neil Shapiro char buf[MAXLINE];
795706f25ae9SGregory Neil Shapiro
795806f25ae9SGregory Neil Shapiro if (tTd(38, 20))
795940266059SGregory Neil Shapiro sm_dprintf("nsd_map_lookup(%s, %s)\n", map->map_mname, name);
796006f25ae9SGregory Neil Shapiro
796106f25ae9SGregory Neil Shapiro buflen = strlen(name);
7962d0cef73dSGregory Neil Shapiro if (buflen > sizeof(keybuf) - 1)
7963d0cef73dSGregory Neil Shapiro buflen = sizeof(keybuf) - 1; /* XXX simply cut off? */
796406f25ae9SGregory Neil Shapiro memmove(keybuf, name, buflen);
796506f25ae9SGregory Neil Shapiro keybuf[buflen] = '\0';
796606f25ae9SGregory Neil Shapiro if (!bitset(MF_NOFOLDCASE, map->map_mflags))
79672fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
796806f25ae9SGregory Neil Shapiro
796906f25ae9SGregory Neil Shapiro ns_map = ns_map_t_find(map->map_file);
797006f25ae9SGregory Neil Shapiro if (ns_map == NULL)
797106f25ae9SGregory Neil Shapiro {
797206f25ae9SGregory Neil Shapiro if (tTd(38, 20))
797340266059SGregory Neil Shapiro sm_dprintf("nsd_map_t_find failed\n");
7974193538b7SGregory Neil Shapiro *statp = EX_UNAVAILABLE;
7975193538b7SGregory Neil Shapiro return NULL;
7976193538b7SGregory Neil Shapiro }
797794c01205SGregory Neil Shapiro r = ns_lookup(ns_map, NULL, map->map_file, keybuf, NULL,
7978d0cef73dSGregory Neil Shapiro buf, sizeof(buf));
7979193538b7SGregory Neil Shapiro if (r == NS_UNAVAIL || r == NS_TRYAGAIN)
7980193538b7SGregory Neil Shapiro {
7981193538b7SGregory Neil Shapiro *statp = EX_TEMPFAIL;
7982193538b7SGregory Neil Shapiro return NULL;
7983193538b7SGregory Neil Shapiro }
79848774250cSGregory Neil Shapiro if (r == NS_BADREQ
79858774250cSGregory Neil Shapiro # ifdef NS_NOPERM
79868774250cSGregory Neil Shapiro || r == NS_NOPERM
79875b0945b5SGregory Neil Shapiro # endif
79888774250cSGregory Neil Shapiro )
7989193538b7SGregory Neil Shapiro {
7990193538b7SGregory Neil Shapiro *statp = EX_CONFIG;
7991193538b7SGregory Neil Shapiro return NULL;
7992193538b7SGregory Neil Shapiro }
7993193538b7SGregory Neil Shapiro if (r != NS_SUCCESS)
7994193538b7SGregory Neil Shapiro {
7995193538b7SGregory Neil Shapiro *statp = EX_NOTFOUND;
799606f25ae9SGregory Neil Shapiro return NULL;
799706f25ae9SGregory Neil Shapiro }
799806f25ae9SGregory Neil Shapiro
7999193538b7SGregory Neil Shapiro *statp = EX_OK;
800006f25ae9SGregory Neil Shapiro
800106f25ae9SGregory Neil Shapiro /* Null out trailing \n */
800206f25ae9SGregory Neil Shapiro if ((p = strchr(buf, '\n')) != NULL)
800306f25ae9SGregory Neil Shapiro *p = '\0';
800406f25ae9SGregory Neil Shapiro
800506f25ae9SGregory Neil Shapiro return map_rewrite(map, buf, strlen(buf), av);
800606f25ae9SGregory Neil Shapiro }
800706f25ae9SGregory Neil Shapiro #endif /* MAP_NSD */
800806f25ae9SGregory Neil Shapiro
800906f25ae9SGregory Neil Shapiro char *
arith_map_lookup(map,name,av,statp)801006f25ae9SGregory Neil Shapiro arith_map_lookup(map, name, av, statp)
801106f25ae9SGregory Neil Shapiro MAP *map;
801206f25ae9SGregory Neil Shapiro char *name;
801306f25ae9SGregory Neil Shapiro char **av;
801406f25ae9SGregory Neil Shapiro int *statp;
801506f25ae9SGregory Neil Shapiro {
801606f25ae9SGregory Neil Shapiro long r;
801706f25ae9SGregory Neil Shapiro long v[2];
801840266059SGregory Neil Shapiro bool res = false;
801906f25ae9SGregory Neil Shapiro bool boolres;
802006f25ae9SGregory Neil Shapiro static char result[16];
802106f25ae9SGregory Neil Shapiro char **cpp;
802206f25ae9SGregory Neil Shapiro
802306f25ae9SGregory Neil Shapiro if (tTd(38, 2))
802406f25ae9SGregory Neil Shapiro {
802540266059SGregory Neil Shapiro sm_dprintf("arith_map_lookup: key '%s'\n", name);
802606f25ae9SGregory Neil Shapiro for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
802740266059SGregory Neil Shapiro sm_dprintf("arith_map_lookup: arg '%s'\n", *cpp);
802806f25ae9SGregory Neil Shapiro }
802906f25ae9SGregory Neil Shapiro r = 0;
803040266059SGregory Neil Shapiro boolres = false;
803106f25ae9SGregory Neil Shapiro cpp = av;
803206f25ae9SGregory Neil Shapiro *statp = EX_OK;
803306f25ae9SGregory Neil Shapiro
803406f25ae9SGregory Neil Shapiro /*
803506f25ae9SGregory Neil Shapiro ** read arguments for arith map
803606f25ae9SGregory Neil Shapiro ** - no check is made whether they are really numbers
803706f25ae9SGregory Neil Shapiro ** - just ignores args after the second
803806f25ae9SGregory Neil Shapiro */
803940266059SGregory Neil Shapiro
804006f25ae9SGregory Neil Shapiro for (++cpp; cpp != NULL && *cpp != NULL && r < 2; cpp++)
804106f25ae9SGregory Neil Shapiro v[r++] = strtol(*cpp, NULL, 0);
804206f25ae9SGregory Neil Shapiro
804306f25ae9SGregory Neil Shapiro /* operator and (at least) two operands given? */
804406f25ae9SGregory Neil Shapiro if (name != NULL && r == 2)
804506f25ae9SGregory Neil Shapiro {
804606f25ae9SGregory Neil Shapiro switch (*name)
804706f25ae9SGregory Neil Shapiro {
804806f25ae9SGregory Neil Shapiro case '|':
804906f25ae9SGregory Neil Shapiro r = v[0] | v[1];
805006f25ae9SGregory Neil Shapiro break;
805106f25ae9SGregory Neil Shapiro
805206f25ae9SGregory Neil Shapiro case '&':
805306f25ae9SGregory Neil Shapiro r = v[0] & v[1];
805406f25ae9SGregory Neil Shapiro break;
805506f25ae9SGregory Neil Shapiro
805606f25ae9SGregory Neil Shapiro case '%':
805706f25ae9SGregory Neil Shapiro if (v[1] == 0)
805806f25ae9SGregory Neil Shapiro return NULL;
805906f25ae9SGregory Neil Shapiro r = v[0] % v[1];
806006f25ae9SGregory Neil Shapiro break;
806106f25ae9SGregory Neil Shapiro case '+':
806206f25ae9SGregory Neil Shapiro r = v[0] + v[1];
806306f25ae9SGregory Neil Shapiro break;
806406f25ae9SGregory Neil Shapiro
806506f25ae9SGregory Neil Shapiro case '-':
806606f25ae9SGregory Neil Shapiro r = v[0] - v[1];
806706f25ae9SGregory Neil Shapiro break;
806806f25ae9SGregory Neil Shapiro
806906f25ae9SGregory Neil Shapiro case '*':
807006f25ae9SGregory Neil Shapiro r = v[0] * v[1];
807106f25ae9SGregory Neil Shapiro break;
807206f25ae9SGregory Neil Shapiro
807306f25ae9SGregory Neil Shapiro case '/':
807406f25ae9SGregory Neil Shapiro if (v[1] == 0)
807506f25ae9SGregory Neil Shapiro return NULL;
807606f25ae9SGregory Neil Shapiro r = v[0] / v[1];
807706f25ae9SGregory Neil Shapiro break;
807806f25ae9SGregory Neil Shapiro
807906f25ae9SGregory Neil Shapiro case 'l':
808006f25ae9SGregory Neil Shapiro res = v[0] < v[1];
808140266059SGregory Neil Shapiro boolres = true;
808206f25ae9SGregory Neil Shapiro break;
808306f25ae9SGregory Neil Shapiro
808406f25ae9SGregory Neil Shapiro case '=':
808506f25ae9SGregory Neil Shapiro res = v[0] == v[1];
808640266059SGregory Neil Shapiro boolres = true;
808706f25ae9SGregory Neil Shapiro break;
808806f25ae9SGregory Neil Shapiro
8089d0cef73dSGregory Neil Shapiro case 'r':
8090d0cef73dSGregory Neil Shapiro r = v[1] - v[0] + 1;
8091d0cef73dSGregory Neil Shapiro if (r <= 0)
8092d0cef73dSGregory Neil Shapiro return NULL;
8093d0cef73dSGregory Neil Shapiro r = get_random() % r + v[0];
8094d0cef73dSGregory Neil Shapiro break;
8095d0cef73dSGregory Neil Shapiro
809606f25ae9SGregory Neil Shapiro default:
809706f25ae9SGregory Neil Shapiro /* XXX */
809806f25ae9SGregory Neil Shapiro *statp = EX_CONFIG;
809906f25ae9SGregory Neil Shapiro if (LogLevel > 10)
810006f25ae9SGregory Neil Shapiro sm_syslog(LOG_WARNING, NOQID,
810106f25ae9SGregory Neil Shapiro "arith_map: unknown operator %c",
81029bd497b8SGregory Neil Shapiro (isascii(*name) && isprint(*name)) ?
81039bd497b8SGregory Neil Shapiro *name : '?');
810406f25ae9SGregory Neil Shapiro return NULL;
810506f25ae9SGregory Neil Shapiro }
810606f25ae9SGregory Neil Shapiro if (boolres)
8107d0cef73dSGregory Neil Shapiro (void) sm_snprintf(result, sizeof(result),
810840266059SGregory Neil Shapiro res ? "TRUE" : "FALSE");
810906f25ae9SGregory Neil Shapiro else
8110d0cef73dSGregory Neil Shapiro (void) sm_snprintf(result, sizeof(result), "%ld", r);
811106f25ae9SGregory Neil Shapiro return result;
811206f25ae9SGregory Neil Shapiro }
811306f25ae9SGregory Neil Shapiro *statp = EX_CONFIG;
811406f25ae9SGregory Neil Shapiro return NULL;
811506f25ae9SGregory Neil Shapiro }
8116e92d3f3fSGregory Neil Shapiro
81175dd76dd0SGregory Neil Shapiro char *
arpa_map_lookup(map,name,av,statp)81185dd76dd0SGregory Neil Shapiro arpa_map_lookup(map, name, av, statp)
81195dd76dd0SGregory Neil Shapiro MAP *map;
81205dd76dd0SGregory Neil Shapiro char *name;
81215dd76dd0SGregory Neil Shapiro char **av;
81225dd76dd0SGregory Neil Shapiro int *statp;
81235dd76dd0SGregory Neil Shapiro {
81245dd76dd0SGregory Neil Shapiro int r;
81255dd76dd0SGregory Neil Shapiro char *rval;
81265dd76dd0SGregory Neil Shapiro char result[128]; /* IPv6: 64 + 10 + 1 would be enough */
81275dd76dd0SGregory Neil Shapiro
81285dd76dd0SGregory Neil Shapiro if (tTd(38, 2))
81295dd76dd0SGregory Neil Shapiro sm_dprintf("arpa_map_lookup: key '%s'\n", name);
81305dd76dd0SGregory Neil Shapiro *statp = EX_DATAERR;
81315dd76dd0SGregory Neil Shapiro r = 1;
81325dd76dd0SGregory Neil Shapiro memset(result, '\0', sizeof(result));
81335dd76dd0SGregory Neil Shapiro rval = NULL;
81345dd76dd0SGregory Neil Shapiro
81355dd76dd0SGregory Neil Shapiro #if NETINET6
81365dd76dd0SGregory Neil Shapiro if (sm_strncasecmp(name, "IPv6:", 5) == 0)
81375dd76dd0SGregory Neil Shapiro {
81385dd76dd0SGregory Neil Shapiro struct in6_addr in6_addr;
81395dd76dd0SGregory Neil Shapiro
81405dd76dd0SGregory Neil Shapiro r = anynet_pton(AF_INET6, name, &in6_addr);
81415dd76dd0SGregory Neil Shapiro if (r == 1)
81425dd76dd0SGregory Neil Shapiro {
81435dd76dd0SGregory Neil Shapiro static char hex_digits[] =
81445dd76dd0SGregory Neil Shapiro { '0', '1', '2', '3', '4', '5', '6', '7', '8',
81455dd76dd0SGregory Neil Shapiro '9', 'a', 'b', 'c', 'd', 'e', 'f' };
81465dd76dd0SGregory Neil Shapiro
81475dd76dd0SGregory Neil Shapiro unsigned char *src;
81485dd76dd0SGregory Neil Shapiro char *dst;
81495dd76dd0SGregory Neil Shapiro int i;
81505dd76dd0SGregory Neil Shapiro
81515dd76dd0SGregory Neil Shapiro src = (unsigned char *) &in6_addr;
81525dd76dd0SGregory Neil Shapiro dst = result;
81535dd76dd0SGregory Neil Shapiro for (i = 15; i >= 0; i--) {
81545dd76dd0SGregory Neil Shapiro *dst++ = hex_digits[src[i] & 0x0f];
81555dd76dd0SGregory Neil Shapiro *dst++ = '.';
81565dd76dd0SGregory Neil Shapiro *dst++ = hex_digits[(src[i] >> 4) & 0x0f];
81575dd76dd0SGregory Neil Shapiro if (i > 0)
81585dd76dd0SGregory Neil Shapiro *dst++ = '.';
81595dd76dd0SGregory Neil Shapiro }
81605dd76dd0SGregory Neil Shapiro *statp = EX_OK;
81615dd76dd0SGregory Neil Shapiro }
81625dd76dd0SGregory Neil Shapiro }
81635dd76dd0SGregory Neil Shapiro else
81645dd76dd0SGregory Neil Shapiro #endif /* NETINET6 */
81655dd76dd0SGregory Neil Shapiro #if NETINET
81665dd76dd0SGregory Neil Shapiro {
81675dd76dd0SGregory Neil Shapiro struct in_addr in_addr;
81685dd76dd0SGregory Neil Shapiro
8169da7d7b9cSGregory Neil Shapiro r = inet_pton(AF_INET, name, &in_addr);
81705dd76dd0SGregory Neil Shapiro if (r == 1)
81715dd76dd0SGregory Neil Shapiro {
81725dd76dd0SGregory Neil Shapiro unsigned char *src;
81735dd76dd0SGregory Neil Shapiro
81745dd76dd0SGregory Neil Shapiro src = (unsigned char *) &in_addr;
81755dd76dd0SGregory Neil Shapiro (void) snprintf(result, sizeof(result),
81765dd76dd0SGregory Neil Shapiro "%u.%u.%u.%u",
81775dd76dd0SGregory Neil Shapiro src[3], src[2], src[1], src[0]);
81785dd76dd0SGregory Neil Shapiro *statp = EX_OK;
81795dd76dd0SGregory Neil Shapiro }
81805dd76dd0SGregory Neil Shapiro }
81815dd76dd0SGregory Neil Shapiro #endif /* NETINET */
81825dd76dd0SGregory Neil Shapiro if (r < 0)
81835dd76dd0SGregory Neil Shapiro *statp = EX_UNAVAILABLE;
81845dd76dd0SGregory Neil Shapiro if (tTd(38, 2))
81855dd76dd0SGregory Neil Shapiro sm_dprintf("arpa_map_lookup: r=%d, result='%s'\n", r, result);
81865dd76dd0SGregory Neil Shapiro if (*statp == EX_OK)
81875dd76dd0SGregory Neil Shapiro {
81885dd76dd0SGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
81895dd76dd0SGregory Neil Shapiro rval = map_rewrite(map, name, strlen(name), NULL);
81905dd76dd0SGregory Neil Shapiro else
81915dd76dd0SGregory Neil Shapiro rval = map_rewrite(map, result, strlen(result), av);
81925dd76dd0SGregory Neil Shapiro }
81935dd76dd0SGregory Neil Shapiro return rval;
81945dd76dd0SGregory Neil Shapiro }
81955dd76dd0SGregory Neil Shapiro
81965b0945b5SGregory Neil Shapiro #if _FFR_SETDEBUG_MAP
81975b0945b5SGregory Neil Shapiro char *
setdebug_map_lookup(map,name,av,statp)81985b0945b5SGregory Neil Shapiro setdebug_map_lookup(map, name, av, statp)
81995b0945b5SGregory Neil Shapiro MAP *map;
82005b0945b5SGregory Neil Shapiro char *name;
82015b0945b5SGregory Neil Shapiro char **av;
82025b0945b5SGregory Neil Shapiro int *statp;
82035b0945b5SGregory Neil Shapiro {
82045b0945b5SGregory Neil Shapiro
82055b0945b5SGregory Neil Shapiro if (tTd(38, 2))
82065b0945b5SGregory Neil Shapiro {
82075b0945b5SGregory Neil Shapiro char **cpp;
82085b0945b5SGregory Neil Shapiro
82095b0945b5SGregory Neil Shapiro sm_dprintf("setdebug_map_lookup: key '%s'\n", name);
82105b0945b5SGregory Neil Shapiro for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
82115b0945b5SGregory Neil Shapiro sm_dprintf("setdebug_map_lookup: arg '%s'\n", *cpp);
82125b0945b5SGregory Neil Shapiro }
82135b0945b5SGregory Neil Shapiro *statp = EX_OK;
82145b0945b5SGregory Neil Shapiro tTflag(name);
82155b0945b5SGregory Neil Shapiro return NULL;
82165b0945b5SGregory Neil Shapiro }
82175b0945b5SGregory Neil Shapiro #endif
82185b0945b5SGregory Neil Shapiro
82195b0945b5SGregory Neil Shapiro #if _FFR_SETOPT_MAP
82205b0945b5SGregory Neil Shapiro char *
setopt_map_lookup(map,name,av,statp)82215b0945b5SGregory Neil Shapiro setopt_map_lookup(map, name, av, statp)
82225b0945b5SGregory Neil Shapiro MAP *map;
82235b0945b5SGregory Neil Shapiro char *name;
82245b0945b5SGregory Neil Shapiro char **av;
82255b0945b5SGregory Neil Shapiro int *statp;
82265b0945b5SGregory Neil Shapiro {
82275b0945b5SGregory Neil Shapiro # if !_FFR_SETANYOPT
82285b0945b5SGregory Neil Shapiro int val;
82295b0945b5SGregory Neil Shapiro # endif
82305b0945b5SGregory Neil Shapiro char **cpp;
82315b0945b5SGregory Neil Shapiro
82325b0945b5SGregory Neil Shapiro if (tTd(38, 2))
82335b0945b5SGregory Neil Shapiro {
82345b0945b5SGregory Neil Shapiro sm_dprintf("setopt_map_lookup: key '%s'\n", name);
82355b0945b5SGregory Neil Shapiro for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
82365b0945b5SGregory Neil Shapiro sm_dprintf("setopt_map_lookup: arg '%s'\n", *cpp);
82375b0945b5SGregory Neil Shapiro }
82385b0945b5SGregory Neil Shapiro # if _FFR_SETANYOPT
82395b0945b5SGregory Neil Shapiro /*
82405b0945b5SGregory Neil Shapiro ** API screwed up...
82415b0945b5SGregory Neil Shapiro ** first arg is the "short" name and second is the entire string...
82425b0945b5SGregory Neil Shapiro */
82435b0945b5SGregory Neil Shapiro
82445b0945b5SGregory Neil Shapiro sm_dprintf("setoption: name=%s\n", name);
82455b0945b5SGregory Neil Shapiro setoption(' ', name, true, false, CurEnv);
82465b0945b5SGregory Neil Shapiro *statp = EX_OK;
82475b0945b5SGregory Neil Shapiro return NULL;
82485b0945b5SGregory Neil Shapiro # else /* _FFR_SETANYOPT */
82495b0945b5SGregory Neil Shapiro *statp = EX_CONFIG;
82505b0945b5SGregory Neil Shapiro
82515b0945b5SGregory Neil Shapiro cpp = av;
82525b0945b5SGregory Neil Shapiro if (cpp == NULL || ++cpp == NULL || *cpp == NULL)
82535b0945b5SGregory Neil Shapiro return NULL;
82545b0945b5SGregory Neil Shapiro *statp = EX_OK;
82555b0945b5SGregory Neil Shapiro errno = 0;
82565b0945b5SGregory Neil Shapiro val = strtol(*cpp, NULL, 0);
82575b0945b5SGregory Neil Shapiro /* check for valid number? */
82585b0945b5SGregory Neil Shapiro
82595b0945b5SGregory Neil Shapiro /* use a table? */
82602fb4f839SGregory Neil Shapiro if (SM_STRCASEEQ(name, "LogLevel"))
82615b0945b5SGregory Neil Shapiro {
82625b0945b5SGregory Neil Shapiro LogLevel = val;
82635b0945b5SGregory Neil Shapiro sm_dprintf("LogLevel=%d\n", val);
82645b0945b5SGregory Neil Shapiro return NULL;
82655b0945b5SGregory Neil Shapiro }
82665b0945b5SGregory Neil Shapiro # endif /* _FFR_SETANYOPT */
82675b0945b5SGregory Neil Shapiro *statp = EX_CONFIG;
82685b0945b5SGregory Neil Shapiro return NULL;
82695b0945b5SGregory Neil Shapiro }
82705b0945b5SGregory Neil Shapiro #endif
82715b0945b5SGregory Neil Shapiro
82725b0945b5SGregory Neil Shapiro
8273e92d3f3fSGregory Neil Shapiro #if SOCKETMAP
8274e92d3f3fSGregory Neil Shapiro
8275e92d3f3fSGregory Neil Shapiro # if NETINET || NETINET6
8276e92d3f3fSGregory Neil Shapiro # include <arpa/inet.h>
82775b0945b5SGregory Neil Shapiro # endif
8278e92d3f3fSGregory Neil Shapiro
8279e92d3f3fSGregory Neil Shapiro # define socket_map_next map_stack[0]
8280e92d3f3fSGregory Neil Shapiro
8281e92d3f3fSGregory Neil Shapiro /*
8282e92d3f3fSGregory Neil Shapiro ** SOCKET_MAP_OPEN -- open socket table
8283e92d3f3fSGregory Neil Shapiro */
8284e92d3f3fSGregory Neil Shapiro
8285e92d3f3fSGregory Neil Shapiro bool
socket_map_open(map,mode)8286e92d3f3fSGregory Neil Shapiro socket_map_open(map, mode)
8287e92d3f3fSGregory Neil Shapiro MAP *map;
8288e92d3f3fSGregory Neil Shapiro int mode;
8289e92d3f3fSGregory Neil Shapiro {
8290e92d3f3fSGregory Neil Shapiro STAB *s;
8291e92d3f3fSGregory Neil Shapiro int sock = 0;
8292da7d7b9cSGregory Neil Shapiro int tmo;
8293e92d3f3fSGregory Neil Shapiro SOCKADDR_LEN_T addrlen = 0;
8294e92d3f3fSGregory Neil Shapiro int addrno = 0;
8295e92d3f3fSGregory Neil Shapiro int save_errno;
8296e92d3f3fSGregory Neil Shapiro char *p;
8297e92d3f3fSGregory Neil Shapiro char *colon;
8298e92d3f3fSGregory Neil Shapiro char *at;
8299e92d3f3fSGregory Neil Shapiro struct hostent *hp = NULL;
8300e92d3f3fSGregory Neil Shapiro SOCKADDR addr;
8301e92d3f3fSGregory Neil Shapiro
8302e92d3f3fSGregory Neil Shapiro if (tTd(38, 2))
8303e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_open(%s, %s, %d)\n",
8304e92d3f3fSGregory Neil Shapiro map->map_mname, map->map_file, mode);
8305e92d3f3fSGregory Neil Shapiro
8306e92d3f3fSGregory Neil Shapiro mode &= O_ACCMODE;
8307e92d3f3fSGregory Neil Shapiro
8308e92d3f3fSGregory Neil Shapiro /* sendmail doesn't have the ability to write to SOCKET (yet) */
8309e92d3f3fSGregory Neil Shapiro if (mode != O_RDONLY)
8310e92d3f3fSGregory Neil Shapiro {
8311e92d3f3fSGregory Neil Shapiro /* issue a pseudo-error message */
8312e92d3f3fSGregory Neil Shapiro errno = SM_EMAPCANTWRITE;
8313e92d3f3fSGregory Neil Shapiro return false;
8314e92d3f3fSGregory Neil Shapiro }
8315e92d3f3fSGregory Neil Shapiro
8316e92d3f3fSGregory Neil Shapiro if (*map->map_file == '\0')
8317e92d3f3fSGregory Neil Shapiro {
8318e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": empty or missing socket information",
8319e92d3f3fSGregory Neil Shapiro map->map_mname);
8320e92d3f3fSGregory Neil Shapiro return false;
8321e92d3f3fSGregory Neil Shapiro }
8322e92d3f3fSGregory Neil Shapiro
8323e92d3f3fSGregory Neil Shapiro s = socket_map_findconn(map->map_file);
8324e92d3f3fSGregory Neil Shapiro if (s->s_socketmap != NULL)
8325e92d3f3fSGregory Neil Shapiro {
8326e92d3f3fSGregory Neil Shapiro /* Copy open connection */
8327e92d3f3fSGregory Neil Shapiro map->map_db1 = s->s_socketmap->map_db1;
8328e92d3f3fSGregory Neil Shapiro
8329e92d3f3fSGregory Neil Shapiro /* Add this map as head of linked list */
8330e92d3f3fSGregory Neil Shapiro map->socket_map_next = s->s_socketmap;
8331e92d3f3fSGregory Neil Shapiro s->s_socketmap = map;
8332e92d3f3fSGregory Neil Shapiro
8333e92d3f3fSGregory Neil Shapiro if (tTd(38, 2))
8334e92d3f3fSGregory Neil Shapiro sm_dprintf("using cached connection\n");
8335e92d3f3fSGregory Neil Shapiro return true;
8336e92d3f3fSGregory Neil Shapiro }
8337e92d3f3fSGregory Neil Shapiro
8338e92d3f3fSGregory Neil Shapiro if (tTd(38, 2))
8339e92d3f3fSGregory Neil Shapiro sm_dprintf("opening new connection\n");
8340e92d3f3fSGregory Neil Shapiro
8341e92d3f3fSGregory Neil Shapiro /* following code is ripped from milter.c */
8342e92d3f3fSGregory Neil Shapiro /* XXX It should be put in a library... */
8343e92d3f3fSGregory Neil Shapiro
8344e92d3f3fSGregory Neil Shapiro /* protocol:filename or protocol:port@host */
8345d0cef73dSGregory Neil Shapiro memset(&addr, '\0', sizeof(addr));
8346e92d3f3fSGregory Neil Shapiro p = map->map_file;
8347e92d3f3fSGregory Neil Shapiro colon = strchr(p, ':');
8348e92d3f3fSGregory Neil Shapiro if (colon != NULL)
8349e92d3f3fSGregory Neil Shapiro {
8350e92d3f3fSGregory Neil Shapiro *colon = '\0';
8351e92d3f3fSGregory Neil Shapiro
8352e92d3f3fSGregory Neil Shapiro if (*p == '\0')
8353e92d3f3fSGregory Neil Shapiro {
8354e92d3f3fSGregory Neil Shapiro # if NETUNIX
8355e92d3f3fSGregory Neil Shapiro /* default to AF_UNIX */
8356e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_UNIX;
8357e92d3f3fSGregory Neil Shapiro # else /* NETUNIX */
8358e92d3f3fSGregory Neil Shapiro # if NETINET
8359e92d3f3fSGregory Neil Shapiro /* default to AF_INET */
8360e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_INET;
8361e92d3f3fSGregory Neil Shapiro # else /* NETINET */
8362e92d3f3fSGregory Neil Shapiro # if NETINET6
8363e92d3f3fSGregory Neil Shapiro /* default to AF_INET6 */
8364e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_INET6;
8365e92d3f3fSGregory Neil Shapiro # else /* NETINET6 */
8366e92d3f3fSGregory Neil Shapiro /* no protocols available */
8367e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": no valid socket protocols available",
8368e92d3f3fSGregory Neil Shapiro map->map_mname);
8369e92d3f3fSGregory Neil Shapiro return false;
8370e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8371e92d3f3fSGregory Neil Shapiro # endif /* NETINET */
8372e92d3f3fSGregory Neil Shapiro # endif /* NETUNIX */
8373e92d3f3fSGregory Neil Shapiro }
8374e92d3f3fSGregory Neil Shapiro # if NETUNIX
83752fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(p, "unix") ||
83762fb4f839SGregory Neil Shapiro SM_STRCASEEQ(p, "local"))
8377e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_UNIX;
8378e92d3f3fSGregory Neil Shapiro # endif /* NETUNIX */
8379e92d3f3fSGregory Neil Shapiro # if NETINET
83802fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(p, "inet"))
8381e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_INET;
8382e92d3f3fSGregory Neil Shapiro # endif /* NETINET */
8383e92d3f3fSGregory Neil Shapiro # if NETINET6
83842fb4f839SGregory Neil Shapiro else if (SM_STRCASEEQ(p, "inet6"))
8385e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_INET6;
8386e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8387e92d3f3fSGregory Neil Shapiro else
8388e92d3f3fSGregory Neil Shapiro {
8389e92d3f3fSGregory Neil Shapiro # ifdef EPROTONOSUPPORT
8390e92d3f3fSGregory Neil Shapiro errno = EPROTONOSUPPORT;
83915b0945b5SGregory Neil Shapiro # else
8392e92d3f3fSGregory Neil Shapiro errno = EINVAL;
8393e92d3f3fSGregory Neil Shapiro # endif /* EPROTONOSUPPORT */
8394e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": unknown socket type %s",
8395e92d3f3fSGregory Neil Shapiro map->map_mname, p);
8396e92d3f3fSGregory Neil Shapiro return false;
8397e92d3f3fSGregory Neil Shapiro }
8398e92d3f3fSGregory Neil Shapiro *colon++ = ':';
8399e92d3f3fSGregory Neil Shapiro }
8400e92d3f3fSGregory Neil Shapiro else
8401e92d3f3fSGregory Neil Shapiro {
8402e92d3f3fSGregory Neil Shapiro colon = p;
8403e92d3f3fSGregory Neil Shapiro # if NETUNIX
8404e92d3f3fSGregory Neil Shapiro /* default to AF_UNIX */
8405e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_UNIX;
8406e92d3f3fSGregory Neil Shapiro # else /* NETUNIX */
8407e92d3f3fSGregory Neil Shapiro # if NETINET
8408e92d3f3fSGregory Neil Shapiro /* default to AF_INET */
8409e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_INET;
8410e92d3f3fSGregory Neil Shapiro # else /* NETINET */
8411e92d3f3fSGregory Neil Shapiro # if NETINET6
8412e92d3f3fSGregory Neil Shapiro /* default to AF_INET6 */
8413e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = AF_INET6;
8414e92d3f3fSGregory Neil Shapiro # else /* NETINET6 */
8415e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": unknown socket type %s",
8416e92d3f3fSGregory Neil Shapiro map->map_mname, p);
8417e92d3f3fSGregory Neil Shapiro return false;
8418e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8419e92d3f3fSGregory Neil Shapiro # endif /* NETINET */
8420e92d3f3fSGregory Neil Shapiro # endif /* NETUNIX */
8421e92d3f3fSGregory Neil Shapiro }
8422e92d3f3fSGregory Neil Shapiro
8423e92d3f3fSGregory Neil Shapiro # if NETUNIX
8424e92d3f3fSGregory Neil Shapiro if (addr.sa.sa_family == AF_UNIX)
8425e92d3f3fSGregory Neil Shapiro {
8426e92d3f3fSGregory Neil Shapiro long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
8427e92d3f3fSGregory Neil Shapiro
8428e92d3f3fSGregory Neil Shapiro at = colon;
8429d0cef73dSGregory Neil Shapiro if (strlen(colon) >= sizeof(addr.sunix.sun_path))
8430e92d3f3fSGregory Neil Shapiro {
8431e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": local socket name %s too long",
8432e92d3f3fSGregory Neil Shapiro map->map_mname, colon);
8433e92d3f3fSGregory Neil Shapiro return false;
8434e92d3f3fSGregory Neil Shapiro }
8435e92d3f3fSGregory Neil Shapiro errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
8436e92d3f3fSGregory Neil Shapiro S_IRUSR|S_IWUSR, NULL);
8437e92d3f3fSGregory Neil Shapiro
8438e92d3f3fSGregory Neil Shapiro if (errno != 0)
8439e92d3f3fSGregory Neil Shapiro {
8440e92d3f3fSGregory Neil Shapiro /* if not safe, don't create */
8441e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": local socket name %s unsafe",
8442e92d3f3fSGregory Neil Shapiro map->map_mname, colon);
8443e92d3f3fSGregory Neil Shapiro return false;
8444e92d3f3fSGregory Neil Shapiro }
8445e92d3f3fSGregory Neil Shapiro
8446e92d3f3fSGregory Neil Shapiro (void) sm_strlcpy(addr.sunix.sun_path, colon,
8447d0cef73dSGregory Neil Shapiro sizeof(addr.sunix.sun_path));
8448e92d3f3fSGregory Neil Shapiro addrlen = sizeof(struct sockaddr_un);
8449e92d3f3fSGregory Neil Shapiro }
8450e92d3f3fSGregory Neil Shapiro else
8451e92d3f3fSGregory Neil Shapiro # endif /* NETUNIX */
8452e92d3f3fSGregory Neil Shapiro # if NETINET || NETINET6
8453e92d3f3fSGregory Neil Shapiro if (false
8454e92d3f3fSGregory Neil Shapiro # if NETINET
8455e92d3f3fSGregory Neil Shapiro || addr.sa.sa_family == AF_INET
84565b0945b5SGregory Neil Shapiro # endif
8457e92d3f3fSGregory Neil Shapiro # if NETINET6
8458e92d3f3fSGregory Neil Shapiro || addr.sa.sa_family == AF_INET6
84595b0945b5SGregory Neil Shapiro # endif
8460e92d3f3fSGregory Neil Shapiro )
8461e92d3f3fSGregory Neil Shapiro {
8462e92d3f3fSGregory Neil Shapiro unsigned short port;
8463e92d3f3fSGregory Neil Shapiro
8464e92d3f3fSGregory Neil Shapiro /* Parse port@host */
8465e92d3f3fSGregory Neil Shapiro at = strchr(colon, '@');
8466e92d3f3fSGregory Neil Shapiro if (at == NULL)
8467e92d3f3fSGregory Neil Shapiro {
8468e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": bad address %s (expected port@host)",
8469e92d3f3fSGregory Neil Shapiro map->map_mname, colon);
8470e92d3f3fSGregory Neil Shapiro return false;
8471e92d3f3fSGregory Neil Shapiro }
8472e92d3f3fSGregory Neil Shapiro *at = '\0';
8473e92d3f3fSGregory Neil Shapiro if (isascii(*colon) && isdigit(*colon))
8474e92d3f3fSGregory Neil Shapiro port = htons((unsigned short) atoi(colon));
8475e92d3f3fSGregory Neil Shapiro else
8476e92d3f3fSGregory Neil Shapiro {
8477e92d3f3fSGregory Neil Shapiro # ifdef NO_GETSERVBYNAME
8478e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": invalid port number %s",
8479e92d3f3fSGregory Neil Shapiro map->map_mname, colon);
8480e92d3f3fSGregory Neil Shapiro return false;
8481e92d3f3fSGregory Neil Shapiro # else /* NO_GETSERVBYNAME */
8482e92d3f3fSGregory Neil Shapiro register struct servent *sp;
8483e92d3f3fSGregory Neil Shapiro
8484e92d3f3fSGregory Neil Shapiro sp = getservbyname(colon, "tcp");
8485e92d3f3fSGregory Neil Shapiro if (sp == NULL)
8486e92d3f3fSGregory Neil Shapiro {
8487e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": unknown port name %s",
8488e92d3f3fSGregory Neil Shapiro map->map_mname, colon);
8489e92d3f3fSGregory Neil Shapiro return false;
8490e92d3f3fSGregory Neil Shapiro }
8491e92d3f3fSGregory Neil Shapiro port = sp->s_port;
8492e92d3f3fSGregory Neil Shapiro # endif /* NO_GETSERVBYNAME */
8493e92d3f3fSGregory Neil Shapiro }
8494e92d3f3fSGregory Neil Shapiro *at++ = '@';
8495e92d3f3fSGregory Neil Shapiro if (*at == '[')
8496e92d3f3fSGregory Neil Shapiro {
8497e92d3f3fSGregory Neil Shapiro char *end;
8498e92d3f3fSGregory Neil Shapiro
8499e92d3f3fSGregory Neil Shapiro end = strchr(at, ']');
8500e92d3f3fSGregory Neil Shapiro if (end != NULL)
8501e92d3f3fSGregory Neil Shapiro {
8502e92d3f3fSGregory Neil Shapiro bool found = false;
8503e92d3f3fSGregory Neil Shapiro # if NETINET
8504e92d3f3fSGregory Neil Shapiro unsigned long hid = INADDR_NONE;
85055b0945b5SGregory Neil Shapiro # endif
8506e92d3f3fSGregory Neil Shapiro # if NETINET6
8507e92d3f3fSGregory Neil Shapiro struct sockaddr_in6 hid6;
85085b0945b5SGregory Neil Shapiro # endif
8509e92d3f3fSGregory Neil Shapiro
8510e92d3f3fSGregory Neil Shapiro *end = '\0';
8511e92d3f3fSGregory Neil Shapiro # if NETINET
8512e92d3f3fSGregory Neil Shapiro if (addr.sa.sa_family == AF_INET &&
8513e92d3f3fSGregory Neil Shapiro (hid = inet_addr(&at[1])) != INADDR_NONE)
8514e92d3f3fSGregory Neil Shapiro {
8515e92d3f3fSGregory Neil Shapiro addr.sin.sin_addr.s_addr = hid;
8516e92d3f3fSGregory Neil Shapiro addr.sin.sin_port = port;
8517e92d3f3fSGregory Neil Shapiro found = true;
8518e92d3f3fSGregory Neil Shapiro }
8519e92d3f3fSGregory Neil Shapiro # endif /* NETINET */
8520e92d3f3fSGregory Neil Shapiro # if NETINET6
8521d0cef73dSGregory Neil Shapiro (void) memset(&hid6, '\0', sizeof(hid6));
8522e92d3f3fSGregory Neil Shapiro if (addr.sa.sa_family == AF_INET6 &&
8523e92d3f3fSGregory Neil Shapiro anynet_pton(AF_INET6, &at[1],
8524e92d3f3fSGregory Neil Shapiro &hid6.sin6_addr) == 1)
8525e92d3f3fSGregory Neil Shapiro {
8526e92d3f3fSGregory Neil Shapiro addr.sin6.sin6_addr = hid6.sin6_addr;
8527e92d3f3fSGregory Neil Shapiro addr.sin6.sin6_port = port;
8528e92d3f3fSGregory Neil Shapiro found = true;
8529e92d3f3fSGregory Neil Shapiro }
8530e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8531e92d3f3fSGregory Neil Shapiro *end = ']';
8532e92d3f3fSGregory Neil Shapiro if (!found)
8533e92d3f3fSGregory Neil Shapiro {
8534e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"",
8535e92d3f3fSGregory Neil Shapiro map->map_mname, at);
8536e92d3f3fSGregory Neil Shapiro return false;
8537e92d3f3fSGregory Neil Shapiro }
8538e92d3f3fSGregory Neil Shapiro }
8539e92d3f3fSGregory Neil Shapiro else
8540e92d3f3fSGregory Neil Shapiro {
8541e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"",
8542e92d3f3fSGregory Neil Shapiro map->map_mname, at);
8543e92d3f3fSGregory Neil Shapiro return false;
8544e92d3f3fSGregory Neil Shapiro }
8545e92d3f3fSGregory Neil Shapiro }
8546e92d3f3fSGregory Neil Shapiro else
8547e92d3f3fSGregory Neil Shapiro {
8548e92d3f3fSGregory Neil Shapiro hp = sm_gethostbyname(at, addr.sa.sa_family);
8549e92d3f3fSGregory Neil Shapiro if (hp == NULL)
8550e92d3f3fSGregory Neil Shapiro {
8551e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": Unknown host name %s",
8552e92d3f3fSGregory Neil Shapiro map->map_mname, at);
8553e92d3f3fSGregory Neil Shapiro return false;
8554e92d3f3fSGregory Neil Shapiro }
8555e92d3f3fSGregory Neil Shapiro addr.sa.sa_family = hp->h_addrtype;
8556e92d3f3fSGregory Neil Shapiro switch (hp->h_addrtype)
8557e92d3f3fSGregory Neil Shapiro {
8558e92d3f3fSGregory Neil Shapiro # if NETINET
8559e92d3f3fSGregory Neil Shapiro case AF_INET:
8560e92d3f3fSGregory Neil Shapiro memmove(&addr.sin.sin_addr,
8561e92d3f3fSGregory Neil Shapiro hp->h_addr, INADDRSZ);
8562e92d3f3fSGregory Neil Shapiro addr.sin.sin_port = port;
8563e92d3f3fSGregory Neil Shapiro addrlen = sizeof(struct sockaddr_in);
8564e92d3f3fSGregory Neil Shapiro addrno = 1;
8565e92d3f3fSGregory Neil Shapiro break;
8566e92d3f3fSGregory Neil Shapiro # endif /* NETINET */
8567e92d3f3fSGregory Neil Shapiro
8568e92d3f3fSGregory Neil Shapiro # if NETINET6
8569e92d3f3fSGregory Neil Shapiro case AF_INET6:
8570e92d3f3fSGregory Neil Shapiro memmove(&addr.sin6.sin6_addr,
8571e92d3f3fSGregory Neil Shapiro hp->h_addr, IN6ADDRSZ);
8572e92d3f3fSGregory Neil Shapiro addr.sin6.sin6_port = port;
8573e92d3f3fSGregory Neil Shapiro addrlen = sizeof(struct sockaddr_in6);
8574e92d3f3fSGregory Neil Shapiro addrno = 1;
8575e92d3f3fSGregory Neil Shapiro break;
8576e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8577e92d3f3fSGregory Neil Shapiro
8578e92d3f3fSGregory Neil Shapiro default:
8579e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": Unknown protocol for %s (%d)",
8580e92d3f3fSGregory Neil Shapiro map->map_mname, at, hp->h_addrtype);
8581e92d3f3fSGregory Neil Shapiro # if NETINET6
8582e92d3f3fSGregory Neil Shapiro freehostent(hp);
85835b0945b5SGregory Neil Shapiro # endif
8584e92d3f3fSGregory Neil Shapiro return false;
8585e92d3f3fSGregory Neil Shapiro }
8586e92d3f3fSGregory Neil Shapiro }
8587e92d3f3fSGregory Neil Shapiro }
8588e92d3f3fSGregory Neil Shapiro else
8589e92d3f3fSGregory Neil Shapiro # endif /* NETINET || NETINET6 */
8590e92d3f3fSGregory Neil Shapiro {
8591e92d3f3fSGregory Neil Shapiro syserr("socket map \"%s\": unknown socket protocol",
8592e92d3f3fSGregory Neil Shapiro map->map_mname);
8593e92d3f3fSGregory Neil Shapiro return false;
8594e92d3f3fSGregory Neil Shapiro }
8595e92d3f3fSGregory Neil Shapiro
8596e92d3f3fSGregory Neil Shapiro /* nope, actually connecting */
8597e92d3f3fSGregory Neil Shapiro for (;;)
8598e92d3f3fSGregory Neil Shapiro {
8599e92d3f3fSGregory Neil Shapiro sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
8600e92d3f3fSGregory Neil Shapiro if (sock < 0)
8601e92d3f3fSGregory Neil Shapiro {
8602e92d3f3fSGregory Neil Shapiro save_errno = errno;
8603e92d3f3fSGregory Neil Shapiro if (tTd(38, 5))
8604e92d3f3fSGregory Neil Shapiro sm_dprintf("socket map \"%s\": error creating socket: %s\n",
8605e92d3f3fSGregory Neil Shapiro map->map_mname,
8606e92d3f3fSGregory Neil Shapiro sm_errstring(save_errno));
8607e92d3f3fSGregory Neil Shapiro # if NETINET6
8608e92d3f3fSGregory Neil Shapiro if (hp != NULL)
8609e92d3f3fSGregory Neil Shapiro freehostent(hp);
8610e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8611e92d3f3fSGregory Neil Shapiro return false;
8612e92d3f3fSGregory Neil Shapiro }
8613e92d3f3fSGregory Neil Shapiro
8614e92d3f3fSGregory Neil Shapiro if (connect(sock, (struct sockaddr *) &addr, addrlen) >= 0)
8615e92d3f3fSGregory Neil Shapiro break;
8616e92d3f3fSGregory Neil Shapiro
8617e92d3f3fSGregory Neil Shapiro /* couldn't connect.... try next address */
8618e92d3f3fSGregory Neil Shapiro save_errno = errno;
8619e92d3f3fSGregory Neil Shapiro p = CurHostName;
8620e92d3f3fSGregory Neil Shapiro CurHostName = at;
8621e92d3f3fSGregory Neil Shapiro if (tTd(38, 5))
8622e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_open (%s): open %s failed: %s\n",
8623e92d3f3fSGregory Neil Shapiro map->map_mname, at, sm_errstring(save_errno));
8624e92d3f3fSGregory Neil Shapiro CurHostName = p;
8625e92d3f3fSGregory Neil Shapiro (void) close(sock);
8626e92d3f3fSGregory Neil Shapiro
8627e92d3f3fSGregory Neil Shapiro /* try next address */
8628e92d3f3fSGregory Neil Shapiro if (hp != NULL && hp->h_addr_list[addrno] != NULL)
8629e92d3f3fSGregory Neil Shapiro {
8630e92d3f3fSGregory Neil Shapiro switch (addr.sa.sa_family)
8631e92d3f3fSGregory Neil Shapiro {
8632e92d3f3fSGregory Neil Shapiro # if NETINET
8633e92d3f3fSGregory Neil Shapiro case AF_INET:
8634e92d3f3fSGregory Neil Shapiro memmove(&addr.sin.sin_addr,
8635e92d3f3fSGregory Neil Shapiro hp->h_addr_list[addrno++],
8636e92d3f3fSGregory Neil Shapiro INADDRSZ);
8637e92d3f3fSGregory Neil Shapiro break;
8638e92d3f3fSGregory Neil Shapiro # endif /* NETINET */
8639e92d3f3fSGregory Neil Shapiro
8640e92d3f3fSGregory Neil Shapiro # if NETINET6
8641e92d3f3fSGregory Neil Shapiro case AF_INET6:
8642e92d3f3fSGregory Neil Shapiro memmove(&addr.sin6.sin6_addr,
8643e92d3f3fSGregory Neil Shapiro hp->h_addr_list[addrno++],
8644e92d3f3fSGregory Neil Shapiro IN6ADDRSZ);
8645e92d3f3fSGregory Neil Shapiro break;
8646e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8647e92d3f3fSGregory Neil Shapiro
8648e92d3f3fSGregory Neil Shapiro default:
8649e92d3f3fSGregory Neil Shapiro if (tTd(38, 5))
8650e92d3f3fSGregory Neil Shapiro sm_dprintf("socket map \"%s\": Unknown protocol for %s (%d)\n",
8651e92d3f3fSGregory Neil Shapiro map->map_mname, at,
8652e92d3f3fSGregory Neil Shapiro hp->h_addrtype);
8653e92d3f3fSGregory Neil Shapiro # if NETINET6
8654e92d3f3fSGregory Neil Shapiro freehostent(hp);
86555b0945b5SGregory Neil Shapiro # endif
8656e92d3f3fSGregory Neil Shapiro return false;
8657e92d3f3fSGregory Neil Shapiro }
8658e92d3f3fSGregory Neil Shapiro continue;
8659e92d3f3fSGregory Neil Shapiro }
8660e92d3f3fSGregory Neil Shapiro p = CurHostName;
8661e92d3f3fSGregory Neil Shapiro CurHostName = at;
8662e92d3f3fSGregory Neil Shapiro if (tTd(38, 5))
8663e92d3f3fSGregory Neil Shapiro sm_dprintf("socket map \"%s\": error connecting to socket map: %s\n",
8664e92d3f3fSGregory Neil Shapiro map->map_mname, sm_errstring(save_errno));
8665e92d3f3fSGregory Neil Shapiro CurHostName = p;
8666e92d3f3fSGregory Neil Shapiro # if NETINET6
8667e92d3f3fSGregory Neil Shapiro if (hp != NULL)
8668e92d3f3fSGregory Neil Shapiro freehostent(hp);
86695b0945b5SGregory Neil Shapiro # endif
8670e92d3f3fSGregory Neil Shapiro return false;
8671e92d3f3fSGregory Neil Shapiro }
8672e92d3f3fSGregory Neil Shapiro # if NETINET6
8673e92d3f3fSGregory Neil Shapiro if (hp != NULL)
8674e92d3f3fSGregory Neil Shapiro {
8675e92d3f3fSGregory Neil Shapiro freehostent(hp);
8676e92d3f3fSGregory Neil Shapiro hp = NULL;
8677e92d3f3fSGregory Neil Shapiro }
8678e92d3f3fSGregory Neil Shapiro # endif /* NETINET6 */
8679e92d3f3fSGregory Neil Shapiro if ((map->map_db1 = (ARBPTR_T) sm_io_open(SmFtStdiofd,
8680e92d3f3fSGregory Neil Shapiro SM_TIME_DEFAULT,
8681e92d3f3fSGregory Neil Shapiro (void *) &sock,
8682e92d3f3fSGregory Neil Shapiro SM_IO_RDWR,
8683e92d3f3fSGregory Neil Shapiro NULL)) == NULL)
8684e92d3f3fSGregory Neil Shapiro {
8685e92d3f3fSGregory Neil Shapiro close(sock);
8686e92d3f3fSGregory Neil Shapiro if (tTd(38, 2))
8687e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_open (%s): failed to create stream: %s\n",
8688e92d3f3fSGregory Neil Shapiro map->map_mname, sm_errstring(errno));
8689e92d3f3fSGregory Neil Shapiro return false;
8690e92d3f3fSGregory Neil Shapiro }
8691e92d3f3fSGregory Neil Shapiro
8692da7d7b9cSGregory Neil Shapiro tmo = map->map_timeout;
8693da7d7b9cSGregory Neil Shapiro if (tmo == 0)
8694da7d7b9cSGregory Neil Shapiro tmo = 30000; /* default: 30s */
8695da7d7b9cSGregory Neil Shapiro else
8696da7d7b9cSGregory Neil Shapiro tmo *= 1000; /* s -> ms */
8697da7d7b9cSGregory Neil Shapiro sm_io_setinfo(map->map_db1, SM_IO_WHAT_TIMEOUT, &tmo);
8698da7d7b9cSGregory Neil Shapiro
8699e92d3f3fSGregory Neil Shapiro /* Save connection for reuse */
8700e92d3f3fSGregory Neil Shapiro s->s_socketmap = map;
8701e92d3f3fSGregory Neil Shapiro return true;
8702e92d3f3fSGregory Neil Shapiro }
8703e92d3f3fSGregory Neil Shapiro
8704e92d3f3fSGregory Neil Shapiro /*
8705e92d3f3fSGregory Neil Shapiro ** SOCKET_MAP_FINDCONN -- find a SOCKET connection to the server
8706e92d3f3fSGregory Neil Shapiro **
8707e92d3f3fSGregory Neil Shapiro ** Cache SOCKET connections based on the connection specifier
8708e92d3f3fSGregory Neil Shapiro ** and PID so we don't have multiple connections open to
8709e92d3f3fSGregory Neil Shapiro ** the same server for different maps. Need a separate connection
8710e92d3f3fSGregory Neil Shapiro ** per PID since a parent process may close the map before the
8711e92d3f3fSGregory Neil Shapiro ** child is done with it.
8712e92d3f3fSGregory Neil Shapiro **
8713e92d3f3fSGregory Neil Shapiro ** Parameters:
8714e92d3f3fSGregory Neil Shapiro ** conn -- SOCKET map connection specifier
8715e92d3f3fSGregory Neil Shapiro **
8716e92d3f3fSGregory Neil Shapiro ** Returns:
8717e92d3f3fSGregory Neil Shapiro ** Symbol table entry for the SOCKET connection.
8718e92d3f3fSGregory Neil Shapiro */
8719e92d3f3fSGregory Neil Shapiro
8720e92d3f3fSGregory Neil Shapiro static STAB *
socket_map_findconn(conn)8721e92d3f3fSGregory Neil Shapiro socket_map_findconn(conn)
8722e92d3f3fSGregory Neil Shapiro const char *conn;
8723e92d3f3fSGregory Neil Shapiro {
8724e92d3f3fSGregory Neil Shapiro char *nbuf;
8725e92d3f3fSGregory Neil Shapiro STAB *SM_NONVOLATILE s = NULL;
8726e92d3f3fSGregory Neil Shapiro
8727e92d3f3fSGregory Neil Shapiro nbuf = sm_stringf_x("%s%c%d", conn, CONDELSE, (int) CurrentPid);
8728e92d3f3fSGregory Neil Shapiro SM_TRY
8729e92d3f3fSGregory Neil Shapiro s = stab(nbuf, ST_SOCKETMAP, ST_ENTER);
8730e92d3f3fSGregory Neil Shapiro SM_FINALLY
8731e92d3f3fSGregory Neil Shapiro sm_free(nbuf);
8732e92d3f3fSGregory Neil Shapiro SM_END_TRY
8733e92d3f3fSGregory Neil Shapiro return s;
8734e92d3f3fSGregory Neil Shapiro }
8735e92d3f3fSGregory Neil Shapiro
8736e92d3f3fSGregory Neil Shapiro /*
8737e92d3f3fSGregory Neil Shapiro ** SOCKET_MAP_CLOSE -- close the socket
8738e92d3f3fSGregory Neil Shapiro */
8739e92d3f3fSGregory Neil Shapiro
8740e92d3f3fSGregory Neil Shapiro void
socket_map_close(map)8741e92d3f3fSGregory Neil Shapiro socket_map_close(map)
8742e92d3f3fSGregory Neil Shapiro MAP *map;
8743e92d3f3fSGregory Neil Shapiro {
8744e92d3f3fSGregory Neil Shapiro STAB *s;
8745e92d3f3fSGregory Neil Shapiro MAP *smap;
8746e92d3f3fSGregory Neil Shapiro
8747e92d3f3fSGregory Neil Shapiro if (tTd(38, 20))
8748e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_close(%s), pid=%ld\n", map->map_file,
8749e92d3f3fSGregory Neil Shapiro (long) CurrentPid);
8750e92d3f3fSGregory Neil Shapiro
8751e92d3f3fSGregory Neil Shapiro /* Check if already closed */
8752e92d3f3fSGregory Neil Shapiro if (map->map_db1 == NULL)
8753e92d3f3fSGregory Neil Shapiro {
8754e92d3f3fSGregory Neil Shapiro if (tTd(38, 20))
8755e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_close(%s) already closed\n",
8756e92d3f3fSGregory Neil Shapiro map->map_file);
8757e92d3f3fSGregory Neil Shapiro return;
8758e92d3f3fSGregory Neil Shapiro }
8759e92d3f3fSGregory Neil Shapiro sm_io_close((SM_FILE_T *)map->map_db1, SM_TIME_DEFAULT);
8760e92d3f3fSGregory Neil Shapiro
8761e92d3f3fSGregory Neil Shapiro /* Mark all the maps that share the connection as closed */
8762e92d3f3fSGregory Neil Shapiro s = socket_map_findconn(map->map_file);
8763e92d3f3fSGregory Neil Shapiro smap = s->s_socketmap;
8764e92d3f3fSGregory Neil Shapiro while (smap != NULL)
8765e92d3f3fSGregory Neil Shapiro {
8766e92d3f3fSGregory Neil Shapiro MAP *next;
8767e92d3f3fSGregory Neil Shapiro
8768e92d3f3fSGregory Neil Shapiro if (tTd(38, 2) && smap != map)
8769e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_close(%s): closed %s (shared SOCKET connection)\n",
8770e92d3f3fSGregory Neil Shapiro map->map_mname, smap->map_mname);
8771e92d3f3fSGregory Neil Shapiro
8772e92d3f3fSGregory Neil Shapiro smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
8773e92d3f3fSGregory Neil Shapiro smap->map_db1 = NULL;
8774e92d3f3fSGregory Neil Shapiro next = smap->socket_map_next;
8775e92d3f3fSGregory Neil Shapiro smap->socket_map_next = NULL;
8776e92d3f3fSGregory Neil Shapiro smap = next;
8777e92d3f3fSGregory Neil Shapiro }
8778e92d3f3fSGregory Neil Shapiro s->s_socketmap = NULL;
8779e92d3f3fSGregory Neil Shapiro }
8780e92d3f3fSGregory Neil Shapiro
8781e92d3f3fSGregory Neil Shapiro /*
8782e92d3f3fSGregory Neil Shapiro ** SOCKET_MAP_LOOKUP -- look up a datum in a SOCKET table
8783e92d3f3fSGregory Neil Shapiro */
8784e92d3f3fSGregory Neil Shapiro
8785e92d3f3fSGregory Neil Shapiro char *
socket_map_lookup(map,name,av,statp)8786e92d3f3fSGregory Neil Shapiro socket_map_lookup(map, name, av, statp)
8787e92d3f3fSGregory Neil Shapiro MAP *map;
8788e92d3f3fSGregory Neil Shapiro char *name;
8789e92d3f3fSGregory Neil Shapiro char **av;
8790e92d3f3fSGregory Neil Shapiro int *statp;
8791e92d3f3fSGregory Neil Shapiro {
8792e92d3f3fSGregory Neil Shapiro unsigned int nettolen, replylen, recvlen;
87935b0945b5SGregory Neil Shapiro int ret;
879413d88268SGregory Neil Shapiro char *replybuf, *rval, *value, *status, *key;
8795e92d3f3fSGregory Neil Shapiro SM_FILE_T *f;
87962fb4f839SGregory Neil Shapiro char keybuf[MAXNAME + 1]; /* EAI:ok */
8797e92d3f3fSGregory Neil Shapiro
8798e92d3f3fSGregory Neil Shapiro replybuf = NULL;
8799e92d3f3fSGregory Neil Shapiro rval = NULL;
8800e92d3f3fSGregory Neil Shapiro f = (SM_FILE_T *)map->map_db1;
8801e92d3f3fSGregory Neil Shapiro if (tTd(38, 20))
8802e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_lookup(%s, %s) %s\n",
8803e92d3f3fSGregory Neil Shapiro map->map_mname, name, map->map_file);
8804e92d3f3fSGregory Neil Shapiro
880513d88268SGregory Neil Shapiro if (!bitset(MF_NOFOLDCASE, map->map_mflags))
880613d88268SGregory Neil Shapiro {
880713d88268SGregory Neil Shapiro nettolen = strlen(name);
8808d0cef73dSGregory Neil Shapiro if (nettolen > sizeof(keybuf) - 1)
8809d0cef73dSGregory Neil Shapiro nettolen = sizeof(keybuf) - 1;
881013d88268SGregory Neil Shapiro memmove(keybuf, name, nettolen);
881113d88268SGregory Neil Shapiro keybuf[nettolen] = '\0';
88122fb4f839SGregory Neil Shapiro makelower_buf(keybuf, keybuf, sizeof(keybuf));
881313d88268SGregory Neil Shapiro key = keybuf;
881413d88268SGregory Neil Shapiro }
881513d88268SGregory Neil Shapiro else
881613d88268SGregory Neil Shapiro key = name;
881713d88268SGregory Neil Shapiro
881813d88268SGregory Neil Shapiro nettolen = strlen(map->map_mname) + 1 + strlen(key);
8819e92d3f3fSGregory Neil Shapiro SM_ASSERT(nettolen > strlen(map->map_mname));
882013d88268SGregory Neil Shapiro SM_ASSERT(nettolen > strlen(key));
8821e92d3f3fSGregory Neil Shapiro if ((sm_io_fprintf(f, SM_TIME_DEFAULT, "%u:%s %s,",
882213d88268SGregory Neil Shapiro nettolen, map->map_mname, key) == SM_IO_EOF) ||
8823e92d3f3fSGregory Neil Shapiro (sm_io_flush(f, SM_TIME_DEFAULT) != 0) ||
8824e92d3f3fSGregory Neil Shapiro (sm_io_error(f)))
8825e92d3f3fSGregory Neil Shapiro {
8826e92d3f3fSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): failed to send lookup request",
8827e92d3f3fSGregory Neil Shapiro map->map_mname);
8828e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8829e92d3f3fSGregory Neil Shapiro goto errcl;
8830e92d3f3fSGregory Neil Shapiro }
8831e92d3f3fSGregory Neil Shapiro
88325b0945b5SGregory Neil Shapiro if ((ret = sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen)) != 1)
8833e92d3f3fSGregory Neil Shapiro {
8834da7d7b9cSGregory Neil Shapiro if (errno == EAGAIN)
8835da7d7b9cSGregory Neil Shapiro {
8836da7d7b9cSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): read timeout",
8837e92d3f3fSGregory Neil Shapiro map->map_mname);
8838da7d7b9cSGregory Neil Shapiro }
88395b0945b5SGregory Neil Shapiro else if (SM_IO_EOF == ret)
88405b0945b5SGregory Neil Shapiro {
88415b0945b5SGregory Neil Shapiro if (LogLevel > 9)
88425b0945b5SGregory Neil Shapiro sm_syslog(LOG_INFO, CurEnv->e_id,
88435b0945b5SGregory Neil Shapiro "socket_map_lookup(%s): EOF",
88445b0945b5SGregory Neil Shapiro map->map_mname);
88455b0945b5SGregory Neil Shapiro }
8846da7d7b9cSGregory Neil Shapiro else
8847da7d7b9cSGregory Neil Shapiro {
8848da7d7b9cSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply %d",
8849da7d7b9cSGregory Neil Shapiro map->map_mname, errno);
8850da7d7b9cSGregory Neil Shapiro }
8851e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8852e92d3f3fSGregory Neil Shapiro goto errcl;
8853e92d3f3fSGregory Neil Shapiro }
8854e92d3f3fSGregory Neil Shapiro if (replylen > SOCKETMAP_MAXL)
8855e92d3f3fSGregory Neil Shapiro {
8856e92d3f3fSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): reply too long: %u",
8857e92d3f3fSGregory Neil Shapiro map->map_mname, replylen);
8858e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8859e92d3f3fSGregory Neil Shapiro goto errcl;
8860e92d3f3fSGregory Neil Shapiro }
8861e92d3f3fSGregory Neil Shapiro if (sm_io_getc(f, SM_TIME_DEFAULT) != ':')
8862e92d3f3fSGregory Neil Shapiro {
8863e92d3f3fSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): missing ':' in reply",
8864e92d3f3fSGregory Neil Shapiro map->map_mname);
8865e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8866e92d3f3fSGregory Neil Shapiro goto error;
8867e92d3f3fSGregory Neil Shapiro }
8868e92d3f3fSGregory Neil Shapiro
8869e92d3f3fSGregory Neil Shapiro replybuf = (char *) sm_malloc(replylen + 1);
8870e92d3f3fSGregory Neil Shapiro if (replybuf == NULL)
8871e92d3f3fSGregory Neil Shapiro {
8872e92d3f3fSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): can't allocate %u bytes",
8873e92d3f3fSGregory Neil Shapiro map->map_mname, replylen + 1);
8874e92d3f3fSGregory Neil Shapiro *statp = EX_OSERR;
8875e92d3f3fSGregory Neil Shapiro goto error;
8876e92d3f3fSGregory Neil Shapiro }
8877e92d3f3fSGregory Neil Shapiro
8878e92d3f3fSGregory Neil Shapiro recvlen = sm_io_read(f, SM_TIME_DEFAULT, replybuf, replylen);
8879e92d3f3fSGregory Neil Shapiro if (recvlen < replylen)
8880e92d3f3fSGregory Neil Shapiro {
8881e92d3f3fSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): received only %u of %u reply characters",
8882e92d3f3fSGregory Neil Shapiro map->map_mname, recvlen, replylen);
8883e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8884e92d3f3fSGregory Neil Shapiro goto errcl;
8885e92d3f3fSGregory Neil Shapiro }
8886e92d3f3fSGregory Neil Shapiro if (sm_io_getc(f, SM_TIME_DEFAULT) != ',')
8887e92d3f3fSGregory Neil Shapiro {
8888e92d3f3fSGregory Neil Shapiro syserr("451 4.3.0 socket_map_lookup(%s): missing ',' in reply",
8889e92d3f3fSGregory Neil Shapiro map->map_mname);
8890e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8891e92d3f3fSGregory Neil Shapiro goto errcl;
8892e92d3f3fSGregory Neil Shapiro }
8893e92d3f3fSGregory Neil Shapiro status = replybuf;
8894e92d3f3fSGregory Neil Shapiro replybuf[recvlen] = '\0';
8895e92d3f3fSGregory Neil Shapiro value = strchr(replybuf, ' ');
8896e92d3f3fSGregory Neil Shapiro if (value != NULL)
8897e92d3f3fSGregory Neil Shapiro {
8898e92d3f3fSGregory Neil Shapiro *value = '\0';
8899e92d3f3fSGregory Neil Shapiro value++;
8900e92d3f3fSGregory Neil Shapiro }
8901e92d3f3fSGregory Neil Shapiro if (strcmp(status, "OK") == 0)
8902e92d3f3fSGregory Neil Shapiro {
8903e92d3f3fSGregory Neil Shapiro *statp = EX_OK;
8904e92d3f3fSGregory Neil Shapiro
8905e92d3f3fSGregory Neil Shapiro /* collect the return value */
8906e92d3f3fSGregory Neil Shapiro if (bitset(MF_MATCHONLY, map->map_mflags))
890713d88268SGregory Neil Shapiro rval = map_rewrite(map, key, strlen(key), NULL);
8908e92d3f3fSGregory Neil Shapiro else
8909e92d3f3fSGregory Neil Shapiro rval = map_rewrite(map, value, strlen(value), av);
8910e92d3f3fSGregory Neil Shapiro }
8911e92d3f3fSGregory Neil Shapiro else if (strcmp(status, "NOTFOUND") == 0)
8912e92d3f3fSGregory Neil Shapiro {
8913e92d3f3fSGregory Neil Shapiro *statp = EX_NOTFOUND;
8914e92d3f3fSGregory Neil Shapiro if (tTd(38, 20))
8915e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_lookup(%s): %s not found\n",
891613d88268SGregory Neil Shapiro map->map_mname, key);
8917e92d3f3fSGregory Neil Shapiro }
8918e92d3f3fSGregory Neil Shapiro else
8919e92d3f3fSGregory Neil Shapiro {
8920e92d3f3fSGregory Neil Shapiro if (tTd(38, 5))
8921e92d3f3fSGregory Neil Shapiro sm_dprintf("socket_map_lookup(%s, %s): server returned error: type=%s, reason=%s\n",
892213d88268SGregory Neil Shapiro map->map_mname, key, status,
8923e92d3f3fSGregory Neil Shapiro value ? value : "");
8924e92d3f3fSGregory Neil Shapiro if ((strcmp(status, "TEMP") == 0) ||
8925e92d3f3fSGregory Neil Shapiro (strcmp(status, "TIMEOUT") == 0))
8926e92d3f3fSGregory Neil Shapiro *statp = EX_TEMPFAIL;
8927e92d3f3fSGregory Neil Shapiro else if(strcmp(status, "PERM") == 0)
8928e92d3f3fSGregory Neil Shapiro *statp = EX_UNAVAILABLE;
8929e92d3f3fSGregory Neil Shapiro else
8930e92d3f3fSGregory Neil Shapiro *statp = EX_PROTOCOL;
8931e92d3f3fSGregory Neil Shapiro }
8932e92d3f3fSGregory Neil Shapiro
89332fb4f839SGregory Neil Shapiro SM_FREE(replybuf);
8934e92d3f3fSGregory Neil Shapiro return rval;
8935e92d3f3fSGregory Neil Shapiro
8936e92d3f3fSGregory Neil Shapiro errcl:
8937e92d3f3fSGregory Neil Shapiro socket_map_close(map);
8938e92d3f3fSGregory Neil Shapiro error:
89392fb4f839SGregory Neil Shapiro SM_FREE(replybuf);
8940e92d3f3fSGregory Neil Shapiro return rval;
8941e92d3f3fSGregory Neil Shapiro }
8942e92d3f3fSGregory Neil Shapiro #endif /* SOCKETMAP */
8943