#include "parms.h" #include "structs.h" #ifdef RCSIDENT static char rcsid[] = "$Header: /usr/local/src/usenet/notes/src/RCS/perms.c,v 1.8 88/11/10 21:49:23 paul Exp $"; #endif RCSIDENT /* * getperms - opens and reads the permission file to * determine the access rights for this user * * Uses a struture similar to PLATO's. A list is scanned * until a match is found. The access rights at that point * are then awarded to the user. In the event that no * match is found, no access rights are granted. * * Original Coding: Ray Essick December 1981 */ #include /* * Make sure that the name NGROUPS is defined. * pre-4.1a probably doesn't define either. * 4.1a uses the NGRPS constant * 4.2 uses the NGROUPS constant * We make sure that NGROUPS is defined and use that in the * generic portion of the routine. The emulation for V7, 4.1, 4.1a * and such use the NGRPS or whatever is appropriate. */ #if defined(NGRPS) && ! defined(NGROUPS) #define NGROUPS NGRPS /* name change! */ #endif #ifndef NGROUPS #define NGROUPS 1 /* could be better */ #endif NGROUPS static char *gnameptr[NGROUPS]; /* point to names */ static int ngroups = 0; /* true if have gids */ getperms (io, sysflag, name) struct io_f *io; int sysflag; /* true for remote system */ char *name; { register int i; FILE * acs, *fopen (); struct group *gr, *getgrgid (); char fn[WDLEN]; struct perm_f entry; int hisperms; /* built up perms */ int given; /* if assigned perms */ if (sysflag == 0 && globuid == Notesuid) /* "notes" omnipotent */ { io -> access = READOK + RESPOK + WRITOK + DRCTOK;/* all */ /* * should I just set it to -1 or something that turns on * all the bits? or leave it with the defined bits only? */ return; } if (sysflag == 0 && ngroups == 0) { register int i, j; /* temp loop stuff */ int gidset[NGROUPS]; /* hold gid list */ ngroups = NGROUPS; /* max allowed */ /* * NOTE that the getgroups system call doesn't behave as * documented in the 4.2 manual. The manual says to call it * ret=getgroups(&ngroups,&gidset) where ngroups is value-result. * and ret is 0 on success. Actual implementation works as below. */ if ((ngroups = getgroups (ngroups, &gidset)) >= 0)/* worked */ { for (i = 0, j = 0; i < ngroups; i++) /* get names */ { if ((gr = getgrgid (gidset[i])) == NULL) continue; /* bogus, skip it */ gnameptr[j++] = strsave (gr -> gr_name);/* save it */ } ngroups = j; /* save count */ } } io -> access = 0; /* default null */ hisperms = 0; /* set up mask */ given = 0; sprintf (fn, "%s/%s/%s", io -> basedir, io -> nf, ACCESS); x ((acs = fopen (fn, "r")) == NULL, "getperms: no list"); while (fread (&entry, sizeof entry, 1, acs) == 1) { if ((sysflag != 0) && (entry.ptype != PERMSYSTEM)) continue; /* looking for systems */ if ((sysflag == 0) && (entry.ptype == PERMSYSTEM)) continue; /* users != systems */ if (strcmp (entry.name, "Other") == 0) { if (!given) /* he hasn't matched */ hisperms = entry.perms; /* give him these */ goto gotit; /* and exit ... */ } switch (entry.ptype) { case PERMUSER: if (strcmp (name, entry.name) == 0) { hisperms = entry.perms; goto gotit; } break; case PERMGROUP: /* a group entry */ for (i = 0; i < ngroups; i++) /* check all */ if (strcmp (entry.name, gnameptr[i]) == 0) { hisperms |= entry.perms; /* OR them in */ given++; /* mark as such */ break; } break; case PERMSYSTEM: if (strcmp (name, entry.name) == 0) { hisperms = entry.perms; given++; goto gotit; } break; default: /* bad access list */ x (1, "getperms: bad list"); } } gotit: fclose (acs); /* close the access file */ io -> access = hisperms; /* what we built */ return; } /* * Some compatibility routines to let us use the fancy 4.2 Bsd * getgroups() system call while running 4.1, 4.1a or V7 kernels. * I've undoubtedly missed some kernels. */ /* * getgroups * * Returns an integer and a set of groups. * Emulates the 4.2 getgroups command under 4.1a Bsd * * Stolen mostly from the 4.1a command "groups". * * Ray Essick, January 1984 * */ #if defined (BSD41A) getgroups (ngroups, gidset) int ngroups; int *gidset; { register int i; register int maxback; /* most to user */ int grps[NGRPS / (sizeof (int) * 8)]; /* NGRPS=NGROUPS */ setgrp (0, grps); /* get groups */ maxback = ngroups; /* save limit */ ngroups = 0; /* start empty */ for (i = 0; i < NGRPS && ngroups < maxback; i++) /* for each */ if (grps[i / (sizeof (int) * 8)] & (1 << (i % (sizeof (int) * 8)))) { *gidset++ = i; /* save the group */ ngroups++; /* and count */ } return (ngroups); } #endif defined (BSD41A) /* * The V7 and 4.1 version of this system call. Also serves well * for the 2.8 Bsd kernels and probably for the more recent BTL * kernels. 2.9BSD had groups as of the Seismo/Harvard update tape SMS * This could be extended to read from /etc/groups to actually give * the user all groups he is permitted. */ #if defined (V7) || defined (BSD41) || defined (BSD28) || defined (USG) getgroups (ngroups, gidset) /* simple V7 one */ int ngroups; int *gidset; { *gidset = getgid () & GIDMASK; ngroups = 1; return (1); } #endif