home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / screen-3.5 / part02 / acl.c next >
C/C++ Source or Header  |  1993-07-25  |  11KB  |  479 lines

  1. /* Copyright (c) 1993
  2.  *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  3.  *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  4.  * Copyright (c) 1987 Oliver Laumann
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program (see the file COPYING); if not, write to the
  18.  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  ****************************************************************
  21.  */
  22. #include "rcs.h"
  23. RCS_ID("$Id: acl.c,v 1.5 1993/07/16 14:04:12 mlschroe Exp $ FAU")
  24.  
  25. #include "config.h"
  26. #include "screen.h"    /* includes acl.h */
  27. #include "extern.h"
  28.  
  29.  
  30. /************************************************************************
  31.  * user managing code, this does not really belong into the acl stuff   *
  32.  ************************************************************************/
  33.  
  34. extern struct comm comms[];
  35. extern struct win *windows, *wtab[];
  36. extern struct display *display, *displays;
  37. static struct user *userroot;
  38.  
  39. #ifdef MULTIUSER
  40. /* record given user ids here */
  41. static AclBits userbits;
  42.  
  43. /* rights a new unknown user will have on windows and cmds */
  44. static char default_w_bit[ACL_BITS_PER_WIN] = 
  45.   1,    /* EXEC */
  46.   1,     /* WRITE */
  47.   1     /* READ */
  48. };
  49.  
  50. static char default_c_bit[ACL_BITS_PER_CMD] = 
  51.   1    /* EXEC */
  52. };
  53.  
  54. /* rights of all users per newly created window */
  55. static AclBits default_w_userbits[ACL_BITS_PER_WIN];
  56.  
  57. /*
  58. static AclBits default_c_userbits[ACL_BITS_PER_CMD];
  59. */
  60.  
  61. static int maxusercount = 0;
  62.  
  63. static int GrowBitfield __P((AclBits *, int, int, int));
  64.  
  65.  
  66.  
  67. static int
  68. GrowBitfield(bfp, len, delta, defaultbit)
  69. AclBits *bfp;
  70. int len, delta, defaultbit;
  71. {
  72.   AclBits n, o = *bfp;
  73.   int i;
  74.  
  75.   if (!(n = (AclBits)calloc(1, (unsigned long)(&ACLBYTE((char *)0, len + delta + 1)))))
  76.     return -1;
  77.   for (i = 0; i < (len + delta); i++)
  78.     {
  79.       if (((i <  len) && (ACLBIT(i) & ACLBYTE(o, i))) ||
  80.           ((i >= len) && (defaultbit)))
  81.     ACLBYTE(n, i) |= ACLBIT(i);
  82.     }
  83.   if (len)
  84.     free(o);
  85.   *bfp = n;
  86.   return 0;
  87. }
  88.  
  89. #endif /* MULTIUSER */
  90.  
  91. /* 
  92.  * Returns an nonzero Address. Its contents is either a User-ptr, 
  93.  * or NULL which may be replaced by a User-ptr to create the entry.
  94.  */
  95. struct user **
  96. FindUserPtr(name)
  97. char *name;
  98. {
  99.   struct user **u;
  100.  
  101.   for (u = &userroot; *u; u = &(*u)->u_next)
  102.     if (!strcmp((*u)->u_name, name))
  103.       break;
  104. #ifdef MULTIUSER
  105.   debug3("FindUserPtr %s %sfound, id %d\n", name, (*u)?"":"not ", 
  106.          (*u)?(*u)->id:-1);
  107. #else
  108.   debug2("FindUserPtr %s %sfound\n", name, (*u)?"":"not ");
  109. #endif
  110.   return u;
  111. }
  112.  
  113. /*
  114.  * Add a new user. His password may be NULL or "" if none. 
  115.  * He is in no groups and thus has no rights.
  116.  */
  117. int
  118. UserAdd(name, pass, up)
  119. char *name, *pass;
  120. struct user **up;
  121. {
  122.   if (!up)
  123.     up = FindUserPtr(name);
  124.   if (*up)
  125.     return 1;        /* he is already there */
  126.   *up = (struct user *)calloc(1, sizeof(struct user));
  127.   if (!*up)
  128.     return -1;        /* he still does not exist */
  129.   strncpy((*up)->u_name, name, 20);
  130.   if (pass)
  131.     strncpy((*up)->u_password, pass, 20);
  132.  
  133. #ifdef MULTIUSER
  134.   /* now find an unused index */
  135.   for ((*up)->id = 0; (*up)->id < maxusercount; (*up)->id++)
  136.     if (!(ACLBIT((*up)->id) & ACLBYTE(userbits, (*up)->id)))
  137.       break;
  138.   debug2("UserAdd %s id %d\n", name, (*up)->id);
  139.   if ((*up)->id == maxusercount)
  140.     {
  141.       int i, j;
  142.       struct win *w;
  143.  
  144.       debug2("growing all bitfields %d += %d\n", maxusercount, USER_CHUNK);
  145.       /* the bitfields are full, grow a chunk */
  146.       /* first, the used_uid_indicator: */
  147.       if (GrowBitfield(&userbits, maxusercount, USER_CHUNK, 0))
  148.         {
  149.       free(*up); *up = NULL; return -1;
  150.     }
  151.       /* second, default command bits  */
  152.       /* (only if we generate commands dynamically) */
  153. /*
  154.       for (j = 0; j < ACL_BITS_PER_CMD; j++)
  155.     if (GrowBitfield(&default_c_userbits[j], maxusercount, USER_CHUNK, 
  156.         default_c_bit[j]))
  157.       {
  158.         free(*up); *up = NULL; return -1;
  159.       }
  160. */
  161.       /* third, the bits for each commands */
  162.       for (i = 0; i <= RC_LAST; i++)
  163.         for (j = 0; j < ACL_BITS_PER_CMD; j++)
  164.       if (GrowBitfield(&comms[i].userbits[j], maxusercount, USER_CHUNK,
  165.           default_c_bit[j]))
  166.         {
  167.           free(*up); *up = NULL; return -1;
  168.         }
  169.       /* fourth, default window and bits */
  170.       for (j = 0; j < ACL_BITS_PER_WIN; j++)
  171.     if (GrowBitfield(&default_w_userbits[j], maxusercount, USER_CHUNK,
  172.         default_w_bit[j]))
  173.       {
  174.         free(*up); *up = NULL; return -1;
  175.       }
  176.       /* fifth, the bits for each window */
  177.       for (w = windows; w; w = w->w_next)
  178.         for (j = 0; j < ACL_BITS_PER_WIN; j++)
  179.       if (GrowBitfield(&w->w_userbits[j], maxusercount, USER_CHUNK,
  180.           default_w_bit[j]))
  181.         {
  182.           free(*up); *up = NULL; return -1;
  183.         }
  184.       maxusercount += USER_CHUNK;
  185.     }
  186.   ACLBYTE(userbits, (*up)->id) |= ACLBIT((*up)->id);    
  187. #else /* MULTIUSER */
  188.   debug1("UserAdd %s\n", name);
  189. #endif /* MULTIUSER */
  190.   return 0;
  191. }
  192.  
  193. /* change user's password */
  194. int 
  195. UserSetPass(name, pass, up)
  196. char *name, *pass;
  197. struct user **up;
  198. {
  199.   if (!up)
  200.     up = FindUserPtr(name);
  201.   if (!*up)
  202.     return UserAdd(name, pass, up);
  203.   strncpy((*up)->u_password, pass ? pass : "", 20);
  204.   (*up)->u_password[20] = '\0';
  205.   return 0;
  206. }
  207.  
  208. /* 
  209.  * Remove a user from the list. 
  210.  * Decrease reference count of all his groups
  211.  * Free his grouplist.
  212.  */
  213. int 
  214. UserDel(name, up)
  215. char *name;
  216. struct user **up;
  217. {
  218.   struct user *u;
  219.   struct display *old, *next;
  220.  
  221.   if (!up)
  222.     up = FindUserPtr(name);
  223.   if (!(u = *up))
  224.     return -1;            /* he who does not exist cannot be removed */
  225.   old = display;
  226.   for (display = displays; display; display = next)
  227.     {
  228.       next = display->_d_next;
  229.       if (d_user != u)
  230.     continue;
  231.       if (display == old)
  232.     old = 0;
  233.       Detach(D_REMOTE);
  234.     }
  235.   display = old;
  236.   *up = u->u_next;
  237. #ifdef MULTIUSER
  238.   ACLBYTE(userbits, u->id) &= ~ACLBIT(u->id);
  239.   AclSetPerm(u, "-rwx", "#?");
  240. #endif
  241.   debug1("FREEING user structure for %s\n", u->u_name);
  242.   free(u);
  243.   return 0;
  244. }
  245.  
  246. /************************************************************************
  247.  *                     end of user managing code                        *
  248.  ************************************************************************/
  249.  
  250.  
  251. #ifdef MULTIUSER
  252.  
  253. extern char *multi;    /* username */
  254.  
  255. /* This gives the users default rights to the new window */
  256. int
  257. NewWindowAcl(w)
  258. struct win *w;
  259. {
  260.   int i, j;
  261.  
  262.   debug1("NewWindowAcl default_w_userbits for window %d\n", w->w_number);
  263.   for (j = 0; j < ACL_BITS_PER_WIN; j++)
  264.     {
  265.       /* we start with len 0 for the new bitfield size and add maxusercount */
  266.       if (GrowBitfield(&w->w_userbits[j], 0, maxusercount, 0))
  267.     {
  268.       while (--j >= 0)
  269.         free(w->w_userbits[j]);
  270.       return -1;
  271.     }
  272.       for (i = 0; i < maxusercount; i++)
  273.         if (ACLBIT(i) & ACLBYTE(default_w_userbits[j], i))
  274.       ACLBYTE(w->w_userbits[j], i) |= ACLBIT(i);
  275.     }
  276.   return 0;
  277. }
  278.  
  279. /* if mode starts with '-' we remove the users exec bit for cmd */
  280. int
  281. AclSetPermCmd(u, mode, cmd)
  282. struct user *u;
  283. char *mode;
  284. struct comm *cmd;
  285. {
  286.   int neg = 0;
  287.  
  288.   if (!multi)
  289.     return 0;
  290.   debug3("AclSetPermCmd %s %s %s\n", u->u_name, mode, cmd->name);
  291.   while (*mode)
  292.     {
  293.       switch (*mode++)
  294.         {
  295.     case '-': 
  296.       neg = 1;
  297.       continue;
  298.         case '+':
  299.       neg = 0;
  300.       continue;
  301.         case 'e': 
  302.         case 'x': 
  303.       if (neg)
  304.         ACLBYTE(cmd->userbits[ACL_EXEC], u->id) &= ~ACLBIT(u->id);
  305.       else
  306.         ACLBYTE(cmd->userbits[ACL_EXEC], u->id) |= ACLBIT(u->id);
  307.       break;
  308.         case 'r':
  309.     case 'w':
  310.       break;
  311.         default:
  312.       return -1;
  313.     }
  314.     }
  315.   return 0;
  316. }
  317.  
  318. /* mode strings of the form +rwx -w+rx r -wx are parsed and evaluated */
  319. int
  320. AclSetPermWin(u, mode, win)
  321. struct user *u;
  322. char *mode;
  323. struct win *win;
  324. {
  325.   int neg = 0;
  326.   int bit;
  327.  
  328.   if (!multi)
  329.     return 0;
  330.   debug3("AclSetPermWin %s %s %d\n", u->u_name, mode, win->w_number);
  331.   while (*mode)
  332.     {
  333.       switch (*mode++)
  334.         {
  335.     case '-': 
  336.       neg = 1;
  337.       continue;
  338.         case '+':
  339.       neg = 0;
  340.       continue;
  341.         case 'r': 
  342.       bit = ACL_READ;
  343.       break;
  344.     case 'w':
  345.       bit = ACL_WRITE;
  346.       break;
  347.         case 'x':
  348.       bit = ACL_EXEC;
  349.       break;
  350.     default:
  351.       return -1;
  352.         }
  353.       if (neg)
  354.     ACLBYTE(win->w_userbits[bit], u->id) &= ~ACLBIT(u->id);
  355.       else
  356.     ACLBYTE(win->w_userbits[bit], u->id) |= ACLBIT(u->id);
  357.     }
  358.   return 0;
  359. }
  360.  
  361. /* string is broken down into comand and window names, mode applies */
  362. int
  363. AclSetPerm(u, mode, s)
  364. struct user *u;
  365. char *mode, *s;
  366. {
  367.   struct win *w;
  368.   int i;
  369.   char *p;
  370.  
  371.   while (*s)
  372.     {
  373.       switch (*s)
  374.     {
  375.     case '*':    /* all windows and all commands */
  376.       return AclSetPerm(u, mode, "#?");
  377.     case '#':    /* all windows */
  378.       for (w = windows; w; w = w->w_next)
  379.         AclSetPermWin(u, mode, w);
  380.       s++;
  381.       break;
  382.     case '?':    /* all windows and all commands */
  383.       for (i = 0; i <= RC_LAST; i++)
  384.         AclSetPermCmd(u, mode, &comms[i]);
  385.       s++;
  386.       break;
  387.     default:
  388.       for (p = s; *p && *p != ' ' && *p != '\t' && *p != ','; p++)
  389.         ;
  390.       if (*p)
  391.         *p++ = '\0';
  392.       else
  393.         *p = '\0';
  394.       if ((i = FindCommnr(s)) != RC_ILLEGAL)
  395.         AclSetPermCmd(u, mode, &comms[i]);
  396.       else if (((i = WindowByNoN(s)) >= 0) && wtab[i])
  397.         AclSetPermWin(u, mode, wtab[i]);
  398.       else
  399.         /* checking group name */
  400.         return -1;
  401.       s = p; 
  402.     }    
  403.     }
  404.   return 0;
  405. }
  406.  
  407. #if 0
  408. void
  409. AclWinSwap(a, b)
  410. int a, b;
  411. {
  412.   int a_bit = 0, b_bit = 0;
  413.   AclGroupList **g;
  414.   AclBits p;
  415.  
  416.   debug2("acl lists swapping windows %d and %d\n", a, b);
  417.   
  418.   for (g = &aclgrouproot; *g; g = &(*g)->next) 
  419.     {
  420.       p = (*g)->group->winbits;
  421.       /* see if there was a bit for window a. zap it */
  422.       if (a >= 0)
  423.     if ((a_bit = ACLBIT(a) & ACLBYTE(p, a)))
  424.       ACLBYTE(p, a) &= ~ACLBIT(a);
  425.       /* see if there was a bit for window b. zap it */
  426.       if (b >= 0)
  427.     if ((b_bit = ACLBIT(b) & ACLBYTE(p, b)))
  428.       ACLBYTE(p, b) &= ~ACLBIT(b);
  429.       /* b may cause a set */
  430.       if (b_bit && a >= 0)
  431.         ACLBYTE(p, a) |= ACLBIT(a);
  432.       /* a may cause b set */
  433.       if (a_bit && b >= 0)
  434.         ACLBYTE(p, b) |= ACLBIT(b);
  435.     }
  436. }
  437. #else
  438. void
  439. AclWinSwap(a, b)
  440. int a, b;
  441. {
  442.   debug2("AclWinSwap(%d, %d) DUMMY\n", a, b);
  443. }
  444. #endif
  445.  
  446. int 
  447. AclCheckPermWin(u, mode, w)
  448. struct user *u;
  449. int mode;
  450. struct win *w;
  451. {
  452.   if (!multi)
  453.     return 0;
  454.   if (mode < 0 || mode >= ACL_BITS_PER_WIN)
  455.     return -1;
  456.   debug3("AclCheckPermWin(%s, %d, %d) = ", u->u_name, mode, w->w_number);
  457.   debug1("%d\n", !(ACLBYTE(w->w_userbits[mode], u->id) & ACLBIT(u->id)));
  458.   return         !(ACLBYTE(w->w_userbits[mode], u->id) & ACLBIT(u->id));
  459. }
  460.  
  461. int 
  462. AclCheckPermCmd(u, mode, c)
  463. struct user *u;
  464. int mode;
  465. struct comm *c;
  466. {
  467.   if (!multi)
  468.     return 0;
  469.   if (mode < 0 || mode >= ACL_BITS_PER_CMD)
  470.     return -1;
  471.   debug3("AclCheckPermCmd(%s %d %s) = ", u->u_name, mode, c->name); 
  472.   debug1("%d\n", !(ACLBYTE(c->userbits[mode], u->id) & ACLBIT(u->id)));
  473.   return         !(ACLBYTE(c->userbits[mode], u->id) & ACLBIT(u->id));
  474. }
  475.  
  476. #endif /* MULTIUSER */
  477.