Deleted Added
full compact
praliases.c (302408) praliases.c (38032)
1/*
1/*
2 * Copyright (c) 1998-2001, 2008 Proofpoint, Inc. and its suppliers.
3 * All rights reserved.
2 * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
4 * Copyright (c) 1983 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
3 * Copyright (c) 1983 Eric P. Allman. All rights reserved.
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
11 */
12
14#include <sm/gen.h>
13#ifndef lint
14static char copyright[] =
15"@(#) Copyright (c) 1988, 1993\n\
16 The Regents of the University of California. All rights reserved.\n";
17#endif /* not lint */
15
18
16SM_IDSTR(copyright,
17"@(#) Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.\n\
18 All rights reserved.\n\
19 Copyright (c) 1983 Eric P. Allman. All rights reserved.\n\
20 Copyright (c) 1988, 1993\n\
21 The Regents of the University of California. All rights reserved.\n")
19#ifndef lint
20static char sccsid[] = "@(#)praliases.c 8.17 (Berkeley) 6/25/98";
21#endif /* not lint */
22
22
23SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.98 2013-11-22 20:51:53 ca Exp $")
23#if !defined(NDBM) && !defined(NEWDB)
24 ERROR README: You must define one of NDBM or NEWDB in order to compile
25 ERROR README: praliases.
26#endif
24
27
25#include <sys/types.h>
26#include <ctype.h>
27#include <stdlib.h>
28#include <unistd.h>
29#ifdef EX_OK
30# undef EX_OK /* unistd.h may have another use for this */
31#endif /* EX_OK */
32#include <sysexits.h>
33
34
28#ifdef NDBM
29# include <ndbm.h>
30#endif
35#ifndef NOT_SENDMAIL
36# define NOT_SENDMAIL
31#ifndef NOT_SENDMAIL
32# define NOT_SENDMAIL
37#endif /* ! NOT_SENDMAIL */
38#include <sendmail/sendmail.h>
39#include <sendmail/pathnames.h>
40#include <libsmdb/smdb.h>
33#endif
34#include
35#ifdef NEWDB
36# include <db.h>
37# ifndef DB_VERSION_MAJOR
38# define DB_VERSION_MAJOR 1
39# endif
40#endif
41
41
42static void praliases __P((char *, int, char **));
42#if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) || \
43 defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__)
44# ifndef HASSTRERROR
45# define HASSTRERROR 1 /* has strerror(3) */
46# endif
47#endif
43
48
44uid_t RealUid;
45gid_t RealGid;
46char *RealUserName;
47uid_t RunAsUid;
48gid_t RunAsGid;
49char *RunAsUserName;
50int Verbose = 2;
51bool DontInitGroups = false;
52uid_t TrustedUid = 0;
53BITMAP256 DontBlameSendmail;
49#if !HASSTRERROR
50extern char *strerror __P((int));
51#endif
54
52
55# define DELIMITERS " ,/"
56# define PATH_SEPARATOR ':'
57
58int
59main(argc, argv)
60 int argc;
61 char **argv;
62{
53int
54main(argc, argv)
55 int argc;
56 char **argv;
57{
63 char *cfile;
64 char *filename = NULL;
65 SM_FILE_T *cfp;
66 int ch;
67 char afilebuf[MAXLINE];
68 char buf[MAXLINE];
69 struct passwd *pw;
70 static char rnamebuf[MAXNAME];
71 extern char *optarg;
72 extern int optind;
58 extern char *optarg;
59 extern int optind;
60#ifdef NDBM
61 DBM *dbp;
62 datum content, key;
63#endif
64 char *filename;
65 int ch;
66#ifdef NEWDB
67 DB *db;
68 DBT newdbkey, newdbcontent;
69 char buf[MAXNAME];
70#endif
73
71
74 clrbitmap(DontBlameSendmail);
75 RunAsUid = RealUid = getuid();
76 RunAsGid = RealGid = getgid();
77 pw = getpwuid(RealUid);
78 if (pw != NULL)
79 {
80 if (strlen(pw->pw_name) > MAXNAME - 1)
81 pw->pw_name[MAXNAME] = 0;
82 sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
83 }
84 else
85 (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
86 "Unknown UID %d", (int) RealUid);
87 RunAsUserName = RealUserName = rnamebuf;
88
89 cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
90 while ((ch = getopt(argc, argv, "C:f:")) != -1)
91 {
92 switch ((char)ch) {
93 case 'C':
94 cfile = optarg;
95 break;
72 filename = "/etc/aliases";
73 while ((ch = getopt(argc, argv, "f:")) != EOF)
74 switch((char)ch) {
96 case 'f':
97 filename = optarg;
98 break;
99 case '?':
100 default:
75 case 'f':
76 filename = optarg;
77 break;
78 case '?':
79 default:
101 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
102 "usage: praliases [-C cffile] [-f aliasfile]"
103 " [key ...]\n");
80 (void)fprintf(stderr, "usage: praliases [-f file]\n");
104 exit(EX_USAGE);
105 }
81 exit(EX_USAGE);
82 }
106 }
107 argc -= optind;
108 argv += optind;
109
83 argc -= optind;
84 argv += optind;
85
110 if (filename != NULL)
86#ifdef NEWDB
87 if (strlen(filename) + 4 >= sizeof buf)
111 {
88 {
112 praliases(filename, argc, argv);
113 exit(EX_OK);
89 fprintf(stderr, "Alias filename too long: %.30s...\n", filename);
90 exit(EX_USAGE);
114 }
91 }
115
116 if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
117 NULL)) == NULL)
92 (void) strcpy(buf, filename);
93 (void) strcat(buf, ".db");
94# if DB_VERSION_MAJOR < 2
95 db = dbopen(buf, O_RDONLY, 0444, DB_HASH, NULL);
96# else
97 db = NULL;
98 errno = db_open(buf, DB_HASH, DB_RDONLY, 0444, NULL, NULL, &db);
99# endif
100 if (db != NULL)
118 {
101 {
119 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
120 "praliases: %s: %s\n", cfile,
121 sm_errstring(errno));
122 exit(EX_NOINPUT);
123 }
102 if (!argc) {
103# if DB_VERSION_MAJOR > 1
104 DBC *dbc;
105# endif
106 bzero(&newdbkey, sizeof newdbkey);
107 bzero(&newdbcontent, sizeof newdbcontent);
124
108
125 while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
126 {
127 register char *b, *p;
128
129 b = strchr(buf, '\n');
130 if (b != NULL)
131 *b = '\0';
132
133 b = buf;
134 switch (*b++)
135 {
136 case 'O': /* option -- see if alias file */
137 if (sm_strncasecmp(b, " AliasFile", 10) == 0 &&
138 !(isascii(b[10]) && isalnum(b[10])))
109# if DB_VERSION_MAJOR < 2
110 while(!db->seq(db, &newdbkey, &newdbcontent, R_NEXT))
111# else
112 if ((errno = db->cursor(db, NULL, &dbc)) == 0)
139 {
113 {
140 /* new form -- find value */
141 b = strchr(b, '=');
142 if (b == NULL)
143 continue;
144 while (isascii(*++b) && isspace(*b))
145 continue;
114 while ((errno = dbc->c_get(dbc, &newdbkey,
115 &newdbcontent,
116 DB_NEXT)) == 0)
117# endif
118 printf("%.*s:%.*s\n",
119 (int) newdbkey.size,
120 (char *) newdbkey.data,
121 (int) newdbcontent.size,
122 (char *) newdbcontent.data);
123# if DB_VERSION_MAJOR > 1
124 (void) dbc->c_close(dbc);
146 }
125 }
147 else if (*b++ != 'A')
126 else
148 {
127 {
149 /* something else boring */
150 continue;
128 fprintf(stderr,
129 "praliases: %s: Could not set cursor: %s\n",
130 buf, strerror(errno));
131 exit(EX_DATAERR);
151 }
132 }
152
153 /* this is the A or AliasFile option -- save it */
154 if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >=
155 sizeof afilebuf)
156 {
157 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
158 "praliases: AliasFile filename too long: %.30s\n",
159 b);
160 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
161 exit(EX_CONFIG);
162 }
163 b = afilebuf;
164
165 for (p = b; p != NULL; )
166 {
167 while (isascii(*p) && isspace(*p))
168 p++;
169 if (*p == '\0')
170 break;
171 b = p;
172
173 p = strpbrk(p, DELIMITERS);
174
175 /* find end of spec */
176 if (p != NULL)
177 {
178 bool quoted = false;
179
180 for (; *p != '\0'; p++)
181 {
182 /*
183 ** Don't break into a quoted
184 ** string.
185 */
186
187 if (*p == '"')
188 quoted = !quoted;
189 else if (*p == ',' && !quoted)
190 break;
191 }
192
193 /* No more alias specs follow */
194 if (*p == '\0')
195 {
196 /* chop trailing whitespace */
197 while (isascii(*p) &&
198 isspace(*p) &&
199 p > b)
200 p--;
201 *p = '\0';
202 p = NULL;
203 }
204 }
205
206 if (p != NULL)
207 {
208 char *e = p - 1;
209
210 /* chop trailing whitespace */
211 while (isascii(*e) &&
212 isspace(*e) &&
213 e > b)
214 e--;
215 *++e = '\0';
216 *p++ = '\0';
217 }
218 praliases(b, argc, argv);
219 }
220
221 default:
222 continue;
133# endif
223 }
134 }
224 }
225 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
226 exit(EX_OK);
227 /* NOTREACHED */
228 return EX_OK;
229}
230
231static void
232praliases(filename, argc, argv)
233 char *filename;
234 int argc;
235 char **argv;
236{
237 int result;
238 char *colon;
239 char *db_name;
240 char *db_type;
241 SMDB_DATABASE *database = NULL;
242 SMDB_CURSOR *cursor = NULL;
243 SMDB_DBENT db_key, db_value;
244 SMDB_DBPARAMS params;
245 SMDB_USER_INFO user_info;
246
247 colon = strchr(filename, PATH_SEPARATOR);
248 if (colon == NULL)
249 {
250 db_name = filename;
251 db_type = SMDB_TYPE_DEFAULT;
252 }
253 else
254 {
255 *colon = '\0';
256 db_name = colon + 1;
257 db_type = filename;
258 }
259
260 /* clean off arguments */
261 for (;;)
262 {
263 while (isascii(*db_name) && isspace(*db_name))
264 db_name++;
265
266 if (*db_name != '-')
267 break;
268 while (*db_name != '\0' &&
269 !(isascii(*db_name) && isspace(*db_name)))
270 db_name++;
271 }
272
273 /* Skip non-file based DB types */
274 if (db_type != NULL && *db_type != '\0')
275 {
276 if (db_type != SMDB_TYPE_DEFAULT &&
277 strcmp(db_type, "hash") != 0 &&
278 strcmp(db_type, "btree") != 0 &&
279 strcmp(db_type, "dbm") != 0)
280 {
281 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
282 "praliases: Skipping non-file based alias type %s\n",
283 db_type);
284 return;
135 else for (; *argv; ++argv) {
136 bzero(&newdbkey, sizeof newdbkey);
137 bzero(&newdbcontent, sizeof newdbcontent);
138 newdbkey.data = *argv;
139 newdbkey.size = strlen(*argv) + 1;
140# if DB_VERSION_MAJOR < 2
141 if (!db->get(db, &newdbkey, &newdbcontent, 0))
142# else
143 if ((errno = db->get(db, NULL, &newdbkey,
144 &newdbcontent, 0)) == 0)
145# endif
146 printf("%s:%.*s\n", (char *) newdbkey.data,
147 (int) newdbcontent.size,
148 (char *) newdbcontent.data);
149 else
150 printf("%s: No such key\n",
151 (char *) newdbkey.data);
285 }
152 }
153# if DB_VERSION_MAJOR < 2
154 (void)db->close(db);
155# else
156 errno = db->close(db, 0);
157# endif
286 }
158 }
287
288 if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
289 {
290 if (colon != NULL)
291 *colon = ':';
292 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
293 "praliases: illegal alias specification: %s\n", filename);
294 goto fatal;
295 }
296
297 memset(&params, '\0', sizeof params);
298 params.smdbp_cache_size = 1024 * 1024;
299
300 user_info.smdbu_id = RunAsUid;
301 user_info.smdbu_group_id = RunAsGid;
302 (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
303 SMDB_MAX_USER_NAME_LEN);
304
305 result = smdb_open_database(&database, db_name, O_RDONLY, 0,
306 SFF_ROOTOK, db_type, &user_info, &params);
307 if (result != SMDBE_OK)
308 {
309 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
310 "praliases: %s: open: %s\n",
311 db_name, sm_errstring(result));
312 goto fatal;
313 }
314
315 if (argc == 0)
316 {
317 memset(&db_key, '\0', sizeof db_key);
318 memset(&db_value, '\0', sizeof db_value);
319
320 result = database->smdb_cursor(database, &cursor, 0);
321 if (result != SMDBE_OK)
322 {
323 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
324 "praliases: %s: set cursor: %s\n", db_name,
325 sm_errstring(result));
326 goto fatal;
159 else {
160#endif
161#ifdef NDBM
162 if ((dbp = dbm_open(filename, O_RDONLY, 0)) == NULL) {
163 (void)fprintf(stderr,
164 "praliases: %s: %s\n", filename, strerror(errno));
165 exit(EX_OSFILE);
327 }
166 }
328
329 while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
330 SMDB_CURSOR_GET_NEXT)) ==
331 SMDBE_OK)
332 {
333#if 0
334 /* skip magic @:@ entry */
335 if (db_key.size == 2 &&
336 db_key.data[0] == '@' &&
337 db_key.data[1] == '\0' &&
338 db_value.size == 2 &&
339 db_value.data[0] == '@' &&
340 db_value.data[1] == '\0')
341 continue;
342#endif /* 0 */
343
344 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
345 "%.*s:%.*s\n",
346 (int) db_key.size,
347 (char *) db_key.data,
348 (int) db_value.size,
349 (char *) db_value.data);
167 if (!argc)
168 for (key = dbm_firstkey(dbp);
169 key.dptr != NULL; key = dbm_nextkey(dbp)) {
170 content = dbm_fetch(dbp, key);
171 (void)printf("%.*s:%.*s\n",
172 (int) key.dsize, key.dptr,
173 (int) content.dsize, content.dptr);
174 }
175 else for (; *argv; ++argv) {
176 key.dptr = *argv;
177 key.dsize = strlen(*argv) + 1;
178 content = dbm_fetch(dbp, key);
179 if (!content.dptr)
180 (void)printf("%s: No such key\n", key.dptr);
181 else
182 (void)printf("%s:%.*s\n", key.dptr,
183 (int) content.dsize, content.dptr);
350 }
184 }
351
352 if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
353 {
354 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
355 "praliases: %s: get value at cursor: %s\n",
356 db_name, sm_errstring(result));
357 goto fatal;
358 }
185 dbm_close(dbp);
186#endif
187#ifdef NEWDB
359 }
188 }
360 else for (; *argv != NULL; ++argv)
361 {
362 int get_res;
189#endif
190 exit(EX_OK);
191}
363
192
364 memset(&db_key, '\0', sizeof db_key);
365 memset(&db_value, '\0', sizeof db_value);
366 db_key.data = *argv;
367 db_key.size = strlen(*argv);
368 get_res = database->smdb_get(database, &db_key, &db_value, 0);
369 if (get_res == SMDBE_NOT_FOUND)
370 {
371 db_key.size++;
372 get_res = database->smdb_get(database, &db_key,
373 &db_value, 0);
374 }
375 if (get_res == SMDBE_OK)
376 {
377 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
378 "%.*s:%.*s\n",
379 (int) db_key.size,
380 (char *) db_key.data,
381 (int) db_value.size,
382 (char *) db_value.data);
383 }
384 else
385 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
386 "%s: No such key\n",
387 (char *)db_key.data);
388 }
193#if !HASSTRERROR
389
194
390 fatal:
391 if (cursor != NULL)
392 (void) cursor->smdbc_close(cursor);
393 if (database != NULL)
394 (void) database->smdb_close(database);
395 if (colon != NULL)
396 *colon = ':';
397 return;
195char *
196strerror(eno)
197 int eno;
198{
199 extern int sys_nerr;
200 extern char *sys_errlist[];
201 static char ebuf[60];
202
203 if (eno >= 0 && eno < sys_nerr)
204 return sys_errlist[eno];
205 (void) sprintf(ebuf, "Error %d", eno);
206 return ebuf;
398}
207}
208
209#endif /* !HASSTRERROR */