1: #include "parms.h" 2: #include "structs.h" 3: 4: #ifdef RCSIDENT 5: static char rcsid[] = "$Header: access.c,v 1.7 85/01/18 15:00:31 notes Rel $"; 6: #endif RCSIDENT 7: 8: /* 9: * access - process access list editing 10: * 11: * functions include: 12: * (1) display access lists 13: * (2) insert new entries 14: * (3) delete old entries 15: * (4) modify existing entries 16: * 17: * Original Coding: Ray Essick January 1982 18: */ 19: #include <pwd.h> 20: #include <grp.h> /* /etc/passwd and /etc/group formats */ 21: 22: char *kmap[] = /* mapping for name types */ 23: { 24: "usr:", "grp:", "sys:" 25: }; 26: char *map[] = 27: { 28: /* ----- */ "Null", 29: /* ----r */ "Read Only", 30: /* ---w- */ "(02)", 31: /* ---wr */ "(03)", 32: /* --d-- */ "(04)", /* nonsense */ 33: /* --d-r */ "(05)", /* nonsense */ 34: /* --dw- */ "(06)", /* nonsense */ 35: /* --dwr */ "(07)", 36: /* -a--- */ "Answer Only", /* nonsense */ 37: /* -a--r */ "Read/Answer", 38: /* -a-w- */ "Write only", 39: /* -a-wr */ "Read/Write", 40: /* -ad-- */ "(014)", /* nonsense */ 41: /* -ad-r */ "(015)", /* nonsense */ 42: /* -adw- */ "(016)", /* nonsense */ 43: /* -adwr */ "Director/R/W" 44: }; 45: 46: struct perm_f entry; 47: static int length; /* max on screen */ 48: 49: accessedit (io) 50: struct io_f *io; /* notefile working with */ 51: { 52: struct passwd *getpwnam (); 53: struct group *getgrnam (); /* check validity of name/group */ 54: FILE * acs, *fopen (); /* stream I/O */ 55: char fn[WDLEN]; 56: struct auth_f me; /* for detecting suicidals */ 57: struct perm_f alist[NPERMS]; /* hold the access list */ 58: 59: int items, 60: base, 61: i, 62: which, 63: changed; 64: char c; 65: short ptype; 66: char zname[NAMESZ + 1]; /* hold new user */ 67: 68: 69: sprintf (fn, "%s/%s/%s", io -> basedir, io -> nf, ACCESS);/* file name */ 70: x ((acs = fopen (fn, "r")) == NULL, "access: no access file"); 71: x ((items = fread (alist, sizeof entry, NPERMS, acs)) == 0, "access: empty file"); 72: fclose (acs); /* and close the file */ 73: changed = 0; /* no changes made to the list yet */ 74: length = nrows - 6; /* max to show */ 75: base = 0; /* which part are we displaying */ 76: erase (); 77: plotit (alist, base, items); 78: while (1) 79: { 80: at (-1, 1); 81: printf ("Option: "); 82: c = gchar (); /* grab command */ 83: printf ("\b \b"); /* overwrite */ 84: switch (c) 85: { 86: case '?': 87: case 'h': 88: help (ACCHLP); /* print the help page */ 89: goto redraw; /* replot the screen */ 90: 91: case '!': /* fork a shell for him */ 92: gshell (); 93: goto redraw; 94: 95: #ifdef K_KEY 96: case 'K': /* same as Q */ 97: #endif K_KEY 98: case 'Q': 99: return 0; /* return to the caller */ 100: 101: case '\004': /* abort notefiles */ 102: return QUITFAST; 103: 104: #ifdef K_KEY 105: case 'k': /* same as q */ 106: #endif K_KEY 107: case 'q': /* update lists (if changed) and leave) */ 108: if (changed) 109: { 110: acssort (alist, items); /* order them */ 111: x ((acs = fopen (fn, "w")) == NULL, "access: reopen"); 112: x (fwrite (alist, sizeof entry, items, acs) != items, "access:update write"); 113: fclose (acs); /* and close the file */ 114: } 115: return 0; 116: 117: case '-': /* scroll display backwards */ 118: base -= length / 2 - 1; /* back a half sreen */ 119: if (base < 0) 120: base = 0; /* don't pass zero */ 121: goto redraw; 122: 123: case '+': /* scroll display forwards */ 124: base += length / 2 - 1; /* up half screen */ 125: if (base >= items - (length / 2)) /* try to keep full */ 126: { 127: base = items - (length - 3); /* don't over-run */ 128: /* 129: * Gotta subtract 3: one for OBOE and two for the "-more-" message 130: * that might be there. 131: */ 132: if (base < 0) 133: base = 0; /* careful */ 134: } 135: goto redraw; 136: 137: case 's': /* sort and replot the list */ 138: acssort (alist, items); /* do the sort */ 139: /* and fall through to ... */ 140: break; 141: 142: case 'r': /* replot the lists */ 143: case '\014': /* everyone else uses ^L, might as well */ 144: redraw: 145: erase (); 146: plotit (alist, base, items); 147: break; /* back to command sucker */ 148: 149: case 'i': /* enter a bunch of permissions */ 150: while (items < NPERMS) /* not if all full */ 151: { 152: reget: at (-4, 40); 153: printf ("Entry type: \b"); 154: if ((c = gchar ()) == '\n' || c == 'q' || c == 'k') 155: break; /* get out */ 156: switch (c) 157: { 158: case 'u': 159: ptype = PERMUSER; 160: break; 161: case 'g': 162: ptype = PERMGROUP; 163: break; 164: case 's': 165: ptype = PERMSYSTEM; 166: break; 167: default: 168: printf ("\07 (u,g,s, q,k,<cr>)"); 169: goto reget; 170: } 171: at (-3, 40); 172: printf ("Name: \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 173: if (gline (zname, NAMESZ) == 1) 174: continue; /* null name */ 175: if (ptype == PERMUSER && strcmp ("Other", zname) != 0) 176: { 177: if (getpwnam (zname) == NULL) 178: { 179: at (-2, 40); 180: printf ("--No such user--"); 181: continue; 182: } 183: } 184: if (ptype == PERMGROUP && strcmp ("Other", zname) != 0) 185: { 186: if (getgrnam (zname) == NULL) 187: { 188: at (-2, 40); 189: printf ("--No such group--"); 190: continue; 191: } 192: } 193: /* 194: * make sure that it isn't already there. 195: */ 196: 197: for (i = 0; i < items; i++) 198: if (alist[i].ptype == ptype && strcmp (alist[i].name, zname) == 0) 199: { 200: at (-2, 40); 201: printf ("%s entry exists", zname); 202: goto reget; 203: } 204: 205: alist[items].perms = DFLTPERMS; /* give him default */ 206: getmode (&alist[items].perms); 207: alist[items].ptype = ptype; 208: strmove (zname, alist[items].name); /* copy things over */ 209: items++; 210: changed = 1; /* and set flags */ 211: acssort (alist, items); 212: erase (); /* clean screen */ 213: plotit (alist, base, items); /* show new list */ 214: } 215: endpwent (); 216: endgrent (); /* close passwd and group files */ 217: break; 218: 219: 220: case 'd': /* delete some permissions */ 221: at (-1, 1); 222: printf ("Delete entry #: "); 223: if ((c = gchar ()) == '\n') 224: break; /* null */ 225: printf ("\b"); 226: which = getnum (c); /* grab number */ 227: if (which <= 0) 228: break; /* don't update */ 229: if (which > items || c < '0' || c > '9') 230: { 231: printf ("Bad entry"); 232: break; 233: } 234: which--; /* adjust to zero base */ 235: getname (&me, 0); /* grab my name */ 236: if ((alist[which].ptype = PERMUSER) && strcmp (me.aname, alist[which].name) == 0) 237: { 238: printf (" Can't Delete self"); 239: break; 240: } 241: items--; /* decrement count and */ 242: for (i = which; i < items; i++) /* tamp down list */ 243: { 244: alist[i].ptype = alist[i + 1].ptype; 245: strmove (alist[i + 1].name, alist[i].name); 246: alist[i].perms = alist[i + 1].perms; 247: } 248: changed = 1; /* mark it as changed */ 249: goto redraw; /* show updated screen */ 250: 251: case 'm': /* modify someones permission */ 252: at (-1, 1); /* grab which slot */ 253: printf ("Modify entry #: "); 254: if ((c = gchar ()) == '\n') 255: break; /* null entry */ 256: printf ("\b"); 257: which = getnum (c); 258: if (which <= 0) 259: break; 260: if (which > items || c < '0' || c > '9')/* check its validity */ 261: { 262: at (-2, 1); 263: printf ("Bad entry"); 264: break; 265: } 266: which--; /* adjust to zero base */ 267: getmode (&alist[which].perms); 268: changed = 1; /* set changed flag */ 269: goto redraw; /* repaint screen */ 270: 271: default: /* wrong key dummy */ 272: printf ("\07"); 273: break; 274: } 275: } 276: } 277: 278: /* 279: * Grab a set of permissions 280: */ 281: getmode (zmode) 282: short *zmode; 283: { /* grab a mode from the tty */ 284: char c; 285: short mode; /* resulting mode */ 286: 287: mode = *zmode; /* set to what passed in */ 288: 289: while (1) 290: { 291: at (-2, 40); 292: printf ("%*s", 25, " "); 293: at (-2, 40); 294: printf (" Mode: %s", map[mode]); 295: at (-1, 40); 296: printf ("Mods: "); 297: c = gchar (); 298: switch (c) 299: { 300: case 'a': /* toggle answer */ 301: if (mode & WRITOK) 302: break; /* write supersedese */ 303: if (mode & RESPOK) 304: mode &= NOT RESPOK; 305: else 306: mode |= RESPOK; 307: break; 308: 309: case 'r': /* toggle read */ 310: if (mode & DRCTOK) 311: break; /* director supersedes */ 312: if (mode & READOK) 313: mode &= NOT READOK; 314: else 315: mode |= READOK; 316: break; 317: 318: case 'w': /* toggle write */ 319: if (mode & DRCTOK) 320: break; /* director supersedes */ 321: if (mode & WRITOK) 322: mode &= NOT WRITOK; 323: else 324: mode |= WRITOK + RESPOK; 325: break; 326: 327: case 'd': /* toggle director */ 328: if (mode & DRCTOK) 329: mode &= NOT DRCTOK; 330: else 331: mode |= DRCTOK + READOK + WRITOK + RESPOK; 332: break; 333: 334: case 'n': /* set to null */ 335: mode = 0; 336: break; 337: 338: case '\n': /* acceptable to him */ 339: #ifdef K_KEY 340: case 'k': /* same as q */ 341: case 'K': 342: #endif K_KEY 343: case 'q': 344: case 'Q': 345: return (*zmode = mode); /* do both ways */ 346: 347: default: 348: printf ("\07 (d,r,w,a,n,q,k<cr>)"); 349: break; 350: } 351: } 352: } 353: plotit (alist, base, items) /* plot the list */ 354: struct perm_f alist[]; 355: int base; 356: int items; 357: { 358: register int atrow, 359: atcol, 360: i; 361: 362: atrow = 1; 363: atcol = 1; 364: if (base != 0) 365: { 366: at (atrow++, atcol); 367: printf (" -- More -- "); 368: } 369: for (i = base; i < items && atrow < length; i++) 370: { 371: at (atrow++, atcol); 372: printf ("%2d %s%-*s %s", i + 1, kmap[alist[i].ptype], NAMESZ, 373: alist[i].name, map[alist[i].perms]); 374: } 375: if (i < items) /* tell him more */ 376: { 377: at (atrow++, atcol); 378: printf (" -- More -- "); 379: } 380: }