access.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:8k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *   access.c - priviledge checking and some semantic
  3.  *              constrait checking 
  4.  *              GNU SQL server
  5.  *
  6.  *  This file is a part of GNU SQL Server
  7.  *
  8.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  9.  *  Developed at the Institute of System Programming
  10.  *  This file is written by Eugene W. Woynov, 1994
  11.  *  Rewritten by Michael Kimelman, 1995
  12.  *
  13.  *  This program is free software; you can redistribute it and/or modify
  14.  *  it under the terms of the GNU General Public License as published by
  15.  *  the Free Software Foundation; either version 2 of the License, or
  16.  *  (at your option) any later version.
  17.  *
  18.  *  This program is distributed in the hope that it will be useful,
  19.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  *  GNU General Public License for more details.
  22.  *
  23.  *  You should have received a copy of the GNU General Public License
  24.  *  along with this program; if not, write to the Free Software
  25.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  26.  *
  27.  *  Contacts:  gss@ispras.ru
  28.  *
  29.  */
  30. /* $Id: access.c,v 1.246 1997/04/24 17:46:44 kml Exp $ */
  31. #include "setup_os.h"
  32. #if STDC_HEADERS
  33. # include <string.h>
  34. #else
  35. # ifndef HAVE_STRCHR
  36. #  define strchr index
  37. # endif
  38. char *strchr ();
  39. #endif
  40. #include "global.h"
  41. #include "seman.h"
  42. #include "funall.h"
  43. #include "cycler.h"
  44. #include "tassert.h"
  45. #include <assert.h>
  46. #define ACT_SELECT       "S"
  47. #define ACT_INSERT       "I"
  48. #define ACT_DELETE       "D"
  49. #define ACT_UPDATE       "U"
  50. #define ACT_GRANT        "G"
  51. #define ACT_REFERENCES   "R"
  52. typedef struct 
  53. {
  54.   char      author[7];
  55.   i4_t      *ulist;
  56.   i4_t       ui;
  57.   i4_t      *rlist;
  58.   i4_t       ri;
  59.   TXTREF    tbl;
  60.   TXTREF    tblptr;
  61. } tbl_pvlg_t;
  62. #define AUTH_CHK(n,a) 
  63.        auth_chk(n,a,NAME(CODE_TRN(cnode)),LOCATION_TRN(cnode))
  64. #define TYPE_ERR(msg)   
  65.        SERROR_MSG(1,LOCATION_TRN(cnode),msg)
  66. #define THE_SAME(s1,s2)  (!strcmp(s1,s2)) /* ==0 */
  67. static TXTREF
  68. check_author(tbl_pvlg_t *p)
  69. {
  70.   if(!p || !p->tbl)
  71.     return TNULL;
  72.   switch(CODE_TRN(p->tbl))
  73.     {
  74.     case TMPTABLE:
  75.       if (!THE_SAME(p->author,ACT_SELECT))
  76.         goto end; /* can't be done */
  77.     case VIEW:
  78.       if (TstF_TRN(VIEW_QUERY(p->tbl),RO_F) &&
  79.           !THE_SAME(p->author,ACT_SELECT) &&
  80.           !THE_SAME(p->author,ACT_REFERENCES))
  81.         goto end;
  82.     case TABLE:
  83.       if (THE_SAME (STRING (GL_AUTHOR), STRING (TBL_FNAME (p->tbl))))
  84.         p->tbl = TNULL;
  85.       else if ( THE_SAME ("DEFINITION_SCHEMA" ,STRING (TBL_FNAME (p->tbl))) &&
  86.                 THE_SAME ("INFORMATION_SCHEMA",STRING (GL_AUTHOR)))
  87.         p->tbl = TNULL;
  88.       else if (0==tabpvlg ((TBL_TABID (p->tbl)).untabid,STRING (GL_AUTHOR),
  89.                            p->author, p->ui, p->ulist, p->ri, p->rlist))
  90.         p->tbl = TNULL;
  91.       break;
  92.     default:
  93.       yyfatal("");
  94.     }
  95.   
  96. end:
  97.   
  98.   if (p->ulist)
  99.     xfree (p->ulist);
  100.   if (p->rlist)
  101.     xfree (p->rlist);
  102.   p->author[0] =0;
  103.   p ->ui = p->ri = 0;
  104.   return p->tbl;
  105. }
  106. static void
  107. check_update(TXTREF asslist, tbl_pvlg_t *p)
  108. {
  109.   TXTREF  assign;
  110.   i4_t     i;
  111.   enum token code = CODE_TRN(asslist);
  112.   
  113.   TASSERT((code == ASSLIST) ||
  114.           (code == UPDATE)  ||
  115.           (code == REFERENCE),
  116.           asslist);
  117.     
  118.   assign = DOWN_TRN (asslist);
  119.   if (code == REFERENCE)
  120.     {
  121.       TASSERT(p->rlist == NULL, asslist);
  122.       p->ri = ARITY_TRN(asslist);
  123.       p->rlist = (i4_t *) xmalloc (p->ri * sizeof (i4_t));
  124.     }
  125.   else
  126.     {
  127.       TASSERT(p->ulist == NULL, asslist);
  128.       p->ui = ARITY_TRN(asslist);
  129.       p->ulist = (i4_t *) xmalloc (p->ui * sizeof (i4_t));
  130.     }
  131.   
  132.   for (i=0;assign;i++, assign = RIGHT_TRN (assign))
  133.     {
  134.       TXTREF scol = TNULL, tabl = TNULL;
  135.       enum token code1 = CODE_TRN(assign);
  136.       if (code == ASSLIST)
  137.         {
  138.           TASSERT(code1 == ASSIGN, asslist);
  139.           scol = OBJ_DESC (DOWN_TRN (assign));
  140.           TASSERT(CODE_TRN(scol) == SCOLUMN,asslist);
  141.           tabl = COR_TBL (COL_TBL (scol));
  142.         }
  143.       else /* UPDATE or REFERENCE */
  144.         {
  145.           TASSERT(code1 == COLPTR, asslist);
  146.           scol = OBJ_DESC (assign);
  147.           TASSERT(CODE_TRN(scol) == COLUMN,asslist);
  148.           tabl = COL_TBL (scol);
  149.         }
  150.       TASSERT(tabl,assign);
  151.       if(p->tbl == TNULL)
  152.         p->tbl = tabl;
  153.       TASSERT( tabl == p->tbl, asslist);
  154.       if(code==REFERENCE)
  155.         p->rlist[i] = COL_NO (scol);
  156.       else
  157.         p->ulist[i] = COL_NO (scol);
  158.     }
  159.   {
  160.     char *act = (CODE_TRN(asslist)==REFERENCE?ACT_REFERENCES : ACT_UPDATE);
  161.     if (!strstr(p->author,act))
  162.       strcat(p->author,act);
  163.   }
  164. }
  165. static TXTREF
  166. check_act (TXTREF node, char *author)
  167. {
  168.   tbl_pvlg_t t1;
  169.   bzero(&t1,sizeof(t1));
  170.   
  171.   if ( THE_SAME(author,ACT_UPDATE) || THE_SAME(author,ACT_REFERENCES))
  172.     {
  173.       check_update(node,&t1);
  174.       return check_author(&t1);
  175.     }
  176.   switch(CODE_TRN(node))
  177.     {
  178.     case SCAN:
  179.       t1.tbl = COR_TBL(node); break;
  180.     case TABLE:
  181.     case VIEW:
  182.       t1.tbl = node; break;
  183.     default:
  184.       yyfatal("Unexpected node checked");
  185.     }
  186.   strcpy(t1.author,author);
  187.   node = check_author(&t1);
  188.   return node;
  189. }
  190. static void
  191. auth_chk(TXTREF node,char *act,char *text,i4_t where)
  192. {
  193.   TXTREF errtbl;
  194.   errtbl  = check_act (node, act);
  195.   if (errtbl)
  196.     {
  197.       char err[100];
  198.       sprintf(err,"permission denied to %s table '%s.%s'",
  199.               text,
  200.               STRING (TBL_FNAME(errtbl)),
  201.               STRING(TBL_NAME(errtbl)));
  202.       SERROR_MSG(1,where,err);
  203.     }
  204. }
  205. TXTREF
  206. ac_proc(TXTREF cnode,i4_t f)
  207. {
  208.   TXTREF t;
  209.   if (f==0)
  210.     cnode = cycler(cnode, ac_proc, CYCLER_LD);
  211.   else if (f == CYCLER_LD)
  212.     switch(CODE_TRN(cnode))
  213.       {
  214.       case FROM:
  215.         for(t=DOWN_TRN(cnode);t; t = RIGHT_TRN(t))
  216.           auth_chk(TABL_DESC(t),ACT_SELECT,"select",LOCATION_TRN(t));
  217.         cycler_skip_subtree = 1;
  218.         break;
  219.       case TBLPTR:
  220.         t = cnode;
  221.         auth_chk(TABL_DESC(t),ACT_SELECT,"select",LOCATION_TRN(t));
  222.         break;
  223.       default: break;
  224.       }
  225.   return cnode;
  226. }
  227. CODERT
  228. access_main (TXTREF root)
  229. {
  230.   static TXTREF cursor;
  231.   static TXTREF gr_table;
  232.   TXTREF cnode;
  233.   for (cnode = root; cnode; cnode = RIGHT_TRN (cnode))
  234.     {
  235.       if(Is_Statement(cnode))   
  236.         ac_proc(cnode,0);      /* check selection rights */
  237.       switch(CODE_TRN(cnode))
  238.         {
  239.         case CUR_AREA:
  240.           cursor = STMT_VCB(cnode);
  241.           access_main(DOWN_TRN(cnode));
  242.           cursor = TNULL;
  243.           break;
  244.         case DECL_CURS:
  245.         case FETCH:
  246.           break;
  247.         case SELECT:
  248.           if (gr_table)
  249.             AUTH_CHK(gr_table,ACT_SELECT);
  250.           break;
  251.         case DELETE:
  252.           AUTH_CHK((gr_table? gr_table : TABL_DESC(DOWN_TRN(cnode))),ACT_DELETE);
  253.           break;
  254.         case INSERT:
  255.           AUTH_CHK((gr_table? gr_table : TABL_DESC(DOWN_TRN(cnode))),ACT_INSERT);
  256.           break;
  257.         case UPDATE:
  258.           AUTH_CHK( (gr_table? cnode : RIGHT_TRN(DOWN_TRN(cnode))), ACT_UPDATE);
  259.           break;
  260.         case ALTER:
  261.         case CREATE:
  262.           if(CODE_TRN(CREATE_OBJ(cnode))==VIEW)
  263.             /* check rights to see source tables for view */
  264.             ac_proc(VIEW_QUERY(CREATE_OBJ(cnode)),0);
  265.           break;
  266.         case GRANT:
  267.           {
  268.             TXTREF refer = RIGHT_TRN(DOWN_TRN(cnode));
  269.             TASSERT(CODE_TRN(refer) == PRIVILEGIES, cnode);
  270.             gr_table = TABL_DESC(DOWN_TRN(cnode));
  271.             if (ARITY_TRN(refer)>0) 
  272.               access_main(DOWN_TRN(refer));
  273.             else /* check all privileges */
  274.               auth_chk(gr_table,"SDIURG","do all",LOCATION_TRN(cnode));
  275.             gr_table = TNULL;
  276.           }  
  277.           break;
  278.         case REFERENCE:
  279.           AUTH_CHK( cnode, ACT_REFERENCES);
  280.           break;
  281.         case DROP:
  282.           if (strcmp (STRING (GL_AUTHOR), STRING (TBL_FNAME (CREATE_OBJ(cnode)))))
  283.             {
  284.               char err[100];
  285.               sprintf(err,"permission denied to DROP table '%s.%s'",
  286.                       STRING(TBL_FNAME(CREATE_OBJ(cnode))),
  287.                       STRING(TBL_NAME (CREATE_OBJ(cnode))));
  288.               SERROR_MSG(1,LOCATION_TRN(cnode),err);
  289.             }
  290.           break;
  291.         case REVOKE: /* nothing to check - in the worst case we'll do useless scan
  292.                       * of priviledge table at runtime
  293.                       */
  294.           break;
  295.         default:
  296.           debug_trn(cnode);
  297.           yyfatal("Unexpected Statement node");
  298.         }
  299.     }
  300.   return SQL_SUCCESS;
  301. }