Fossil SCM

Set an authorizer when running the ticket-table SQL. Ticket [56b82836ffba9952].

drh 2020-08-17 14:09 sec2020
Commit fb41384045cb639141f00bd4756a0325babe101c518d75927fd76b024530d6d8
3 files changed +51 -14 +3 -3 +72
+51 -14
--- src/db.c
+++ src/db.c
@@ -130,10 +130,13 @@
130130
char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
131131
int nBeforeCommit; /* Number of entries in azBeforeCommit */
132132
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
133133
const char *zStartFile; /* File in which transaction was started */
134134
int iStartLine; /* Line of zStartFile where transaction started */
135
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
136
+ void *pAuthArg; /* Argument to the authorizer */
137
+ const char *zAuthName; /* Name of the authorizer */
135138
} db = {0, 0, 0, 0, 0, 0, };
136139
137140
/*
138141
** Arrange for the given file to be deleted on a failure.
139142
*/
@@ -316,10 +319,36 @@
316319
}
317320
db.aHook[db.nCommitHook].sequence = sequence;
318321
db.aHook[db.nCommitHook].xHook = x;
319322
db.nCommitHook++;
320323
}
324
+
325
+/*
326
+** Set or unset the query authorizer callback function
327
+*/
328
+void db_set_authorizer(
329
+ int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
330
+ void *pArg,
331
+ const char *zName /* for tracing */
332
+){
333
+ if( db.xAuth ){
334
+ fossil_panic("multiple active db_set_authorizer() calls");
335
+ }
336
+ if( g.db ) sqlite3_set_authorizer(g.db, xAuth, pArg);
337
+ db.xAuth = xAuth;
338
+ db.pAuthArg = pArg;
339
+ db.zAuthName = zName;
340
+ if( g.fSqlTrace ) fossil_trace("-- set authorizer %s\n", zName);
341
+}
342
+void db_clear_authorizer(void){
343
+ if( db.zAuthName && g.fSqlTrace ){
344
+ fossil_trace("-- discontinue authorizer %s\n", db.zAuthName);
345
+ }
346
+ if( g.db ) sqlite3_set_authorizer(g.db, 0, 0);
347
+ db.xAuth = 0;
348
+ db.pAuthArg = 0;
349
+}
321350
322351
#if INTERFACE
323352
/*
324353
** Possible flags to db_vprepare
325354
*/
@@ -844,34 +873,37 @@
844873
void db_init_database(
845874
const char *zFileName, /* Name of database file to create */
846875
const char *zSchema, /* First part of schema */
847876
... /* Additional SQL to run. Terminate with NULL. */
848877
){
849
- sqlite3 *db;
878
+ sqlite3 *xdb;
850879
int rc;
851880
const char *zSql;
852881
va_list ap;
853882
854
- db = db_open(zFileName ? zFileName : ":memory:");
855
- sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
856
- rc = sqlite3_exec(db, zSchema, 0, 0, 0);
883
+ xdb = db_open(zFileName ? zFileName : ":memory:");
884
+ sqlite3_exec(xdb, "BEGIN EXCLUSIVE", 0, 0, 0);
885
+ if( db.xAuth ){
886
+ sqlite3_set_authorizer(xdb, db.xAuth, db.pAuthArg);
887
+ }
888
+ rc = sqlite3_exec(xdb, zSchema, 0, 0, 0);
857889
if( rc!=SQLITE_OK ){
858
- db_err("%s", sqlite3_errmsg(db));
890
+ db_err("%s", sqlite3_errmsg(xdb));
859891
}
860892
va_start(ap, zSchema);
861893
while( (zSql = va_arg(ap, const char*))!=0 ){
862
- rc = sqlite3_exec(db, zSql, 0, 0, 0);
894
+ rc = sqlite3_exec(xdb, zSql, 0, 0, 0);
863895
if( rc!=SQLITE_OK ){
864
- db_err("%s", sqlite3_errmsg(db));
896
+ db_err("%s", sqlite3_errmsg(xdb));
865897
}
866898
}
867899
va_end(ap);
868
- sqlite3_exec(db, "COMMIT", 0, 0, 0);
900
+ sqlite3_exec(xdb, "COMMIT", 0, 0, 0);
869901
if( zFileName || g.db!=0 ){
870
- sqlite3_close(db);
902
+ sqlite3_close(xdb);
871903
}else{
872
- g.db = db;
904
+ g.db = xdb;
873905
}
874906
}
875907
876908
/*
877909
** Function to return the number of seconds since 1970. This is
@@ -2089,10 +2121,11 @@
20892121
** argument is true. Ignore unfinalized statements when false.
20902122
*/
20912123
void db_close(int reportErrors){
20922124
sqlite3_stmt *pStmt;
20932125
if( g.db==0 ) return;
2126
+ sqlite3_set_authorizer(g.db, 0, 0);
20942127
if( g.fSqlStats ){
20952128
int cur, hiwtr;
20962129
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &hiwtr, 0);
20972130
fprintf(stderr, "-- LOOKASIDE_USED %10d %10d\n", cur, hiwtr);
20982131
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &cur, &hiwtr, 0);
@@ -2118,17 +2151,20 @@
21182151
fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare);
21192152
}
21202153
while( db.pAllStmt ){
21212154
db_finalize(db.pAllStmt);
21222155
}
2123
- if( db.nBegin && reportErrors ){
2124
- fossil_warning("Transaction started at %s:%d never commits",
2125
- db.zStartFile, db.iStartLine);
2156
+ if( db.nBegin ){
2157
+ if( reportErrors ){
2158
+ fossil_warning("Transaction started at %s:%d never commits",
2159
+ db.zStartFile, db.iStartLine);
2160
+ }
21262161
db_end_transaction(1);
21272162
}
21282163
pStmt = 0;
2129
- g.dbIgnoreErrors++; /* Stop "database locked" warnings from PRAGMA optimize */
2164
+ sqlite3_busy_timeout(g.db, 0);
2165
+ g.dbIgnoreErrors++; /* Stop "database locked" warnings */
21302166
sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
21312167
g.dbIgnoreErrors--;
21322168
db_close_config();
21332169
21342170
/* If the localdb has a lot of unused free space,
@@ -2168,10 +2204,11 @@
21682204
if( g.db ){
21692205
int rc;
21702206
sqlite3_wal_checkpoint(g.db, 0);
21712207
rc = sqlite3_close(g.db);
21722208
if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
2209
+ db_clear_authorizer();
21732210
}
21742211
g.db = 0;
21752212
g.repositoryOpen = 0;
21762213
g.localOpen = 0;
21772214
}
21782215
--- src/db.c
+++ src/db.c
@@ -130,10 +130,13 @@
130 char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
131 int nBeforeCommit; /* Number of entries in azBeforeCommit */
132 int nPriorChanges; /* sqlite3_total_changes() at transaction start */
133 const char *zStartFile; /* File in which transaction was started */
134 int iStartLine; /* Line of zStartFile where transaction started */
 
 
 
135 } db = {0, 0, 0, 0, 0, 0, };
136
137 /*
138 ** Arrange for the given file to be deleted on a failure.
139 */
@@ -316,10 +319,36 @@
316 }
317 db.aHook[db.nCommitHook].sequence = sequence;
318 db.aHook[db.nCommitHook].xHook = x;
319 db.nCommitHook++;
320 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
322 #if INTERFACE
323 /*
324 ** Possible flags to db_vprepare
325 */
@@ -844,34 +873,37 @@
844 void db_init_database(
845 const char *zFileName, /* Name of database file to create */
846 const char *zSchema, /* First part of schema */
847 ... /* Additional SQL to run. Terminate with NULL. */
848 ){
849 sqlite3 *db;
850 int rc;
851 const char *zSql;
852 va_list ap;
853
854 db = db_open(zFileName ? zFileName : ":memory:");
855 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
856 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
 
 
 
857 if( rc!=SQLITE_OK ){
858 db_err("%s", sqlite3_errmsg(db));
859 }
860 va_start(ap, zSchema);
861 while( (zSql = va_arg(ap, const char*))!=0 ){
862 rc = sqlite3_exec(db, zSql, 0, 0, 0);
863 if( rc!=SQLITE_OK ){
864 db_err("%s", sqlite3_errmsg(db));
865 }
866 }
867 va_end(ap);
868 sqlite3_exec(db, "COMMIT", 0, 0, 0);
869 if( zFileName || g.db!=0 ){
870 sqlite3_close(db);
871 }else{
872 g.db = db;
873 }
874 }
875
876 /*
877 ** Function to return the number of seconds since 1970. This is
@@ -2089,10 +2121,11 @@
2089 ** argument is true. Ignore unfinalized statements when false.
2090 */
2091 void db_close(int reportErrors){
2092 sqlite3_stmt *pStmt;
2093 if( g.db==0 ) return;
 
2094 if( g.fSqlStats ){
2095 int cur, hiwtr;
2096 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &hiwtr, 0);
2097 fprintf(stderr, "-- LOOKASIDE_USED %10d %10d\n", cur, hiwtr);
2098 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &cur, &hiwtr, 0);
@@ -2118,17 +2151,20 @@
2118 fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare);
2119 }
2120 while( db.pAllStmt ){
2121 db_finalize(db.pAllStmt);
2122 }
2123 if( db.nBegin && reportErrors ){
2124 fossil_warning("Transaction started at %s:%d never commits",
2125 db.zStartFile, db.iStartLine);
 
 
2126 db_end_transaction(1);
2127 }
2128 pStmt = 0;
2129 g.dbIgnoreErrors++; /* Stop "database locked" warnings from PRAGMA optimize */
 
