7 /* dictionary manager interface to NIS maps
9 /* #include <dict_nis.h>
11 /* DICT *dict_nis_open(map, open_flags, dict_flags)
16 /* dict_nis_open() makes the specified NIS map accessible via
17 /* the generic dictionary operations described in dict_open(3).
19 /* dict(3) generic dictionary manager
21 /* Fatal errors: out of memory, attempt to update NIS map.
25 /* The Secure Mailer license must be distributed with this software.
28 /* IBM T.J. Watson Research
30 /* Yorktown Heights, NY 10598, USA
38 #ifdef STRCASECMP_IN_STRINGS_H
44 #include <rpcsvc/ypclnt.h>
49 #define YPERR_ACCESS 15
54 /* Utility library. */
59 #include "stringops.h"
65 /* Application-specific. */
68 DICT dict
; /* generic members */
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
);
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.
103 return ("args to function are bad");
105 return ("RPC failure - domain has been unbound");
107 return ("can't bind to server on this domain");
109 return ("no such map in server's domain");
111 return ("no such key in map");
113 return ("internal yp server or client error");
115 return ("resource allocation failure");
117 return ("no more records in map database");
119 return ("can't communicate with portmapper");
121 return ("can't communicate with ypbind");
123 return ("can't communicate with ypserv");
125 return ("local domain name not set");
127 return ("yp database is bad");
129 return ("yp version mismatch");
131 return ("access violation");
133 return ("database busy");
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
;
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");
156 if (dict_nis_domain
== dict_nis_disabled
)
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
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
);
178 dict
->flags
&= ~DICT_FLAG_TRY0NULL
;
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
);
192 dict
->flags
&= ~DICT_FLAG_TRY1NULL
;
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
;
214 /* dict_nis_close - close NIS map */
216 static void dict_nis_close(DICT
*dict
)
219 vstring_free(dict
->fold_buf
);
223 /* dict_nis_open - open NIS map */
225 DICT
*dict_nis_open(const char *map
, int open_flags
, int dict_flags
)
229 if (open_flags
!= O_RDONLY
)
230 msg_fatal("%s:%s map requires O_RDONLY access mode",
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)
243 return (DICT_DEBUG (&dict_nis
->dict
));