1: # include   <ingres.h>
   2: # include   <aux.h>
   3: # include   <catalog.h>
   4: # include   <access.h>
   5: # include   <tree.h>
   6: # include   <symbol.h>
   7: # include   <lock.h>
   8: # include   <pv.h>
   9: # include   <func.h>
  10: # include   "qrymod.h"
  11: # include   <sccs.h>
  12: # include   <errors.h>
  13: 
  14: SCCSID(@(#)d_prot.c	8.3	2/8/85)
  15: 
  16: 
  17: 
  18: /*
  19: **  D_PROT -- define protection constraint
  20: **
  21: **	A protection constraint as partially defined by the last tree
  22: **	defined by d_tree is defined.
  23: **
  24: **	The stuff that comes through the pipe as parameters is complex.
  25: **	It comes as a sequence of strings:
  26: **	 # The operation set, already encoded in the parser into a
  27: **	   bit map.  If the PRO_RETR permission is set, the PRO_TEST
  28: **	   and PRO_AGGR permissions will also be set.
  29: **	 # The relation name.
  30: **	 # The relation owner.
  31: **	 # The user name.  This must be a user name as specified in
  32: **	   the 'users' file, or the keyword 'all', meaning all users.
  33: **	 # The terminal id.  Must be a string of the form 'ttyx' or
  34: **	   the keyword 'all'.
  35: **	 # The starting time of day, as minutes-since-midnight.
  36: **	 # The ending time of day.
  37: **	 # The starting day-of-week, with 0 = Sunday.
  38: **	 # The ending dow.
  39: **
  40: **	The domain reference set is build automatically from the
  41: **	target list of the tree.  Thus, the target list must exist,
  42: **	but it is not inserted into the tree.  The target list must
  43: **	be a flat sequence of RESDOM nodes with VAR nodes hanging
  44: **	of the rhs; also, the VAR nodes must all be for Qt.qt_resvar.
  45: **	If there is no target list on the tree, the set of all var-
  46: **	iables is assumed.
  47: **
  48: **	The relstat field in the relation relation is updated to
  49: **	reflect any changes.
  50: **
  51: **	It only makes sense for the DBA to execute this command.
  52: **
  53: **	If there is one of the special cases
  54: **		permit all to all
  55: **		permit retrieve to all
  56: **	it is caught, and the effect is achieved by diddling
  57: **	relstat bits instead of inserting into the protect catalog.
  58: **
  59: **	Parameters:
  60: **		none
  61: **
  62: **	Returns:
  63: **		none
  64: **
  65: **	Side Effects:
  66: **		Activity in 'protect' and 'relation' catalogs.
  67: **
  68: **	Trace Flags:
  69: **		59
  70: */
  71: 
  72: extern struct admin Admin;
  73: extern DESC     Prodes;
  74: extern DESC     Reldes;
  75: 
  76: extern      d_prot(), null_fn();
  77: extern short    tTqm[80];
  78: 
  79: struct fn_def   DefProFn =
  80: {
  81:     "DPROT",
  82:     d_prot,
  83:     null_fn,
  84:     null_fn,
  85:     NULL,
  86:     0,
  87:     tTqm,
  88:     80,
  89:     'Q',
  90:     0
  91: };
  92: 
  93: d_prot(pc, pv)
  94: int pc;
  95: PARM    *pv;
  96: {
  97:     struct protect  protup;
  98:     struct tup_id   protid;
  99:     struct protect  prokey;
 100:     struct protect  proxtup;
 101:     char        buf[30];
 102:     char        ubuf[MAXLINE + 1];
 103:     register int    i;
 104:     auto short  ix;
 105:     int     treeid;
 106:     register QTREE  *t;
 107:     QTREE       *root;
 108:     register char   *p;
 109:     struct relation reltup;
 110:     struct relation relkey;
 111:     struct tup_id   reltid;
 112:     int     relstat;
 113:     int     all_pro;
 114: 
 115:     /*
 116: 	**  Fill in the protection tuple with the information
 117: 	**	from the parser, validating as we go.
 118: 	**
 119: 	**	Also, determine if we have a PERMIT xx to ALL
 120: 	**	with no further qualification case.  The variable
 121: 	**	'all_pro' is set to reflect this.
 122: 	*/
 123: 
 124:     clr_tuple(&Prodes, &protup);
 125:     all_pro = TRUE;
 126: 
 127:     /* read operation set */
 128:     if (pv->pv_type != PV_INT)
 129:         syserr("d_prot: opset");
 130:     protup.proopset = pv->pv_val.pv_int;
 131:     if ((protup.proopset & PRO_RETR) != 0)
 132:         protup.proopset |= PRO_TEST | PRO_AGGR;
 133:     pv++;
 134: 
 135:     /* read relation name */
 136:     if (pv->pv_type != PV_STR)
 137:         syserr("d_prot: relid");
 138:     pmove(pv->pv_val.pv_str, protup.prorelid, MAXNAME, ' ');
 139:     pv++;
 140: 
 141:     /* read relation owner */
 142:     if (pv->pv_type != PV_STR)
 143:         syserr("d_prot: relid");
 144:     bmove(pv->pv_val.pv_str, protup.prorelown, 2);
 145:     pv++;
 146: 
 147:     /* read user name */
 148:     if (pv->pv_type != PV_STR)
 149:         syserr("d_prot: user");
 150:     if (sequal(pv->pv_val.pv_str, "all"))
 151:         bmove("  ", protup.prouser, 2);
 152:     else
 153:     {
 154:         /* look up user in 'users' file */
 155:         if (getnuser(pv->pv_val.pv_str, ubuf))
 156:             qmerror(BADUSRNAME, -1, Qt.qt_resvar, pv->pv_val.pv_str, 0);
 157:         for (p = ubuf; *p != ':' && *p != 0; p++)
 158:             continue;
 159:         bmove(++p, protup.prouser, 2);
 160:         if (p[0] == ':' || p[1] == ':' || p[2] != ':')
 161:             syserr("d_prot: users %s", ubuf);
 162:         all_pro = FALSE;
 163:     }
 164:     pv++;
 165: 
 166:     /* read terminal id */
 167:     if (pv->pv_type != PV_STR)
 168:         syserr("d_prot: user");
 169:     if (sequal(pv->pv_val.pv_str, "all"))
 170:         pmove("", protup.proterm, sizeof protup.proterm, ' ');
 171:     else
 172:     {
 173:         pmove(pv->pv_val.pv_str, protup.proterm, sizeof protup.proterm, ' ');
 174:         if (!isttyname(pv->pv_val.pv_str))
 175:             qmerror(BADTERM, -1, Qt.qt_resvar, pv->pv_val.pv_str, 0);
 176:         all_pro = FALSE;
 177:     }
 178:     pv++;
 179: 
 180:     /* read starting time of day */
 181:     if (pv->pv_type != PV_INT)
 182:         syserr("d_prot: btod");
 183:     protup.protodbgn = pv->pv_val.pv_int;
 184:     if (pv->pv_val.pv_int > 0)
 185:         all_pro = FALSE;
 186:     pv++;
 187: 
 188:     /* read ending time of day */
 189:     if (pv->pv_type != PV_INT)
 190:         syserr("d_prot: etod");
 191:     protup.protodend = pv->pv_val.pv_int;
 192:     if (pv->pv_val.pv_int < 24 * 60 - 1)
 193:         all_pro = FALSE;
 194:     pv++;
 195: 
 196:     /* read beginning day of week */
 197:     if (pv->pv_type != PV_STR)
 198:         syserr("d_prot: bdow");
 199:     i = cvt_dow(pv->pv_val.pv_str);
 200:     if (i < 0)
 201:         qmerror(BADDOW, -1, Qt.qt_resvar, pv->pv_val.pv_str, 0);    /* bad dow */
 202:     protup.prodowbgn = i;
 203:     if (i > 0)
 204:         all_pro = FALSE;
 205:     pv++;
 206: 
 207:     /* read ending day of week */
 208:     if (pv->pv_type != PV_STR)
 209:         syserr("d_prot: edow");
 210:     i = cvt_dow(pv->pv_val.pv_str);
 211:     if (i < 0)
 212:         qmerror(BADDOW, -1, Qt.qt_resvar, pv->pv_val.pv_str, 0);    /* bad dow */
 213:     protup.prodowend = i;
 214:     if (i < 6)
 215:         all_pro = FALSE;
 216:     pv++;
 217: 
 218:     /*
 219: 	**  Check for valid tree:
 220: 	**	There must be a tree defined, and all variables
 221: 	**	referenced must be owned by the current user; this
 222: 	**	is because you could otherwise get at data by
 223: 	**	mentioning it in a permit statement; see protect.c
 224: 	**	for a better explanation of this.
 225: 	*/
 226: 
 227:     if (pv->pv_type != PV_QTREE)
 228:         syserr("d_prot: tree");
 229:     root = (QTREE *) pv->pv_val.pv_qtree;
 230:     pv++;
 231: 
 232:     for (i = 0; i < MAXVAR + 1; i++)
 233:     {
 234:         if (Qt.qt_rangev[i].rngvdesc == NULL)
 235:             continue;
 236:         if (!bequal(Qt.qt_rangev[i].rngvdesc->reldum.relowner, Usercode, UCODE_SZ))
 237:             qmerror(OWNEDNOT, -1, i, 0);
 238:     }
 239: 
 240:     /* test for dba */
 241:     if (!bequal(Usercode, Admin.adhdr.adowner, UCODE_SZ))
 242:         qmerror(NOTDBA, -1, Qt.qt_resvar, 0);
 243: 
 244:     /* get domain reference set from target list */
 245:     /* (also, find the TREE node) */
 246:     t = root->left;
 247:     if (t->sym.type == TREE)
 248:     {
 249:         for (i = 0; i < 8; i++)
 250:             protup.prodomset[i] = -1;
 251:     }
 252:     else
 253:     {
 254:         for (i = 0; i < 8; i++)
 255:             protup.prodomset[i] = 0;
 256:         for (; t->sym.type != TREE; t = t->left)
 257:         {
 258:             if (t->right->sym.type != VAR ||
 259:                 t->sym.type != RESDOM ||
 260:                 t->right->sym.value.sym_var.varno != Qt.qt_resvar)
 261:                 syserr("d_prot: garbage tree");
 262:             lsetbit(t->right->sym.value.sym_var.attno, protup.prodomset);
 263:         }
 264:         all_pro = FALSE;
 265:     }
 266: 
 267:     /* trim off the target list, since it isn't used again */
 268:     root->left = t;
 269: 
 270:     /*
 271: 	**  Check out the target relation.
 272: 	**	We first save the varno of the relation which is
 273: 	**	getting the permit stuff.  Also, we check to see
 274: 	**	that the relation mentioned is a base relation,
 275: 	**	and not a view, since that tuple would never do
 276: 	**	anything anyway.  Finally, we clear the Qt.qt_resvar
 277: 	**	so that it does not get output to the tree catalog.
 278: 	**	This would result in a 'syserr' when we tried to
 279: 	**	read it.
 280: 	*/
 281: 
 282:     protup.proresvar = Qt.qt_resvar;
 283: #	ifdef xQTR3
 284:     if (Qt.qt_resvar < 0)
 285:         syserr("d_prot: Rv %d", Qt.qt_resvar);
 286: #	endif
 287:     if (bitset(S_VIEW, Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relstat))
 288:         qmerror(NOTREALREL, -1, Qt.qt_resvar, 0);   /* is a view */
 289: 
 290:     /* clear the (unused) Qt.qt_qmode */
 291: #	ifdef xQTR3
 292:     if (Qt.qt_qmode != mdPROT)
 293:         syserr("d_prot: Qt.qt_qmode %d", Qt.qt_qmode);
 294: #	endif
 295:     Qt.qt_qmode = -1;
 296: 
 297:     /*
 298: 	**  Check for PERMIT xx to ALL case.
 299: 	**	The relstat bits will be adjusted as necessary
 300: 	**	to reflect these special cases.
 301: 	**
 302: 	**	This is actually a little tricky, since we cannot
 303: 	**	afford to turn off any permissions.  If we already
 304: 	**	have some form of PERMIT xx to ALL access, we must
 305: 	**	leave it.
 306: 	*/
 307: 
 308:     relstat = Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relstat;
 309:     if (all_pro && (protup.proopset & PRO_RETR) != 0)
 310:     {
 311:         if (protup.proopset == -1)
 312:             relstat &= ~S_PROTALL;
 313:         else
 314:         {
 315:             relstat &= ~S_PROTRET;
 316:             if ((protup.proopset & ~(PRO_RETR|PRO_AGGR|PRO_TEST)) != 0)
 317:             {
 318:                 /* some special case: still insert prot tuple */
 319:                 all_pro = FALSE;
 320:             }
 321:         }
 322:     }
 323:     else
 324:         all_pro = FALSE;
 325: 
 326:     /* see if we are adding any tuples */
 327:     if (!all_pro)
 328:         relstat |= S_PROTUPS;
 329: 
 330:     /*
 331: 	**  Change relstat field in relation catalog if changed
 332: 	*/
 333: 
 334:     if (relstat != Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relstat)
 335:     {
 336:         opencatalog("relation", OR_WRITE);
 337:         setkey(&Reldes, &relkey, Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relid, RELID);
 338:         setkey(&Reldes, &relkey, Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relowner, RELOWNER);
 339:         i = getequal(&Reldes, &relkey, &reltup, &reltid);
 340:         if (i != 0)
 341:             syserr("d_prot: geteq %d", i);
 342:         reltup.relstat = relstat;
 343:         i = replace(&Reldes, &reltid, &reltup, FALSE);
 344:         if (i != 0)
 345:             syserr("d_prot: repl %d", i);
 346:         if (noclose(&Reldes) != 0)
 347:             syserr("d_prot: noclose(rel)");
 348:     }
 349: 
 350:     Qt.qt_resvar = -1;
 351: 
 352:     if (!all_pro)
 353:     {
 354:         /*
 355: 		**  Output the created tuple to the protection catalog
 356: 		**  after making other internal adjustments and deter-
 357: 		**  mining a unique sequence number (with the protect
 358: 		**  catalog locked).
 359: 		*/
 360: 
 361:         if (root->right->sym.type != QLEND)
 362:             protup.protree = puttree(root, protup.prorelid, protup.prorelown, mdPROT);
 363:         else
 364:             protup.protree = -1;
 365: 
 366:         /* compute unique permission id */
 367:         opencatalog("protect", OR_WRITE);
 368:         setrll(A_SLP, Prodes.reltid.ltid, M_EXCL);
 369:         setkey(&Prodes, &prokey, protup.prorelid, PRORELID);
 370:         setkey(&Prodes, &prokey, protup.prorelown, PRORELOWN);
 371:         for (ix = 2; ; ix++)
 372:         {
 373:             setkey(&Prodes, &prokey, &ix, PROPERMID);
 374:             i = getequal(&Prodes, &prokey, &proxtup, &protid);
 375:             if (i < 0)
 376:                 syserr("d_prot: geteq");
 377:             else if (i > 0)
 378:                 break;
 379:         }
 380:         protup.propermid = ix;
 381: 
 382:         /* do actual insert */
 383:         i = insert(&Prodes, &protid, &protup, FALSE);
 384:         if (i < 0)
 385:             syserr("d_prot: insert");
 386:         if (noclose(&Prodes) != 0)
 387:             syserr("d_prot: noclose(pro)");
 388: 
 389:         /* clear the lock */
 390:         unlrl(Prodes.reltid.ltid);
 391:     }
 392: }
 393: /*
 394: **  CVT_DOW -- convert day of week
 395: **
 396: **	Converts the day of the week from string form to a number.
 397: **
 398: **	Parameters:
 399: **		sdow -- dow in string form.
 400: **
 401: **	Returns:
 402: **		0 -> 6 -- the encoded day of the week.
 403: **		-1 -- error.
 404: **
 405: **	Side Effects:
 406: **		none
 407: **
 408: **	Defines:
 409: **		Dowlist -- a mapping from day of week to number.
 410: **		cvt_dow
 411: **
 412: **	Called By:
 413: **		d_prot
 414: */
 415: 
 416: struct downame
 417: {
 418:     char    *dow_name;
 419:     int dow_num;
 420: };
 421: 
 422: struct downame  Dowlist[] =
 423: {
 424:     "sun",      0,
 425:     "sunday",   0,
 426:     "mon",      1,
 427:     "monday",   1,
 428:     "tue",      2,
 429:     "tues",     2,
 430:     "tuesday",  2,
 431:     "wed",      3,
 432:     "wednesday",    3,
 433:     "thu",      4,
 434:     "thurs",    4,
 435:     "thursday", 4,
 436:     "fri",      5,
 437:     "friday",   5,
 438:     "sat",      6,
 439:     "saturday", 6,
 440:     NULL
 441: };
 442: 
 443: cvt_dow(sdow)
 444: char    *sdow;
 445: {
 446:     register struct downame *d;
 447:     register char       *s;
 448: 
 449:     s = sdow;
 450: 
 451:     for (d = Dowlist; d->dow_name != NULL; d++)
 452:         if (sequal(d->dow_name, s))
 453:             return (d->dow_num);
 454:     return (-1);
 455: }
 456: /*
 457: **  ISTTYNAME -- "is a legal terminal name" predicate
 458: **
 459: **	Returns TRUE if the argument is a legal terminal name,
 460: **	otherwise FALSE.
 461: **
 462: **	It may make sense to have this routine check if the given
 463: **	file name really exists.
 464: **
 465: **	WARNING:
 466: **		This routine may be installation-dependent!
 467: **
 468: **	Parameters:
 469: **		n -- the name to check.
 470: **
 471: **	Returns:
 472: **		TRUE -- n is a legal tty name at this installation.
 473: **		FALSE -- otherwise.
 474: **
 475: **	Side Effects:
 476: **		none
 477: **
 478: **	History:
 479: **		8/1/79 (eric) -- written.
 480: */
 481: 
 482: 
 483: isttyname(n)
 484: register char   *n;
 485: {
 486:     return (sequal(n, "console") || bequal(n, "tty", 3));
 487: }

Defined functions

cvt_dow defined in line 443; used 2 times
d_prot defined in line 93; used 2 times
isttyname defined in line 483; used 1 times

Defined variables

DefProFn defined in line 79; never used
Dowlist defined in line 422; used 1 times

Defined struct's

downame defined in line 416; used 4 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1293
Valid CSS Valid XHTML 1.0 Strict