2130 sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
2131 g.dbIgnoreErrors--;
2132 db_close_config();
2133
2134 /* If the localdb has a lot of unused free space,
@@ -2168,10 +2204,11 @@
2168 if( g.db ){
2169 int rc;
2170 sqlite3_wal_checkpoint(g.db, 0);
2171 rc = sqlite3_close(g.db);
2172 if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
 
2173 }
2174 g.db = 0;
2175 g.repositoryOpen = 0;
2176 g.localOpen = 0;
2177 }
2178
--- src/db.c
+++ src/db.c
@@ -130,10 +130,13 @@
130 char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
131 int nBeforeCommit; /* Number of entries in azBeforeCommit */
132 int nPriorChanges; /* sqlite3_total_changes() at transaction start */
133 const char *zStartFile; /* File in which transaction was started */
134 int iStartLine; /* Line of zStartFile where transaction started */
135 int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
136 void *pAuthArg; /* Argument to the authorizer */
137 const char *zAuthName; /* Name of the authorizer */
138 } db = {0, 0, 0, 0, 0, 0, };
139
140 /*
141 ** Arrange for the given file to be deleted on a failure.
142 */
@@ -316,10 +319,36 @@
319 }
320 db.aHook[db.nCommitHook].sequence = sequence;
321 db.aHook[db.nCommitHook].xHook = x;
322 db.nCommitHook++;
323 }
324
325 /*
326 ** Set or unset the query authorizer callback function
327 */
328 void db_set_authorizer(
329 int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
330 void *pArg,
331 const char *zName /* for tracing */
332 ){
333 if( db.xAuth ){
334 fossil_panic("multiple active db_set_authorizer() calls");
335 }
336 if( g.db ) sqlite3_set_authorizer(g.db, xAuth, pArg);
337 db.xAuth = xAuth;
338 db.pAuthArg = pArg;
339 db.zAuthName = zName;
340 if( g.fSqlTrace ) fossil_trace("-- set authorizer %s\n", zName);
341 }
342 void db_clear_authorizer(void){
343 if( db.zAuthName && g.fSqlTrace ){
344 fossil_trace("-- discontinue authorizer %s\n", db.zAuthName);
345 }
346 if( g.db ) sqlite3_set_authorizer(g.db, 0, 0);
347 db.xAuth = 0;
348 db.pAuthArg = 0;
349 }
350
351 #if INTERFACE
352 /*
353 ** Possible flags to db_vprepare
354 */
@@ -844,34 +873,37 @@
873 void db_init_database(
874 const char *zFileName, /* Name of database file to create */
875 const char *zSchema, /* First part of schema */
876 ... /* Additional SQL to run. Terminate with NULL. */
877 ){
878 sqlite3 *xdb;
879 int rc;
880 const char *zSql;
881 va_list ap;
882
883 xdb = db_open(zFileName ? zFileName : ":memory:");
884 sqlite3_exec(xdb, "BEGIN EXCLUSIVE", 0, 0, 0);
885 if( db.xAuth ){
886 sqlite3_set_authorizer(xdb, db.xAuth, db.pAuthArg);
887 }
888 rc = sqlite3_exec(xdb, zSchema, 0, 0, 0);
889 if( rc!=SQLITE_OK ){
890 db_err("%s", sqlite3_errmsg(xdb));
891 }
892 va_start(ap, zSchema);
893 while( (zSql = va_arg(ap, const char*))!=0 ){
894 rc = sqlite3_exec(xdb, zSql, 0, 0, 0);
895 if( rc!=SQLITE_OK ){
896 db_err("%s", sqlite3_errmsg(xdb));
897 }
898 }
899 va_end(ap);
900 sqlite3_exec(xdb, "COMMIT", 0, 0, 0);
901 if( zFileName || g.db!=0 ){
902 sqlite3_close(xdb);
903 }else{
904 g.db = xdb;
905 }
906 }
907
908 /*
909 ** Function to return the number of seconds since 1970. This is
@@ -2089,10 +2121,11 @@
2121 ** argument is true. Ignore unfinalized statements when false.
2122 */
2123 void db_close(int reportErrors){
2124 sqlite3_stmt *pStmt;
2125 if( g.db==0 ) return;
2126 sqlite3_set_authorizer(g.db, 0, 0);
2127 if( g.fSqlStats ){
2128 int cur, hiwtr;
2129 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &hiwtr, 0);
2130 fprintf(stderr, "-- LOOKASIDE_USED %10d %10d\n", cur, hiwtr);
2131 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &cur, &hiwtr, 0);
@@ -2118,17 +2151,20 @@
2151 fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare);
2152 }
2153 while( db.pAllStmt ){
2154 db_finalize(db.pAllStmt);
2155 }
2156 if( db.nBegin ){
2157 if( reportErrors ){
2158 fossil_warning("Transaction started at %s:%d never commits",
2159 db.zStartFile, db.iStartLine);
2160 }
2161 db_end_transaction(1);
2162 }
2163 pStmt = 0;
2164 sqlite3_busy_timeout(g.db, 0);
2165 g.dbIgnoreErrors++; /* Stop "database locked" warnings */
2166 sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
2167 g.dbIgnoreErrors--;
2168 db_close_config();
2169
2170 /* If the localdb has a lot of unused free space,
@@ -2168,10 +2204,11 @@
2204 if( g.db ){
2205 int rc;
2206 sqlite3_wal_checkpoint(g.db, 0);
2207 rc = sqlite3_close(g.db);
2208 if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
2209 db_clear_authorizer();
2210 }
2211 g.db = 0;
2212 g.repositoryOpen = 0;
2213 g.localOpen = 0;
2214 }
2215
+3 -3
--- src/report.c
+++ src/report.c
@@ -230,15 +230,15 @@
230230
231231
/*
232232
** Activate the query authorizer
233233
*/
234234
void report_restrict_sql(char **pzErr){
235
- sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)pzErr);
235
+ db_set_authorizer(report_query_authorizer,(void*)pzErr,"Ticket-Report");
236236
sqlite3_limit(g.db, SQLITE_LIMIT_VDBE_OP, 10000);
237237
}
238238
void report_unrestrict_sql(void){
239
- sqlite3_set_authorizer(g.db, 0, 0);
239
+ db_clear_authorizer();
240240
}
241241
242242
243243
/*
244244
** Check the given SQL to see if is a valid query that does not
@@ -680,11 +680,11 @@
680680
*/
681681
if( pState->nCount==0 ){
682682
/* Turn off the authorizer. It is no longer doing anything since the
683683
** query has already been prepared.
684684
*/
685
- sqlite3_set_authorizer(g.db, 0, 0);
685
+ db_clear_authorizer();
686686
687687
/* Figure out the number of columns, the column that determines background
688688
** color, and whether or not this row of data is represented by multiple
689689
** rows in the table.
690690
*/
691691
--- src/report.c
+++ src/report.c
@@ -230,15 +230,15 @@
230
231 /*
232 ** Activate the query authorizer
233 */
234 void report_restrict_sql(char **pzErr){
235 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)pzErr);
236 sqlite3_limit(g.db, SQLITE_LIMIT_VDBE_OP, 10000);
237 }
238 void report_unrestrict_sql(void){
239 sqlite3_set_authorizer(g.db, 0, 0);
240 }
241
242
243 /*
244 ** Check the given SQL to see if is a valid query that does not
@@ -680,11 +680,11 @@
680 */
681 if( pState->nCount==0 ){
682 /* Turn off the authorizer. It is no longer doing anything since the
683 ** query has already been prepared.
684 */
685 sqlite3_set_authorizer(g.db, 0, 0);
686
687 /* Figure out the number of columns, the column that determines background
688 ** color, and whether or not this row of data is represented by multiple
689 ** rows in the table.
690 */
691
--- src/report.c
+++ src/report.c
@@ -230,15 +230,15 @@
230
231 /*
232 ** Activate the query authorizer
233 */
234 void report_restrict_sql(char **pzErr){
235 db_set_authorizer(report_query_authorizer,(void*)pzErr,"Ticket-Report");
236 sqlite3_limit(g.db, SQLITE_LIMIT_VDBE_OP, 10000);
237 }
238 void report_unrestrict_sql(void){
239 db_clear_authorizer();
240 }
241
242
243 /*
244 ** Check the given SQL to see if is a valid query that does not
@@ -680,11 +680,11 @@
680 */
681 if( pState->nCount==0 ){
682 /* Turn off the authorizer. It is no longer doing anything since the
683 ** query has already been prepared.
684 */
685 db_clear_authorizer();
686
687 /* Figure out the number of columns, the column that determines background
688 ** color, and whether or not this row of data is represented by multiple
689 ** rows in the table.
690 */
691
+72
--- src/tkt.c
+++ src/tkt.c
@@ -370,10 +370,79 @@
370370
Th_FossilInit(TH_INIT_DEFAULT);
371371
Th_Store("uuid", zUuid);
372372
zConfig = ticket_change_code();
373373
return Th_Eval(g.interp, 0, zConfig, -1);
374374
}
375
+
376
+/*
377
+** An authorizer function for the SQL used to initialize the
378
+** schema for the ticketing system. Only allow CREATE TABLE and
379
+** CREATE INDEX for tables whose names begin with "ticket" and
380
+** changes to tables whose names begin with "ticket".
381
+*/
382
+static int ticket_schema_auth(
383
+ void *pNErr,
384
+ int eCode,
385
+ const char *z0,
386
+ const char *z1,
387
+ const char *z2,
388
+ const char *z3
389
+){
390
+ switch( eCode ){
391
+ case SQLITE_CREATE_TABLE: {
392
+ if( sqlite3_stricmp(z2,"main")!=0
393
+ && sqlite3_stricmp(z2,"repository")!=0
394
+ ){
395
+ goto ticket_schema_error;
396
+ }
397
+ if( sqlite3_strnicmp(z0,"ticket",6)!=0 ){
398
+ goto ticket_schema_error;
399
+ }
400
+ break;
401
+ }
402
+ case SQLITE_CREATE_INDEX: {
403
+ if( sqlite3_stricmp(z2,"main")!=0
404
+ && sqlite3_stricmp(z2,"repository")!=0
405
+ ){
406
+ goto ticket_schema_error;
407
+ }
408
+ if( sqlite3_strnicmp(z1,"ticket",6)!=0 ){
409
+ goto ticket_schema_error;
410
+ }
411
+ break;
412
+ }
413
+ case SQLITE_INSERT:
414
+ case SQLITE_UPDATE:
415
+ case SQLITE_DELETE: {
416
+ if( sqlite3_stricmp(z2,"main")!=0
417
+ && sqlite3_stricmp(z2,"repository")!=0
418
+ ){
419
+ goto ticket_schema_error;
420
+ }
421
+ if( sqlite3_strnicmp(z0,"ticket",6)!=0
422
+ && sqlite3_strnicmp(z0,"sqlite_",7)!=0
423
+ ){
424
+ goto ticket_schema_error;
425
+ }
426
+ break;
427
+ }
428
+ case SQLITE_REINDEX:
429
+ case SQLITE_TRANSACTION:
430
+ case SQLITE_READ: {
431
+ break;
432
+ }
433
+ default: {
434
+ goto ticket_schema_error;
435
+ }
436
+ }
437
+ return SQLITE_OK;
438
+
439
+ticket_schema_error:
440
+ if( pNErr ) *(int*)pNErr = 1;
441
+ return SQLITE_DENY;
442
+}
443
+
375444
376445
/*
377446
** Recreate the TICKET and TICKETCHNG tables.
378447
*/
379448
void ticket_create_table(int separateConnection){
@@ -384,14 +453,17 @@
384453
"DROP TABLE IF EXISTS ticketchng;"
385454
);
386455
zSql = ticket_table_schema();
387456
if( separateConnection ){
388457
if( db_transaction_nesting_depth() ) db_end_transaction(0);
458
+ db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
389459
db_init_database(g.zRepositoryName, zSql, 0);
390460
}else{
461
+ db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
391462
db_multi_exec("%s", zSql/*safe-for-%s*/);
392463
}
464
+ db_clear_authorizer();
393465
fossil_free(zSql);
394466
}
395467
396468
/*
397469
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
398470
--- src/tkt.c
+++ src/tkt.c
@@ -370,10 +370,79 @@
370 Th_FossilInit(TH_INIT_DEFAULT);
371 Th_Store("uuid", zUuid);
372 zConfig = ticket_change_code();
373 return Th_Eval(g.interp, 0, zConfig, -1);
374 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
376 /*
377 ** Recreate the TICKET and TICKETCHNG tables.
378 */
379 void ticket_create_table(int separateConnection){
@@ -384,14 +453,17 @@
384 "DROP TABLE IF EXISTS ticketchng;"
385 );
386 zSql = ticket_table_schema();
387 if( separateConnection ){
388 if( db_transaction_nesting_depth() ) db_end_transaction(0);
 
389 db_init_database(g.zRepositoryName, zSql, 0);
390 }else{
 
391 db_multi_exec("%s", zSql/*safe-for-%s*/);
392 }
 
