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