Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / dict_unix.c
blob067c0cc844f9547700d47fa949ea38d998db0e64
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* dict_unix 3
6 /* SUMMARY
7 /* dictionary manager interface to UNIX tables
8 /* SYNOPSIS
9 /* #include <dict_unix.h>
11 /* DICT *dict_unix_open(map, dummy, dict_flags)
12 /* const char *map;
13 /* int dummy;
14 /* int dict_flags;
15 /* DESCRIPTION
16 /* dict_unix_open() makes the specified UNIX table accessible via
17 /* the generic dictionary operations described in dict_open(3).
18 /* The \fIdummy\fR argument is not used.
20 /* Known map names:
21 /* .IP passwd.byname
22 /* The table is the UNIX password database. The key is a login name.
23 /* The result is a password file entry in passwd(5) format.
24 /* .IP group.byname
25 /* The table is the UNIX group database. The key is a group name.
26 /* The result is a group file entry in group(5) format.
27 /* SEE ALSO
28 /* dict(3) generic dictionary manager
29 /* DIAGNOSTICS
30 /* Fatal errors: out of memory, unknown map name, attempt to update map.
31 /* LICENSE
32 /* .ad
33 /* .fi
34 /* The Secure Mailer license must be distributed with this software.
35 /* AUTHOR(S)
36 /* Wietse Venema
37 /* IBM T.J. Watson Research
38 /* P.O. Box 704
39 /* Yorktown Heights, NY 10598, USA
40 /*--*/
42 /* System library. */
44 #include "sys_defs.h"
45 #include <unistd.h>
46 #include <errno.h>
47 #include <string.h>
48 #include <pwd.h>
49 #include <grp.h>
51 /* Utility library. */
53 #include "msg.h"
54 #include "mymalloc.h"
55 #include "vstring.h"
56 #include "stringops.h"
57 #include "dict.h"
58 #include "dict_unix.h"
60 /* Application-specific. */
62 typedef struct {
63 DICT dict; /* generic members */
64 } DICT_UNIX;
66 /* dict_unix_getpwnam - find password table entry */
68 static const char *dict_unix_getpwnam(DICT *dict, const char *key)
70 struct passwd *pwd;
71 static VSTRING *buf;
72 static int sanity_checked;
74 dict_errno = 0;
77 * Optionally fold the key.
79 if (dict->flags & DICT_FLAG_FOLD_FIX) {
80 if (dict->fold_buf == 0)
81 dict->fold_buf = vstring_alloc(10);
82 vstring_strcpy(dict->fold_buf, key);
83 key = lowercase(vstring_str(dict->fold_buf));
85 if ((pwd = getpwnam(key)) == 0) {
86 if (sanity_checked == 0) {
87 sanity_checked = 1;
88 errno = 0;
89 if (getpwuid(0) == 0) {
90 msg_warn("cannot access UNIX password database: %m");
91 dict_errno = DICT_ERR_RETRY;
94 return (0);
95 } else {
96 if (buf == 0)
97 buf = vstring_alloc(10);
98 sanity_checked = 1;
99 vstring_sprintf(buf, "%s:%s:%ld:%ld:%s:%s:%s",
100 pwd->pw_name, pwd->pw_passwd, (long) pwd->pw_uid,
101 (long) pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir,
102 pwd->pw_shell);
103 return (vstring_str(buf));
107 /* dict_unix_getgrnam - find group table entry */
109 static const char *dict_unix_getgrnam(DICT *dict, const char *key)
111 struct group *grp;
112 static VSTRING *buf;
113 char **cpp;
114 static int sanity_checked;
116 dict_errno = 0;
119 * Optionally fold the key.
121 if (dict->flags & DICT_FLAG_FOLD_FIX) {
122 if (dict->fold_buf == 0)
123 dict->fold_buf = vstring_alloc(10);
124 vstring_strcpy(dict->fold_buf, key);
125 key = lowercase(vstring_str(dict->fold_buf));
127 if ((grp = getgrnam(key)) == 0) {
128 if (sanity_checked == 0) {
129 sanity_checked = 1;
130 errno = 0;
131 if (getgrgid(0) == 0) {
132 msg_warn("cannot access UNIX group database: %m");
133 dict_errno = DICT_ERR_RETRY;
136 return (0);
137 } else {
138 if (buf == 0)
139 buf = vstring_alloc(10);
140 sanity_checked = 1;
141 vstring_sprintf(buf, "%s:%s:%ld:",
142 grp->gr_name, grp->gr_passwd, (long) grp->gr_gid);
143 for (cpp = grp->gr_mem; *cpp; cpp++) {
144 vstring_strcat(buf, *cpp);
145 if (cpp[1])
146 VSTRING_ADDCH(buf, ',');
148 VSTRING_TERMINATE(buf);
149 return (vstring_str(buf));
153 /* dict_unix_close - close UNIX map */
155 static void dict_unix_close(DICT *dict)
157 if (dict->fold_buf)
158 vstring_free(dict->fold_buf);
159 dict_free(dict);
162 /* dict_unix_open - open UNIX map */
164 DICT *dict_unix_open(const char *map, int unused_flags, int dict_flags)
166 DICT_UNIX *dict_unix;
167 struct dict_unix_lookup {
168 char *name;
169 const char *(*lookup) (DICT *, const char *);
171 static struct dict_unix_lookup dict_unix_lookup[] = {
172 "passwd.byname", dict_unix_getpwnam,
173 "group.byname", dict_unix_getgrnam,
176 struct dict_unix_lookup *lp;
178 dict_errno = 0;
180 dict_unix = (DICT_UNIX *) dict_alloc(DICT_TYPE_UNIX, map,
181 sizeof(*dict_unix));
182 for (lp = dict_unix_lookup; /* void */ ; lp++) {
183 if (lp->name == 0)
184 msg_fatal("dict_unix_open: unknown map name: %s", map);
185 if (strcmp(map, lp->name) == 0)
186 break;
188 dict_unix->dict.lookup = lp->lookup;
189 dict_unix->dict.close = dict_unix_close;
190 dict_unix->dict.flags = dict_flags | DICT_FLAG_FIXED;
191 if (dict_flags & DICT_FLAG_FOLD_FIX)
192 dict_unix->dict.fold_buf = vstring_alloc(10);
194 return (DICT_DEBUG (&dict_unix->dict));