From: drh Date: Thu, 11 Sep 2014 14:40:27 +0000 (+0000) Subject: Fix the sqlite3_user_change() interface so that it does allow a X-Git-Tag: version-3.8.7~120^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=570f187f78872b349cea66822595cc23304dc378;p=thirdparty%2Fsqlite.git Fix the sqlite3_user_change() interface so that it does allow a non-admin user to change their own password. FossilOrigin-Name: 52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 --- diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt index 8b64617c36..ba4eabc137 100644 --- a/ext/userauth/user-auth.txt +++ b/ext/userauth/user-auth.txt @@ -44,12 +44,11 @@ By default a database does not require authentication. The sqlite3_open(), sqlite3_open16(), and sqlite3_open_v2() interfaces work as before: they open a new database connection. However, if the -database being opened requires authentication, then attempts to prepare -SQL statements (using sqlite3_prepare_v2(), for example) will fail -with an SQLITE_AUTH error until after sqlite3_user_authenticate() -has been called successfully. The sqlite3_user_authenticate() call -will return SQLITE_OK if the authentication credentials are accepted -and SQLITE_ERROR if not. +database being opened requires authentication, then attempts to read +or write from the database will fail with an SQLITE_AUTH error until +after sqlite3_user_authenticate() has been called successfully. The +sqlite3_user_authenticate() call will return SQLITE_OK if the +authentication credentials are accepted and SQLITE_ERROR if not. Calling sqlite3_user_authenticate() on a no-authentication-required database connection is a harmless no-op. @@ -133,12 +132,12 @@ new table: pw BLOB ) WITHOUT ROWID; -This table is inaccessible (unreadable and unwriteable) to non-admin users -and is read-only for admin users. However, if the same database file is -opened by a version of SQLite that omits the -DSQLITE_USER_AUTHENTICATION -compile-time option, then the sqlite_user table will be readable by -anybody and writeable by anybody if the "PRAGMA writable_schema=ON" -statement is run first. +The sqlite_user table is inaccessible (unreadable and unwriteable) to +non-admin users and is read-only for admin users. However, if the same +database file is opened by a version of SQLite that omits +the -DSQLITE_USER_AUTHENTICATION compile-time option, then the sqlite_user +table will be readable by anybody and writeable by anybody if +the "PRAGMA writable_schema=ON" statement is run first. The sqlite_user.pw field is encoded by a built-in SQL function "sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 343e49e6ff..19e9f6f762 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -268,7 +268,11 @@ int sqlite3_user_change( int isAdmin /* Modified admin privilege for the user */ ){ sqlite3_stmt *pStmt; - if( db->auth.authLevelauth.authLevel; + if( authLevelauth.authLevel==UAUTH_Admin) ){ + }else if( isAdmin!=(authLevel==UAUTH_Admin) ){ /* Cannot change the isAdmin setting for self */ return SQLITE_AUTH; } + db->auth.authLevel = UAUTH_Admin; if( !userTableExists(db, "main") ){ /* This routine is a no-op if the user to be modified does not exist */ - return SQLITE_OK; + }else{ + pStmt = sqlite3UserAuthPrepare(db, + "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" + " WHERE uname=%Q", isAdmin, zUsername); + if( pStmt==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_finalize(pStmt); + } } - pStmt = sqlite3UserAuthPrepare(db, - "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" - " WHERE uname=%Q", isAdmin, zUsername); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); - sqlite3_step(pStmt); - return sqlite3_finalize(pStmt); + db->auth.authLevel = authLevel; + return rc; } /* diff --git a/manifest b/manifest index 2e3e9eb42d..b1a2451fb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\suser\sauthentication\sblocking\sfrom\ssqlite3_prepare()\sover\sto\sthe\ntable\slock\sgenerator,\sthus\sallowing\sSQL\sstatements\s(like\s\n"PRAGMA\slocking_mode")\sthat\sdo\snot\stouch\sdatabase\scontent\sto\srun\nprior\sto\sauthentication. -D 2014-09-11T14:01:41.319 +C Fix\sthe\ssqlite3_user_change()\sinterface\sso\sthat\sit\sdoes\sallow\sa\nnon-admin\suser\sto\schange\stheir\sown\spassword. +D 2014-09-11T14:40:27.156 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,8 +145,8 @@ F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 -F ext/userauth/user-auth.txt 527aaec593ae34dcaf543324623c8351a5d33d3f -F ext/userauth/userauth.c a66cd3abcc3b2c10b3999ab49f900d561e8ddd33 +F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 +F ext/userauth/userauth.c bcd1aedb0b810b1a1125945e637af54ce3d299f1 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -1057,7 +1057,7 @@ F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b -F test/userauth01.test 695ead5a47e8827dea283abca69c121b679176af +F test/userauth01.test 3be4d454af151aa8d59804f2fe4e593f367014c3 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 596e728b0eb19a34c888e33d4d37978ca2bf1e00 -R c54f70fc39612d9ea503f6c456a7ab1f +P 70121e7cf868b7d6d19bf98794ddc3809a901456 +R fc5d3c327123005770c7e41594123732 U drh -Z e2993baf94376fc5d680228ffe933715 +Z 21dad64c9f9cfa4863908b784242b9b1 diff --git a/manifest.uuid b/manifest.uuid index a5702df9c7..5b03dbec59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70121e7cf868b7d6d19bf98794ddc3809a901456 \ No newline at end of file +52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 \ No newline at end of file diff --git a/test/userauth01.test b/test/userauth01.test index 60e617e3ba..9f0eb5d85a 100644 --- a/test/userauth01.test +++ b/test/userauth01.test @@ -70,5 +70,47 @@ do_test userauth01-1.5 { } } {NULL 1 2.5 'three' X'4444' alice 1 sqlite_user t1} +# The sqlite3_user_add() interface can be used (by an admin user only) +# to create a new user. +# +do_test userauth01-1.6 { + sqlite3_user_add db bob pw-4-bob 0 + sqlite3_user_add db cindy pw-4-cindy 0 + sqlite3_user_add db david pw-4-david 0 + execsql { + SELECT uname, isadmin FROM sqlite_user ORDER BY uname; + } +} {alice 1 bob 0 cindy 0 david 0} + +# The sqlite_user table is inaccessible (unreadable and unwriteable) to +# non-admin users and is read-only for admin users. However, if the same +# +do_test userauth01-1.7 { + sqlite3 db2 test.db + sqlite3_user_authenticate db2 cindy pw-4-cindy + db2 eval { + SELECT quote(x) FROM t1 ORDER BY x; + SELECT name FROM sqlite_master ORDER BY name; + } +} {NULL 1 2.5 'three' X'4444' sqlite_user t1} +do_test userauth01-1.8 { + catchsql { + SELECT uname, isadmin FROM sqlite_user ORDER BY uname; + } db2 +} {1 {no such table: sqlite_user}} + +# Any user can change their own password. +# +do_test userauth01-1.9 { + sqlite3_user_change db2 cindy xyzzy-cindy 0 +} {SQLITE_OK} +do_test userauth01-1.10 { + sqlite3_user_authenticate db2 cindy pw-4-cindy +} {SQLITE_AUTH} +do_test userauth01-1.11 { + sqlite3_user_authenticate db2 cindy xyzzy-cindy +} {SQLITE_OK} + + finish_test