mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Non-working preliminary implementation attempts on user authentication.
FossilOrigin-Name: 8440f093bac19a41d44ee352744354eab897fe4e
This commit is contained in:
151
ext/userauth/user-auth.txt
Normal file
151
ext/userauth/user-auth.txt
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
Activate the user authentication logic by compiling SQLite with
|
||||||
|
the -DSQLITE_USER_AUTHENTICATION compile-time option.
|
||||||
|
|
||||||
|
The following new APIs are available when user authentication is
|
||||||
|
activated:
|
||||||
|
|
||||||
|
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 */
|
||||||
|
);
|
||||||
|
|
||||||
|
int sqlite3_user_add(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername, /* Username to be added */
|
||||||
|
int isAdmin, /* True to give new user admin privilege */
|
||||||
|
int nPW, /* Number of bytes in aPW[] */
|
||||||
|
const void *aPW /* Password or credentials */
|
||||||
|
);
|
||||||
|
|
||||||
|
int sqlite3_user_change(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername, /* Username to change */
|
||||||
|
int isAdmin, /* Modified admin privilege for the user */
|
||||||
|
int nPW, /* Number of bytes in aPW[] */
|
||||||
|
const void *aPW /* Modified password or credentials */
|
||||||
|
);
|
||||||
|
|
||||||
|
int sqlite3_user_delete(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername /* Username to remove */
|
||||||
|
);
|
||||||
|
|
||||||
|
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 the database
|
||||||
|
connection will be unusable until after sqlite3_user_authenticate()
|
||||||
|
has been called successfully [1c]. 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.
|
||||||
|
|
||||||
|
If the database is encrypted, then sqlite3_key_v2() must be called first,
|
||||||
|
with the correct decryption key, prior to invoking sqlite3_user_authenticate().
|
||||||
|
|
||||||
|
To recapitulate: When opening an existing unencrypted authentication-
|
||||||
|
required database, the call sequence is:
|
||||||
|
|
||||||
|
sqlite3_open_v2()
|
||||||
|
sqlite3_user_authenticate();
|
||||||
|
/* Database is now usable */
|
||||||
|
|
||||||
|
To open an existing, encrypted, authentication-required database, the
|
||||||
|
call sequence is:
|
||||||
|
|
||||||
|
sqlite3_open_v2();
|
||||||
|
sqlite3_key_v2();
|
||||||
|
sqlite3_user_authenticate();
|
||||||
|
/* Database is now usable */
|
||||||
|
|
||||||
|
When opening a no-authentication-required database, the database
|
||||||
|
connection is treated as if it was authenticated as an admin user.
|
||||||
|
|
||||||
|
When ATTACH-ing new database files to a connection, each newly attached
|
||||||
|
database that is an authentication-required database is checked using
|
||||||
|
the same username and password as supplied to the main database. If that
|
||||||
|
check fails, then the ATTACH-ed database is unreadable [1g].
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Hence, to create a new, unencrypted, authentication-required database,
|
||||||
|
the call sequence is:
|
||||||
|
|
||||||
|
sqlite3_open_v2();
|
||||||
|
sqlite3_user_add();
|
||||||
|
|
||||||
|
And to create a new, encrypted, authentication-required database, the call
|
||||||
|
sequence is:
|
||||||
|
|
||||||
|
sqlite3_open_v2();
|
||||||
|
sqlite3_key_v2();
|
||||||
|
sqlite3_user_add();
|
||||||
|
|
||||||
|
The sqlite3_user_delete() interface can be used (by an admin user only)
|
||||||
|
to delete a user. The currently logged-in user cannot be deleted,
|
||||||
|
which guarantees that there is always an admin user and hence that
|
||||||
|
the database cannot be converted into a no-authentication-required
|
||||||
|
database [3].
|
||||||
|
|
||||||
|
The sqlite3_user_change() interface can be used to change a users
|
||||||
|
login credentials or admin privilege. Any user can change their own
|
||||||
|
login credentials [1b]. Only an admin user can change another users login
|
||||||
|
credentials or admin privilege setting. No user may change their own
|
||||||
|
admin privilege setting.
|
||||||
|
|
||||||
|
The sqlite3_set_authorizer() callback is modified to take a 7th parameter
|
||||||
|
which is the username of the currently logged in user, or NULL for a
|
||||||
|
no-authentication-required database [1d].
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Implementation notes:
|
||||||
|
|
||||||
|
An authentication-required database is identified by the presence of a
|
||||||
|
new table:
|
||||||
|
|
||||||
|
CREATE TABLE sqlite_user(
|
||||||
|
uname TEXT PRIMARY KEY,
|
||||||
|
isAdmin BOOLEAN,
|
||||||
|
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.pw field is encoded by a built-in SQL function
|
||||||
|
"sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument
|
||||||
|
is the plaintext password supplied to the sqlite3_user_authenticate()
|
||||||
|
interface. The second argument is the sqlite_user.pw value and is supplied
|
||||||
|
so that the function can extra the "salt" used by the password encoder.
|
||||||
|
the result of sqlite_crypt(X,Y) is another blob which is the value that
|
||||||
|
ends up being stored in sqlite_user.pw. To verify credentials X supplied
|
||||||
|
by the sqlite3_user_authenticate() routine, SQLite runs:
|
||||||
|
|
||||||
|
sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw)
|
||||||
|
|
||||||
|
To compute an appropriate sqlite_user.pw value from a new or modified
|
||||||
|
password X, sqlite_crypt(X,NULL) is run. A new random salt is selected
|
||||||
|
when the second argument is NULL.
|
||||||
|
|
||||||
|
The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher
|
||||||
|
which prevents passwords from being revealed by search the raw database
|
||||||
|
for ASCII text, but is otherwise trivally broken. To truly secure the
|
||||||
|
passwords, the database should be encrypted using the SQLite Encryption
|
||||||
|
Extension or similar technology. Or, the application can use the
|
||||||
|
sqlite3_create_function() interface to provide an alternative
|
||||||
|
implementation of sqlite_crypt() that computes a stronger password hash,
|
||||||
|
perhaps using a cryptographic hash function like SHA1.
|
197
ext/userauth/userauth.c
Normal file
197
ext/userauth/userauth.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
** 2014-09-08
|
||||||
|
**
|
||||||
|
** 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 contains the bulk of the implementation of the
|
||||||
|
** user-authentication extension feature. Some parts of the user-
|
||||||
|
** authentication code are contained within the SQLite core (in the
|
||||||
|
** src/ subdirectory of the main source code tree) but those parts
|
||||||
|
** that could reasonable be separated out are moved into this file.
|
||||||
|
**
|
||||||
|
** To compile with the user-authentication feature, append this file to
|
||||||
|
** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION
|
||||||
|
** compile-time option. See the user-auth.txt file in the same source
|
||||||
|
** directory as this file for additional information.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_USER_AUTHENTICATION
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Prepare an SQL statement for use by the user authentication logic.
|
||||||
|
** Return a pointer to the prepared statement on success. Return a
|
||||||
|
** NULL pointer if there is an error of any kind.
|
||||||
|
*/
|
||||||
|
static sqlite3_stmt *sqlite3UserAuthPrepare(
|
||||||
|
sqlite3 *db,
|
||||||
|
const char *zFormat,
|
||||||
|
...
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
char *zSql;
|
||||||
|
int rc;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, zFormat);
|
||||||
|
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if( zSql==0 ) return 0;
|
||||||
|
savedFlags = db->auth.authFlags;
|
||||||
|
db->auth.authFlags |= UAUTH_Ovrd;
|
||||||
|
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||||
|
db->auth.authFlags = savedFlags;
|
||||||
|
sqlite3_free(zSql);
|
||||||
|
if( rc ){
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
|
pStmt = 0;
|
||||||
|
}
|
||||||
|
return pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Check to see if database zDb has a "sqlite_user" table and if it does
|
||||||
|
** whether that table can authenticate zUser with nPw,zPw.
|
||||||
|
*/
|
||||||
|
static int sqlite3UserAuthCheckLogin(
|
||||||
|
sqlite3 *db, /* The database connection to check */
|
||||||
|
const char *zDb, /* Name of specific database to check */
|
||||||
|
const char *zUser, /* User name */
|
||||||
|
int nPw, /* Size of password in bytes */
|
||||||
|
const char *zPw, /* Password */
|
||||||
|
int *pbOk /* OUT: write boolean result here */
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
char *zSql;
|
||||||
|
int rc;
|
||||||
|
int iResult;
|
||||||
|
|
||||||
|
*pbOk = 0;
|
||||||
|
iResult = 0;
|
||||||
|
pStmt = sqlite3UserAuthPrepare(db,
|
||||||
|
"SELECT 1 FROM \"%w\".sqlite_master "
|
||||||
|
" WHERE name='sqlite_user' AND type='table'", zDb);
|
||||||
|
if( pStmt==0 ) return SQLITE_NOMEM;
|
||||||
|
rc = sqlite3_step(pStmt):
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
|
if( rc==SQLITE_DONE ){
|
||||||
|
*pbOk = 1;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
pStmt = sqlite3UserAuthPrepare(db,
|
||||||
|
"SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user"
|
||||||
|
" WHERE uname=?2", zDb);
|
||||||
|
if( pStmt==0 ) return SQLITE_NOMEM;
|
||||||
|
sqlite3_bind_blob(pStmt, 1, zPw, nPw, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(pStmt, 2, zUser, -1, SQLITE_STATIC);
|
||||||
|
rc = sqlite_step(pStmt);
|
||||||
|
if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){
|
||||||
|
*pbOk = sqlite3_column_int(pStmt, 1);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If a database contains the SQLITE_USER table, then the
|
||||||
|
** sqlite3_user_authenticate() interface must be invoked with an
|
||||||
|
** appropriate username and password prior to enable read and write
|
||||||
|
** access to the database.
|
||||||
|
**
|
||||||
|
** Return SQLITE_OK on success or SQLITE_ERROR if the username/password
|
||||||
|
** combination is incorrect or unknown.
|
||||||
|
**
|
||||||
|
** If the SQLITE_USER table is not present in the database file, then
|
||||||
|
** this interface is a harmless no-op returnning SQLITE_OK.
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
|
){
|
||||||
|
int bOk = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = sqlite3UserAuthCheckLogin(db, zUsername, nPw, zPw, &bOk);
|
||||||
|
if( bOk ){
|
||||||
|
db->auth.authFlags = bOk==2 ? UAUTH_Auth|UAUTH_Admin : UAUTH_Auth;
|
||||||
|
sqlite3_free(db->auth.zAuthUser);
|
||||||
|
db->auth.zAuthUser = sqlite3_malloc("%s", zUsername);
|
||||||
|
sqlite3_free(db->auth.zPw);
|
||||||
|
db->auth.zPw = sqlite3_malloc( nPw+1 );
|
||||||
|
if( db->auth.zPw ){
|
||||||
|
memcpy(db->auth.zPw,zPw,nPw);
|
||||||
|
db->auth.nPw = nPw;
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else{
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
db->auth.authFlags = 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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, automatically makes the added user an
|
||||||
|
** administrator, and logs in the current connection as that user.
|
||||||
|
** 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.
|
||||||
|
*/
|
||||||
|
int sqlite3_user_add(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername, /* Username to be added */
|
||||||
|
int isAdmin, /* True to give new user admin privilege */
|
||||||
|
int nPW, /* Number of bytes in aPW[] */
|
||||||
|
const void *aPW /* Password or credentials */
|
||||||
|
){
|
||||||
|
if( !DbIsAdmin(db) ) return SQLITE_ERROR;
|
||||||
|
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The sqlite3_user_change() interface can be used to change a users
|
||||||
|
** login credentials or admin privilege. Any user can change their own
|
||||||
|
** login credentials. Only an admin user can change another users login
|
||||||
|
** credentials or admin privilege setting. No user may change their own
|
||||||
|
** admin privilege setting.
|
||||||
|
*/
|
||||||
|
int sqlite3_user_change(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername, /* Username to change */
|
||||||
|
int isAdmin, /* Modified admin privilege for the user */
|
||||||
|
int nPW, /* Number of bytes in aPW[] */
|
||||||
|
const void *aPW /* Modified password or credentials */
|
||||||
|
){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The sqlite3_user_delete() interface can be used (by an admin user only)
|
||||||
|
** to delete a user. The currently logged-in user cannot be deleted,
|
||||||
|
** which guarantees that there is always an admin user and hence that
|
||||||
|
** the database cannot be converted into a no-authentication-required
|
||||||
|
** database.
|
||||||
|
*/
|
||||||
|
int sqlite3_user_delete(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername /* Username to remove */
|
||||||
|
){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SQLITE_USER_AUTHENTICATION */
|
88
ext/userauth/userauth.h
Normal file
88
ext/userauth/userauth.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
** 2014-09-08
|
||||||
|
**
|
||||||
|
** 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 contains the application interface definitions for the
|
||||||
|
** user-authentication extension feature.
|
||||||
|
**
|
||||||
|
** To compile with the user-authentication feature, append this file to
|
||||||
|
** end of an SQLite amalgamation header file ("sqlite3.h"), then add
|
||||||
|
** the SQLITE_USER_AUTHENTICATION compile-time option. See the
|
||||||
|
** user-auth.txt file in the same source directory as this file for
|
||||||
|
** additional information.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_USER_AUTHENTICATION
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If a database contains the SQLITE_USER table, then the
|
||||||
|
** sqlite3_user_authenticate() interface must be invoked with an
|
||||||
|
** appropriate username and password prior to enable read and write
|
||||||
|
** access to the database.
|
||||||
|
**
|
||||||
|
** Return SQLITE_OK on success or SQLITE_ERROR if the username/password
|
||||||
|
** combination is incorrect or unknown.
|
||||||
|
**
|
||||||
|
** If the SQLITE_USER table is not present in the database file, then
|
||||||
|
** this interface is a harmless no-op returnning SQLITE_OK.
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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, automatically makes the added user an
|
||||||
|
** administrator, and logs in the current connection as that user.
|
||||||
|
** 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.
|
||||||
|
*/
|
||||||
|
int sqlite3_user_add(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername, /* Username to be added */
|
||||||
|
int isAdmin, /* True to give new user admin privilege */
|
||||||
|
int nPW, /* Number of bytes in aPW[] */
|
||||||
|
const void *aPW /* Password or credentials */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The sqlite3_user_change() interface can be used to change a users
|
||||||
|
** login credentials or admin privilege. Any user can change their own
|
||||||
|
** login credentials. Only an admin user can change another users login
|
||||||
|
** credentials or admin privilege setting. No user may change their own
|
||||||
|
** admin privilege setting.
|
||||||
|
*/
|
||||||
|
int sqlite3_user_change(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername, /* Username to change */
|
||||||
|
int isAdmin, /* Modified admin privilege for the user */
|
||||||
|
int nPW, /* Number of bytes in aPW[] */
|
||||||
|
const void *aPW /* Modified password or credentials */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The sqlite3_user_delete() interface can be used (by an admin user only)
|
||||||
|
** to delete a user. The currently logged-in user cannot be deleted,
|
||||||
|
** which guarantees that there is always an admin user and hence that
|
||||||
|
** the database cannot be converted into a no-authentication-required
|
||||||
|
** database.
|
||||||
|
*/
|
||||||
|
int sqlite3_user_delete(
|
||||||
|
sqlite3 *db, /* Database connection */
|
||||||
|
const char *zUsername /* Username to remove */
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif /* SQLITE_USER_AUTHENTICATION */
|
28
manifest
28
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fixes\sto\sos_unix.c\sto\ssupport\sdatabase\s(and\sother)\sfiles\slarger\sthan\s2GiB\son\sAndroid.
|
C Non-working\spreliminary\simplementation\sattempts\son\suser\sauthentication.
|
||||||
D 2014-09-06T17:06:13.410
|
D 2014-09-09T14:47:53.726
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -144,6 +144,9 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
|||||||
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
|
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
|
||||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||||
|
F ext/userauth/user-auth.txt f471c5a363ab0682b109d85982ea857f9a144ccc
|
||||||
|
F ext/userauth/userauth.c cea064a9b66d7497c74cc504b3a01d7f390cbe6e
|
||||||
|
F ext/userauth/userauth.h efbfb68ff083749ad63b12dcb5877b936c3458d6
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||||
@ -171,7 +174,7 @@ F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
|
|||||||
F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd
|
F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd
|
||||||
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
|
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
|
||||||
F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc
|
F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc
|
||||||
F src/build.c 8cb237719c185eec7bd8449b2e747491ded11932
|
F src/build.c 8b4c67c9fb638fb2e64b2bcd24677e71a5d61bfc
|
||||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||||
F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
|
F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
|
||||||
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
|
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
|
||||||
@ -190,7 +193,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
|||||||
F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a
|
F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a
|
||||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||||
F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab
|
F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab
|
||||||
F src/main.c e48517e3da289d93ad86e8b7b4f68078df5e6e51
|
F src/main.c 26299e9d9a72239f0652ac9a23e04ced3f536e70
|
||||||
F src/malloc.c 954de5f998c23237e04474a3f2159bf483bba65a
|
F src/malloc.c 954de5f998c23237e04474a3f2159bf483bba65a
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
|
F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
|
||||||
@ -217,8 +220,8 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
|
|||||||
F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be
|
F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be
|
||||||
F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a
|
F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a
|
||||||
F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa
|
F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa
|
||||||
F src/pragma.c 14bcdb504128a476cce5bbc086d5226c5e46c225
|
F src/pragma.c e4f6421d7a1f23cd21bf281f2d8c56874879e1d0
|
||||||
F src/prepare.c 3842c1dfc0b053458e3adcf9f6efc48e03e3fe3d
|
F src/prepare.c 9548c8efb80dbc14b0d54d58574c8a7414cde4db
|
||||||
F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2
|
F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2
|
||||||
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
||||||
F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb
|
F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb
|
||||||
@ -228,7 +231,7 @@ F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50
|
|||||||
F src/sqlite.h.in 64a77f2822f1325b12050972003184f99b655a0f
|
F src/sqlite.h.in 64a77f2822f1325b12050972003184f99b655a0f
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4
|
F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4
|
||||||
F src/sqliteInt.h 4d1b0488f097aa7be346176c4d5e3cc1e25d99da
|
F src/sqliteInt.h 883f905f17a78bb09061a8efa4f2708faa6ffacc
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08
|
F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08
|
||||||
@ -1193,7 +1196,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P e62aab5e9290503869e1f4d5e0fefd2b4dee0a69 9dca7ce55797b3eb617859f6189c1a2ec6f66566
|
P ad7063aa1a0db32cdbe71815545b2edca57d3bcc
|
||||||
R 4eacabb789e62917f709201f03eadd53
|
R 8d9410cfb98bb3b10637c181b910724f
|
||||||
U dan
|
T *branch * user-auth
|
||||||
Z f60ed4f30cad7188918c7dd18fc1b985
|
T *sym-user-auth *
|
||||||
|
T -sym-trunk *
|
||||||
|
U drh
|
||||||
|
Z 7af3a6ca660957a95167232843af8c9e
|
||||||
|
@ -1 +1 @@
|
|||||||
ad7063aa1a0db32cdbe71815545b2edca57d3bcc
|
8440f093bac19a41d44ee352744354eab897fe4e
|
18
src/build.c
18
src/build.c
@ -271,6 +271,16 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
|
|||||||
pParse->nested--;
|
pParse->nested--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
/*
|
||||||
|
** Return TRUE if zTable is the name of the system table that stores the
|
||||||
|
** list of users and their access credentials.
|
||||||
|
*/
|
||||||
|
int sqlite3UserAuthTable(const char *zTable){
|
||||||
|
return sqlite3_stricmp(zTable, "sqlite_user")==0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Locate the in-memory structure that describes a particular database
|
** Locate the in-memory structure that describes a particular database
|
||||||
** table given the name of that table and (optionally) the name of the
|
** table given the name of that table and (optionally) the name of the
|
||||||
@ -289,6 +299,11 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
|||||||
assert( zName!=0 );
|
assert( zName!=0 );
|
||||||
/* All mutexes are required for schema access. Make sure we hold them. */
|
/* All mutexes are required for schema access. Make sure we hold them. */
|
||||||
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
|
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
/* Only the admin user is allowed to know that the sqlite_user table
|
||||||
|
** exists */
|
||||||
|
if( DbIsAdmin(db)==0 && sqlite3UserAuthTable(zName)!=0 ) return 0;
|
||||||
|
#endif
|
||||||
for(i=OMIT_TEMPDB; i<db->nDb; i++){
|
for(i=OMIT_TEMPDB; i<db->nDb; i++){
|
||||||
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
||||||
if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
|
if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
|
||||||
@ -2867,6 +2882,9 @@ Index *sqlite3CreateIndex(
|
|||||||
assert( pTab!=0 );
|
assert( pTab!=0 );
|
||||||
assert( pParse->nErr==0 );
|
assert( pParse->nErr==0 );
|
||||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
|
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
&& sqlite3UserAuthTable(pTab->zName)==0
|
||||||
|
#endif
|
||||||
&& sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
|
&& sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
|
||||||
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
|
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
|
@ -985,6 +985,10 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
|||||||
sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
|
sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
|
||||||
sqlite3ValueFree(db->pErr);
|
sqlite3ValueFree(db->pErr);
|
||||||
sqlite3CloseExtensions(db);
|
sqlite3CloseExtensions(db);
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
sqlite3_free(db->auth.zAuthUser);
|
||||||
|
sqlite3_free(db->auth.zAuthPW);
|
||||||
|
#endif
|
||||||
|
|
||||||
db->magic = SQLITE_MAGIC_ERROR;
|
db->magic = SQLITE_MAGIC_ERROR;
|
||||||
|
|
||||||
@ -2566,6 +2570,9 @@ static int openDatabase(
|
|||||||
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
|
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
|
||||||
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
|
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
|
||||||
|
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
db->auth.authFlags = UAUTH_Auth|UAUTH_Admin;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The default safety_level for the main database is 'full'; for the temp
|
/* The default safety_level for the main database is 'full'; for the temp
|
||||||
** database it is 'NONE'. This matches the pager layer defaults.
|
** database it is 'NONE'. This matches the pager layer defaults.
|
||||||
|
@ -1397,6 +1397,12 @@ void sqlite3Pragma(
|
|||||||
** in auto-commit mode. */
|
** in auto-commit mode. */
|
||||||
mask &= ~(SQLITE_ForeignKeys);
|
mask &= ~(SQLITE_ForeignKeys);
|
||||||
}
|
}
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
if( !DbIsAdmin(db) ){
|
||||||
|
/* Do not allow non-admin users to modify the schema arbitrarily */
|
||||||
|
mask &= ~(SQLITE_WriteSchema);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if( sqlite3GetBoolean(zRight, 0) ){
|
if( sqlite3GetBoolean(zRight, 0) ){
|
||||||
db->flags |= mask;
|
db->flags |= mask;
|
||||||
|
@ -206,6 +206,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
if( ALWAYS(pTab) ){
|
if( ALWAYS(pTab) ){
|
||||||
pTab->tabFlags |= TF_Readonly;
|
pTab->tabFlags |= TF_Readonly;
|
||||||
}
|
}
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
db->auth.authFlags = UAUTH_Auth|UAUTH_Admin;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create a cursor to hold the database open
|
/* Create a cursor to hold the database open
|
||||||
*/
|
*/
|
||||||
@ -361,6 +364,14 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
DbSetProperty(db, iDb, DB_SchemaLoaded);
|
DbSetProperty(db, iDb, DB_SchemaLoaded);
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
if( rc==SQLITE_OK && iDb!=1 ){
|
||||||
|
if( sqlite3FindTable(db, "sqlite_user", db->aDb[iDb].zName)!=0 ){
|
||||||
|
db->auth.authFlags = UAUTH_AuthReqd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Jump here for an error that occurs after successfully allocating
|
/* Jump here for an error that occurs after successfully allocating
|
||||||
** curMain and calling sqlite3BtreeEnter(). For an error that occurs
|
** curMain and calling sqlite3BtreeEnter(). For an error that occurs
|
||||||
@ -720,6 +731,17 @@ static int sqlite3LockAndPrepare(
|
|||||||
sqlite3_finalize(*ppStmt);
|
sqlite3_finalize(*ppStmt);
|
||||||
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
|
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
|
||||||
}
|
}
|
||||||
|
#if SQLITE_USER_AUTHENTICATION
|
||||||
|
assert( rc==SQLITE_OK || *ppStmt==0 );
|
||||||
|
printf("rc=%d init=%d auth=%d sql=[%.50s]\n", rc, db->init.busy, db->auth.authFlags, zSql);
|
||||||
|
fflush(stdout);
|
||||||
|
if( rc==SQLITE_OK && !DbIsAuth(db) && db->init.busy==0 ){
|
||||||
|
sqlite3_finalize(*ppStmt);
|
||||||
|
*ppStmt = 0;
|
||||||
|
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "user not authenticated");
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
sqlite3_mutex_leave(db->mutex);
|
sqlite3_mutex_leave(db->mutex);
|
||||||
assert( rc==SQLITE_OK || *ppStmt==0 );
|
assert( rc==SQLITE_OK || *ppStmt==0 );
|
||||||
|
@ -988,6 +988,35 @@ struct FuncDefHash {
|
|||||||
FuncDef *a[23]; /* Hash table for functions */
|
FuncDef *a[23]; /* Hash table for functions */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SQLITE_USER_AUTHENTICATION
|
||||||
|
/*
|
||||||
|
** Information held in the "sqlite3" database connection object and used
|
||||||
|
** to manage user authentication.
|
||||||
|
*/
|
||||||
|
typedef struct sqlite3_userauth sqlite3_userauth;
|
||||||
|
struct sqlite3_userauth {
|
||||||
|
u8 authFlags; /* Status flags for user authentication */
|
||||||
|
int nAuthPW; /* Size of the zAuthPW in bytes */
|
||||||
|
char *zAuthPW; /* Password used to authenticate */
|
||||||
|
char *zAuthUser; /* User name used to authenticate */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Allowed values for sqlite3_userauth.authFlags */
|
||||||
|
#define UAUTH_Ovrd 0x01 /* Do not enforce access restrictions */
|
||||||
|
#define UAUTH_Auth 0x02 /* True if the user has authenticated */
|
||||||
|
#define UAUTH_Admin 0x04 /* True if the user is an administrator */
|
||||||
|
#define UAUTH_AuthReqd 0x08 /* True if main has an sqlite_user table */
|
||||||
|
|
||||||
|
/* Macros for accessing sqlite3.auth.authFlags */
|
||||||
|
#define DbIsAuth(D) (((D)->auth.authFlags&UAUTH_Auth)!=0)
|
||||||
|
#define DbIsAdmin(D) (((D)->auth.authFlags&UAUTH_Admin)!=0)
|
||||||
|
|
||||||
|
/* Functions used only by user authorization logic */
|
||||||
|
int sqlite3UserAuthTable(const char*);
|
||||||
|
|
||||||
|
#endif /* SQLITE_USER_AUTHENTICATION */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Each database connection is an instance of the following structure.
|
** Each database connection is an instance of the following structure.
|
||||||
*/
|
*/
|
||||||
@ -1082,7 +1111,6 @@ struct sqlite3 {
|
|||||||
i64 nDeferredCons; /* Net deferred constraints this transaction. */
|
i64 nDeferredCons; /* Net deferred constraints this transaction. */
|
||||||
i64 nDeferredImmCons; /* Net deferred immediate constraints */
|
i64 nDeferredImmCons; /* Net deferred immediate constraints */
|
||||||
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
|
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||||
/* The following variables are all protected by the STATIC_MASTER
|
/* The following variables are all protected by the STATIC_MASTER
|
||||||
** mutex, not by sqlite3.mutex. They are used by code in notify.c.
|
** mutex, not by sqlite3.mutex. They are used by code in notify.c.
|
||||||
@ -1100,6 +1128,9 @@ struct sqlite3 {
|
|||||||
void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
|
void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
|
||||||
sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
|
sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_USER_AUTHENTICATION
|
||||||
|
sqlite3_userauth auth; /* User authentication information */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user