/ Check-in [8a746fbf]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix some authorization callback problems.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8a746fbfd51f70f56e25ade59df49d2dc03c131c
User & Date: dan 2009-08-31 08:22:46
References
2009-09-17
00:47 Fixed ticket [e25d9ea7]: Cascading delete trigger fails. plus 4 other changes artifact: df2f80f3 user: drh
2009-09-14
22:28 Ticket [a696379c] Access violation error trying to insert into triggered view status still Open with 1 other change artifact: 3e27afc2 user: drh
Context
2009-08-31
15:27
More fixes for test cases. check-in: 85d9f23b user: dan tags: trunk
08:22
Fix some authorization callback problems. check-in: 8a746fbf user: dan tags: trunk
05:39
Merge with main branch. check-in: 6e09e287 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/auth.c.

109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124





125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
  sqlite3 *db = pParse->db;
  int rc;
  Table *pTab = 0;      /* The table being read */
  const char *zCol;     /* Name of the column of the table */
  int iSrc;             /* Index in pTabList->a[] of table being read */
  const char *zDBase;   /* Name of database being accessed */
  int iDb;              /* The index of the database the expression refers to */


  if( db->xAuth==0 ) return;
  assert( pExpr->op==TK_COLUMN );
  iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
  if( iDb<0 ){
    /* An attempt to read a column out of a subquery or other
    ** temporary table. */
    return;
  }





  if( pTabList ){
    for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
      if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
        pTab = pTabList->a[iSrc].pTab;
	break;
      }
    }
  }
  if( !pTab ){
    TriggerStack *pStack = pParse->trigStack;
    if( ALWAYS(pStack) ){
      /* This must be an attempt to read the NEW or OLD pseudo-tables
      ** of a trigger.  */
      assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
      pTab = pStack->pTab;
    }
  }
  if( NEVER(pTab==0) ) return;
  if( pExpr->iColumn>=0 ){

    assert( pExpr->iColumn<pTab->nCol );
    zCol = pTab->aCol[pExpr->iColumn].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( iDb>=0 && iDb<db->nDb );







>


<






>
>
>
>
>
|



|



|
|
<
<
<
<
<
|
<
<
<
>
|
|







109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139





140



141
142
143
144
145
146
147
148
149
150
  sqlite3 *db = pParse->db;
  int rc;
  Table *pTab = 0;      /* The table being read */
  const char *zCol;     /* Name of the column of the table */
  int iSrc;             /* Index in pTabList->a[] of table being read */
  const char *zDBase;   /* Name of database being accessed */
  int iDb;              /* The index of the database the expression refers to */
  int iCol;             /* Index of column in table */

  if( db->xAuth==0 ) return;

  iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
  if( iDb<0 ){
    /* An attempt to read a column out of a subquery or other
    ** temporary table. */
    return;
  }

  assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
  if( pExpr->op==TK_TRIGGER ){
    pTab = pParse->pTriggerTab;
  }else{
    assert( pTabList );
    for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
      if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
        pTab = pTabList->a[iSrc].pTab;
        break;
      }
    }
  }
  iCol = pExpr->iColumn;
  if( NEVER(pTab==0) ) return;









  if( iCol>=0 ){
    assert( iCol<pTab->nCol );
    zCol = pTab->aCol[iCol].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( iDb>=0 && iDb<db->nDb );

Changes to src/expr.c.

2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
      break;
    }

    case TK_TRIGGER: {
      int iVal = pExpr->iTable * (pExpr->pTab->nCol+1) + 1 + pExpr->iColumn;
      sqlite3VdbeAddOp2(v, OP_Param, iVal, target);
      VdbeComment((v, "%s.%s -> $%d", 
        (pExpr->iTable ? "new" : "old"), 
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
	target
      ));
      break;
    }


    /*
    ** Form A:







|
|

|







2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
      break;
    }

    case TK_TRIGGER: {
      int iVal = pExpr->iTable * (pExpr->pTab->nCol+1) + 1 + pExpr->iColumn;
      sqlite3VdbeAddOp2(v, OP_Param, iVal, target);
      VdbeComment((v, "%s.%s -> $%d",
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
        target
      ));
      break;
    }


    /*
    ** Form A:

Changes to src/resolve.c.

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
236
237
238
239
240
241
242
243


244
245
246
247
248
249
250
251
252
253
254
255



256
257










258
259
260
261
262
263
264
...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
  int cnt = 0;                      /* Number of matching column names */
  int cntTab = 0;                   /* Number of matching table names */
  sqlite3 *db = pParse->db;         /* The database connection */
  struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
  Schema *pSchema = 0;              /* Schema of the expression */
  int isTrigger = 0;                /* True if a new.* or old.* reference. */

  assert( pNC );     /* the name context cannot be NULL. */
  assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
  assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );

  /* Initialize the node to no-match */
  pExpr->iTable = -1;
