1: #include "parms.h" 2: #include "structs.h" 3: 4: #ifdef RCSIDENT 5: static char rcsid[] = "$Header: acssort.c,v 1.7 85/01/18 15:40:40 notes Rel $"; 6: #endif RCSIDENT 7: 8: /* 9: * acssort 10: * 11: * Routines in this file are used to sort access lists. 12: * Splintered off from access.c so that nfaccess.c can use 13: * them. 14: * 15: * Also contains routines to add entries to an access list 16: * and to parse an ascii representation of an access right. 17: * 18: * Ray Essick 19: */ 20: 21: 22: acscmp (a, b) 23: struct perm_f *a, 24: *b; 25: { 26: /* 27: * people before groups before systems 28: * Alphabetical within each class 29: */ 30: if (a -> ptype < b -> ptype) 31: return (-1); 32: if (a -> ptype > b -> ptype) 33: return 1; 34: if (strcmp ("Other", a -> name) == 0) 35: if (strcmp ("Other", b -> name) == 0) 36: return 0; 37: else 38: return 1; /* put "Other" last */ 39: if (strcmp ("Other", b -> name) == 0) 40: return (-1); /* is correct */ 41: return strcmp (a -> name, b -> name); 42: } 43: 44: /* 45: * acssort 46: * 47: * sort the access list 48: */ 49: 50: acssort (alist, items) 51: struct perm_f alist[]; 52: int items; 53: { 54: qsort (alist, items, sizeof (struct perm_f), acscmp); 55: } 56: /* 57: * addmodes(io) struct io_f *io; 58: * 59: * reads the access list and adds the modes specified in the 60: * Newmodes array. 61: * Checks for duplication and merely replaces with the new 62: * permission in those cases. 63: */ 64: 65: addmodes (io, nmodes, Newmodes, verbose) 66: struct io_f *io; 67: int nmodes; 68: struct perm_f *Newmodes; 69: int verbose; 70: { 71: struct perm_f alist[NPERMS]; 72: int pcount; /* items in list */ 73: FILE * acs; 74: int i, 75: j; 76: char fn[WDLEN]; /* hold a filename */ 77: 78: sprintf (fn, "%s/%s/%s", io -> basedir, io -> nf, ACCESS); 79: x ((acs = fopen (fn, "r")) == NULL, "addmode: no access list"); 80: x ((pcount = fread (alist, sizeof (struct perm_f), NPERMS, acs)) == 0, "addmode: empty access list"); 81: fclose (acs); 82: 83: for (i = 0; i < nmodes; i++) /* for each mode */ 84: { 85: for (j = 0; j < pcount; j++) /* look for match */ 86: if (Newmodes[i].ptype == alist[j].ptype && 87: strcmp (Newmodes[i].name, alist[j].name) == 0) 88: break; /* match */ 89: if (j == pcount) /* wasn't there */ 90: { 91: if (pcount == NPERMS) 92: { 93: if (verbose) 94: printf ("%s: access list full\n", io -> nf); 95: break; 96: } 97: alist[pcount].ptype = Newmodes[i].ptype; 98: alist[pcount].perms = Newmodes[i].perms; 99: strcpy (alist[pcount].name, Newmodes[i].name); 100: pcount++; 101: } 102: else /* update existing one */ 103: { 104: alist[j].perms = Newmodes[i].perms; 105: if (verbose) 106: printf ("%s: replaced extant permission for %s\n", 107: io -> nf, Newmodes[i].name); 108: } 109: } 110: /* 111: * replace the access list 112: */ 113: 114: acssort (alist, pcount); 115: x ((acs = fopen (fn, "w")) == NULL, "addmodes: can't write access list"); 116: x (fwrite (alist, sizeof (struct perm_f), pcount, acs) != pcount, "addmodes: writing access"); 117: fclose (acs); 118: } 119: 120: /* 121: * parsemode 122: * 123: * Parse the supplied (character string) access specification 124: * into the specified perm_f structure. 125: * 126: * Ray Essick 127: */ 128: 129: parsemode (asciimode, pstuff, verbose) 130: char *asciimode; 131: struct perm_f *pstuff; 132: int verbose; 133: { 134: char *p; 135: char name[WDLEN]; /* hold the name */ 136: char namespec[WDLEN]; /* entire name */ 137: int nametype; /* name class */ 138: char mode[WDLEN]; /* and the mode */ 139: char imode = 0; /* internalized */ 140: 141: 142: if ((p = index (asciimode, '=')) == NULL) /* find the mode */ 143: { 144: if (verbose) 145: printf ("No mode separator: %s\n", asciimode); 146: return (1); 147: } 148: 149: *p++ = '\0'; /* split out mode */ 150: strcpy (mode, p); /* grab mode */ 151: strcpy (namespec, asciimode); /* and name */ 152: *--p = '='; /* replace marker */ 153: 154: 155: if ((p = index (namespec, ':')) == NULL) /* implicitly user? */ 156: { 157: strcpy (name, namespec); /* user name */ 158: nametype = PERMUSER; /* default to user */ 159: } 160: else 161: { 162: *p++ = '\0'; /* break specification */ 163: strcpy (name, p); /* load name */ 164: switch (namespec[0]) /* determine class */ 165: { 166: case 'u': 167: case 'U': 168: nametype = PERMUSER; 169: break; 170: 171: case 'g': 172: case 'G': 173: nametype = PERMGROUP; 174: break; 175: 176: case 's': 177: case 'S': 178: nametype = PERMSYSTEM; 179: break; 180: 181: default: 182: if (verbose) 183: printf ("Invalid name class: %s\n", namespec); 184: return (1); 185: break; 186: } 187: 188: } 189: /* 190: * Check that user/group are defined on our system. Don't 191: * want to be filling our tables with bogus stuff. 192: */ 193: 194: switch (nametype) 195: { 196: case PERMUSER: 197: if (getpwnam (name) == NULL) /* does he exist? */ 198: { 199: if (verbose) 200: printf ("%s: no such user\n", name); 201: return (1); 202: } 203: break; 204: 205: case PERMGROUP: 206: if (getgrnam (name) == NULL) /* does it exist */ 207: { 208: if (verbose) 209: printf ("%s: no such group\n", name); 210: return (1); 211: } 212: break; 213: 214: case PERMSYSTEM: 215: default: 216: break; 217: } 218: 219: /* 220: * Now internalize the mode 221: */ 222: 223: imode = 0; /* initially null */ 224: for (p = mode; *p; p++) /* each specifier */ 225: { 226: switch (*p) 227: { 228: case 'd': /* director */ 229: imode = DRCTOK + READOK + WRITOK + RESPOK; 230: break; 231: case 'r': /* read */ 232: imode |= READOK; 233: break; 234: case 'w': /* write (and respond) */ 235: imode |= WRITOK + RESPOK; 236: break; 237: case 'a': /* respond */ 238: imode |= RESPOK; 239: break; 240: case 'n': /* nullify */ 241: imode = 0; 242: break; 243: default: 244: if (verbose) 245: printf ("%c: Invalid permission mode\n", *p); 246: break; 247: } 248: 249: } 250: pstuff -> ptype = nametype; /* load structure */ 251: pstuff -> perms = imode; 252: strcpy (pstuff -> name, name); 253: return 0; 254: }