393 fossil_free(zSql);
394 }
395
396 /*
397 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
398
--- src/tkt.c
+++ src/tkt.c
@@ -370,10 +370,79 @@
370 Th_FossilInit(TH_INIT_DEFAULT);
371 Th_Store("uuid", zUuid);
372 zConfig = ticket_change_code();
373 return Th_Eval(g.interp, 0, zConfig, -1);
374 }
375
376 /*
377 ** An authorizer function for the SQL used to initialize the
378 ** schema for the ticketing system. Only allow CREATE TABLE and
379 ** CREATE INDEX for tables whose names begin with "ticket" and
380 ** changes to tables whose names begin with "ticket".
381 */
382 static int ticket_schema_auth(
383 void *pNErr,
384 int eCode,
385 const char *z0,
386 const char *z1,
387 const char *z2,
388 const char *z3
389 ){
390 switch( eCode ){
391 case SQLITE_CREATE_TABLE: {
392 if( sqlite3_stricmp(z2,"main")!=0
393 && sqlite3_stricmp(z2,"repository")!=0
394 ){
395 goto ticket_schema_error;
396 }
397 if( sqlite3_strnicmp(z0,"ticket",6)!=0 ){
398 goto ticket_schema_error;
399 }
400 break;
401 }
402 case SQLITE_CREATE_INDEX: {
403 if( sqlite3_stricmp(z2,"main")!=0
404 && sqlite3_stricmp(z2,"repository")!=0
405 ){
406 goto ticket_schema_error;
407 }
408 if( sqlite3_strnicmp(z1,"ticket",6)!=0 ){
409 goto ticket_schema_error;
410 }
411 break;
412 }
413 case SQLITE_INSERT:
414 case SQLITE_UPDATE:
415 case SQLITE_DELETE: {
416 if( sqlite3_stricmp(z2,"main")!=0
417 && sqlite3_stricmp(z2,"repository")!=0
418 ){
419 goto ticket_schema_error;
420 }
421 if( sqlite3_strnicmp(z0,"ticket",6)!=0
422 && sqlite3_strnicmp(z0,"sqlite_",7)!=0
423 ){
424 goto ticket_schema_error;
425 }
426 break;
427 }
428 case SQLITE_REINDEX:
429 case SQLITE_TRANSACTION:
430 case SQLITE_READ: {
431 break;
432 }
433 default: {
434 goto ticket_schema_error;
435 }
436 }
437 return SQLITE_OK;
438
439 ticket_schema_error:
440 if( pNErr ) *(int*)pNErr = 1;
441 return SQLITE_DENY;
442 }
443
444
445 /*
446 ** Recreate the TICKET and TICKETCHNG tables.
447 */
448 void ticket_create_table(int separateConnection){
@@ -384,14 +453,17 @@
453 "DROP TABLE IF EXISTS ticketchng;"
454 );
455 zSql = ticket_table_schema();
456 if( separateConnection ){
457 if( db_transaction_nesting_depth() ) db_end_transaction(0);
458 db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
459 db_init_database(g.zRepositoryName, zSql, 0);
460 }else{
461 db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
462 db_multi_exec("%s", zSql/*safe-for-%s*/);
463 }
464 db_clear_authorizer();
465 fossil_free(zSql);
466 }
467
468 /*
469 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
470

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button