................................................................................
        piColMask = &(pParse->oldmask);
      }

      if( pTab ){ 
        int iCol;
        pSchema = pTab->pSchema;
        cntTab++;
        isTrigger = 1;


        for(iCol=0; iCol<pTab->nCol; iCol++){
          Column *pCol = &pTab->aCol[iCol];
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            cnt++;
            pExpr->iColumn = iCol==pTab->iPKey ? -1 : (i16)iCol;
            testcase( iCol==31 );
            testcase( iCol==32 );
            if( iCol>=32 ){
              *piColMask = 0xffffffff;
            }else{
              *piColMask |= ((u32)1)<<iCol;
            }



            break;
          }










        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

    /*
    ** Perhaps the name is a reference to the ROWID
................................................................................

  /* Clean up and return
  */
  sqlite3ExprDelete(db, pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(db, pExpr->pRight);
  pExpr->pRight = 0;
  pExpr->op = TK_COLUMN;
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
    sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
    /* Increment the nRef value on all name contexts from TopNC up to
    ** the point where the name matched. */
    for(;;){
      assert( pTopNC!=0 );
      pTopNC->nRef++;
      if( pTopNC==pNC ) break;
      pTopNC = pTopNC->pNext;
    }
    if( isTrigger ){
      pExpr->pTab = pParse->pTriggerTab;
      pExpr->op = TK_TRIGGER;
    }
    return WRC_Prune;
  } else {
    return WRC_Abort;
  }
}

/*







|







 







|
>
>
|
|
|
<
<
|
|
|
|
|
|
|
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>







 







|












<
<
<
<







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
236
237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394




395
396
397
398
399
400
401
  int cnt = 0;                      /* Number of matching column names */
  int cntTab = 0;                   /* Number of matching table names */
  sqlite3 *db = pParse->db;         /* The database connection */
  struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
  Schema *pSchema = 0;              /* Schema of the expression */
  int isTrigger = 0;

  assert( pNC );     /* the name context cannot be NULL. */
  assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
  assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );

  /* Initialize the node to no-match */
  pExpr->iTable = -1;
