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 */
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 !smdb_is_db_type(db_type))
279 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
280 "praliases: Skipping non-file based alias type %s\n",
286 if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
290 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
291 "praliases: illegal alias specification: %s\n", filename);
295 memset(¶ms, '\0', sizeof params);
296 params.smdbp_cache_size = 1024 * 1024;
298 user_info.smdbu_id = RunAsUid;
299 user_info.smdbu_group_id = RunAsGid;
300 (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
301 SMDB_MAX_USER_NAME_LEN);
303 result = smdb_open_database(&database, db_name, O_RDONLY, 0,
304 SFF_ROOTOK, db_type, &user_info, ¶ms);
305 if (result != SMDBE_OK)
307 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
308 "praliases: %s: open: %s\n",
309 db_name, sm_errstring(result));
315 memset(&db_key, '\0', sizeof db_key);
316 memset(&db_value, '\0', sizeof db_value);
318 result = database->smdb_cursor(database, &cursor, 0);
319 if (result != SMDBE_OK)
321 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
322 "praliases: %s: set cursor: %s\n", db_name,
323 sm_errstring(result));
327 while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
328 SMDB_CURSOR_GET_NEXT)) ==
332 /* skip magic @:@ entry */
333 if (db_key.size == 2 &&
334 db_key.data[0] == '@' &&
335 db_key.data[1] == '\0' &&
336 db_value.size == 2 &&
337 db_value.data[0] == '@' &&
338 db_value.data[1] == '\0')
342 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
345 (char *) db_key.data,
347 (char *) db_value.data);
350 if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
352 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
353 "praliases: %s: get value at cursor: %s\n",
354 db_name, sm_errstring(result));
358 else for (; *argv != NULL; ++argv)
362 memset(&db_key, '\0', sizeof db_key);
363 memset(&db_value, '\0', sizeof db_value);
365 db_key.size = strlen(*argv);
366 get_res = database->smdb_get(database, &db_key, &db_value, 0);
367 if (get_res == SMDBE_NOT_FOUND)
370 get_res = database->smdb_get(database, &db_key,
373 if (get_res == SMDBE_OK)
375 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
378 (char *) db_key.data,
380 (char *) db_value.data);
383 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
385 (char *)db_key.data);
390 (void) cursor->smdbc_close(cursor);
391 if (database != NULL)
392 (void) database->smdb_close(database);