1d4530979Sdrh /*
2d4530979Sdrh ** 2014-09-08
3d4530979Sdrh **
4d4530979Sdrh ** The author disclaims copyright to this source code. In place of
5d4530979Sdrh ** a legal notice, here is a blessing:
6d4530979Sdrh **
7d4530979Sdrh ** May you do good and not evil.
8d4530979Sdrh ** May you find forgiveness for yourself and forgive others.
9d4530979Sdrh ** May you share freely, never taking more than you give.
10d4530979Sdrh **
11d4530979Sdrh *************************************************************************
12d4530979Sdrh **
13d4530979Sdrh ** This file contains the bulk of the implementation of the
14d4530979Sdrh ** user-authentication extension feature. Some parts of the user-
15d4530979Sdrh ** authentication code are contained within the SQLite core (in the
16d4530979Sdrh ** src/ subdirectory of the main source code tree) but those parts
17d4530979Sdrh ** that could reasonable be separated out are moved into this file.
18d4530979Sdrh **
19d4530979Sdrh ** To compile with the user-authentication feature, append this file to
20d4530979Sdrh ** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION
21d4530979Sdrh ** compile-time option. See the user-auth.txt file in the same source
22d4530979Sdrh ** directory as this file for additional information.
23d4530979Sdrh */
24d4530979Sdrh #ifdef SQLITE_USER_AUTHENTICATION
25666d34c7Sdrh #ifndef SQLITEINT_H
26e933b83fSdrh # include "sqliteInt.h"
27c891c6c7Sdrh #endif
28d4530979Sdrh
29d4530979Sdrh /*
30d4530979Sdrh ** Prepare an SQL statement for use by the user authentication logic.
31d4530979Sdrh ** Return a pointer to the prepared statement on success. Return a
32d4530979Sdrh ** NULL pointer if there is an error of any kind.
33d4530979Sdrh */
sqlite3UserAuthPrepare(sqlite3 * db,const char * zFormat,...)34d4530979Sdrh static sqlite3_stmt *sqlite3UserAuthPrepare(
35d4530979Sdrh sqlite3 *db,
36d4530979Sdrh const char *zFormat,
37d4530979Sdrh ...
38d4530979Sdrh ){
39d4530979Sdrh sqlite3_stmt *pStmt;
40d4530979Sdrh char *zSql;
41d4530979Sdrh int rc;
42d4530979Sdrh va_list ap;
43*39ef8b31Sdan u64 savedFlags = db->flags;
44d4530979Sdrh
45d4530979Sdrh va_start(ap, zFormat);
46d4530979Sdrh zSql = sqlite3_vmprintf(zFormat, ap);
47d4530979Sdrh va_end(ap);
48d4530979Sdrh if( zSql==0 ) return 0;
4909e60541Sdrh db->flags |= SQLITE_WriteSchema;
50d4530979Sdrh rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
5109e60541Sdrh db->flags = savedFlags;
52d4530979Sdrh sqlite3_free(zSql);
53d4530979Sdrh if( rc ){
54d4530979Sdrh sqlite3_finalize(pStmt);
55d4530979Sdrh pStmt = 0;
56d4530979Sdrh }
57d4530979Sdrh return pStmt;
58d4530979Sdrh }
59d4530979Sdrh
60d4530979Sdrh /*
61f442e33eSdrh ** Check to see if the sqlite_user table exists in database zDb.
62f442e33eSdrh */
userTableExists(sqlite3 * db,const char * zDb)63f442e33eSdrh static int userTableExists(sqlite3 *db, const char *zDb){
64f442e33eSdrh int rc;
65f442e33eSdrh sqlite3_mutex_enter(db->mutex);
66f442e33eSdrh sqlite3BtreeEnterAll(db);
6709e60541Sdrh if( db->init.busy==0 ){
6809e60541Sdrh char *zErr = 0;
6909e60541Sdrh sqlite3Init(db, &zErr);
7009e60541Sdrh sqlite3DbFree(db, zErr);
7109e60541Sdrh }
72f442e33eSdrh rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0;
73f442e33eSdrh sqlite3BtreeLeaveAll(db);
74f442e33eSdrh sqlite3_mutex_leave(db->mutex);
75f442e33eSdrh return rc;
76f442e33eSdrh }
77f442e33eSdrh
78f442e33eSdrh /*
79d4530979Sdrh ** Check to see if database zDb has a "sqlite_user" table and if it does
80e933b83fSdrh ** whether that table can authenticate zUser with nPw,zPw. Write one of
81e933b83fSdrh ** the UAUTH_* user authorization level codes into *peAuth and return a
82e933b83fSdrh ** result code.
83d4530979Sdrh */
userAuthCheckLogin(sqlite3 * db,const char * zDb,u8 * peAuth)84e933b83fSdrh static int userAuthCheckLogin(
85d4530979Sdrh sqlite3 *db, /* The database connection to check */
86d4530979Sdrh const char *zDb, /* Name of specific database to check */
87e933b83fSdrh u8 *peAuth /* OUT: One of UAUTH_* constants */
88d4530979Sdrh ){
89d4530979Sdrh sqlite3_stmt *pStmt;
90d4530979Sdrh int rc;
91d4530979Sdrh
92e933b83fSdrh *peAuth = UAUTH_Unknown;
93f442e33eSdrh if( !userTableExists(db, "main") ){
94e933b83fSdrh *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */
9509e60541Sdrh return SQLITE_OK;
96d4530979Sdrh }
97e933b83fSdrh if( db->auth.zAuthUser==0 ){
98e933b83fSdrh *peAuth = UAUTH_Fail;
99e933b83fSdrh return SQLITE_OK;
100e933b83fSdrh }
101d4530979Sdrh pStmt = sqlite3UserAuthPrepare(db,
102d4530979Sdrh "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user"
103d4530979Sdrh " WHERE uname=?2", zDb);
104d4530979Sdrh if( pStmt==0 ) return SQLITE_NOMEM;
105e933b83fSdrh sqlite3_bind_blob(pStmt, 1, db->auth.zAuthPW, db->auth.nAuthPW,SQLITE_STATIC);
106e933b83fSdrh sqlite3_bind_text(pStmt, 2, db->auth.zAuthUser, -1, SQLITE_STATIC);
107e933b83fSdrh rc = sqlite3_step(pStmt);
108d4530979Sdrh if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){
109e933b83fSdrh *peAuth = sqlite3_column_int(pStmt, 1) + UAUTH_User;
110e933b83fSdrh }else{
111e933b83fSdrh *peAuth = UAUTH_Fail;
112d4530979Sdrh }
11309e60541Sdrh return sqlite3_finalize(pStmt);
114d4530979Sdrh }
sqlite3UserAuthCheckLogin(sqlite3 * db,const char * zDb,u8 * peAuth)115e933b83fSdrh int sqlite3UserAuthCheckLogin(
116e933b83fSdrh sqlite3 *db, /* The database connection to check */
117e933b83fSdrh const char *zDb, /* Name of specific database to check */
118e933b83fSdrh u8 *peAuth /* OUT: One of UAUTH_* constants */
119e933b83fSdrh ){
120e933b83fSdrh int rc;
121e933b83fSdrh u8 savedAuthLevel;
1227883ecfcSdrh assert( zDb!=0 );
1237883ecfcSdrh assert( peAuth!=0 );
124e933b83fSdrh savedAuthLevel = db->auth.authLevel;
125e933b83fSdrh db->auth.authLevel = UAUTH_Admin;
126e933b83fSdrh rc = userAuthCheckLogin(db, zDb, peAuth);
127e933b83fSdrh db->auth.authLevel = savedAuthLevel;
128e933b83fSdrh return rc;
129e933b83fSdrh }
130e933b83fSdrh
131f442e33eSdrh /*
1327883ecfcSdrh ** If the current authLevel is UAUTH_Unknown, the take actions to figure
1337883ecfcSdrh ** out what authLevel should be
1347883ecfcSdrh */
sqlite3UserAuthInit(sqlite3 * db)1357883ecfcSdrh void sqlite3UserAuthInit(sqlite3 *db){
1367883ecfcSdrh if( db->auth.authLevel==UAUTH_Unknown ){
1377883ecfcSdrh u8 authLevel = UAUTH_Fail;
1387883ecfcSdrh sqlite3UserAuthCheckLogin(db, "main", &authLevel);
1397883ecfcSdrh db->auth.authLevel = authLevel;
1407883ecfcSdrh if( authLevel<UAUTH_Admin ) db->flags &= ~SQLITE_WriteSchema;
1417883ecfcSdrh }
1427883ecfcSdrh }
1437883ecfcSdrh
1447883ecfcSdrh /*
145f442e33eSdrh ** Implementation of the sqlite_crypt(X,Y) function.
146f442e33eSdrh **
147f442e33eSdrh ** If Y is NULL then generate a new hash for password X and return that
148f442e33eSdrh ** hash. If Y is not null, then generate a hash for password X using the
149f442e33eSdrh ** same salt as the previous hash Y and return the new hash.
150f442e33eSdrh */
sqlite3CryptFunc(sqlite3_context * context,int NotUsed,sqlite3_value ** argv)151f442e33eSdrh void sqlite3CryptFunc(
152f442e33eSdrh sqlite3_context *context,
153f442e33eSdrh int NotUsed,
154f442e33eSdrh sqlite3_value **argv
155f442e33eSdrh ){
156f442e33eSdrh const char *zIn;
157f442e33eSdrh int nIn, ii;
158f442e33eSdrh u8 *zOut;
159f442e33eSdrh char zSalt[8];
160f442e33eSdrh zIn = sqlite3_value_blob(argv[0]);
161f442e33eSdrh nIn = sqlite3_value_bytes(argv[0]);
162f442e33eSdrh if( sqlite3_value_type(argv[1])==SQLITE_BLOB
163f442e33eSdrh && sqlite3_value_bytes(argv[1])==nIn+sizeof(zSalt)
164f442e33eSdrh ){
165f442e33eSdrh memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt));
166f442e33eSdrh }else{
167f442e33eSdrh sqlite3_randomness(sizeof(zSalt), zSalt);
168f442e33eSdrh }
169f442e33eSdrh zOut = sqlite3_malloc( nIn+sizeof(zSalt) );
170f442e33eSdrh if( zOut==0 ){
171f442e33eSdrh sqlite3_result_error_nomem(context);
172f442e33eSdrh }else{
173f442e33eSdrh memcpy(zOut, zSalt, sizeof(zSalt));
174f442e33eSdrh for(ii=0; ii<nIn; ii++){
175f442e33eSdrh zOut[ii+sizeof(zSalt)] = zIn[ii]^zSalt[ii&0x7];
176f442e33eSdrh }
177f442e33eSdrh sqlite3_result_blob(context, zOut, nIn+sizeof(zSalt), sqlite3_free);
178f442e33eSdrh }
179f442e33eSdrh }
180d4530979Sdrh
181d4530979Sdrh /*
182d4530979Sdrh ** If a database contains the SQLITE_USER table, then the
183d4530979Sdrh ** sqlite3_user_authenticate() interface must be invoked with an
184d4530979Sdrh ** appropriate username and password prior to enable read and write
185d4530979Sdrh ** access to the database.
186d4530979Sdrh **
187d4530979Sdrh ** Return SQLITE_OK on success or SQLITE_ERROR if the username/password
188d4530979Sdrh ** combination is incorrect or unknown.
189d4530979Sdrh **
190d4530979Sdrh ** If the SQLITE_USER table is not present in the database file, then
191d4530979Sdrh ** this interface is a harmless no-op returnning SQLITE_OK.
192d4530979Sdrh */
sqlite3_user_authenticate(sqlite3 * db,const char * zUsername,const char * zPW,int nPW)193d4530979Sdrh int sqlite3_user_authenticate(
194d4530979Sdrh sqlite3 *db, /* The database connection */
195d4530979Sdrh const char *zUsername, /* Username */
196d39c40ffSdrh const char *zPW, /* Password or credentials */
197d39c40ffSdrh int nPW /* Number of bytes in aPW[] */
198d4530979Sdrh ){
199d4530979Sdrh int rc;
200e933b83fSdrh u8 authLevel = UAUTH_Fail;
201e933b83fSdrh db->auth.authLevel = UAUTH_Unknown;
202d4530979Sdrh sqlite3_free(db->auth.zAuthUser);
203e933b83fSdrh sqlite3_free(db->auth.zAuthPW);
204e933b83fSdrh memset(&db->auth, 0, sizeof(db->auth));
205e933b83fSdrh db->auth.zAuthUser = sqlite3_mprintf("%s", zUsername);
206e933b83fSdrh if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM;
207e933b83fSdrh db->auth.zAuthPW = sqlite3_malloc( nPW+1 );
208e933b83fSdrh if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM;
209e933b83fSdrh memcpy(db->auth.zAuthPW,zPW,nPW);
210e933b83fSdrh db->auth.nAuthPW = nPW;
211e933b83fSdrh rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel);
212e933b83fSdrh db->auth.authLevel = authLevel;
21385c6892aSdan sqlite3ExpirePreparedStatements(db, 0);
214e933b83fSdrh if( rc ){
215e933b83fSdrh return rc; /* OOM error, I/O error, etc. */
216d4530979Sdrh }
217e933b83fSdrh if( authLevel<UAUTH_User ){
218e933b83fSdrh return SQLITE_AUTH; /* Incorrect username and/or password */
219d4530979Sdrh }
220e933b83fSdrh return SQLITE_OK; /* Successful login */
221d4530979Sdrh }
222d4530979Sdrh
223d4530979Sdrh /*
224d4530979Sdrh ** The sqlite3_user_add() interface can be used (by an admin user only)
225d4530979Sdrh ** to create a new user. When called on a no-authentication-required
226d4530979Sdrh ** database, this routine converts the database into an authentication-
227d4530979Sdrh ** required database, automatically makes the added user an
228d4530979Sdrh ** administrator, and logs in the current connection as that user.
229d4530979Sdrh ** The sqlite3_user_add() interface only works for the "main" database, not
230d4530979Sdrh ** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a
231d4530979Sdrh ** non-admin user results in an error.
232d4530979Sdrh */
sqlite3_user_add(sqlite3 * db,const char * zUsername,const char * aPW,int nPW,int isAdmin)233d4530979Sdrh int sqlite3_user_add(
234d4530979Sdrh sqlite3 *db, /* Database connection */
235d4530979Sdrh const char *zUsername, /* Username to be added */
236d39c40ffSdrh const char *aPW, /* Password or credentials */
237d4530979Sdrh int nPW, /* Number of bytes in aPW[] */
238d39c40ffSdrh int isAdmin /* True to give new user admin privilege */
239d4530979Sdrh ){
240f442e33eSdrh sqlite3_stmt *pStmt;
241f442e33eSdrh int rc;
2427883ecfcSdrh sqlite3UserAuthInit(db);
243f442e33eSdrh if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH;
244f442e33eSdrh if( !userTableExists(db, "main") ){
245f442e33eSdrh if( !isAdmin ) return SQLITE_AUTH;
246f442e33eSdrh pStmt = sqlite3UserAuthPrepare(db,
247f442e33eSdrh "CREATE TABLE sqlite_user(\n"
248f442e33eSdrh " uname TEXT PRIMARY KEY,\n"
249f442e33eSdrh " isAdmin BOOLEAN,\n"
250f442e33eSdrh " pw BLOB\n"
251f442e33eSdrh ") WITHOUT ROWID;");
252f442e33eSdrh if( pStmt==0 ) return SQLITE_NOMEM;
253f442e33eSdrh sqlite3_step(pStmt);
254f442e33eSdrh rc = sqlite3_finalize(pStmt);
255f442e33eSdrh if( rc ) return rc;
256f442e33eSdrh }
257f442e33eSdrh pStmt = sqlite3UserAuthPrepare(db,
25809e60541Sdrh "INSERT INTO sqlite_user(uname,isAdmin,pw)"
25909e60541Sdrh " VALUES(%Q,%d,sqlite_crypt(?1,NULL))",
260f442e33eSdrh zUsername, isAdmin!=0);
261f442e33eSdrh if( pStmt==0 ) return SQLITE_NOMEM;
262f442e33eSdrh sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
263f442e33eSdrh sqlite3_step(pStmt);
264f442e33eSdrh rc = sqlite3_finalize(pStmt);
265f442e33eSdrh if( rc ) return rc;
266f442e33eSdrh if( db->auth.zAuthUser==0 ){
267f442e33eSdrh assert( isAdmin!=0 );
268d39c40ffSdrh sqlite3_user_authenticate(db, zUsername, aPW, nPW);
269f442e33eSdrh }
270d4530979Sdrh return SQLITE_OK;
271d4530979Sdrh }
272d4530979Sdrh
273d4530979Sdrh /*
274d4530979Sdrh ** The sqlite3_user_change() interface can be used to change a users
275d4530979Sdrh ** login credentials or admin privilege. Any user can change their own
276d4530979Sdrh ** login credentials. Only an admin user can change another users login
277d4530979Sdrh ** credentials or admin privilege setting. No user may change their own
278d4530979Sdrh ** admin privilege setting.
279d4530979Sdrh */
sqlite3_user_change(sqlite3 * db,const char * zUsername,const char * aPW,int nPW,int isAdmin)280d4530979Sdrh int sqlite3_user_change(
281d4530979Sdrh sqlite3 *db, /* Database connection */
282d4530979Sdrh const char *zUsername, /* Username to change */
283d39c40ffSdrh const char *aPW, /* Modified password or credentials */
284d4530979Sdrh int nPW, /* Number of bytes in aPW[] */
285d39c40ffSdrh int isAdmin /* Modified admin privilege for the user */
286d4530979Sdrh ){
28709e60541Sdrh sqlite3_stmt *pStmt;
288570f187fSdrh int rc;
289570f187fSdrh u8 authLevel;
290570f187fSdrh
291570f187fSdrh authLevel = db->auth.authLevel;
292570f187fSdrh if( authLevel<UAUTH_User ){
29309e60541Sdrh /* Must be logged in to make a change */
29409e60541Sdrh return SQLITE_AUTH;
29509e60541Sdrh }
29609e60541Sdrh if( strcmp(db->auth.zAuthUser, zUsername)!=0 ){
29709e60541Sdrh if( db->auth.authLevel<UAUTH_Admin ){
29809e60541Sdrh /* Must be an administrator to change a different user */
29909e60541Sdrh return SQLITE_AUTH;
30009e60541Sdrh }
301570f187fSdrh }else if( isAdmin!=(authLevel==UAUTH_Admin) ){
30209e60541Sdrh /* Cannot change the isAdmin setting for self */
30309e60541Sdrh return SQLITE_AUTH;
30409e60541Sdrh }
305570f187fSdrh db->auth.authLevel = UAUTH_Admin;
30609e60541Sdrh if( !userTableExists(db, "main") ){
30709e60541Sdrh /* This routine is a no-op if the user to be modified does not exist */
308570f187fSdrh }else{
30909e60541Sdrh pStmt = sqlite3UserAuthPrepare(db,
31009e60541Sdrh "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)"
31109e60541Sdrh " WHERE uname=%Q", isAdmin, zUsername);
312570f187fSdrh if( pStmt==0 ){
313570f187fSdrh rc = SQLITE_NOMEM;
314570f187fSdrh }else{
31509e60541Sdrh sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
31609e60541Sdrh sqlite3_step(pStmt);
317570f187fSdrh rc = sqlite3_finalize(pStmt);
318570f187fSdrh }
319570f187fSdrh }
320570f187fSdrh db->auth.authLevel = authLevel;
321570f187fSdrh return rc;
32209e60541Sdrh }
323d4530979Sdrh
324d4530979Sdrh /*
325d4530979Sdrh ** The sqlite3_user_delete() interface can be used (by an admin user only)
326d4530979Sdrh ** to delete a user. The currently logged-in user cannot be deleted,
327d4530979Sdrh ** which guarantees that there is always an admin user and hence that
328d4530979Sdrh ** the database cannot be converted into a no-authentication-required
329d4530979Sdrh ** database.
330d4530979Sdrh */
sqlite3_user_delete(sqlite3 * db,const char * zUsername)331d4530979Sdrh int sqlite3_user_delete(
332d4530979Sdrh sqlite3 *db, /* Database connection */
333d4530979Sdrh const char *zUsername /* Username to remove */
334d4530979Sdrh ){
33509e60541Sdrh sqlite3_stmt *pStmt;
33609e60541Sdrh if( db->auth.authLevel<UAUTH_Admin ){
33709e60541Sdrh /* Must be an administrator to delete a user */
33809e60541Sdrh return SQLITE_AUTH;
33909e60541Sdrh }
34009e60541Sdrh if( strcmp(db->auth.zAuthUser, zUsername)==0 ){
34109e60541Sdrh /* Cannot delete self */
34209e60541Sdrh return SQLITE_AUTH;
34309e60541Sdrh }
34409e60541Sdrh if( !userTableExists(db, "main") ){
34509e60541Sdrh /* This routine is a no-op if the user to be deleted does not exist */
346d4530979Sdrh return SQLITE_OK;
347d4530979Sdrh }
34809e60541Sdrh pStmt = sqlite3UserAuthPrepare(db,
3499d5b0df1Sdrh "DELETE FROM sqlite_user WHERE uname=%Q", zUsername);
35009e60541Sdrh if( pStmt==0 ) return SQLITE_NOMEM;
35109e60541Sdrh sqlite3_step(pStmt);
35209e60541Sdrh return sqlite3_finalize(pStmt);
35309e60541Sdrh }
354d4530979Sdrh
355d4530979Sdrh #endif /* SQLITE_USER_AUTHENTICATION */
356