7 /* dictionary manager interface to UNIX tables
9 /* #include <dict_unix.h>
11 /* DICT *dict_unix_open(map, dummy, dict_flags)
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.
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.
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.
28 /* dict(3) generic dictionary manager
30 /* Fatal errors: out of memory, unknown map name, attempt to update map.
34 /* The Secure Mailer license must be distributed with this software.
37 /* IBM T.J. Watson Research
39 /* Yorktown Heights, NY 10598, USA
51 /* Utility library. */
56 #include "stringops.h"
58 #include "dict_unix.h"
60 /* Application-specific. */
63 DICT dict
; /* generic members */
66 /* dict_unix_getpwnam - find password table entry */
68 static const char *dict_unix_getpwnam(DICT
*dict
, const char *key
)
72 static int sanity_checked
;
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) {
89 if (getpwuid(0) == 0) {
90 msg_warn("cannot access UNIX password database: %m");
91 dict_errno
= DICT_ERR_RETRY
;
97 buf
= vstring_alloc(10);
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
,
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
)
114 static int sanity_checked
;
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) {
131 if (getgrgid(0) == 0) {
132 msg_warn("cannot access UNIX group database: %m");
133 dict_errno
= DICT_ERR_RETRY
;
139 buf
= vstring_alloc(10);
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
);
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
)
158 vstring_free(dict
->fold_buf
);
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
{
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
;
180 dict_unix
= (DICT_UNIX
*) dict_alloc(DICT_TYPE_UNIX
, map
,
182 for (lp
= dict_unix_lookup
; /* void */ ; lp
++) {
184 msg_fatal("dict_unix_open: unknown map name: %s", map
);
185 if (strcmp(map
, lp
->name
) == 0)
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
));