int sqlite3_user_authenticate(
sqlite3 *db, /* The database connection */
const char *zUsername, /* Username */
- int nPW, /* Number of bytes in aPW[] */
- const char *aPW /* Password or credentials */
+ const char *aPW, /* Password or credentials */
+ int nPW /* Number of bytes in aPW[] */
);
/*
int sqlite3_user_add(
sqlite3 *db, /* Database connection */
const char *zUsername, /* Username to be added */
- int isAdmin, /* True to give new user admin privilege */
+ const char *aPW, /* Password or credentials */
int nPW, /* Number of bytes in aPW[] */
- const char *aPW /* Password or credentials */
+ int isAdmin /* True to give new user admin privilege */
);
/*
int sqlite3_user_change(
sqlite3 *db, /* Database connection */
const char *zUsername, /* Username to change */
- int isAdmin, /* Modified admin privilege for the user */
+ const char *aPW, /* New password or credentials */
int nPW, /* Number of bytes in aPW[] */
- const char *aPW /* Modified password or credentials */
+ int isAdmin /* Modified admin privilege for the user */
);
/*
int sqlite3_user_authenticate(
sqlite3 *db, /* The database connection */
const char *zUsername, /* Username */
- int nPW, /* Number of bytes in aPW[] */
- const void *aPW /* Password or credentials */
+ const char *aPW, /* Password or credentials */
+ int nPW /* Number of bytes in aPW[] */
);
int sqlite3_user_add(
sqlite3 *db, /* Database connection */
const char *zUsername, /* Username to be added */
- int isAdmin, /* True to give new user admin privilege */
+ const char *aPW, /* Password or credentials */
int nPW, /* Number of bytes in aPW[] */
- const void *aPW /* Password or credentials */
+ int isAdmin /* True to give new user admin privilege */
);
int sqlite3_user_change(
sqlite3 *db, /* Database connection */
const char *zUsername, /* Username to change */
- int isAdmin, /* Modified admin privilege for the user */
+ const void *aPW, /* Modified password or credentials */
int nPW, /* Number of bytes in aPW[] */
- const void *aPW /* Modified password or credentials */
+ int isAdmin /* Modified admin privilege for the user */
);
int sqlite3_user_delete(
The sqlite3_user_add() interface can be used (by an admin user only)
to create a new user. When called on a no-authentication-required
-database, this routine converts the database into an authentication-
-required database [3], automatically makes the added user an
-administrator [1b], and logs in the current connection as that user [1a].
-The sqlite3_user_add() interface only works for the "main" database, not
-for any ATTACH-ed databases. Any call to sqlite3_user_add() by a
-non-admin user results in an error.
+database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine
+converts the database into an authentication-required database and
+logs the database connection D in using user U with password P,N.
+To convert a no-authentication-required database into an authentication-
+required database, the isAdmin parameter must be true. If
+sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required
+database and A is false, then the call fails with an SQLITE_AUTH error.
+
+Any call to sqlite3_user_add() by a non-admin user results in an error.
Hence, to create a new, unencrypted, authentication-required database,
the call sequence is:
int sqlite3_user_authenticate(
sqlite3 *db, /* The database connection */
const char *zUsername, /* Username */
- int nPW, /* Number of bytes in aPW[] */
- const char *zPW /* Password or credentials */
+ const char *zPW, /* Password or credentials */
+ int nPW /* Number of bytes in aPW[] */
){
int rc;
u8 authLevel = UAUTH_Fail;
int sqlite3_user_add(
sqlite3 *db, /* Database connection */
const char *zUsername, /* Username to be added */
- int isAdmin, /* True to give new user admin privilege */
+ const char *aPW, /* Password or credentials */
int nPW, /* Number of bytes in aPW[] */
- const char *aPW /* Password or credentials */
+ int isAdmin /* True to give new user admin privilege */
){
sqlite3_stmt *pStmt;
int rc;
if( rc ) return rc;
if( db->auth.zAuthUser==0 ){
assert( isAdmin!=0 );
- sqlite3_user_authenticate(db, zUsername, nPW, aPW);
+ sqlite3_user_authenticate(db, zUsername, aPW, nPW);
}
return SQLITE_OK;
}
int sqlite3_user_change(
sqlite3 *db, /* Database connection */
const char *zUsername, /* Username to change */
- int isAdmin, /* Modified admin privilege for the user */
+ const char *aPW, /* Modified password or credentials */
int nPW, /* Number of bytes in aPW[] */
- const char *aPW /* Modified password or credentials */
+ int isAdmin /* Modified admin privilege for the user */
){
sqlite3_stmt *pStmt;
if( db->auth.authLevel<UAUTH_User ){
-C Complete\sthe\simplementation\sof\sthe\svarious\sAPIs.\s\sFix\sseveral\sproblems.\nThis\sis\sanother\sincremental\scheck-in\sthat\sdoes\snot\scompletely\swork.
-D 2014-09-10T22:46:46.526
+C Reorder\sparameters\son\sthe\ssqlite3_user_*()\sinterfaces\sfor\sconsistency.\nAdd\sthe\sfirst\sTCL\stest\scases.
+D 2014-09-11T00:27:53.371
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
-F ext/userauth/sqlite3userauth.h 6e15b0006e7b07b7b008c9f9297b3781a7514337
-F ext/userauth/user-auth.txt f471c5a363ab0682b109d85982ea857f9a144ccc
-F ext/userauth/userauth.c e14ab212e1e2cd3f3a5d324f2c3e0b0c5a950c86
+F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
+F ext/userauth/user-auth.txt a0340e6219f0b70fde57502c8f6b1c5fdb23023e
+F ext/userauth/userauth.c a66cd3abcc3b2c10b3999ab49f900d561e8ddd33
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a
-F src/shell.c 4dac2ec625fb15a51b06ab998e7cec8c1e6a40eb
+F src/shell.c 7d26b6526fb9daab994265446b751fb86fd9d675
F src/sqlite.h.in 577876beef2264a0b031c0d744c81855983088f9
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08
F src/tclsqlite.c 8d6d6833c0053f0b3b1aeb1c5c7a7eeff0ad4d3f
-F src/test1.c 22bfe1ce9f2f3746d682093a475ec0a33e0e55d8
+F src/test1.c 523cd70ded28db71af9a30ec184cbe0957de9575
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8
F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb
F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
+F test/userauth01.test 695ead5a47e8827dea283abca69c121b679176af
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P a0455f9deb603bf91684158d911269622720fc1a
-R 7c5d50077d463af5ab8f09588f919ad0
+P 4eaaa7fa87aa912d24f8b35440ab60310dc08310
+R b62ab47ef5a1f118b5c6bf446676036b
U drh
-Z 0eb3e0d5d27e81783efc050a8d458d7f
+Z 388f9ca2f5e0d91d315989cc617a17a1
-4eaaa7fa87aa912d24f8b35440ab60310dc08310
\ No newline at end of file
+2f6d8f32eef526b5912f42ab467e3c7812480d8b
\ No newline at end of file
rc = 1;
goto meta_command_exit;
}
- rc = sqlite3_user_authenticate(p->db, azArg[2], (int)strlen(azArg[3]), azArg[3]);
+ rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
+ (int)strlen(azArg[3]));
if( rc ){
fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
rc = 1;
}
}else if( strcmp(azArg[1],"add")==0 ){
if( nArg!=5 ){
- fprintf(stderr, "Usage: .user add USER ISADMIN PASSWORD\n");
+ fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
rc = 1;
goto meta_command_exit;
}
- rc = sqlite3_user_add(p->db, azArg[2], booleanValue(azArg[3]),
- (int)strlen(azArg[4]), azArg[4]);
+ rc = sqlite3_user_add(p->db, azArg[2],
+ azArg[3], (int)strlen(azArg[3]),
+ booleanValue(azArg[4]));
if( rc ){
fprintf(stderr, "User-Add failed: %d\n", rc);
rc = 1;
}
}else if( strcmp(azArg[1],"edit")==0 ){
if( nArg!=5 ){
- fprintf(stderr, "Usage: .user edit USER ISADMIN PASSWORD\n");
+ fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
rc = 1;
goto meta_command_exit;
}
- rc = sqlite3_user_change(p->db, azArg[2], booleanValue(azArg[3]),
- (int)strlen(azArg[4]), azArg[4]);
+ rc = sqlite3_user_change(p->db, azArg[2],
+ azArg[3], (int)strlen(azArg[3]),
+ booleanValue(azArg[4]));
if( rc ){
fprintf(stderr, "User-Edit failed: %d\n", rc);
rc = 1;
}
+#ifdef SQLITE_USER_AUTHENTICATION
+#include "sqlite3userauth.h"
+/*
+** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD
+*/
+static int test_user_authenticate(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ char *zUser = 0;
+ char *zPasswd = 0;
+ int nPasswd = 0;
+ sqlite3 *db;
+ int rc;
+
+ if( objc!=4 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD");
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ zUser = Tcl_GetString(objv[2]);
+ zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
+ rc = sqlite3_user_authenticate(db, zUser, zPasswd, nPasswd);
+ Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
+ return TCL_OK;
+}
+#endif /* SQLITE_USER_AUTHENTICATION */
+
+#ifdef SQLITE_USER_AUTHENTICATION
+/*
+** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN
+*/
+static int test_user_add(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ char *zUser = 0;
+ char *zPasswd = 0;
+ int nPasswd = 0;
+ int isAdmin = 0;
+ sqlite3 *db;
+ int rc;
+
+ if( objc!=5 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ zUser = Tcl_GetString(objv[2]);
+ zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
+ Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
+ rc = sqlite3_user_add(db, zUser, zPasswd, nPasswd, isAdmin);
+ Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
+ return TCL_OK;
+}
+#endif /* SQLITE_USER_AUTHENTICATION */
+
+#ifdef SQLITE_USER_AUTHENTICATION
+/*
+** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN
+*/
+static int test_user_change(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ char *zUser = 0;
+ char *zPasswd = 0;
+ int nPasswd = 0;
+ int isAdmin = 0;
+ sqlite3 *db;
+ int rc;
+
+ if( objc!=5 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ zUser = Tcl_GetString(objv[2]);
+ zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
+ Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
+ rc = sqlite3_user_change(db, zUser, zPasswd, nPasswd, isAdmin);
+ Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
+ return TCL_OK;
+}
+#endif /* SQLITE_USER_AUTHENTICATION */
+
+#ifdef SQLITE_USER_AUTHENTICATION
+/*
+** tclcmd: sqlite3_user_delete DB USERNAME
+*/
+static int test_user_delete(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ char *zUser = 0;
+ sqlite3 *db;
+ int rc;
+
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME");
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ zUser = Tcl_GetString(objv[2]);
+ rc = sqlite3_user_delete(db, zUser);
+ Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
+ return TCL_OK;
+}
+#endif /* SQLITE_USER_AUTHENTICATION */
+
/*
** Register commands with the TCL interpreter.
*/
{ "load_static_extension", tclLoadStaticExtensionCmd },
{ "sorter_test_fakeheap", sorter_test_fakeheap },
{ "sorter_test_sort4_helper", sorter_test_sort4_helper },
+#ifdef SQLITE_USER_AUTHENTICATION
+ { "sqlite3_user_authenticate", test_user_authenticate, 0 },
+ { "sqlite3_user_add", test_user_add, 0 },
+ { "sqlite3_user_change", test_user_change, 0 },
+ { "sqlite3_user_delete", test_user_delete, 0 },
+#endif
+
};
static int bitmask_size = sizeof(Bitmask)*8;
int i;
--- /dev/null
+# 2014-09-10
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This file implements tests of the SQLITE_USER_AUTHENTICATION extension.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix userauth01
+
+ifcapable !userauth {
+ finish_test
+ return
+}
+
+# Create a no-authentication-required database
+#
+do_execsql_test userauth01-1.0 {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(1),(2.5),('three'),(x'4444'),(NULL);
+ SELECT quote(x) FROM t1 ORDER BY x;
+ SELECT name FROM sqlite_master;
+} {NULL 1 2.5 'three' X'4444' t1}
+
+# Calling sqlite3_user_authenticate() on a no-authentication-required
+# database connection is a harmless no-op.
+#
+do_test userauth01-1.1 {
+ sqlite3_user_authenticate db alice pw-4-alice
+ execsql {
+ SELECT quote(x) FROM t1 ORDER BY x;
+ SELECT name FROM sqlite_master;
+ }
+} {NULL 1 2.5 'three' X'4444' t1}
+
+# If sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required
+# database and A is false, then the call fails with an SQLITE_AUTH error.
+#
+do_test userauth01-1.2 {
+ sqlite3_user_add db bob pw-4-bob 0
+} {SQLITE_AUTH}
+do_test userauth01-1.3 {
+ execsql {
+ SELECT quote(x) FROM t1 ORDER BY x;
+ SELECT name FROM sqlite_master;
+ }
+} {NULL 1 2.5 'three' X'4444' t1}
+
+# When called on a no-authentication-required
+# database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine
+# converts the database into an authentication-required database and
+# logs the database connection D in using user U with password P,N.
+#
+do_test userauth01-1.4 {
+ sqlite3_user_add db alice pw-4-alice 1
+} {SQLITE_OK}
+do_test userauth01-1.5 {
+ execsql {
+ SELECT quote(x) FROM t1 ORDER BY x;
+ SELECT uname, isadmin FROM sqlite_user ORDER BY uname;
+ SELECT name FROM sqlite_master ORDER BY name;
+ }
+} {NULL 1 2.5 'three' X'4444' alice 1 sqlite_user t1}
+
+
+finish_test