"Fossies" - the Fresh Open Source Software Archive

Member "sendmail-8.15.2/editmap/editmap.c" (5 Dec 2014, 8567 Bytes) of package /linux/misc/sendmail.8.15.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "editmap.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 8.14.9_vs_8.15.1.

    1 /*
    2  * Copyright (c) 1998-2002, 2004 Proofpoint, Inc. and its suppliers.
    3  *  All rights reserved.
    4  * Copyright (c) 1992 Eric P. Allman.  All rights reserved.
    5  * Copyright (c) 1992, 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 
   14 #include <sm/gen.h>
   15 #ifndef lint
   16 SM_UNUSED(static char copyright[]) =
   17 "@(#) Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.\n\
   18     All rights reserved.\n\
   19      Copyright (c) 1992 Eric P. Allman.  All rights reserved.\n\
   20      Copyright (c) 1992, 1993\n\
   21     The Regents of the University of California.  All rights reserved.\n";
   22 #endif /* ! lint */
   23 
   24 #ifndef lint
   25 SM_UNUSED(static char id[]) = "@(#)$Id: editmap.c,v 1.26 2013-11-22 20:51:26 ca Exp $";
   26 #endif /* ! lint */
   27 
   28 
   29 #include <sys/types.h>
   30 #ifndef ISC_UNIX
   31 # include <sys/file.h>
   32 #endif /* ! ISC_UNIX */
   33 #include <ctype.h>
   34 #include <stdlib.h>
   35 #include <unistd.h>
   36 #ifdef EX_OK
   37 # undef EX_OK       /* unistd.h may have another use for this */
   38 #endif /* EX_OK */
   39 #include <sysexits.h>
   40 #include <assert.h>
   41 #include <sendmail/sendmail.h>
   42 #include <sendmail/pathnames.h>
   43 #include <libsmdb/smdb.h>
   44 
   45 uid_t   RealUid;
   46 gid_t   RealGid;
   47 char    *RealUserName;
   48 uid_t   RunAsUid;
   49 gid_t   RunAsGid;
   50 char    *RunAsUserName;
   51 int Verbose = 2;
   52 bool    DontInitGroups = false;
   53 uid_t   TrustedUid = 0;
   54 BITMAP256 DontBlameSendmail;
   55 
   56 #define BUFSIZE     1024
   57 #define ISSEP(c) (isascii(c) && isspace(c))
   58 
   59 
   60 static void usage __P((char *));
   61 
   62 static void
   63 usage(progname)
   64     char *progname;
   65 {
   66     fprintf(stderr,
   67         "Usage: %s [-C cffile] [-N] [-f] [-q|-u|-x] maptype mapname key [ \"value ...\" ]\n",
   68         progname);
   69     exit(EX_USAGE);
   70 }
   71 
   72 int
   73 main(argc, argv)
   74     int argc;
   75     char **argv;
   76 {
   77     char *progname;
   78     char *cfile;
   79     bool query = false;
   80     bool update = false;
   81     bool remove = false;
   82     bool inclnull = false;
   83     bool foldcase = true;
   84     unsigned int nops = 0;
   85     int exitstat;
   86     int opt;
   87     char *typename = NULL;
   88     char *mapname = NULL;
   89     char *keyname = NULL;
   90     char *value = NULL;
   91     int mode;
   92     int smode;
   93     int putflags = 0;
   94     long sff = SFF_ROOTOK|SFF_REGONLY;
   95     struct passwd *pw;
   96     SMDB_DATABASE *database;
   97     SMDB_DBENT db_key, db_val;
   98     SMDB_DBPARAMS params;
   99     SMDB_USER_INFO user_info;
  100 #if HASFCHOWN
  101     FILE *cfp;
  102     char buf[MAXLINE];
  103 #endif /* HASFCHOWN */
  104     static char rnamebuf[MAXNAME];  /* holds RealUserName */
  105     extern char *optarg;
  106     extern int optind;
  107 
  108     memset(&params, '\0', sizeof params);
  109     params.smdbp_cache_size = 1024 * 1024;
  110 
  111     progname = strrchr(argv[0], '/');
  112     if (progname != NULL)
  113         progname++;
  114     else
  115         progname = argv[0];
  116     cfile = _PATH_SENDMAILCF;
  117 
  118     clrbitmap(DontBlameSendmail);
  119     RunAsUid = RealUid = getuid();
  120     RunAsGid = RealGid = getgid();
  121     pw = getpwuid(RealUid);
  122     if (pw != NULL)
  123         (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf);
  124     else
  125         (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
  126                    "Unknown UID %d", (int) RealUid);
  127     RunAsUserName = RealUserName = rnamebuf;
  128     user_info.smdbu_id = RunAsUid;
  129     user_info.smdbu_group_id = RunAsGid;
  130     (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
  131               SMDB_MAX_USER_NAME_LEN);
  132 
  133 #define OPTIONS     "C:fquxN"
  134     while ((opt = getopt(argc, argv, OPTIONS)) != -1)
  135     {
  136         switch (opt)
  137         {
  138           case 'C':
  139             cfile = optarg;
  140             break;
  141 
  142           case 'f':
  143             foldcase = false;
  144             break;
  145 
  146           case 'q':
  147             query = true;
  148             nops++;
  149             break;
  150 
  151           case 'u':
  152             update = true;
  153             nops++;
  154             break;
  155 
  156           case 'x':
  157             remove = true;
  158             nops++;
  159             break;
  160 
  161           case 'N':
  162             inclnull = true;
  163             break;
  164 
  165           default:
  166             usage(progname);
  167             assert(0);  /* NOTREACHED */
  168         }
  169     }
  170 
  171     if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
  172         sff |= SFF_NOSLINK;
  173     if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
  174         sff |= SFF_NOHLINK;
  175     if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
  176         sff |= SFF_NOWLINK;
  177 
  178     argc -= optind;
  179     argv += optind;
  180     if ((nops != 1) ||
  181         (query && argc != 3) ||
  182         (remove && argc != 3) ||
  183         (update && argc <= 3))
  184     {
  185         usage(progname);
  186         assert(0);  /* NOTREACHED */
  187     }
  188 
  189     typename = argv[0];
  190     mapname = argv[1];
  191     keyname = argv[2];
  192     if (update)
  193         value = argv[3];
  194 
  195     if (foldcase)
  196     {
  197         char *p;
  198 
  199         for (p = keyname; *p != '\0'; p++)
  200         {
  201             if (isascii(*p) && isupper(*p))
  202                 *p = tolower(*p);
  203         }
  204     }
  205 
  206 
  207 #if HASFCHOWN
  208     /* Find TrustedUser value in sendmail.cf */
  209     if ((cfp = fopen(cfile, "r")) == NULL)
  210     {
  211         fprintf(stderr, "%s: %s: %s\n", progname,
  212             cfile, sm_errstring(errno));
  213         exit(EX_NOINPUT);
  214     }
  215     while (fgets(buf, sizeof(buf), cfp) != NULL)
  216     {
  217         register char *b;
  218 
  219         if ((b = strchr(buf, '\n')) != NULL)
  220             *b = '\0';
  221 
  222         b = buf;
  223         switch (*b++)
  224         {
  225           case 'O':     /* option */
  226             if (strncasecmp(b, " TrustedUser", 12) == 0 &&
  227                 !(isascii(b[12]) && isalnum(b[12])))
  228             {
  229                 b = strchr(b, '=');
  230                 if (b == NULL)
  231                     continue;
  232                 while (isascii(*++b) && isspace(*b))
  233                     continue;
  234                 if (isascii(*b) && isdigit(*b))
  235                     TrustedUid = atoi(b);
  236                 else
  237                 {
  238                     TrustedUid = 0;
  239                     pw = getpwnam(b);
  240                     if (pw == NULL)
  241                         fprintf(stderr,
  242                             "TrustedUser: unknown user %s\n", b);
  243                     else
  244                         TrustedUid = pw->pw_uid;
  245                 }
  246 
  247 # ifdef UID_MAX
  248                 if (TrustedUid > UID_MAX)
  249                 {
  250                     fprintf(stderr,
  251                         "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
  252                         (long) TrustedUid,
  253                         (long) UID_MAX);
  254                     TrustedUid = 0;
  255                 }
  256 # endif /* UID_MAX */
  257                 break;
  258             }
  259 
  260 
  261           default:
  262             continue;
  263         }
  264     }
  265     (void) fclose(cfp);
  266 #endif /* HASFCHOWN */
  267 
  268     if (query)
  269     {
  270         mode = O_RDONLY;
  271         smode = S_IRUSR;
  272     }
  273     else
  274     {
  275         mode = O_RDWR | O_CREAT;
  276         sff |= SFF_CREAT|SFF_NOTEXCL;
  277         smode = S_IWUSR;
  278     }
  279 
  280     params.smdbp_num_elements = 4096;
  281 
  282     errno = smdb_open_database(&database, mapname, mode, smode, sff,
  283                    typename, &user_info, &params);
  284     if (errno != SMDBE_OK)
  285     {
  286         char *hint;
  287 
  288         if (errno == SMDBE_UNSUPPORTED_DB_TYPE &&
  289             (hint = smdb_db_definition(typename)) != NULL)
  290             fprintf(stderr,
  291                 "%s: Need to recompile with -D%s for %s support\n",
  292                 progname, hint, typename);
  293         else
  294             fprintf(stderr,
  295                 "%s: error opening type %s map %s: %s\n",
  296                 progname, typename, mapname,
  297                 sm_errstring(errno));
  298         exit(EX_CANTCREAT);
  299     }
  300 
  301     (void) database->smdb_sync(database, 0);
  302 
  303     if (geteuid() == 0 && TrustedUid != 0)
  304     {
  305         errno = database->smdb_set_owner(database, TrustedUid, -1);
  306         if (errno != SMDBE_OK)
  307         {
  308             fprintf(stderr,
  309                 "WARNING: ownership change on %s failed %s",
  310                 mapname, sm_errstring(errno));
  311         }
  312     }
  313 
  314     exitstat = EX_OK;
  315     if (query)
  316     {
  317         memset(&db_key, '\0', sizeof db_key);
  318         memset(&db_val, '\0', sizeof db_val);
  319 
  320         db_key.data = keyname;
  321         db_key.size = strlen(keyname);
  322         if (inclnull)
  323             db_key.size++;
  324 
  325         errno = database->smdb_get(database, &db_key, &db_val, 0);
  326         if (errno != SMDBE_OK)
  327         {
  328             /* XXX - Need to distinguish between not found */
  329             fprintf(stderr,
  330                 "%s: couldn't find key %s in map %s\n",
  331                 progname, keyname, mapname);
  332             exitstat = EX_UNAVAILABLE;
  333         }
  334         else
  335         {
  336             printf("%.*s\n", (int) db_val.size,
  337                    (char *) db_val.data);
  338         }
  339     }
  340     else if (update)
  341     {
  342         memset(&db_key, '\0', sizeof db_key);
  343         memset(&db_val, '\0', sizeof db_val);
  344 
  345         db_key.data = keyname;
  346         db_key.size = strlen(keyname);
  347         if (inclnull)
  348             db_key.size++;
  349         db_val.data = value;
  350         db_val.size = strlen(value);
  351         if (inclnull)
  352             db_val.size++;
  353 
  354         errno = database->smdb_put(database, &db_key, &db_val,
  355                        putflags);
  356         if (errno != SMDBE_OK)
  357         {
  358             fprintf(stderr,
  359                 "%s: error updating (%s, %s) in map %s: %s\n",
  360                 progname, keyname, value, mapname,
  361                 sm_errstring(errno));
  362             exitstat = EX_IOERR;
  363         }
  364     }
  365     else if (remove)
  366     {
  367         memset(&db_key, '\0', sizeof db_key);
  368         memset(&db_val, '\0', sizeof db_val);
  369 
  370         db_key.data = keyname;
  371         db_key.size = strlen(keyname);
  372         if (inclnull)
  373             db_key.size++;
  374 
  375         errno = database->smdb_del(database, &db_key, 0);
  376 
  377         switch (errno)
  378         {
  379         case SMDBE_NOT_FOUND:
  380             fprintf(stderr,
  381                 "%s: key %s doesn't exist in map %s\n",
  382                 progname, keyname, mapname);
  383             /* Don't set exitstat */
  384             break;
  385         case SMDBE_OK:
  386             /* All's well */
  387             break;
  388         default:
  389             fprintf(stderr,
  390                 "%s: couldn't remove key %s in map %s (error)\n",
  391                 progname, keyname, mapname);
  392             exitstat = EX_IOERR;
  393             break;
  394         }
  395     }
  396     else
  397     {
  398         assert(0);  /* NOT REACHED */
  399     }
  400 
  401     /*
  402     **  Now close the database.
  403     */
  404 
  405     errno = database->smdb_close(database);
  406     if (errno != SMDBE_OK)
  407     {
  408         fprintf(stderr, "%s: close(%s): %s\n",
  409             progname, mapname, sm_errstring(errno));
  410         exitstat = EX_IOERR;
  411     }
  412     smdb_free_database(database);
  413 
  414     exit(exitstat);
  415     /* NOTREACHED */
  416     return exitstat;
  417 }