Remove the never-used and never-documented and long-ago deprecated
user-authentication feature option. FossilOrigin-Name: 3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147
This commit is contained in:
parent
fe5602ffd9
commit
bc4df6079c
@ -1,96 +0,0 @@
|
||||
/*
|
||||
** 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
const char *aPW, /* Password or credentials */
|
||||
int nPW /* Number of bytes in aPW[] */
|
||||
);
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
const char *aPW, /* Password or credentials */
|
||||
int nPW, /* Number of bytes in aPW[] */
|
||||
int isAdmin /* True to give new user admin privilege */
|
||||
);
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
const char *aPW, /* New password or credentials */
|
||||
int nPW, /* Number of bytes in aPW[] */
|
||||
int isAdmin /* Modified admin privilege for the user */
|
||||
);
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of the 'extern "C"' block */
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
@ -1,176 +0,0 @@
|
||||
*********************************** NOTICE ************************************
|
||||
* This extension is deprecated. The SQLite developers do not maintain this *
|
||||
* extension. At some point in the future, it might disappear from the source *
|
||||
* tree. *
|
||||
* *
|
||||
* If you are using this extension and think it should be supported moving *
|
||||
* forward, visit the SQLite Forum (https://sqlite.org/forum) and argue your *
|
||||
* case there. *
|
||||
* *
|
||||
* This deprecation notice was added on 2024-01-22. *
|
||||
*******************************************************************************
|
||||
|
||||
Activate the user authentication logic by including the
|
||||
ext/userauth/userauth.c source code file in the build and
|
||||
adding the -DSQLITE_USER_AUTHENTICATION compile-time option.
|
||||
The ext/userauth/sqlite3userauth.h header file is available to
|
||||
applications to define the interface.
|
||||
|
||||
When using the SQLite amalgamation, it is sufficient to append
|
||||
the ext/userauth/userauth.c source file onto the end of the
|
||||
amalgamation.
|
||||
|
||||
The following new APIs are available when user authentication is
|
||||
activated:
|
||||
|
||||
int sqlite3_user_authenticate(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zUsername, /* Username */
|
||||
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 */
|
||||
const char *aPW, /* Password or credentials */
|
||||
int nPW, /* Number of bytes in aPW[] */
|
||||
int isAdmin /* True to give new user admin privilege */
|
||||
);
|
||||
|
||||
int sqlite3_user_change(
|
||||
sqlite3 *db, /* Database connection */
|
||||
const char *zUsername, /* Username to change */
|
||||
const void *aPW, /* Modified password or credentials */
|
||||
int nPW, /* Number of bytes in aPW[] */
|
||||
int isAdmin /* Modified admin privilege for the user */
|
||||
);
|
||||
|
||||
int sqlite3_user_delete(
|
||||
sqlite3 *db, /* Database connection */
|
||||
const char *zUsername /* Username to remove */
|
||||
);
|
||||
|
||||
With this extension, a database can be marked as requiring authentication.
|
||||
By default a database does not require authentication.
|
||||
|
||||
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 attempts to read
|
||||
or write from the database will fail with an SQLITE_AUTH error until
|
||||
after sqlite3_user_authenticate() has been called successfully. 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 command fails with an SQLITE_AUTH error.
|
||||
|
||||
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 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 in the database connection D as 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:
|
||||
|
||||
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.
|
||||
|
||||
The sqlite3_user_change() interface can be used to change a users
|
||||
login credentials or admin privilege. Any user can change their own
|
||||
password. 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.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
The sqlite_user 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 extract 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 searching the raw database
|
||||
for ASCII text, but is otherwise trivally broken. For better password
|
||||
security, 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.
|
@ -1,355 +0,0 @@
|
||||
/*
|
||||
** 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
|
||||
#ifndef SQLITEINT_H
|
||||
# include "sqliteInt.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** 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;
|
||||
u64 savedFlags = db->flags;
|
||||
|
||||
va_start(ap, zFormat);
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
if( zSql==0 ) return 0;
|
||||
db->flags |= SQLITE_WriteSchema;
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
db->flags = savedFlags;
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if the sqlite_user table exists in database zDb.
|
||||
*/
|
||||
static int userTableExists(sqlite3 *db, const char *zDb){
|
||||
int rc;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3BtreeEnterAll(db);
|
||||
if( db->init.busy==0 ){
|
||||
char *zErr = 0;
|
||||
sqlite3Init(db, &zErr);
|
||||
sqlite3DbFree(db, zErr);
|
||||
}
|
||||
rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0;
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if database zDb has a "sqlite_user" table and if it does
|
||||
** whether that table can authenticate zUser with nPw,zPw. Write one of
|
||||
** the UAUTH_* user authorization level codes into *peAuth and return a
|
||||
** result code.
|
||||
*/
|
||||
static int userAuthCheckLogin(
|
||||
sqlite3 *db, /* The database connection to check */
|
||||
const char *zDb, /* Name of specific database to check */
|
||||
u8 *peAuth /* OUT: One of UAUTH_* constants */
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
|
||||
*peAuth = UAUTH_Unknown;
|
||||
if( !userTableExists(db, "main") ){
|
||||
*peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( db->auth.zAuthUser==0 ){
|
||||
*peAuth = UAUTH_Fail;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
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, db->auth.zAuthPW, db->auth.nAuthPW,SQLITE_STATIC);
|
||||
sqlite3_bind_text(pStmt, 2, db->auth.zAuthUser, -1, SQLITE_STATIC);
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){
|
||||
*peAuth = sqlite3_column_int(pStmt, 1) + UAUTH_User;
|
||||
}else{
|
||||
*peAuth = UAUTH_Fail;
|
||||
}
|
||||
return sqlite3_finalize(pStmt);
|
||||
}
|
||||
int sqlite3UserAuthCheckLogin(
|
||||
sqlite3 *db, /* The database connection to check */
|
||||
const char *zDb, /* Name of specific database to check */
|
||||
u8 *peAuth /* OUT: One of UAUTH_* constants */
|
||||
){
|
||||
int rc;
|
||||
u8 savedAuthLevel;
|
||||
assert( zDb!=0 );
|
||||
assert( peAuth!=0 );
|
||||
savedAuthLevel = db->auth.authLevel;
|
||||
db->auth.authLevel = UAUTH_Admin;
|
||||
rc = userAuthCheckLogin(db, zDb, peAuth);
|
||||
db->auth.authLevel = savedAuthLevel;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the current authLevel is UAUTH_Unknown, the take actions to figure
|
||||
** out what authLevel should be
|
||||
*/
|
||||
void sqlite3UserAuthInit(sqlite3 *db){
|
||||
if( db->auth.authLevel==UAUTH_Unknown ){
|
||||
u8 authLevel = UAUTH_Fail;
|
||||
sqlite3UserAuthCheckLogin(db, "main", &authLevel);
|
||||
db->auth.authLevel = authLevel;
|
||||
if( authLevel<UAUTH_Admin ) db->flags &= ~SQLITE_WriteSchema;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the sqlite_crypt(X,Y) function.
|
||||
**
|
||||
** If Y is NULL then generate a new hash for password X and return that
|
||||
** hash. If Y is not null, then generate a hash for password X using the
|
||||
** same salt as the previous hash Y and return the new hash.
|
||||
*/
|
||||
void sqlite3CryptFunc(
|
||||
sqlite3_context *context,
|
||||
int NotUsed,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const char *zIn;
|
||||
int nIn, ii;
|
||||
u8 *zOut;
|
||||
char zSalt[8];
|
||||
zIn = sqlite3_value_blob(argv[0]);
|
||||
nIn = sqlite3_value_bytes(argv[0]);
|
||||
if( sqlite3_value_type(argv[1])==SQLITE_BLOB
|
||||
&& sqlite3_value_bytes(argv[1])==nIn+sizeof(zSalt)
|
||||
){
|
||||
memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt));
|
||||
}else{
|
||||
sqlite3_randomness(sizeof(zSalt), zSalt);
|
||||
}
|
||||
zOut = sqlite3_malloc( nIn+sizeof(zSalt) );
|
||||
if( zOut==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
memcpy(zOut, zSalt, sizeof(zSalt));
|
||||
for(ii=0; ii<nIn; ii++){
|
||||
zOut[ii+sizeof(zSalt)] = zIn[ii]^zSalt[ii&0x7];
|
||||
}
|
||||
sqlite3_result_blob(context, zOut, nIn+sizeof(zSalt), sqlite3_free);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
const char *zPW, /* Password or credentials */
|
||||
int nPW /* Number of bytes in aPW[] */
|
||||
){
|
||||
int rc;
|
||||
u8 authLevel = UAUTH_Fail;
|
||||
db->auth.authLevel = UAUTH_Unknown;
|
||||
sqlite3_free(db->auth.zAuthUser);
|
||||
sqlite3_free(db->auth.zAuthPW);
|
||||
memset(&db->auth, 0, sizeof(db->auth));
|
||||
db->auth.zAuthUser = sqlite3_mprintf("%s", zUsername);
|
||||
if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM;
|
||||
db->auth.zAuthPW = sqlite3_malloc( nPW+1 );
|
||||
if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM;
|
||||
memcpy(db->auth.zAuthPW,zPW,nPW);
|
||||
db->auth.nAuthPW = nPW;
|
||||
rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel);
|
||||
db->auth.authLevel = authLevel;
|
||||
sqlite3ExpirePreparedStatements(db, 0);
|
||||
if( rc ){
|
||||
return rc; /* OOM error, I/O error, etc. */
|
||||
}
|
||||
if( authLevel<UAUTH_User ){
|
||||
return SQLITE_AUTH; /* Incorrect username and/or password */
|
||||
}
|
||||
return SQLITE_OK; /* Successful login */
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
const char *aPW, /* Password or credentials */
|
||||
int nPW, /* Number of bytes in aPW[] */
|
||||
int isAdmin /* True to give new user admin privilege */
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
sqlite3UserAuthInit(db);
|
||||
if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH;
|
||||
if( !userTableExists(db, "main") ){
|
||||
if( !isAdmin ) return SQLITE_AUTH;
|
||||
pStmt = sqlite3UserAuthPrepare(db,
|
||||
"CREATE TABLE sqlite_user(\n"
|
||||
" uname TEXT PRIMARY KEY,\n"
|
||||
" isAdmin BOOLEAN,\n"
|
||||
" pw BLOB\n"
|
||||
") WITHOUT ROWID;");
|
||||
if( pStmt==0 ) return SQLITE_NOMEM;
|
||||
sqlite3_step(pStmt);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
if( rc ) return rc;
|
||||
}
|
||||
pStmt = sqlite3UserAuthPrepare(db,
|
||||
"INSERT INTO sqlite_user(uname,isAdmin,pw)"
|
||||
" VALUES(%Q,%d,sqlite_crypt(?1,NULL))",
|
||||
zUsername, isAdmin!=0);
|
||||
if( pStmt==0 ) return SQLITE_NOMEM;
|
||||
sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
|
||||
sqlite3_step(pStmt);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
if( rc ) return rc;
|
||||
if( db->auth.zAuthUser==0 ){
|
||||
assert( isAdmin!=0 );
|
||||
sqlite3_user_authenticate(db, zUsername, aPW, nPW);
|
||||
}
|
||||
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 */
|
||||
const char *aPW, /* Modified password or credentials */
|
||||
int nPW, /* Number of bytes in aPW[] */
|
||||
int isAdmin /* Modified admin privilege for the user */
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
u8 authLevel;
|
||||
|
||||
authLevel = db->auth.authLevel;
|
||||
if( authLevel<UAUTH_User ){
|
||||
/* Must be logged in to make a change */
|
||||
return SQLITE_AUTH;
|
||||
}
|
||||
if( strcmp(db->auth.zAuthUser, zUsername)!=0 ){
|
||||
if( db->auth.authLevel<UAUTH_Admin ){
|
||||
/* Must be an administrator to change a different user */
|
||||
return SQLITE_AUTH;
|
||||
}
|
||||
}else if( isAdmin!=(authLevel==UAUTH_Admin) ){
|
||||
/* Cannot change the isAdmin setting for self */
|
||||
return SQLITE_AUTH;
|
||||
}
|
||||
db->auth.authLevel = UAUTH_Admin;
|
||||
if( !userTableExists(db, "main") ){
|
||||
/* This routine is a no-op if the user to be modified does not exist */
|
||||
}else{
|
||||
pStmt = sqlite3UserAuthPrepare(db,
|
||||
"UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)"
|
||||
" WHERE uname=%Q", isAdmin, zUsername);
|
||||
if( pStmt==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
|
||||
sqlite3_step(pStmt);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
}
|
||||
}
|
||||
db->auth.authLevel = authLevel;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
if( db->auth.authLevel<UAUTH_Admin ){
|
||||
/* Must be an administrator to delete a user */
|
||||
return SQLITE_AUTH;
|
||||
}
|
||||
if( strcmp(db->auth.zAuthUser, zUsername)==0 ){
|
||||
/* Cannot delete self */
|
||||
return SQLITE_AUTH;
|
||||
}
|
||||
if( !userTableExists(db, "main") ){
|
||||
/* This routine is a no-op if the user to be deleted does not exist */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
pStmt = sqlite3UserAuthPrepare(db,
|
||||
"DELETE FROM sqlite_user WHERE uname=%Q", zUsername);
|
||||
if( pStmt==0 ) return SQLITE_NOMEM;
|
||||
sqlite3_step(pStmt);
|
||||
return sqlite3_finalize(pStmt);
|
||||
}
|
||||
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
13
main.mk
13
main.mk
@ -305,7 +305,7 @@ T.cc.sqlite ?= $(T.cc)
|
||||
CFLAGS.intree_includes = \
|
||||
-I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \
|
||||
-I$(TOP)/ext/fts3 -I$(TOP)/ext/session \
|
||||
-I$(TOP)/ext/misc -I$(TOP)/ext/userauth
|
||||
-I$(TOP)/ext/misc
|
||||
T.cc.sqlite += $(CFLAGS.intree_includes)
|
||||
|
||||
#
|
||||
@ -433,7 +433,7 @@ LIBOBJS0 = alter.o analyze.o attach.o auth.o \
|
||||
random.o resolve.o rowset.o rtree.o \
|
||||
sqlite3session.o select.o sqlite3rbu.o status.o stmt.o \
|
||||
table.o threads.o tokenize.o treeview.o trigger.o \
|
||||
update.o upsert.o userauth.o utf.o util.o vacuum.o \
|
||||
update.o upsert.o utf.o util.o vacuum.o \
|
||||
vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
|
||||
vdbetrace.o vdbevtab.o vtab.o \
|
||||
wal.o walker.o where.o wherecode.o whereexpr.o \
|
||||
@ -591,9 +591,6 @@ SRC += \
|
||||
SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
SRC += \
|
||||
$(TOP)/ext/userauth/userauth.c \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
SRC += \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.h \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.c
|
||||
@ -705,7 +702,6 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/unionvtab.c \
|
||||
$(TOP)/ext/misc/wholenumber.c \
|
||||
$(TOP)/ext/misc/zipfile.c \
|
||||
$(TOP)/ext/userauth/userauth.c \
|
||||
$(TOP)/ext/rtree/test_rtreedoc.c
|
||||
|
||||
# Source code to the library files needed by the test fixture
|
||||
@ -808,8 +804,6 @@ EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
|
||||
#
|
||||
# Executables needed for testing
|
||||
@ -2081,9 +2075,6 @@ fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(DEPS_EXT_COMMON)
|
||||
rtree.o: $(TOP)/ext/rtree/rtree.c $(DEPS_EXT_COMMON)
|
||||
$(T.cc.extension) -c $(TOP)/ext/rtree/rtree.c
|
||||
|
||||
userauth.o: $(TOP)/ext/userauth/userauth.c $(DEPS_EXT_COMMON)
|
||||
$(T.cc.extension) -c $(TOP)/ext/userauth/userauth.c
|
||||
|
||||
sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(DEPS_EXT_COMMON)
|
||||
$(T.cc.extension) -c $(TOP)/ext/session/sqlite3session.c
|
||||
|
||||
|
44
manifest
44
manifest
@ -1,5 +1,5 @@
|
||||
C Perform\ssome\smakefile\sacrobatics\sto\sget\sthe\stclConfig.sh\sstate\sapplied\sfor\sstatic\smakefiles.
|
||||
D 2024-10-28T17:20:18.788
|
||||
C Remove\sthe\snever-used\sand\snever-documented\sand\slong-ago\sdeprecated\nuser-authentication\sfeature\soption.
|
||||
D 2024-10-28T17:27:15.255
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2
|
||||
@ -614,9 +614,6 @@ F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009e
|
||||
F ext/session/sqlite3session.c 3d0a7f0f7a1c946e01818c716a55a40ae30542a29a9045cb05daf7fb658cdafa
|
||||
F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b
|
||||
F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/GNUmakefile 311aa0d5edc7006409962cc77cc26560d92f9be69c2c4302e8bbc68189fd02db
|
||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||
@ -702,7 +699,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk e9ff755b0d6f2ab6a95fab7bb11f742485de6ad1606822932d24bbfa14a9884a
|
||||
F main.mk 79392fb2e964f1359518d71df364182d7e53cc26a8fc4b25362ded9aeb4a17f7
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
@ -716,18 +713,18 @@ F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03
|
||||
F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91
|
||||
F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532
|
||||
F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb
|
||||
F src/attach.c 08235ab62ed5ccc93c22bf36e640d19effcd632319615851bccf724ec9341333
|
||||
F src/auth.c 4c1ea890e0069ad73bead5d17a5b12c34cfa4f1a24175c8147ea439b64be271c
|
||||
F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80
|
||||
F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
|
||||
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
||||
F src/btree.c 63ca6b647342e8cef643863cd0962a542f133e1069460725ba4461dcda92b03c
|
||||
F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50
|
||||
F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
|
||||
F src/build.c 3a1840d9d171ce2d24f4c1f7acda7266ab796c664290c1acba65ff98ce2bd01e
|
||||
F src/build.c c6b09342d870a509529244ed8e19b4175a261f2e3163c199241d69e1d8a57607
|
||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64
|
||||
F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b
|
||||
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
|
||||
F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
@ -735,7 +732,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
|
||||
F src/expr.c a9d9f5fdfbdd3b2c94d7af1b11f181464b8a641736cf32cb92fa3c5e7ecb30df
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||
F src/func.c 1d093b93b8f097665721e59a1c404d7db4dc591e1a777a7a1022dfbda21e108b
|
||||
F src/func.c fa138d44348e189817542f6efa6232420b3e0081c835ced65883adc7fd777d65
|
||||
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
@ -745,7 +742,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
|
||||
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
||||
F src/main.c d55d27db5a3b7bb12e1b723e350efd833586f22baa4b15ca2c0b4bde9a44ae29
|
||||
F src/main.c f6daba376adac080fe9287c6746fb15e12c7e47d022f2e9f2986ed364b7e0329
|
||||
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@ -775,7 +772,7 @@ F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
||||
F src/pragma.c cd613126f7cdd0c2ded4648c3c7b7b0239e678d7f3489e88c4b6d6858372fd07
|
||||
F src/pragma.c a2ec3657a953fa7dea7c1e680e4358b6ce6ae570b6c5234e0f5ef219d308d223
|
||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c 3ba0ad907b7773ed642f66cea8a2c9c8edc18841aa1050b6218dbb3479e86225
|
||||
F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2
|
||||
@ -783,17 +780,17 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
||||
F src/shell.c.in 2fb0947424944f8baa1b4efdfd9eca70dc0691bbc1cb4d283db7fc142937fa3a
|
||||
F src/shell.c.in b6b7944fc076c2fd29d38edb61e3da978e838e3f79e1cf2c96a1342c423b3892
|
||||
F src/sqlite.h.in 29fc900a58f394c7488d093fd7a8dcb14d3fa6399d5178cb20adcf88dbedfe39
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h baae24292817e13e7fe748851c62efc381dcc4dac241b1182eac3d2f05eae52c
|
||||
F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 47d4bb6eb06aab48d643eeb8c4f65b5fa9529fa5526fdcbf223ea32277ed1b56
|
||||
F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153
|
||||
F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
|
||||
F src/test1.c 370668f1832dc7bc2ab0212d807d880b6cdb0d5949550489593ce0cdb4a61012
|
||||
F src/test1.c 9df74d1d8c0513b0f906942d004b7d7aff5c6f47320a921a0b890748bac0e34d
|
||||
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
|
||||
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
|
||||
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
|
||||
@ -806,7 +803,7 @@ F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d97
|
||||
F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
|
||||
F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
|
||||
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
|
||||
F src/test_config.c e8d041a84151cbaee4dd82eb32e4153abe06856bcfab4771968a8cf930a86332
|
||||
F src/test_config.c bff5e1625c007f14a9ea4d346b6a741149b5e1f885c1c7ae69bb28a8ddade151
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
|
||||
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
|
||||
@ -1948,7 +1945,6 @@ F test/upsert5.test 9953b180d02d1369cdbb6c73c900834e5fef8cb78e98e07511c8762ec21c
|
||||
F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35
|
||||
F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384
|
||||
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
|
||||
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
|
||||
F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da
|
||||
F test/vacuum-into.test 77845cee98770c416dae9b0da6bb3229753861f2da65c11b4f9715d081712d8a
|
||||
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||
@ -2143,7 +2139,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
|
||||
F tool/mkccode.tcl 4cb8ad7e7330aaed052b0657a1bfacbc67103c400e41860aff643a482cfc2d3e x
|
||||
F tool/mkctimec.tcl e3af51acc2ef92062fe6d622de010a27a34b497258a248dada04388b916c61c6 x
|
||||
F tool/mkctimec.tcl ef6a67ec82e5b6fc19152a4c79f237227b18bf67ff16d155bac7adb94355d9cf x
|
||||
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
|
||||
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
@ -2205,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P f98da150a9c18dfaf9d5178ceee227caf7fce9c9c9194a7a4291abb40de832fa
|
||||
R e203eb86dfdd2daea7dd35f993a3ed58
|
||||
U stephan
|
||||
Z ba3f561a89835f0184bfa691acd0be76
|
||||
P 9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8
|
||||
R 9407a62c47c06c3fbba4fc768b189643
|
||||
U drh
|
||||
Z 30f01ab7792d4b857d7e101ce9a3bf79
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8
|
||||
3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147
|
||||
|
@ -227,15 +227,6 @@ static void attachFunc(
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
assert( zErrDyn==0 || rc!=SQLITE_OK );
|
||||
}
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){
|
||||
u8 newAuth = 0;
|
||||
rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth);
|
||||
if( newAuth<db->auth.authLevel ){
|
||||
rc = SQLITE_AUTH_USER;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( rc ){
|
||||
if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){
|
||||
int iDb = db->nDb - 1;
|
||||
|
12
src/auth.c
12
src/auth.c
@ -112,11 +112,7 @@ int sqlite3AuthReadCol(
|
||||
int rc; /* Auth callback return code */
|
||||
|
||||
if( db->init.busy ) return SQLITE_OK;
|
||||
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
,db->auth.zAuthUser
|
||||
#endif
|
||||
);
|
||||
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
|
||||
if( rc==SQLITE_DENY ){
|
||||
char *z = sqlite3_mprintf("%s.%s", zTab, zCol);
|
||||
if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z);
|
||||
@ -223,11 +219,7 @@ int sqlite3AuthCheck(
|
||||
testcase( zArg3==0 );
|
||||
testcase( pParse->zAuthContext==0 );
|
||||
|
||||
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
,db->auth.zAuthUser
|
||||
#endif
|
||||
);
|
||||
rc = db->xAuth(db->pAuthArg,code,zArg1,zArg2,zArg3,pParse->zAuthContext);
|
||||
if( rc==SQLITE_DENY ){
|
||||
sqlite3ErrorMsg(pParse, "not authorized");
|
||||
pParse->rc = SQLITE_AUTH;
|
||||
|
31
src/build.c
31
src/build.c
@ -189,17 +189,6 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
}
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
|
||||
#if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||
if( pParse->nTableLock>0 && db->init.busy==0 ){
|
||||
sqlite3UserAuthInit(db);
|
||||
if( db->auth.authLevel<UAUTH_User ){
|
||||
sqlite3ErrorMsg(pParse, "user not authenticated");
|
||||
pParse->rc = SQLITE_AUTH_USER;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The cookie mask contains one bit for each database file open.
|
||||
** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
|
||||
** set for each database that is used. Generate code to start a
|
||||
@ -328,16 +317,6 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
|
||||
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
|
||||
** table given the name of that table and (optionally) the name of the
|
||||
@ -356,13 +335,6 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
|
||||
/* All mutexes are required for schema access. Make sure we hold them. */
|
||||
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
/* Only the admin user is allowed to know that the sqlite_user table
|
||||
** exists */
|
||||
if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if( zDatabase ){
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break;
|
||||
@ -4021,9 +3993,6 @@ void sqlite3CreateIndex(
|
||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
|
||||
&& db->init.busy==0
|
||||
&& pTblName!=0
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
&& sqlite3UserAuthTable(pTab->zName)==0
|
||||
#endif
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
|
||||
goto exit_create_index;
|
||||
|
@ -767,9 +767,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#ifdef SQLITE_UNTESTABLE
|
||||
"UNTESTABLE",
|
||||
#endif
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
"USER_AUTHENTICATION",
|
||||
#endif
|
||||
#ifdef SQLITE_USE_ALLOCA
|
||||
"USE_ALLOCA",
|
||||
#endif
|
||||
|
@ -2678,9 +2678,6 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
SFUNCTION(load_extension, 1, 0, 0, loadExt ),
|
||||
SFUNCTION(load_extension, 2, 0, 0, loadExt ),
|
||||
#endif
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
||||
DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
|
||||
DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
|
||||
|
@ -1423,10 +1423,6 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
|
||||
sqlite3ValueFree(db->pErr);
|
||||
sqlite3CloseExtensions(db);
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
sqlite3_free(db->auth.zAuthUser);
|
||||
sqlite3_free(db->auth.zAuthPW);
|
||||
#endif
|
||||
|
||||
db->eOpenState = SQLITE_STATE_ERROR;
|
||||
|
||||
|
@ -1144,12 +1144,6 @@ void sqlite3Pragma(
|
||||
** in auto-commit mode. */
|
||||
mask &= ~(SQLITE_ForeignKeys);
|
||||
}
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
if( db->auth.authLevel==UAUTH_User ){
|
||||
/* Do not allow non-admin users to modify the schema arbitrarily */
|
||||
mask &= ~(SQLITE_WriteSchema);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( sqlite3GetBoolean(zRight, 0) ){
|
||||
if( (mask & SQLITE_WriteSchema)==0
|
||||
|
@ -104,9 +104,6 @@ typedef unsigned short int u16;
|
||||
typedef sqlite3_int64 i64;
|
||||
typedef sqlite3_uint64 u64;
|
||||
typedef unsigned char u8;
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
# include "sqlite3userauth.h"
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
@ -11758,69 +11755,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
#endif
|
||||
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
if( c=='u' && cli_strncmp(azArg[0], "user", n)==0 ){
|
||||
if( nArg<2 ){
|
||||
eputz("Usage: .user SUBCOMMAND ...\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
open_db(p, 0);
|
||||
if( cli_strcmp(azArg[1],"login")==0 ){
|
||||
if( nArg!=4 ){
|
||||
eputz("Usage: .user login USER PASSWORD\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
|
||||
strlen30(azArg[3]));
|
||||
if( rc ){
|
||||
sqlite3_fprintf(stderr,"Authentication failed for user %s\n", azArg[2]);
|
||||
rc = 1;
|
||||
}
|
||||
}else if( cli_strcmp(azArg[1],"add")==0 ){
|
||||
if( nArg!=5 ){
|
||||
eputz("Usage: .user add USER PASSWORD ISADMIN\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
|
||||
booleanValue(azArg[4]));
|
||||
if( rc ){
|
||||
sqlite3_fprintf(stderr,"User-Add failed: %d\n", rc);
|
||||
rc = 1;
|
||||
}
|
||||
}else if( cli_strcmp(azArg[1],"edit")==0 ){
|
||||
if( nArg!=5 ){
|
||||
eputz("Usage: .user edit USER PASSWORD ISADMIN\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
|
||||
booleanValue(azArg[4]));
|
||||
if( rc ){
|
||||
sqlite3_fprintf(stderr,"User-Edit failed: %d\n", rc);
|
||||
rc = 1;
|
||||
}
|
||||
}else if( cli_strcmp(azArg[1],"delete")==0 ){
|
||||
if( nArg!=3 ){
|
||||
eputz("Usage: .user delete USER\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
rc = sqlite3_user_delete(p->db, azArg[2]);
|
||||
if( rc ){
|
||||
sqlite3_fprintf(stderr,"User-Delete failed: %d\n", rc);
|
||||
rc = 1;
|
||||
}
|
||||
}else{
|
||||
eputz("Usage: .user login|add|edit|delete ...\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
||||
|
||||
if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){
|
||||
char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit";
|
||||
sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
|
||||
|
@ -1602,47 +1602,11 @@ struct FuncDefHash {
|
||||
};
|
||||
#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
|
||||
|
||||
#if defined(SQLITE_USER_AUTHENTICATION)
|
||||
# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \
|
||||
See ext/userauth/user-auth.txt for details."
|
||||
#endif
|
||||
#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 authLevel; /* Current authentication level */
|
||||
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.authLevel */
|
||||
#define UAUTH_Unknown 0 /* Authentication not yet checked */
|
||||
#define UAUTH_Fail 1 /* User authentication failed */
|
||||
#define UAUTH_User 2 /* Authenticated as a normal user */
|
||||
#define UAUTH_Admin 3 /* Authenticated as an administrator */
|
||||
|
||||
/* Functions used only by user authorization logic */
|
||||
int sqlite3UserAuthTable(const char*);
|
||||
int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*);
|
||||
void sqlite3UserAuthInit(sqlite3*);
|
||||
void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
|
||||
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
||||
|
||||
/*
|
||||
** typedef for the authorization callback function.
|
||||
*/
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
|
||||
const char*, const char*);
|
||||
#else
|
||||
typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
|
||||
const char*);
|
||||
#endif
|
||||
typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
|
||||
const char*);
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
|
||||
@ -1803,9 +1767,6 @@ struct sqlite3 {
|
||||
void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
|
||||
sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
|
||||
#endif
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
sqlite3_userauth auth; /* User authentication information */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1155,9 +1155,6 @@ static int auth_callback(
|
||||
const char *zArg2,
|
||||
const char *zArg3,
|
||||
const char *zArg4
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
,const char *zArg5
|
||||
#endif
|
||||
){
|
||||
const char *zCode;
|
||||
Tcl_DString str;
|
||||
@ -1217,9 +1214,6 @@ static int auth_callback(
|
||||
Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
|
||||
Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
|
||||
Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
|
||||
#endif
|
||||
rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
|
||||
Tcl_DStringFree(&str);
|
||||
zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
|
||||
|
131
src/test1.c
131
src/test1.c
@ -8324,131 +8324,6 @@ static int SQLITE_TCLAPI sorter_test_sort4_helper(
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
#include "sqlite3userauth.h"
|
||||
/*
|
||||
** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD
|
||||
*/
|
||||
static int SQLITE_TCLAPI 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;
|
||||
Tcl_Size 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, (int)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 SQLITE_TCLAPI 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;
|
||||
Tcl_Size 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, (int)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 SQLITE_TCLAPI 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;
|
||||
Tcl_Size 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, (int)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 SQLITE_TCLAPI 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 */
|
||||
|
||||
/*
|
||||
** tclcmd: register_dbstat_vtab DB
|
||||
@ -9169,12 +9044,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "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
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
{ "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 },
|
||||
{ "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 },
|
||||
|
@ -745,12 +745,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
Tcl_SetVar2(interp, "sqlite_options", "userauth", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "userauth", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_MULTIPLEX_EXT_OVWR
|
||||
Tcl_SetVar2(interp, "sqlite_options", "multiplex_ext_overwrite", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
@ -1,257 +0,0 @@
|
||||
# 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}
|
||||
|
||||
# The sqlite3_user_add() interface can be used (by an admin user only)
|
||||
# to create a new user.
|
||||
#
|
||||
do_test userauth01-1.6 {
|
||||
sqlite3_user_add db bob pw-4-bob 0
|
||||
sqlite3_user_add db cindy pw-4-cindy 0
|
||||
sqlite3_user_add db david pw-4-david 0
|
||||
execsql {
|
||||
SELECT uname, isadmin FROM sqlite_user ORDER BY uname;
|
||||
}
|
||||
} {alice 1 bob 0 cindy 0 david 0}
|
||||
|
||||
# The sqlite_user table is inaccessible (unreadable and unwriteable) to
|
||||
# non-admin users and is read-only for admin users. However, if the same
|
||||
#
|
||||
do_test userauth01-1.7 {
|
||||
sqlite3 db2 test.db
|
||||
sqlite3_user_authenticate db2 cindy pw-4-cindy
|
||||
db2 eval {
|
||||
SELECT quote(x) FROM t1 ORDER BY x;
|
||||
SELECT name FROM sqlite_master ORDER BY name;
|
||||
}
|
||||
} {NULL 1 2.5 'three' X'4444' sqlite_user t1}
|
||||
do_test userauth01-1.8 {
|
||||
catchsql {
|
||||
SELECT uname, isadmin FROM sqlite_user ORDER BY uname;
|
||||
} db2
|
||||
} {1 {no such table: sqlite_user}}
|
||||
|
||||
# Any user can change their own password.
|
||||
#
|
||||
do_test userauth01-1.9 {
|
||||
sqlite3_user_change db2 cindy xyzzy-cindy 0
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.10 {
|
||||
sqlite3_user_authenticate db2 cindy pw-4-cindy
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.11 {
|
||||
sqlite3_user_authenticate db2 cindy xyzzy-cindy
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.12 {
|
||||
sqlite3_user_change db alice xyzzy-alice 1
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.13 {
|
||||
sqlite3_user_authenticate db alice pw-4-alice
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.14 {
|
||||
sqlite3_user_authenticate db alice xyzzy-alice
|
||||
} {SQLITE_OK}
|
||||
|
||||
# No user may change their own admin privilege setting.
|
||||
#
|
||||
do_test userauth01-1.15 {
|
||||
sqlite3_user_change db alice xyzzy-alice 0
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.16 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 bob 0 cindy 0 david 0}
|
||||
do_test userauth01-1.17 {
|
||||
sqlite3_user_change db2 cindy xyzzy-cindy 1
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.18 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 bob 0 cindy 0 david 0}
|
||||
|
||||
# The sqlite3_user_change() interface can be used to change a users
|
||||
# login credentials or admin privilege.
|
||||
#
|
||||
do_test userauth01-1.20 {
|
||||
sqlite3_user_change db david xyzzy-david 1
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.21 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 bob 0 cindy 0 david 1}
|
||||
do_test userauth01-1.22 {
|
||||
sqlite3_user_authenticate db2 david xyzzy-david
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.23 {
|
||||
db2 eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 bob 0 cindy 0 david 1}
|
||||
do_test userauth01-1.24 {
|
||||
sqlite3_user_change db david pw-4-david 0
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.25 {
|
||||
sqlite3_user_authenticate db2 david pw-4-david
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.26 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 bob 0 cindy 0 david 0}
|
||||
do_test userauth01-1.27 {
|
||||
catchsql {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} db2
|
||||
} {1 {no such table: sqlite_user}}
|
||||
|
||||
# Only an admin user can change another users login
|
||||
# credentials or admin privilege setting.
|
||||
#
|
||||
do_test userauth01-1.30 {
|
||||
sqlite3_user_change db2 bob xyzzy-bob 1
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.31 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 bob 0 cindy 0 david 0}
|
||||
|
||||
# The sqlite3_user_delete() interface can be used (by an admin user only)
|
||||
# to delete a user.
|
||||
#
|
||||
do_test userauth01-1.40 {
|
||||
sqlite3_user_delete db bob
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.41 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 cindy 0 david 0}
|
||||
do_test userauth01-1.42 {
|
||||
sqlite3_user_delete db2 cindy
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.43 {
|
||||
sqlite3_user_delete db2 alice
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.44 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 cindy 0 david 0}
|
||||
|
||||
# The currently logged-in user cannot be deleted
|
||||
#
|
||||
do_test userauth01-1.50 {
|
||||
sqlite3_user_delete db alice
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.51 {
|
||||
db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname}
|
||||
} {alice 1 cindy 0 david 0}
|
||||
|
||||
# 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 command fails with an SQLITE_AUTH error.
|
||||
#
|
||||
do_test userauth01-1.60 {
|
||||
forcedelete test3.db
|
||||
sqlite3 db3 test3.db
|
||||
sqlite3_user_add db3 alice xyzzy-alice 1
|
||||
} {SQLITE_OK}
|
||||
do_test userauth01-1.61 {
|
||||
db3 eval {
|
||||
CREATE TABLE t3(a,b,c); INSERT INTO t3 VALUES(1,2,3);
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {1 2 3}
|
||||
do_test userauth01-1.62 {
|
||||
db eval {
|
||||
ATTACH 'test3.db' AS aux;
|
||||
SELECT * FROM t1, t3 ORDER BY x LIMIT 1;
|
||||
DETACH aux;
|
||||
}
|
||||
} {{} 1 2 3}
|
||||
do_test userauth01-1.63 {
|
||||
sqlite3_user_change db alice pw-4-alice 1
|
||||
sqlite3_user_authenticate db alice pw-4-alice
|
||||
catchsql {
|
||||
ATTACH 'test3.db' AS aux;
|
||||
}
|
||||
} {1 {unable to open database: test3.db}}
|
||||
do_test userauth01-1.64 {
|
||||
sqlite3_extended_errcode db
|
||||
} {SQLITE_AUTH}
|
||||
do_test userauth01-1.65 {
|
||||
db eval {PRAGMA database_list}
|
||||
} {~/test3.db/}
|
||||
|
||||
# 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.
|
||||
#
|
||||
proc auth {args} {
|
||||
lappend ::authargs $args
|
||||
return SQLITE_OK
|
||||
}
|
||||
do_test authuser01-2.1 {
|
||||
unset -nocomplain ::authargs
|
||||
db auth auth
|
||||
db eval {SELECT x FROM t1}
|
||||
set ::authargs
|
||||
} {/SQLITE_SELECT {} {} {} {} alice/}
|
||||
|
||||
|
||||
finish_test
|
@ -279,7 +279,6 @@ set boolean_defnil_options {
|
||||
SQLITE_UNTESTABLE
|
||||
SQLITE_USE_ALLOCA
|
||||
SQLITE_USE_FCNTL_TRACE
|
||||
SQLITE_USER_AUTHENTICATION
|
||||
SQLITE_USE_URI
|
||||
SQLITE_VDBE_COVERAGE
|
||||
SQLITE_WIN32_MALLOC
|
||||
|
Loading…
Reference in New Issue
Block a user