1Activate the user authentication logic by including the 2ext/userauth/userauth.c source code file in the build and 3adding the -DSQLITE_USER_AUTHENTICATION compile-time option. 4The ext/userauth/sqlite3userauth.h header file is available to 5applications to define the interface. 6 7When using the SQLite amalgamation, it is sufficient to append 8the ext/userauth/userauth.c source file onto the end of the 9amalgamation. 10 11The following new APIs are available when user authentication is 12activated: 13 14 int sqlite3_user_authenticate( 15 sqlite3 *db, /* The database connection */ 16 const char *zUsername, /* Username */ 17 const char *aPW, /* Password or credentials */ 18 int nPW /* Number of bytes in aPW[] */ 19 ); 20 21 int sqlite3_user_add( 22 sqlite3 *db, /* Database connection */ 23 const char *zUsername, /* Username to be added */ 24 const char *aPW, /* Password or credentials */ 25 int nPW, /* Number of bytes in aPW[] */ 26 int isAdmin /* True to give new user admin privilege */ 27 ); 28 29 int sqlite3_user_change( 30 sqlite3 *db, /* Database connection */ 31 const char *zUsername, /* Username to change */ 32 const void *aPW, /* Modified password or credentials */ 33 int nPW, /* Number of bytes in aPW[] */ 34 int isAdmin /* Modified admin privilege for the user */ 35 ); 36 37 int sqlite3_user_delete( 38 sqlite3 *db, /* Database connection */ 39 const char *zUsername /* Username to remove */ 40 ); 41 42With this extension, a database can be marked as requiring authentication. 43By default a database does not require authentication. 44 45The sqlite3_open(), sqlite3_open16(), and sqlite3_open_v2() interfaces 46work as before: they open a new database connection. However, if the 47database being opened requires authentication, then attempts to read 48or write from the database will fail with an SQLITE_AUTH error until 49after sqlite3_user_authenticate() has been called successfully. The 50sqlite3_user_authenticate() call will return SQLITE_OK if the 51authentication credentials are accepted and SQLITE_ERROR if not. 52 53Calling sqlite3_user_authenticate() on a no-authentication-required 54database connection is a harmless no-op. 55 56If the database is encrypted, then sqlite3_key_v2() must be called first, 57with the correct decryption key, prior to invoking sqlite3_user_authenticate(). 58 59To recapitulate: When opening an existing unencrypted authentication- 60required database, the call sequence is: 61 62 sqlite3_open_v2() 63 sqlite3_user_authenticate(); 64 /* Database is now usable */ 65 66To open an existing, encrypted, authentication-required database, the 67call sequence is: 68 69 sqlite3_open_v2(); 70 sqlite3_key_v2(); 71 sqlite3_user_authenticate(); 72 /* Database is now usable */ 73 74When opening a no-authentication-required database, the database 75connection is treated as if it was authenticated as an admin user. 76 77When ATTACH-ing new database files to a connection, each newly attached 78database that is an authentication-required database is checked using 79the same username and password as supplied to the main database. If that 80check fails, then the ATTACH command fails with an SQLITE_AUTH error. 81 82The sqlite3_user_add() interface can be used (by an admin user only) 83to create a new user. When called on a no-authentication-required 84database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine 85converts the database into an authentication-required database and 86logs in the database connection D as user U with password P,N. 87To convert a no-authentication-required database into an authentication- 88required database, the isAdmin parameter must be true. If 89sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required 90database and A is false, then the call fails with an SQLITE_AUTH error. 91 92Any call to sqlite3_user_add() by a non-admin user results in an error. 93 94Hence, to create a new, unencrypted, authentication-required database, 95the call sequence is: 96 97 sqlite3_open_v2(); 98 sqlite3_user_add(); 99 100And to create a new, encrypted, authentication-required database, the call 101sequence is: 102 103 sqlite3_open_v2(); 104 sqlite3_key_v2(); 105 sqlite3_user_add(); 106 107The sqlite3_user_delete() interface can be used (by an admin user only) 108to delete a user. The currently logged-in user cannot be deleted, 109which guarantees that there is always an admin user and hence that 110the database cannot be converted into a no-authentication-required 111database. 112 113The sqlite3_user_change() interface can be used to change a users 114login credentials or admin privilege. Any user can change their own 115password. Only an admin user can change another users login 116credentials or admin privilege setting. No user may change their own 117admin privilege setting. 118 119The sqlite3_set_authorizer() callback is modified to take a 7th parameter 120which is the username of the currently logged in user, or NULL for a 121no-authentication-required database. 122 123----------------------------------------------------------------------------- 124Implementation notes: 125 126An authentication-required database is identified by the presence of a 127new table: 128 129 CREATE TABLE sqlite_user( 130 uname TEXT PRIMARY KEY, 131 isAdmin BOOLEAN, 132 pw BLOB 133 ) WITHOUT ROWID; 134 135The sqlite_user table is inaccessible (unreadable and unwriteable) to 136non-admin users and is read-only for admin users. However, if the same 137database file is opened by a version of SQLite that omits 138the -DSQLITE_USER_AUTHENTICATION compile-time option, then the sqlite_user 139table will be readable by anybody and writeable by anybody if 140the "PRAGMA writable_schema=ON" statement is run first. 141 142The sqlite_user.pw field is encoded by a built-in SQL function 143"sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument 144is the plaintext password supplied to the sqlite3_user_authenticate() 145interface. The second argument is the sqlite_user.pw value and is supplied 146so that the function can extract the "salt" used by the password encoder. 147The result of sqlite_crypt(X,Y) is another blob which is the value that 148ends up being stored in sqlite_user.pw. To verify credentials X supplied 149by the sqlite3_user_authenticate() routine, SQLite runs: 150 151 sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw) 152 153To compute an appropriate sqlite_user.pw value from a new or modified 154password X, sqlite_crypt(X,NULL) is run. A new random salt is selected 155when the second argument is NULL. 156 157The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher 158which prevents passwords from being revealed by searching the raw database 159for ASCII text, but is otherwise trivally broken. For better password 160security, the database should be encrypted using the SQLite Encryption 161Extension or similar technology. Or, the application can use the 162sqlite3_create_function() interface to provide an alternative 163implementation of sqlite_crypt() that computes a stronger password hash, 164perhaps using a cryptographic hash function like SHA1. 165