xref: /sqlite-3.40.0/ext/userauth/userauth.c (revision 39ef8b31)
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