................................................................................
        piColMask = &(pParse->oldmask);
      }

      if( pTab ){ 
        int iCol;
        pSchema = pTab->pSchema;
        cntTab++;
        if( sqlite3IsRowid(zCol) ){
          iCol = -1;
        }else{
          for(iCol=0; iCol<pTab->nCol; iCol++){
            Column *pCol = &pTab->aCol[iCol];
            if( sqlite3StrICmp(pCol->zName, zCol)==0 ){


              testcase( iCol==31 );
              testcase( iCol==32 );
              if( iCol>=32 ){
                *piColMask = 0xffffffff;
              }else{
                *piColMask |= ((u32)1)<<iCol;
              }
              if( iCol==pTab->iPKey ){
                iCol = -1;
              }
              break;
            }
          }
        }
        if( iCol<pTab->nCol ){
          cnt++;
          if( iCol<0 ){
            pExpr->affinity = SQLITE_AFF_INTEGER;
          }
          pExpr->iColumn = iCol;
          pExpr->pTab = pTab;
          isTrigger = 1;
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

    /*
    ** Perhaps the name is a reference to the ROWID
................................................................................

  /* Clean up and return
  */
  sqlite3ExprDelete(db, pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(db, pExpr->pRight);
  pExpr->pRight = 0;
  pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
    sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
    /* Increment the nRef value on all name contexts from TopNC up to
    ** the point where the name matched. */
    for(;;){
      assert( pTopNC!=0 );
      pTopNC->nRef++;
      if( pTopNC==pNC ) break;
      pTopNC = pTopNC->pNext;
    }




    return WRC_Prune;
  } else {
    return WRC_Abort;
  }
}

/*

Changes to src/trigger.c.

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
...
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
      sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
................................................................................
  pC->orconf = orconf;

  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pSubParse;
  pSubParse->db = db;
  pSubParse->pTriggerTab = pTab;
  pSubParse->pRoot = pRoot;

  /* Push an entry on to the auth context stack */
  sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);

  v = sqlite3GetVdbe(pSubParse);
  if( v ){
    VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
      pTrigger->zName, onErrorText(orconf),
      (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
        (op==TK_UPDATE ? "UPDATE" : ""),
................................................................................
      AutoincInfo *p = pSubParse->pAinc;
      pSubParse->pAinc = p->pNext;
      sqlite3DbFree(db, p);
    }
  }
  sqlite3StackFree(db, pSubParse);

  /* Pop the entry off the authorization stack */
  sqlite3AuthContextPop(&sContext);
  return pC;
}
    
static CodedTrigger *getRowTrigger(
  Parse *pParse,
  Trigger *pTrigger,   /* Trigger to code */
  int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */







|







 







|
<
<







 







<
<







527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
815
816
817
818
819
820
821
822


823
824
825
826
827
828
829
...
873
874
875
876
877
878
879


880
881
882
883
884
885
886
  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
      sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
................................................................................
  pC->orconf = orconf;

  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pSubParse;
  pSubParse->db = db;
  pSubParse->pTriggerTab = pTab;
  pSubParse->pRoot = pRoot;
  pSubParse->zAuthContext = pTrigger->zName;



  v = sqlite3GetVdbe(pSubParse);
  if( v ){
    VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
      pTrigger->zName, onErrorText(orconf),
      (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
        (op==TK_UPDATE ? "UPDATE" : ""),
................................................................................
      AutoincInfo *p = pSubParse->pAinc;
      pSubParse->pAinc = p->pNext;
      sqlite3DbFree(db, p);
    }
  }
  sqlite3StackFree(db, pSubParse);



  return pC;
}
    
static CodedTrigger *getRowTrigger(
  Parse *pParse,
  Trigger *pTrigger,   /* Trigger to code */
  int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */

Changes to test/auth.test.

2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282


2283
2284
2285
2286
2287
2288
2289
  set authargs {}
  execsql {
    DELETE FROM v1 WHERE x=117
  }
  set authargs
} [list \
  SQLITE_DELETE v1     {} main {} \
  SQLITE_INSERT v1chng {} main r3 \
  SQLITE_READ   v1     x  main r3 \
  SQLITE_SELECT {}     {} {}   v1 \
  SQLITE_READ   t2     a  main v1 \
  SQLITE_READ   t2     b  main v1 \
  SQLITE_SELECT {}     {} {}   {} \
  SQLITE_READ   v1     x  main v1 \


]

} ;# ifcapable view && trigger

# Ticket #1338:  Make sure authentication works in the presence of an AS
# clause.
#







<
<





>
>







2269
2270
2271
2272
2273
2274
2275


2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
  set authargs {}
  execsql {
    DELETE FROM v1 WHERE x=117
  }
  set authargs
} [list \
  SQLITE_DELETE v1     {} main {} \


  SQLITE_SELECT {}     {} {}   v1 \
  SQLITE_READ   t2     a  main v1 \
  SQLITE_READ   t2     b  main v1 \
  SQLITE_SELECT {}     {} {}   {} \
  SQLITE_READ   v1     x  main v1 \
  SQLITE_INSERT v1chng {} main r3 \
  SQLITE_READ   v1     x  main r3 \
]

} ;# ifcapable view && trigger

# Ticket #1338:  Make sure authentication works in the presence of an AS
# clause.
#