138032Speter/* 2261363Sgshapiro * Copyright (c) 1998-2001, 2008 Proofpoint, Inc. and its suppliers. 364565Sgshapiro * All rights reserved. 438032Speter * Copyright (c) 1983 Eric P. Allman. All rights reserved. 538032Speter * Copyright (c) 1988, 1993 638032Speter * The Regents of the University of California. All rights reserved. 738032Speter * 838032Speter * By using this file, you agree to the terms and conditions set 938032Speter * forth in the LICENSE file which can be found at the top level of 1038032Speter * the sendmail distribution. 1138032Speter * 1238032Speter */ 1338032Speter 1490795Sgshapiro#include <sm/gen.h> 1590795Sgshapiro 1690795SgshapiroSM_IDSTR(copyright, 17261363Sgshapiro"@(#) Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.\n\ 1864565Sgshapiro All rights reserved.\n\ 1964565Sgshapiro Copyright (c) 1983 Eric P. Allman. All rights reserved.\n\ 2064565Sgshapiro Copyright (c) 1988, 1993\n\ 2190795Sgshapiro The Regents of the University of California. All rights reserved.\n") 2238032Speter 23266692SgshapiroSM_IDSTR(id, "@(#)$Id: praliases.c,v 8.98 2013-11-22 20:51:53 ca Exp $") 2438032Speter 2564565Sgshapiro#include <sys/types.h> 2664565Sgshapiro#include <ctype.h> 2764565Sgshapiro#include <stdlib.h> 2864565Sgshapiro#include <unistd.h> 2964565Sgshapiro#ifdef EX_OK 3064565Sgshapiro# undef EX_OK /* unistd.h may have another use for this */ 3164565Sgshapiro#endif /* EX_OK */ 3264565Sgshapiro#include <sysexits.h> 3364565Sgshapiro 3464565Sgshapiro 3538032Speter#ifndef NOT_SENDMAIL 3638032Speter# define NOT_SENDMAIL 3764565Sgshapiro#endif /* ! NOT_SENDMAIL */ 3864565Sgshapiro#include <sendmail/sendmail.h> 3964565Sgshapiro#include <sendmail/pathnames.h> 4064565Sgshapiro#include <libsmdb/smdb.h> 4138032Speter 4264565Sgshapirostatic void praliases __P((char *, int, char **)); 4338032Speter 4464565Sgshapirouid_t RealUid; 4564565Sgshapirogid_t RealGid; 4664565Sgshapirochar *RealUserName; 4764565Sgshapirouid_t RunAsUid; 48173343Sgshapirogid_t RunAsGid; 4964565Sgshapirochar *RunAsUserName; 5064565Sgshapiroint Verbose = 2; 5190795Sgshapirobool DontInitGroups = false; 5264565Sgshapirouid_t TrustedUid = 0; 5364565SgshapiroBITMAP256 DontBlameSendmail; 5438032Speter 5571348Sgshapiro# define DELIMITERS " ,/" 5671348Sgshapiro# define PATH_SEPARATOR ':' 5764565Sgshapiro 5838032Speterint 5938032Spetermain(argc, argv) 6038032Speter int argc; 6138032Speter char **argv; 6238032Speter{ 6342580Speter char *cfile; 6442580Speter char *filename = NULL; 6590795Sgshapiro SM_FILE_T *cfp; 6638032Speter int ch; 6742580Speter char afilebuf[MAXLINE]; 6842580Speter char buf[MAXLINE]; 6964565Sgshapiro struct passwd *pw; 7064565Sgshapiro static char rnamebuf[MAXNAME]; 7164565Sgshapiro extern char *optarg; 7264565Sgshapiro extern int optind; 7338032Speter 7464565Sgshapiro clrbitmap(DontBlameSendmail); 7564565Sgshapiro RunAsUid = RealUid = getuid(); 7664565Sgshapiro RunAsGid = RealGid = getgid(); 7764565Sgshapiro pw = getpwuid(RealUid); 7864565Sgshapiro if (pw != NULL) 7964565Sgshapiro { 8064565Sgshapiro if (strlen(pw->pw_name) > MAXNAME - 1) 8164565Sgshapiro pw->pw_name[MAXNAME] = 0; 8290795Sgshapiro sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name); 8364565Sgshapiro } 8464565Sgshapiro else 8590795Sgshapiro (void) sm_snprintf(rnamebuf, sizeof rnamebuf, 8690795Sgshapiro "Unknown UID %d", (int) RealUid); 8764565Sgshapiro RunAsUserName = RealUserName = rnamebuf; 8864565Sgshapiro 8990795Sgshapiro cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); 9042580Speter while ((ch = getopt(argc, argv, "C:f:")) != -1) 9142580Speter { 9242580Speter switch ((char)ch) { 9342580Speter case 'C': 9442580Speter cfile = optarg; 9542580Speter break; 9638032Speter case 'f': 9738032Speter filename = optarg; 9838032Speter break; 9938032Speter case '?': 10038032Speter default: 10190795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 102203004Sgshapiro "usage: praliases [-C cffile] [-f aliasfile]" 103203004Sgshapiro " [key ...]\n"); 10438032Speter exit(EX_USAGE); 10538032Speter } 10642580Speter } 10738032Speter argc -= optind; 10838032Speter argv += optind; 10938032Speter 11042580Speter if (filename != NULL) 11142580Speter { 11242580Speter praliases(filename, argc, argv); 11342580Speter exit(EX_OK); 11442580Speter } 11542580Speter 11690795Sgshapiro if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, 11790795Sgshapiro NULL)) == NULL) 11842580Speter { 11990795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 12090795Sgshapiro "praliases: %s: %s\n", cfile, 12190795Sgshapiro sm_errstring(errno)); 12242580Speter exit(EX_NOINPUT); 12342580Speter } 12442580Speter 125249729Sgshapiro while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) 12642580Speter { 12742580Speter register char *b, *p; 12842580Speter 12964565Sgshapiro b = strchr(buf, '\n'); 13064565Sgshapiro if (b != NULL) 13164565Sgshapiro *b = '\0'; 13264565Sgshapiro 13342580Speter b = buf; 13442580Speter switch (*b++) 13542580Speter { 13642580Speter case 'O': /* option -- see if alias file */ 13790795Sgshapiro if (sm_strncasecmp(b, " AliasFile", 10) == 0 && 13842580Speter !(isascii(b[10]) && isalnum(b[10]))) 13942580Speter { 14042580Speter /* new form -- find value */ 14142580Speter b = strchr(b, '='); 14242580Speter if (b == NULL) 14342580Speter continue; 14442580Speter while (isascii(*++b) && isspace(*b)) 14542580Speter continue; 14642580Speter } 14742580Speter else if (*b++ != 'A') 14842580Speter { 14942580Speter /* something else boring */ 15042580Speter continue; 15142580Speter } 15242580Speter 15342580Speter /* this is the A or AliasFile option -- save it */ 15490795Sgshapiro if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >= 15564565Sgshapiro sizeof afilebuf) 15642580Speter { 15790795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 15890795Sgshapiro "praliases: AliasFile filename too long: %.30s\n", 15942580Speter b); 16090795Sgshapiro (void) sm_io_close(cfp, SM_TIME_DEFAULT); 16142580Speter exit(EX_CONFIG); 16242580Speter } 16342580Speter b = afilebuf; 16442580Speter 16542580Speter for (p = b; p != NULL; ) 16642580Speter { 16742580Speter while (isascii(*p) && isspace(*p)) 16842580Speter p++; 16942580Speter if (*p == '\0') 17042580Speter break; 17142580Speter b = p; 17242580Speter 17371348Sgshapiro p = strpbrk(p, DELIMITERS); 17464565Sgshapiro 17542580Speter /* find end of spec */ 17642580Speter if (p != NULL) 17764565Sgshapiro { 17890795Sgshapiro bool quoted = false; 17964565Sgshapiro 18064565Sgshapiro for (; *p != '\0'; p++) 18164565Sgshapiro { 18264565Sgshapiro /* 18364565Sgshapiro ** Don't break into a quoted 18464565Sgshapiro ** string. 18564565Sgshapiro */ 18664565Sgshapiro 18764565Sgshapiro if (*p == '"') 18864565Sgshapiro quoted = !quoted; 18964565Sgshapiro else if (*p == ',' && !quoted) 19064565Sgshapiro break; 19164565Sgshapiro } 19264565Sgshapiro 19364565Sgshapiro /* No more alias specs follow */ 19464565Sgshapiro if (*p == '\0') 19564565Sgshapiro { 19664565Sgshapiro /* chop trailing whitespace */ 19764565Sgshapiro while (isascii(*p) && 19864565Sgshapiro isspace(*p) && 19964565Sgshapiro p > b) 20064565Sgshapiro p--; 20164565Sgshapiro *p = '\0'; 20264565Sgshapiro p = NULL; 20364565Sgshapiro } 20464565Sgshapiro } 20564565Sgshapiro 20642580Speter if (p != NULL) 20764565Sgshapiro { 20864565Sgshapiro char *e = p - 1; 20964565Sgshapiro 21064565Sgshapiro /* chop trailing whitespace */ 21164565Sgshapiro while (isascii(*e) && 21264565Sgshapiro isspace(*e) && 21364565Sgshapiro e > b) 21464565Sgshapiro e--; 21564565Sgshapiro *++e = '\0'; 21642580Speter *p++ = '\0'; 21764565Sgshapiro } 21842580Speter praliases(b, argc, argv); 21942580Speter } 22042580Speter 22142580Speter default: 22242580Speter continue; 22342580Speter } 22442580Speter } 22590795Sgshapiro (void) sm_io_close(cfp, SM_TIME_DEFAULT); 22642580Speter exit(EX_OK); 22764565Sgshapiro /* NOTREACHED */ 22864565Sgshapiro return EX_OK; 22942580Speter} 23042580Speter 23142580Speterstatic void 23242580Speterpraliases(filename, argc, argv) 23342580Speter char *filename; 23464565Sgshapiro int argc; 23542580Speter char **argv; 23642580Speter{ 23764565Sgshapiro int result; 23864565Sgshapiro char *colon; 23964565Sgshapiro char *db_name; 24064565Sgshapiro char *db_type; 24164565Sgshapiro SMDB_DATABASE *database = NULL; 24264565Sgshapiro SMDB_CURSOR *cursor = NULL; 24364565Sgshapiro SMDB_DBENT db_key, db_value; 24464565Sgshapiro SMDB_DBPARAMS params; 24564565Sgshapiro SMDB_USER_INFO user_info; 24642580Speter 24771348Sgshapiro colon = strchr(filename, PATH_SEPARATOR); 24864565Sgshapiro if (colon == NULL) 24942580Speter { 25064565Sgshapiro db_name = filename; 25164565Sgshapiro db_type = SMDB_TYPE_DEFAULT; 25242580Speter } 25364565Sgshapiro else 25438032Speter { 25564565Sgshapiro *colon = '\0'; 25664565Sgshapiro db_name = colon + 1; 25764565Sgshapiro db_type = filename; 25838032Speter } 25964565Sgshapiro 26064565Sgshapiro /* clean off arguments */ 26164565Sgshapiro for (;;) 26238032Speter { 26364565Sgshapiro while (isascii(*db_name) && isspace(*db_name)) 26464565Sgshapiro db_name++; 26571348Sgshapiro 26664565Sgshapiro if (*db_name != '-') 26764565Sgshapiro break; 26864565Sgshapiro while (*db_name != '\0' && 26964565Sgshapiro !(isascii(*db_name) && isspace(*db_name))) 27064565Sgshapiro db_name++; 27164565Sgshapiro } 27238032Speter 27373191Sgshapiro /* Skip non-file based DB types */ 27473191Sgshapiro if (db_type != NULL && *db_type != '\0') 27573191Sgshapiro { 27673191Sgshapiro if (db_type != SMDB_TYPE_DEFAULT && 27773191Sgshapiro strcmp(db_type, "hash") != 0 && 27873191Sgshapiro strcmp(db_type, "btree") != 0 && 27973191Sgshapiro strcmp(db_type, "dbm") != 0) 28073191Sgshapiro { 28190795Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 28290795Sgshapiro "praliases: Skipping non-file based alias type %s\n", 28373191Sgshapiro db_type); 28473191Sgshapiro return; 28573191Sgshapiro } 28673191Sgshapiro } 28773191Sgshapiro 28864565Sgshapiro if (*db_name == '\0' || (db_type != NULL && *db_type == '\0')) 28942580Speter { 29064565Sgshapiro if (colon != NULL) 29164565Sgshapiro *colon = ':'; 29290795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 29390795Sgshapiro "praliases: illegal alias specification: %s\n", filename); 29464565Sgshapiro goto fatal; 29542580Speter } 29642580Speter 29764565Sgshapiro memset(¶ms, '\0', sizeof params); 29864565Sgshapiro params.smdbp_cache_size = 1024 * 1024; 29942580Speter 30064565Sgshapiro user_info.smdbu_id = RunAsUid; 30164565Sgshapiro user_info.smdbu_group_id = RunAsGid; 30290795Sgshapiro (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, 30390795Sgshapiro SMDB_MAX_USER_NAME_LEN); 30464565Sgshapiro 30564565Sgshapiro result = smdb_open_database(&database, db_name, O_RDONLY, 0, 30664565Sgshapiro SFF_ROOTOK, db_type, &user_info, ¶ms); 30764565Sgshapiro if (result != SMDBE_OK) 30842580Speter { 30990795Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 31090795Sgshapiro "praliases: %s: open: %s\n", 31190795Sgshapiro db_name, sm_errstring(result)); 31264565Sgshapiro goto fatal; 31342580Speter } 31464565Sgshapiro 31564565Sgshapiro if (argc == 0) 31642580Speter { 31764565Sgshapiro memset(&db_key, '\0', sizeof db_key); 31864565Sgshapiro memset(&db_value, '\0', sizeof db_value); 31964565Sgshapiro 32064565Sgshapiro result = database->smdb_cursor(database, &cursor, 0); 32164565Sgshapiro if (result != SMDBE_OK) 32242580Speter { 32390795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 32490795Sgshapiro "praliases: %s: set cursor: %s\n", db_name, 32590795Sgshapiro sm_errstring(result)); 32664565Sgshapiro goto fatal; 32738032Speter } 32864565Sgshapiro 32964565Sgshapiro while ((result = cursor->smdbc_get(cursor, &db_key, &db_value, 33064565Sgshapiro SMDB_CURSOR_GET_NEXT)) == 33164565Sgshapiro SMDBE_OK) 33264565Sgshapiro { 33364565Sgshapiro#if 0 33464565Sgshapiro /* skip magic @:@ entry */ 33571348Sgshapiro if (db_key.size == 2 && 33671348Sgshapiro db_key.data[0] == '@' && 33771348Sgshapiro db_key.data[1] == '\0' && 33871348Sgshapiro db_value.size == 2 && 33971348Sgshapiro db_value.data[0] == '@' && 34071348Sgshapiro db_value.data[1] == '\0') 34164565Sgshapiro continue; 34264565Sgshapiro#endif /* 0 */ 34364565Sgshapiro 34490795Sgshapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 34590795Sgshapiro "%.*s:%.*s\n", 34690795Sgshapiro (int) db_key.size, 34790795Sgshapiro (char *) db_key.data, 34890795Sgshapiro (int) db_value.size, 34990795Sgshapiro (char *) db_value.data); 35064565Sgshapiro } 35164565Sgshapiro 35264565Sgshapiro if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY) 35364565Sgshapiro { 35490795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 35564565Sgshapiro "praliases: %s: get value at cursor: %s\n", 35690795Sgshapiro db_name, sm_errstring(result)); 35764565Sgshapiro goto fatal; 35864565Sgshapiro } 35942580Speter } 36064565Sgshapiro else for (; *argv != NULL; ++argv) 36142580Speter { 36277352Sgshapiro int get_res; 36377352Sgshapiro 36464565Sgshapiro memset(&db_key, '\0', sizeof db_key); 36564565Sgshapiro memset(&db_value, '\0', sizeof db_value); 36671348Sgshapiro db_key.data = *argv; 36777352Sgshapiro db_key.size = strlen(*argv); 36877352Sgshapiro get_res = database->smdb_get(database, &db_key, &db_value, 0); 36977352Sgshapiro if (get_res == SMDBE_NOT_FOUND) 37042580Speter { 37177352Sgshapiro db_key.size++; 37277352Sgshapiro get_res = database->smdb_get(database, &db_key, 37377352Sgshapiro &db_value, 0); 37477352Sgshapiro } 37577352Sgshapiro if (get_res == SMDBE_OK) 37677352Sgshapiro { 37790795Sgshapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 37890795Sgshapiro "%.*s:%.*s\n", 37990795Sgshapiro (int) db_key.size, 38090795Sgshapiro (char *) db_key.data, 38190795Sgshapiro (int) db_value.size, 38290795Sgshapiro (char *) db_value.data); 38338032Speter } 38464565Sgshapiro else 38590795Sgshapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 38690795Sgshapiro "%s: No such key\n", 38790795Sgshapiro (char *)db_key.data); 38838032Speter } 38964565Sgshapiro 39064565Sgshapiro fatal: 39164565Sgshapiro if (cursor != NULL) 39264565Sgshapiro (void) cursor->smdbc_close(cursor); 39364565Sgshapiro if (database != NULL) 39464565Sgshapiro (void) database->smdb_close(database); 39564565Sgshapiro if (colon != NULL) 39664565Sgshapiro *colon = ':'; 39764565Sgshapiro return; 39842580Speter} 399