2 * Copyright (c) 1998-2001, 2008 Proofpoint, Inc. and its suppliers.
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.
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.
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")
23 SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.98 2013-11-22 20:51:53 ca Exp $")
25 #include <sys/types.h>
30 # undef EX_OK /* unistd.h may have another use for this */
37 #endif /* ! NOT_SENDMAIL */
38 #include <sendmail/sendmail.h>
39 #include <sendmail/pathnames.h>
40 #include <libsmdb/smdb.h>
42 static void praliases __P((char *, int, char **));
51 bool DontInitGroups = false;
53 BITMAP256 DontBlameSendmail;
55 # define DELIMITERS " ,/"
56 # define PATH_SEPARATOR ':'
64 char *filename = NULL;
67 char afilebuf[MAXLINE];
70 static char rnamebuf[MAXNAME];
74 clrbitmap(DontBlameSendmail);
75 RunAsUid = RealUid = getuid();
76 RunAsGid = RealGid = getgid();
77 pw = getpwuid(RealUid);
80 if (strlen(pw->pw_name) > MAXNAME - 1)
81 pw->pw_name[MAXNAME] = 0;
82 sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
85 (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
86 "Unknown UID %d", (int) RealUid);
87 RunAsUserName = RealUserName = rnamebuf;
89 cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
90 while ((ch = getopt(argc, argv, "C:f:")) != -1)
101 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
102 "usage: praliases [-C cffile] [-f aliasfile]"
110 if (filename != NULL)
112 praliases(filename, argc, argv);
116 if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
119 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
120 "praliases: %s: %s\n", cfile,
121 sm_errstring(errno));
125 while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
127 register char *b, *p;
129 b = strchr(buf, '\n');
136 case 'O': /* option -- see if alias file */
137 if (sm_strncasecmp(b, " AliasFile", 10) == 0 &&
138 !(isascii(b[10]) && isalnum(b[10])))
140 /* new form -- find value */
144 while (isascii(*++b) && isspace(*b))
147 else if (*b++ != 'A')
149 /* something else boring */
153 /* this is the A or AliasFile option -- save it */
154 if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >=
157 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
158 "praliases: AliasFile filename too long: %.30s\n",
160 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
165 for (p = b; p != NULL; )
167 while (isascii(*p) && isspace(*p))
173 p = strpbrk(p, DELIMITERS);
175 /* find end of spec */
180 for (; *p != '\0'; p++)
183 ** Don't break into a quoted
189 else if (*p == ',' && !quoted)
193 /* No more alias specs follow */
196 /* chop trailing whitespace */
197 while (isascii(*p) &&
210 /* chop trailing whitespace */
211 while (isascii(*e) &&
218 praliases(b, argc, argv);
225 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
232 praliases(filename, argc, argv)
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;
247 colon = strchr(filename, PATH_SEPARATOR);
251 db_type = SMDB_TYPE_DEFAULT;
260 /* clean off arguments */
263 while (isascii(*db_name) && isspace(*db_name))
268 while (*db_name != '\0' &&
269 !(isascii(*db_name) && isspace(*db_name)))
273 /* Skip non-file based DB types */
274 if (db_type != NULL && *db_type != '\0')
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)
281 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
282 "praliases: Skipping non-file based alias type %s\n",
288 if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
292 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
293 "praliases: illegal alias specification: %s\n", filename);
297 memset(¶ms, '\0', sizeof params);
298 params.smdbp_cache_size = 1024 * 1024;
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);
305 result = smdb_open_database(&database, db_name, O_RDONLY, 0,
306 SFF_ROOTOK, db_type, &user_info, ¶ms);
307 if (result != SMDBE_OK)
309 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
310 "praliases: %s: open: %s\n",
311 db_name, sm_errstring(result));
317 memset(&db_key, '\0', sizeof db_key);
318 memset(&db_value, '\0', sizeof db_value);
320 result = database->smdb_cursor(database, &cursor, 0);
321 if (result != SMDBE_OK)
323 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
324 "praliases: %s: set cursor: %s\n", db_name,
325 sm_errstring(result));
329 while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
330 SMDB_CURSOR_GET_NEXT)) ==
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')
344 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
347 (char *) db_key.data,
349 (char *) db_value.data);
352 if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
354 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
355 "praliases: %s: get value at cursor: %s\n",
356 db_name, sm_errstring(result));
360 else for (; *argv != NULL; ++argv)
364 memset(&db_key, '\0', sizeof db_key);
365 memset(&db_value, '\0', sizeof db_value);
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)
372 get_res = database->smdb_get(database, &db_key,
375 if (get_res == SMDBE_OK)
377 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
380 (char *) db_key.data,
382 (char *) db_value.data);
385 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
387 (char *)db_key.data);
392 (void) cursor->smdbc_close(cursor);
393 if (database != NULL)
394 (void) database->smdb_close(database);