No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / dict_nis.c
blob095e48f6b88a198afee53dfbcddd95183624cf27
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* dict_nis 3
6 /* SUMMARY
7 /* dictionary manager interface to NIS maps
8 /* SYNOPSIS
9 /* #include <dict_nis.h>
11 /* DICT *dict_nis_open(map, open_flags, dict_flags)
12 /* const char *map;
13 /* int open_flags;
14 /* int dict_flags;
15 /* DESCRIPTION
16 /* dict_nis_open() makes the specified NIS map accessible via
17 /* the generic dictionary operations described in dict_open(3).
18 /* SEE ALSO
19 /* dict(3) generic dictionary manager
20 /* DIAGNOSTICS
21 /* Fatal errors: out of memory, attempt to update NIS map.
22 /* LICENSE
23 /* .ad
24 /* .fi
25 /* The Secure Mailer license must be distributed with this software.
26 /* AUTHOR(S)
27 /* Wietse Venema
28 /* IBM T.J. Watson Research
29 /* P.O. Box 704
30 /* Yorktown Heights, NY 10598, USA
31 /*--*/
33 /* System library. */
35 #include "sys_defs.h"
36 #include <string.h>
38 #ifdef STRCASECMP_IN_STRINGS_H
39 #include <strings.h>
40 #endif
42 #ifdef HAS_NIS
44 #include <rpcsvc/ypclnt.h>
45 #ifndef YPERR_BUSY
46 #define YPERR_BUSY 16
47 #endif
48 #ifndef YPERR_ACCESS
49 #define YPERR_ACCESS 15
50 #endif
52 #endif
54 /* Utility library. */
56 #include "msg.h"
57 #include "mymalloc.h"
58 #include "vstring.h"
59 #include "stringops.h"
60 #include "dict.h"
61 #include "dict_nis.h"
63 #ifdef HAS_NIS
65 /* Application-specific. */
67 typedef struct {
68 DICT dict; /* generic members */
69 } DICT_NIS;
72 * Class variables, so that multiple maps can share this info.
74 static char dict_nis_disabled[1];
75 static char *dict_nis_domain;
77 /* dict_nis_init - NIS binding */
79 static void dict_nis_init(void)
81 const char *myname = "dict_nis_init";
83 if (yp_get_default_domain(&dict_nis_domain) != 0
84 || dict_nis_domain == 0 || *dict_nis_domain == 0
85 || strcasecmp(dict_nis_domain, "(none)") == 0) {
86 dict_nis_domain = dict_nis_disabled;
87 msg_warn("%s: NIS domain name not set - NIS lookups disabled", myname);
89 if (msg_verbose)
90 msg_info("%s: NIS domain %s", myname, dict_nis_domain);
93 /* dict_nis_strerror - map error number to string */
95 static char *dict_nis_strerror(int err)
99 * Grr. There should be a standard function for this.
101 switch (err) {
102 case YPERR_BADARGS:
103 return ("args to function are bad");
104 case YPERR_RPC:
105 return ("RPC failure - domain has been unbound");
106 case YPERR_DOMAIN:
107 return ("can't bind to server on this domain");
108 case YPERR_MAP:
109 return ("no such map in server's domain");
110 case YPERR_KEY:
111 return ("no such key in map");
112 case YPERR_YPERR:
113 return ("internal yp server or client error");
114 case YPERR_RESRC:
115 return ("resource allocation failure");
116 case YPERR_NOMORE:
117 return ("no more records in map database");
118 case YPERR_PMAP:
119 return ("can't communicate with portmapper");
120 case YPERR_YPBIND:
121 return ("can't communicate with ypbind");
122 case YPERR_YPSERV:
123 return ("can't communicate with ypserv");
124 case YPERR_NODOM:
125 return ("local domain name not set");
126 case YPERR_BADDB:
127 return ("yp database is bad");
128 case YPERR_VERS:
129 return ("yp version mismatch");
130 case YPERR_ACCESS:
131 return ("access violation");
132 case YPERR_BUSY:
133 return ("database busy");
134 default:
135 return ("unknown NIS lookup error");
139 /* dict_nis_lookup - find table entry */
141 static const char *dict_nis_lookup(DICT *dict, const char *key)
143 DICT_NIS *dict_nis = (DICT_NIS *) dict;
144 static char *result;
145 int result_len;
146 int err;
147 static VSTRING *buf;
150 * Sanity check.
152 if ((dict->flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
153 msg_panic("dict_nis_lookup: no DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL flag");
155 dict_errno = 0;
156 if (dict_nis_domain == dict_nis_disabled)
157 return (0);
160 * Optionally fold the key.
162 if (dict->flags & DICT_FLAG_FOLD_FIX) {
163 if (dict->fold_buf == 0)
164 dict->fold_buf = vstring_alloc(10);
165 vstring_strcpy(dict->fold_buf, key);
166 key = lowercase(vstring_str(dict->fold_buf));
170 * See if this NIS map was written with one null byte appended to key and
171 * value.
173 if (dict->flags & DICT_FLAG_TRY1NULL) {
174 err = yp_match(dict_nis_domain, dict_nis->dict.name,
175 (void *) key, strlen(key) + 1,
176 &result, &result_len);
177 if (err == 0) {
178 dict->flags &= ~DICT_FLAG_TRY0NULL;
179 return (result);
184 * See if this NIS map was written with no null byte appended to key and
185 * value. This should never be the case, but better play safe.
187 if (dict->flags & DICT_FLAG_TRY0NULL) {
188 err = yp_match(dict_nis_domain, dict_nis->dict.name,
189 (void *) key, strlen(key),
190 &result, &result_len);
191 if (err == 0) {
192 dict->flags &= ~DICT_FLAG_TRY1NULL;
193 if (buf == 0)
194 buf = vstring_alloc(10);
195 vstring_strncpy(buf, result, result_len);
196 return (vstring_str(buf));
201 * When the NIS lookup fails for reasons other than "key not found", keep
202 * logging warnings, and hope that someone will eventually notice the
203 * problem and fix it.
205 if (err != YPERR_KEY) {
206 msg_warn("lookup %s, NIS domain %s, map %s: %s",
207 key, dict_nis_domain, dict_nis->dict.name,
208 dict_nis_strerror(err));
209 dict_errno = DICT_ERR_RETRY;
211 return (0);
214 /* dict_nis_close - close NIS map */
216 static void dict_nis_close(DICT *dict)
218 if (dict->fold_buf)
219 vstring_free(dict->fold_buf);
220 dict_free(dict);
223 /* dict_nis_open - open NIS map */
225 DICT *dict_nis_open(const char *map, int open_flags, int dict_flags)
227 DICT_NIS *dict_nis;
229 if (open_flags != O_RDONLY)
230 msg_fatal("%s:%s map requires O_RDONLY access mode",
231 DICT_TYPE_NIS, map);
233 dict_nis = (DICT_NIS *) dict_alloc(DICT_TYPE_NIS, map, sizeof(*dict_nis));
234 dict_nis->dict.lookup = dict_nis_lookup;
235 dict_nis->dict.close = dict_nis_close;
236 dict_nis->dict.flags = dict_flags | DICT_FLAG_FIXED;
237 if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
238 dict_nis->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
239 if (dict_flags & DICT_FLAG_FOLD_FIX)
240 dict_nis->dict.fold_buf = vstring_alloc(10);
241 if (dict_nis_domain == 0)
242 dict_nis_init();
243 return (DICT_DEBUG (&dict_nis->dict));
246 #endif