home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / uuconf.subproj / rdperm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  11.5 KB  |  453 lines

  1. /* rdperm.c
  2.    Read the HDB Permissions file.
  3.  
  4.    Copyright (C) 1992, 1993 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP uuconf library.
  7.  
  8.    This library is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU Library General Public License
  10.    as published by the Free Software Foundation; either version 2 of
  11.    the License, or (at your option) any later version.
  12.  
  13.    This library is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    Library General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU Library General Public
  19.    License along with this library; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucnfi.h"
  27.  
  28. #if USE_RCS_ID
  29. const char _uuconf_rdperm_rcsid[] = "$Id: rdperm.c,v 1.9 1995/06/21 19:23:54 ian Rel $";
  30. #endif
  31.  
  32. #include <errno.h>
  33. #include <ctype.h>
  34.  
  35. static int ihcolon P((pointer pglobal, int argc, char **argv, pointer pvar,
  36.               pointer pinfo));
  37. static int ihsendfiles P((pointer pglobal, int argc, char **argv,
  38.               pointer pvar, pointer pinfo));
  39. static int ihunknownperm P((pointer pglobal, int argc, char **argv,
  40.                 pointer pvar, pointer pinfo));
  41. static int ihadd_norw P((struct sglobal *qglobal, char ***ppz, char **pzno));
  42.  
  43. /* These routines reads in the HDB Permissions file.  We store the
  44.    entries in a linked list of shpermissions structures, so we only
  45.    have to actually read the file once.  */
  46.  
  47. /* This command table and static structure are used to parse a line
  48.    from Permissions.  The entries are parsed as follows:
  49.  
  50.    Multiple strings separated by colons: LOGNAME, MACHINE, READ,
  51.    WRITE, NOREAD, NOWRITE, COMMANDS, VALIDATE, ALIAS.
  52.  
  53.    Boolean values: REQUEST, CALLBACK.
  54.  
  55.    Simple strings: MYNAME, PUBDIR.
  56.  
  57.    "Yes" or "call": SENDFILES.
  58.  
  59.    The NOREAD and NOWRITE entries are merged into the READ and WRITE
  60.    entries, rather than being permanently stored.  They are handled
  61.    specially in the uuconf_cmdtab table.  */
  62.  
  63. static const struct cmdtab_offset asHperm_cmds[] =
  64. {
  65.   { "NOREAD", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
  66.   { "NOWRITE", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
  67.   { "LOGNAME", UUCONF_CMDTABTYPE_FN | 2,
  68.       offsetof (struct shpermissions, pzlogname), ihcolon },
  69.   { "MACHINE", UUCONF_CMDTABTYPE_FN | 2,
  70.       offsetof (struct shpermissions, pzmachine), ihcolon },
  71.   { "REQUEST", UUCONF_CMDTABTYPE_BOOLEAN,
  72.       offsetof (struct shpermissions, frequest), NULL },
  73.   { "SENDFILES", UUCONF_CMDTABTYPE_FN | 2,
  74.       offsetof (struct shpermissions, fsendfiles), ihsendfiles },
  75.   { "READ", UUCONF_CMDTABTYPE_FN | 2,
  76.       offsetof (struct shpermissions, pzread), ihcolon },
  77.   { "WRITE", UUCONF_CMDTABTYPE_FN | 2,
  78.       offsetof (struct shpermissions, pzwrite), ihcolon },
  79.   { "CALLBACK", UUCONF_CMDTABTYPE_BOOLEAN,
  80.       offsetof (struct shpermissions, fcallback), NULL },
  81.   { "COMMANDS", UUCONF_CMDTABTYPE_FN | 2,
  82.       offsetof (struct shpermissions, pzcommands), ihcolon },
  83.   { "VALIDATE", UUCONF_CMDTABTYPE_FN | 2,
  84.       offsetof (struct shpermissions, pzvalidate), ihcolon },
  85.   { "MYNAME", UUCONF_CMDTABTYPE_STRING,
  86.       offsetof (struct shpermissions, zmyname), NULL },
  87.   { "PUBDIR", UUCONF_CMDTABTYPE_STRING,
  88.       offsetof (struct shpermissions, zpubdir), NULL },
  89.   { "ALIAS", UUCONF_CMDTABTYPE_FN | 2,
  90.       offsetof (struct shpermissions, pzalias), ihcolon },
  91.   { NULL, 0, 0, NULL }
  92. };
  93.  
  94. #define CHPERM_CMDS (sizeof asHperm_cmds / sizeof asHperm_cmds[0])
  95.  
  96. /* Actually read the Permissions file into a linked list of
  97.    structures.  */
  98.  
  99. int
  100. _uuconf_ihread_permissions (qglobal)
  101.      struct sglobal *qglobal;
  102. {
  103.   char *zperm;
  104.   FILE *e;
  105.   int iret;
  106.   struct uuconf_cmdtab as[CHPERM_CMDS];
  107.   char **pznoread, **pznowrite;
  108.   struct shpermissions shperm;
  109.   char *zline;
  110.   size_t cline;
  111.   char **pzsplit;
  112.   size_t csplit;
  113.   int cchars;
  114.   struct shpermissions *qlist, **pq;
  115.  
  116.   if (qglobal->qprocess->fhdb_read_permissions)
  117.     return UUCONF_SUCCESS;
  118.  
  119.   zperm = (char *) uuconf_malloc (qglobal->pblock,
  120.                   (sizeof OLDCONFIGLIB
  121.                    + sizeof HDB_PERMISSIONS - 1));
  122.   if (zperm == NULL)
  123.     {
  124.       qglobal->ierrno = errno;
  125.       return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
  126.     }
  127.  
  128.   memcpy ((pointer) zperm, (pointer) OLDCONFIGLIB,
  129.       sizeof OLDCONFIGLIB - 1);
  130.   memcpy ((pointer) (zperm + sizeof OLDCONFIGLIB - 1),
  131.       (pointer) HDB_PERMISSIONS, sizeof HDB_PERMISSIONS);
  132.  
  133.   e = fopen (zperm, "r");
  134.   if (e == NULL)
  135.     {
  136.       uuconf_free (qglobal->pblock, zperm);
  137.       qglobal->qprocess->fhdb_read_permissions = TRUE;
  138.       return UUCONF_SUCCESS;
  139.     }
  140.  
  141.   _uuconf_ucmdtab_base (asHperm_cmds, CHPERM_CMDS, (char *) &shperm, as);
  142.   as[0].uuconf_pvar = (pointer) &pznoread;
  143.   as[1].uuconf_pvar = (pointer) &pznowrite;
  144.  
  145.   zline = NULL;
  146.   cline = 0;
  147.   pzsplit = NULL;
  148.   csplit = 0;
  149.  
  150.   qlist = NULL;
  151.   pq = &qlist;
  152.  
  153.   qglobal->ilineno = 0;
  154.  
  155.   iret = UUCONF_SUCCESS;
  156.  
  157.   while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0)
  158.     {
  159.       int centries;
  160.       struct shpermissions *qnew;
  161.       int i;
  162.  
  163.       ++qglobal->ilineno;
  164.  
  165.       --cchars;
  166.       if (zline[cchars] == '\n')
  167.     zline[cchars] = '\0';
  168.       if (zline[0] == '#')
  169.     continue;
  170.  
  171.       centries = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
  172.       if (centries < 0)
  173.     {
  174.       qglobal->ierrno = errno;
  175.       iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
  176.       break;
  177.     }
  178.  
  179.       if (centries == 0)
  180.     continue;
  181.  
  182.       shperm.pzlogname = (char **) &_uuconf_unset;
  183.       shperm.pzmachine = (char **) &_uuconf_unset;
  184.       shperm.frequest = -1;
  185.       shperm.fsendfiles = -1;
  186.       shperm.pzread = (char **) &_uuconf_unset;
  187.       shperm.pzwrite = (char **) &_uuconf_unset;
  188.       shperm.fcallback = -1;
  189.       shperm.pzcommands = (char **) &_uuconf_unset;
  190.       shperm.pzvalidate = (char **) &_uuconf_unset;
  191.       shperm.zmyname = (char *) &_uuconf_unset;
  192.       shperm.zpubdir = (char *) &_uuconf_unset;
  193.       shperm.pzalias = (char **) &_uuconf_unset;
  194.       pznoread = (char **) &_uuconf_unset;
  195.       pznowrite = (char **) &_uuconf_unset;
  196.  
  197.       for (i = 0; i < centries; i++)
  198.     {
  199.       char *zeq;
  200.       char *azargs[2];
  201.  
  202.       zeq = strchr (pzsplit[i], '=');
  203.       if (zeq == NULL)
  204.         {
  205.           iret = UUCONF_SYNTAX_ERROR;
  206.           qglobal->qprocess->fhdb_read_permissions = TRUE;
  207.           break;
  208.         }
  209.       *zeq = '\0';
  210.  
  211.       azargs[0] = pzsplit[i];
  212.       azargs[1] = zeq + 1;
  213.  
  214.       iret = uuconf_cmd_args (qglobal, 2, azargs, as, (pointer) NULL,
  215.                   ihunknownperm, 0, qglobal->pblock);
  216.       if ((iret & UUCONF_CMDTABRET_KEEP) != 0)
  217.         {
  218.           iret &=~ UUCONF_CMDTABRET_KEEP;
  219.  
  220.           if (uuconf_add_block (qglobal->pblock, zline) != 0)
  221.         {
  222.           qglobal->ierrno = errno;
  223.           iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
  224.           break;
  225.         }
  226.  
  227.           zline = NULL;
  228.           cline = 0;
  229.         }
  230.       if ((iret & UUCONF_CMDTABRET_EXIT) != 0)
  231.         {
  232.           iret &=~ UUCONF_CMDTABRET_EXIT;
  233.           break;
  234.         }
  235.     }
  236.  
  237.       if (iret != UUCONF_SUCCESS)
  238.     break;
  239.  
  240.       if (shperm.pzmachine == (char **) &_uuconf_unset
  241.       && shperm.pzlogname == (char **) &_uuconf_unset)
  242.     {
  243.       iret = UUCONF_SYNTAX_ERROR;
  244.       qglobal->qprocess->fhdb_read_permissions = TRUE;
  245.       break;
  246.     }
  247.  
  248.       /* Attach any NOREAD or NOWRITE entries to the corresponding
  249.      READ or WRITE entries in the format expected for the
  250.      pzlocal_receive, etc., fields in uuconf_system.  */
  251.       if (pznoread != NULL)
  252.     {
  253.       iret = ihadd_norw (qglobal, &shperm.pzread, pznoread);
  254.       if (iret != UUCONF_SUCCESS)
  255.         break;
  256.       uuconf_free (qglobal->pblock, pznoread);
  257.     }
  258.  
  259.       if (pznowrite != NULL)
  260.     {
  261.       iret = ihadd_norw (qglobal, &shperm.pzwrite, pznowrite);
  262.       if (iret != UUCONF_SUCCESS)
  263.         break;
  264.       uuconf_free (qglobal->pblock, pznowrite);
  265.     }
  266.  
  267.       qnew = ((struct shpermissions *)
  268.           uuconf_malloc (qglobal->pblock,
  269.                  sizeof (struct shpermissions)));
  270.       if (qnew == NULL)
  271.     {
  272.       qglobal->ierrno = errno;
  273.       iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
  274.       break;
  275.     }
  276.  
  277.       *qnew = shperm;
  278.       *pq = qnew;
  279.       pq = &qnew->qnext;
  280.       *pq = NULL;
  281.     }
  282.  
  283.   (void) fclose (e);
  284.  
  285.   if (zline != NULL)
  286.     free ((pointer) zline);
  287.   if (pzsplit != NULL)
  288.     free ((pointer) pzsplit);
  289.  
  290.   if (iret == UUCONF_SUCCESS)
  291.     {
  292.       qglobal->qprocess->qhdb_permissions = qlist;
  293.       qglobal->qprocess->fhdb_read_permissions = TRUE;
  294.     }
  295.   else
  296.     {
  297.       qglobal->zfilename = zperm;
  298.       iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
  299.     }
  300.  
  301.   return iret;
  302. }
  303.  
  304. /* Split the argument into colon separated strings, and assign a NULL
  305.    terminated array of strings to pvar.  */
  306.  
  307. /*ARGSUSED*/
  308. static int
  309. ihcolon (pglobal, argc, argv, pvar, pinfo)
  310.      pointer pglobal;
  311.      int argc;
  312.      char **argv;
  313.      pointer pvar;
  314.      pointer pinfo;
  315. {
  316.   struct sglobal *qglobal = (struct sglobal *) pglobal;
  317.   char ***ppz = (char ***) pvar;
  318.   char **pzsplit;
  319.   size_t csplit;
  320.   int centries;
  321.   int i;
  322.   int iret;
  323.  
  324.   *ppz = NULL;
  325.  
  326.   pzsplit = NULL;
  327.   csplit = 0;
  328.  
  329.   centries = _uuconf_istrsplit (argv[1], ':', &pzsplit, &csplit);
  330.   if (centries < 0)
  331.     {
  332.       qglobal->ierrno = errno;
  333.       return (UUCONF_MALLOC_FAILED
  334.           | UUCONF_ERROR_ERRNO
  335.           | UUCONF_CMDTABRET_EXIT);
  336.     }
  337.  
  338.   if (centries == 0)
  339.     {
  340.       if (pzsplit != NULL)
  341.     free ((pointer) pzsplit);
  342.       return UUCONF_CMDTABRET_CONTINUE;
  343.     }
  344.  
  345.   iret = UUCONF_SUCCESS;
  346.  
  347.   for (i = 0; i < centries; i++)
  348.     {
  349.       iret = _uuconf_iadd_string (qglobal, pzsplit[i], FALSE, FALSE,
  350.                   ppz, qglobal->pblock);
  351.       if (iret != UUCONF_SUCCESS)
  352.     {
  353.       iret |= UUCONF_CMDTABRET_EXIT;
  354.       break;
  355.     }
  356.     }
  357.  
  358.   free ((pointer) pzsplit);
  359.  
  360.   return UUCONF_CMDTABRET_KEEP;
  361. }
  362.  
  363. /* Handle the SENDFILES parameter, which can take "yes" or "call" or
  364.    "no" as an argument.  The string "call" is equivalent to "no".  */
  365.  
  366. /*ARGSUSED*/
  367. static int
  368. ihsendfiles (pglobal, argc, argv, pvar, pinfo)
  369.      pointer pglobal;
  370.      int argc;
  371.      char **argv;
  372.      pointer pvar;
  373.      pointer pinfo;
  374. {
  375.   int *pi = (int *) pvar;
  376.  
  377.   switch (argv[1][0])
  378.     {
  379.     case 'C':
  380.     case 'c':
  381.     case 'N':
  382.     case 'n':
  383.       *pi = FALSE;
  384.       break;
  385.     case 'Y':
  386.     case 'y':
  387.       *pi = TRUE;
  388.       break;
  389.     default:
  390.       return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
  391.     }
  392.  
  393.   return UUCONF_CMDTABRET_CONTINUE;
  394. }
  395.  
  396. /* If there is an unknown Permissions entry, return a syntax error.
  397.    This should probably be more clever.  */
  398.  
  399. /*ARGSUSED*/
  400. static int
  401. ihunknownperm (pglobal, argc, argv, pvar, pinfo)
  402.      pointer pglobal;
  403.      int argc;
  404.      char **argv;
  405.      pointer pvar;
  406.      pointer pinfo;
  407. {
  408.   return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
  409. }
  410.  
  411. /* Add a NOREAD or NOWRITE entry to a READ or WRITE entry.  */
  412.  
  413. static int
  414. ihadd_norw (qglobal, ppz, pzno)
  415.      struct sglobal *qglobal;
  416.      char ***ppz;
  417.      char **pzno;
  418. {
  419.   register char **pz;
  420.  
  421.   if (pzno == (char **) &_uuconf_unset)
  422.     return UUCONF_SUCCESS;
  423.  
  424.   for (pz = pzno; *pz != NULL; pz++)
  425.     {
  426.       size_t csize;
  427.       char *znew;
  428.       int iret;
  429.  
  430.       /* Ignore an attempt to say NOREAD or NOWRITE with an empty
  431.      string, since it will be interpreted as an attempt to deny
  432.      everything.  */
  433.       if (**pz != '\0')
  434.     {
  435.       csize = strlen (*pz) + 1;
  436.       znew = (char *) uuconf_malloc (qglobal->pblock, csize + 1);
  437.       if (znew == NULL)
  438.         {
  439.           qglobal->ierrno = errno;
  440.           return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
  441.         }
  442.       znew[0] = '!';
  443.       memcpy ((pointer) (znew + 1), (pointer) *pz, csize);
  444.       iret = _uuconf_iadd_string (qglobal, znew, FALSE, FALSE, ppz,
  445.                       qglobal->pblock);
  446.       if (iret != UUCONF_SUCCESS)
  447.         return iret;
  448.     }
  449.     }
  450.  
  451.   return UUCONF_SUCCESS;
  452. }
  453.