@@ -224401,3 +224401,359 @@ SQLITE_API int sqlite3_stmt_init(
224401
224401
/* Return the source-id for this library */
224402
224402
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
224403
224403
/************************** End of sqlite3.c ******************************/
224404
+
224405
+ /*
224406
+ ** 2014-09-08
224407
+ **
224408
+ ** The author disclaims copyright to this source code. In place of
224409
+ ** a legal notice, here is a blessing:
224410
+ **
224411
+ ** May you do good and not evil.
224412
+ ** May you find forgiveness for yourself and forgive others.
224413
+ ** May you share freely, never taking more than you give.
224414
+ **
224415
+ *************************************************************************
224416
+ **
224417
+ ** This file contains the bulk of the implementation of the
224418
+ ** user-authentication extension feature. Some parts of the user-
224419
+ ** authentication code are contained within the SQLite core (in the
224420
+ ** src/ subdirectory of the main source code tree) but those parts
224421
+ ** that could reasonable be separated out are moved into this file.
224422
+ **
224423
+ ** To compile with the user-authentication feature, append this file to
224424
+ ** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION
224425
+ ** compile-time option. See the user-auth.txt file in the same source
224426
+ ** directory as this file for additional information.
224427
+ */
224428
+ #ifdef SQLITE_USER_AUTHENTICATION
224429
+ #ifndef SQLITEINT_H
224430
+ # include "sqliteInt.h"
224431
+ #endif
224432
+
224433
+ /*
224434
+ ** Prepare an SQL statement for use by the user authentication logic.
224435
+ ** Return a pointer to the prepared statement on success. Return a
224436
+ ** NULL pointer if there is an error of any kind.
224437
+ */
224438
+ static sqlite3_stmt *sqlite3UserAuthPrepare(
224439
+ sqlite3 *db,
224440
+ const char *zFormat,
224441
+ ...
224442
+ ){
224443
+ sqlite3_stmt *pStmt;
224444
+ char *zSql;
224445
+ int rc;
224446
+ va_list ap;
224447
+ int savedFlags = db->flags;
224448
+
224449
+ va_start(ap, zFormat);
224450
+ zSql = sqlite3_vmprintf(zFormat, ap);
224451
+ va_end(ap);
224452
+ if( zSql==0 ) return 0;
224453
+ db->flags |= SQLITE_WriteSchema;
224454
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
224455
+ db->flags = savedFlags;
224456
+ sqlite3_free(zSql);
224457
+ if( rc ){
224458
+ sqlite3_finalize(pStmt);
224459
+ pStmt = 0;
224460
+ }
224461
+ return pStmt;
224462
+ }
224463
+
224464
+ /*
224465
+ ** Check to see if the sqlite_user table exists in database zDb.
224466
+ */
224467
+ static int userTableExists(sqlite3 *db, const char *zDb){
224468
+ int rc;
224469
+ sqlite3_mutex_enter(db->mutex);
224470
+ sqlite3BtreeEnterAll(db);
224471
+ if( db->init.busy==0 ){
224472
+ char *zErr = 0;
224473
+ sqlite3Init(db, &zErr);
224474
+ sqlite3DbFree(db, zErr);
224475
+ }
224476
+ rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0;
224477
+ sqlite3BtreeLeaveAll(db);
224478
+ sqlite3_mutex_leave(db->mutex);
224479
+ return rc;
224480
+ }
224481
+
224482
+ /*
224483
+ ** Check to see if database zDb has a "sqlite_user" table and if it does
224484
+ ** whether that table can authenticate zUser with nPw,zPw. Write one of
224485
+ ** the UAUTH_* user authorization level codes into *peAuth and return a
224486
+ ** result code.
224487
+ */
224488
+ static int userAuthCheckLogin(
224489
+ sqlite3 *db, /* The database connection to check */
224490
+ const char *zDb, /* Name of specific database to check */
224491
+ u8 *peAuth /* OUT: One of UAUTH_* constants */
224492
+ ){
224493
+ sqlite3_stmt *pStmt;
224494
+ int rc;
224495
+
224496
+ *peAuth = UAUTH_Unknown;
224497
+ if( !userTableExists(db, "main") ){
224498
+ *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */
224499
+ return SQLITE_OK;
224500
+ }
224501
+ if( db->auth.zAuthUser==0 ){
224502
+ *peAuth = UAUTH_Fail;
224503
+ return SQLITE_OK;
224504
+ }
224505
+ pStmt = sqlite3UserAuthPrepare(db,
224506
+ "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user"
224507
+ " WHERE uname=?2", zDb);
224508
+ if( pStmt==0 ) return SQLITE_NOMEM;
224509
+ sqlite3_bind_blob(pStmt, 1, db->auth.zAuthPW, db->auth.nAuthPW,SQLITE_STATIC);
224510
+ sqlite3_bind_text(pStmt, 2, db->auth.zAuthUser, -1, SQLITE_STATIC);
224511
+ rc = sqlite3_step(pStmt);
224512
+ if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){
224513
+ *peAuth = sqlite3_column_int(pStmt, 1) + UAUTH_User;
224514
+ }else{
224515
+ *peAuth = UAUTH_Fail;
224516
+ }
224517
+ return sqlite3_finalize(pStmt);
224518
+ }
224519
+ int sqlite3UserAuthCheckLogin(
224520
+ sqlite3 *db, /* The database connection to check */
224521
+ const char *zDb, /* Name of specific database to check */
224522
+ u8 *peAuth /* OUT: One of UAUTH_* constants */
224523
+ ){
224524
+ int rc;
224525
+ u8 savedAuthLevel;
224526
+ assert( zDb!=0 );
224527
+ assert( peAuth!=0 );
224528
+ savedAuthLevel = db->auth.authLevel;
224529
+ db->auth.authLevel = UAUTH_Admin;
224530
+ rc = userAuthCheckLogin(db, zDb, peAuth);
224531
+ db->auth.authLevel = savedAuthLevel;
224532
+ return rc;
224533
+ }
224534
+
224535
+ /*
224536
+ ** If the current authLevel is UAUTH_Unknown, the take actions to figure
224537
+ ** out what authLevel should be
224538
+ */
224539
+ void sqlite3UserAuthInit(sqlite3 *db){
224540
+ if( db->auth.authLevel==UAUTH_Unknown ){
224541
+ u8 authLevel = UAUTH_Fail;
224542
+ sqlite3UserAuthCheckLogin(db, "main", &authLevel);
224543
+ db->auth.authLevel = authLevel;
224544
+ if( authLevel<UAUTH_Admin ) db->flags &= ~SQLITE_WriteSchema;
224545
+ }
224546
+ }
224547
+
224548
+ /*
224549
+ ** Implementation of the sqlite_crypt(X,Y) function.
224550
+ **
224551
+ ** If Y is NULL then generate a new hash for password X and return that
224552
+ ** hash. If Y is not null, then generate a hash for password X using the
224553
+ ** same salt as the previous hash Y and return the new hash.
224554
+ */
224555
+ void sqlite3CryptFunc(
224556
+ sqlite3_context *context,
224557
+ int NotUsed,
224558
+ sqlite3_value **argv
224559
+ ){
224560
+ const char *zIn;
224561
+ int nIn, ii;
224562
+ u8 *zOut;
224563
+ char zSalt[8];
224564
+ zIn = sqlite3_value_blob(argv[0]);
224565
+ nIn = sqlite3_value_bytes(argv[0]);
224566
+ if( sqlite3_value_type(argv[1])==SQLITE_BLOB
224567
+ && sqlite3_value_bytes(argv[1])==nIn+sizeof(zSalt)
224568
+ ){
224569
+ memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt));
224570
+ }else{
224571
+ sqlite3_randomness(sizeof(zSalt), zSalt);
224572
+ }
224573
+ zOut = sqlite3_malloc( nIn+sizeof(zSalt) );
224574
+ if( zOut==0 ){
224575
+ sqlite3_result_error_nomem(context);
224576
+ }else{
224577
+ memcpy(zOut, zSalt, sizeof(zSalt));
224578
+ for(ii=0; ii<nIn; ii++){
224579
+ zOut[ii+sizeof(zSalt)] = zIn[ii]^zSalt[ii&0x7];
224580
+ }
224581
+ sqlite3_result_blob(context, zOut, nIn+sizeof(zSalt), sqlite3_free);
224582
+ }
224583
+ }
224584
+
224585
+ /*
224586
+ ** If a database contains the SQLITE_USER table, then the
224587
+ ** sqlite3_user_authenticate() interface must be invoked with an
224588
+ ** appropriate username and password prior to enable read and write
224589
+ ** access to the database.
224590
+ **
224591
+ ** Return SQLITE_OK on success or SQLITE_ERROR if the username/password
224592
+ ** combination is incorrect or unknown.
224593
+ **
224594
+ ** If the SQLITE_USER table is not present in the database file, then
224595
+ ** this interface is a harmless no-op returnning SQLITE_OK.
224596
+ */
224597
+ int sqlite3_user_authenticate(
224598
+ sqlite3 *db, /* The database connection */
224599
+ const char *zUsername, /* Username */
224600
+ const char *zPW, /* Password or credentials */
224601
+ int nPW /* Number of bytes in aPW[] */
224602
+ ){
224603
+ int rc;
224604
+ u8 authLevel = UAUTH_Fail;
224605
+ db->auth.authLevel = UAUTH_Unknown;
224606
+ sqlite3_free(db->auth.zAuthUser);
224607
+ sqlite3_free(db->auth.zAuthPW);
224608
+ memset(&db->auth, 0, sizeof(db->auth));
224609
+ db->auth.zAuthUser = sqlite3_mprintf("%s", zUsername);
224610
+ if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM;
224611
+ db->auth.zAuthPW = sqlite3_malloc( nPW+1 );
224612
+ if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM;
224613
+ memcpy(db->auth.zAuthPW,zPW,nPW);
224614
+ db->auth.nAuthPW = nPW;
224615
+ rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel);
224616
+ db->auth.authLevel = authLevel;
224617
+ sqlite3ExpirePreparedStatements(db, 0);
224618
+ if( rc ){
224619
+ return rc; /* OOM error, I/O error, etc. */
224620
+ }
224621
+ if( authLevel<UAUTH_User ){
224622
+ return SQLITE_AUTH; /* Incorrect username and/or password */
224623
+ }
224624
+ return SQLITE_OK; /* Successful login */
224625
+ }
224626
+
224627
+ /*
224628
+ ** The sqlite3_user_add() interface can be used (by an admin user only)
224629
+ ** to create a new user. When called on a no-authentication-required
224630
+ ** database, this routine converts the database into an authentication-
224631
+ ** required database, automatically makes the added user an
224632
+ ** administrator, and logs in the current connection as that user.
224633
+ ** The sqlite3_user_add() interface only works for the "main" database, not
224634
+ ** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a
224635
+ ** non-admin user results in an error.
224636
+ */
224637
+ int sqlite3_user_add(
224638
+ sqlite3 *db, /* Database connection */
224639
+ const char *zUsername, /* Username to be added */
224640
+ const char *aPW, /* Password or credentials */
224641
+ int nPW, /* Number of bytes in aPW[] */
224642
+ int isAdmin /* True to give new user admin privilege */
224643
+ ){
224644
+ sqlite3_stmt *pStmt;
224645
+ int rc;
224646
+ sqlite3UserAuthInit(db);
224647
+ if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH;
224648
+ if( !userTableExists(db, "main") ){
224649
+ if( !isAdmin ) return SQLITE_AUTH;
224650
+ pStmt = sqlite3UserAuthPrepare(db,
224651
+ "CREATE TABLE sqlite_user(\n"
224652
+ " uname TEXT PRIMARY KEY,\n"
224653
+ " isAdmin BOOLEAN,\n"
224654
+ " pw BLOB\n"
224655
+ ") WITHOUT ROWID;");
224656
+ if( pStmt==0 ) return SQLITE_NOMEM;
224657
+ sqlite3_step(pStmt);
224658
+ rc = sqlite3_finalize(pStmt);
224659
+ if( rc ) return rc;
224660
+ }
224661
+ pStmt = sqlite3UserAuthPrepare(db,
224662
+ "INSERT INTO sqlite_user(uname,isAdmin,pw)"
224663
+ " VALUES(%Q,%d,sqlite_crypt(?1,NULL))",
224664
+ zUsername, isAdmin!=0);
224665
+ if( pStmt==0 ) return SQLITE_NOMEM;
224666
+ sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
224667
+ sqlite3_step(pStmt);
224668
+ rc = sqlite3_finalize(pStmt);
224669
+ if( rc ) return rc;
224670
+ if( db->auth.zAuthUser==0 ){
224671
+ assert( isAdmin!=0 );
224672
+ sqlite3_user_authenticate(db, zUsername, aPW, nPW);
224673
+ }
224674
+ return SQLITE_OK;
224675
+ }
224676
+
224677
+ /*
224678
+ ** The sqlite3_user_change() interface can be used to change a users
224679
+ ** login credentials or admin privilege. Any user can change their own
224680
+ ** login credentials. Only an admin user can change another users login
224681
+ ** credentials or admin privilege setting. No user may change their own
224682
+ ** admin privilege setting.
224683
+ */
224684
+ int sqlite3_user_change(
224685
+ sqlite3 *db, /* Database connection */
224686
+ const char *zUsername, /* Username to change */
224687
+ const char *aPW, /* Modified password or credentials */
224688
+ int nPW, /* Number of bytes in aPW[] */
224689
+ int isAdmin /* Modified admin privilege for the user */
224690
+ ){
224691
+ sqlite3_stmt *pStmt;
224692
+ int rc;
224693
+ u8 authLevel;
224694
+
224695
+ authLevel = db->auth.authLevel;
224696
+ if( authLevel<UAUTH_User ){
224697
+ /* Must be logged in to make a change */
224698
+ return SQLITE_AUTH;
224699
+ }
224700
+ if( strcmp(db->auth.zAuthUser, zUsername)!=0 ){
224701
+ if( db->auth.authLevel<UAUTH_Admin ){
224702
+ /* Must be an administrator to change a different user */
224703
+ return SQLITE_AUTH;
224704
+ }
224705
+ }else if( isAdmin!=(authLevel==UAUTH_Admin) ){
224706
+ /* Cannot change the isAdmin setting for self */
224707
+ return SQLITE_AUTH;
224708
+ }
224709
+ db->auth.authLevel = UAUTH_Admin;
224710
+ if( !userTableExists(db, "main") ){
224711
+ /* This routine is a no-op if the user to be modified does not exist */
224712
+ }else{
224713
+ pStmt = sqlite3UserAuthPrepare(db,
224714
+ "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)"
224715
+ " WHERE uname=%Q", isAdmin, zUsername);
224716
+ if( pStmt==0 ){
224717
+ rc = SQLITE_NOMEM;
224718
+ }else{
224719
+ sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
224720
+ sqlite3_step(pStmt);
224721
+ rc = sqlite3_finalize(pStmt);
224722
+ }
224723
+ }
224724
+ db->auth.authLevel = authLevel;
224725
+ return rc;
224726
+ }
224727
+
224728
+ /*
224729
+ ** The sqlite3_user_delete() interface can be used (by an admin user only)
224730
+ ** to delete a user. The currently logged-in user cannot be deleted,
224731
+ ** which guarantees that there is always an admin user and hence that
224732
+ ** the database cannot be converted into a no-authentication-required
224733
+ ** database.
224734
+ */
224735
+ int sqlite3_user_delete(
224736
+ sqlite3 *db, /* Database connection */
224737
+ const char *zUsername /* Username to remove */
224738
+ ){
224739
+ sqlite3_stmt *pStmt;
224740
+ if( db->auth.authLevel<UAUTH_Admin ){
224741
+ /* Must be an administrator to delete a user */
224742
+ return SQLITE_AUTH;
224743
+ }
224744
+ if( strcmp(db->auth.zAuthUser, zUsername)==0 ){
224745
+ /* Cannot delete self */
224746
+ return SQLITE_AUTH;
224747
+ }
224748
+ if( !userTableExists(db, "main") ){
224749
+ /* This routine is a no-op if the user to be deleted does not exist */
224750
+ return SQLITE_OK;
224751
+ }
224752
+ pStmt = sqlite3UserAuthPrepare(db,
224753
+ "DELETE FROM sqlite_user WHERE uname=%Q", zUsername);
224754
+ if( pStmt==0 ) return SQLITE_NOMEM;
224755
+ sqlite3_step(pStmt);
224756
+ return sqlite3_finalize(pStmt);
224757
+ }
224758
+
224759
+ #endif /* SQLITE_USER_AUTHENTICATION */
0 commit comments