/ Check-in [a0455f9d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the ".user" shell command and implement the sqlite3_user_add() routine. Incremental check-in. The code compiles but does not work.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | user-auth
Files: files | file ages | folders
SHA1: a0455f9deb603bf91684158d911269622720fc1a
User & Date: drh 2014-09-10 19:01:14
Context
2014-09-10
22:46
Complete the implementation of the various APIs. Fix several problems. This is another incremental check-in that does not completely work. check-in: 4eaaa7fa user: drh tags: user-auth
19:01
Add the ".user" shell command and implement the sqlite3_user_add() routine. Incremental check-in. The code compiles but does not work. check-in: a0455f9d user: drh tags: user-auth
17:34
Further ideas on user authentication. Not yet working code. check-in: c8171ecd user: drh tags: user-auth
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Name change from ext/userauth/userauth.h to ext/userauth/sqlite3userauth.h.

    33     33   ** If the SQLITE_USER table is not present in the database file, then
    34     34   ** this interface is a harmless no-op returnning SQLITE_OK.
    35     35   */
    36     36   int sqlite3_user_authenticate(
    37     37     sqlite3 *db,           /* The database connection */
    38     38     const char *zUsername, /* Username */
    39     39     int nPW,               /* Number of bytes in aPW[] */
    40         -  const void *aPW        /* Password or credentials */
           40  +  const char *aPW        /* Password or credentials */
    41     41   );
    42     42   
    43     43   /*
    44     44   ** The sqlite3_user_add() interface can be used (by an admin user only)
    45     45   ** to create a new user.  When called on a no-authentication-required
    46     46   ** database, this routine converts the database into an authentication-
    47     47   ** required database, automatically makes the added user an
................................................................................
    51     51   ** non-admin user results in an error.
    52     52   */
    53     53   int sqlite3_user_add(
    54     54     sqlite3 *db,           /* Database connection */
    55     55     const char *zUsername, /* Username to be added */
    56     56     int isAdmin,           /* True to give new user admin privilege */
    57     57     int nPW,               /* Number of bytes in aPW[] */
    58         -  const void *aPW        /* Password or credentials */
           58  +  const char *aPW        /* Password or credentials */
    59     59   );
    60     60   
    61     61   /*
    62     62   ** The sqlite3_user_change() interface can be used to change a users
    63     63   ** login credentials or admin privilege.  Any user can change their own
    64     64   ** login credentials.  Only an admin user can change another users login
    65     65   ** credentials or admin privilege setting.  No user may change their own 
................................................................................
    66     66   ** admin privilege setting.
    67     67   */
    68     68   int sqlite3_user_change(
    69     69     sqlite3 *db,           /* Database connection */
    70     70     const char *zUsername, /* Username to change */
    71     71     int isAdmin,           /* Modified admin privilege for the user */
    72     72     int nPW,               /* Number of bytes in aPW[] */
    73         -  const void *aPW        /* Modified password or credentials */
           73  +  const char *aPW        /* Modified password or credentials */
    74     74   );
    75     75   
    76     76   /*
    77     77   ** The sqlite3_user_delete() interface can be used (by an admin user only)
    78     78   ** to delete a user.  The currently logged-in user cannot be deleted,
    79     79   ** which guarantees that there is always an admin user and hence that
    80     80   ** the database cannot be converted into a no-authentication-required

Changes to ext/userauth/userauth.c.

    19     19   ** To compile with the user-authentication feature, append this file to
    20     20   ** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION
    21     21   ** compile-time option.  See the user-auth.txt file in the same source
    22     22   ** directory as this file for additional information.
    23     23   */
    24     24   #ifdef SQLITE_USER_AUTHENTICATION
    25     25   #include "sqliteInt.h"
           26  +#include "sqlite3userauth.h"
    26     27   
    27     28   /*
    28     29   ** Prepare an SQL statement for use by the user authentication logic.
    29     30   ** Return a pointer to the prepared statement on success.  Return a
    30     31   ** NULL pointer if there is an error of any kind.
    31     32   */
    32     33   static sqlite3_stmt *sqlite3UserAuthPrepare(
................................................................................
    47     48     sqlite3_free(zSql);
    48     49     if( rc ){
    49     50       sqlite3_finalize(pStmt);
    50     51       pStmt = 0;
    51     52     }
    52     53     return pStmt;
    53     54   }
           55  +
           56  +/*
           57  +** Check to see if the sqlite_user table exists in database zDb.
           58  +*/
           59  +static int userTableExists(sqlite3 *db, const char *zDb){
           60  +  int rc;
           61  +  sqlite3_mutex_enter(db->mutex);
           62  +  sqlite3BtreeEnterAll(db);
           63  +  rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0;
           64  +  sqlite3BtreeLeaveAll(db);
           65  +  sqlite3_mutex_leave(db->mutex);
           66  +  return rc;
           67  +}
    54     68   
    55     69   /*
    56     70   ** Check to see if database zDb has a "sqlite_user" table and if it does
    57     71   ** whether that table can authenticate zUser with nPw,zPw.  Write one of
    58     72   ** the UAUTH_* user authorization level codes into *peAuth and return a
    59     73   ** result code.
    60     74   */
................................................................................
    63     77     const char *zDb,           /* Name of specific database to check */
    64     78     u8 *peAuth                 /* OUT: One of UAUTH_* constants */
    65     79   ){
    66     80     sqlite3_stmt *pStmt;
    67     81     int rc;
    68     82   
    69     83     *peAuth = UAUTH_Unknown;
    70         -  pStmt = sqlite3UserAuthPrepare(db, 
    71         -              "SELECT 1 FROM \"%w\".sqlite_master "
    72         -              " WHERE name='sqlite_user' AND type='table'", zDb);
    73         -  if( pStmt==0 ){
    74         -    return SQLITE_NOMEM;
    75         -  }
    76         -  rc = sqlite3_step(pStmt);
    77         -  sqlite3_finalize(pStmt);
    78         -  if( rc==SQLITE_DONE ){
           84  +  if( !userTableExists(db, "main") ){
    79     85       *peAuth = UAUTH_Admin;  /* No sqlite_user table.  Everybody is admin. */
    80         -    return SQLITE_OK;
    81         -  }
    82         -  if( rc!=SQLITE_ROW ){
    83         -    return rc;
    84     86     }
    85     87     if( db->auth.zAuthUser==0 ){
    86     88       *peAuth = UAUTH_Fail;
    87     89       return SQLITE_OK;
    88     90     }
    89     91     pStmt = sqlite3UserAuthPrepare(db,
    90     92               "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user"
................................................................................
   111    113     savedAuthLevel = db->auth.authLevel;
   112    114     db->auth.authLevel = UAUTH_Admin;
   113    115     rc = userAuthCheckLogin(db, zDb, peAuth);
   114    116     db->auth.authLevel = savedAuthLevel;
   115    117     return rc;
   116    118   }
   117    119   
          120  +/*
          121  +** Implementation of the sqlite_crypt(X,Y) function.
          122  +**
          123  +** If Y is NULL then generate a new hash for password X and return that
          124  +** hash.  If Y is not null, then generate a hash for password X using the
          125  +** same salt as the previous hash Y and return the new hash.
          126  +*/
          127  +void sqlite3CryptFunc(
          128  +  sqlite3_context *context,
          129  +  int NotUsed,
          130  +  sqlite3_value **argv
          131  +){
          132  +  const char *zIn;
          133  +  int nIn, ii;
          134  +  u8 *zOut;
          135  +  char zSalt[8];
          136  +  zIn = sqlite3_value_blob(argv[0]);
          137  +  nIn = sqlite3_value_bytes(argv[0]);
          138  +  if( sqlite3_value_type(argv[1])==SQLITE_BLOB
          139  +   && sqlite3_value_bytes(argv[1])==nIn+sizeof(zSalt)
          140  +  ){
          141  +    memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt));
          142  +  }else{
          143  +    sqlite3_randomness(sizeof(zSalt), zSalt);
          144  +  }
          145  +  zOut = sqlite3_malloc( nIn+sizeof(zSalt) );
          146  +  if( zOut==0 ){
          147  +    sqlite3_result_error_nomem(context);
          148  +  }else{
          149  +    memcpy(zOut, zSalt, sizeof(zSalt));
          150  +    for(ii=0; ii<nIn; ii++){
          151  +      zOut[ii+sizeof(zSalt)] = zIn[ii]^zSalt[ii&0x7];
          152  +    }
          153  +    sqlite3_result_blob(context, zOut, nIn+sizeof(zSalt), sqlite3_free);
          154  +  }
          155  +}
   118    156   
   119    157   /*
   120    158   ** If a database contains the SQLITE_USER table, then the
   121    159   ** sqlite3_user_authenticate() interface must be invoked with an
   122    160   ** appropriate username and password prior to enable read and write
   123    161   ** access to the database.
   124    162   **
................................................................................
   144    182     if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM;
   145    183     db->auth.zAuthPW = sqlite3_malloc( nPW+1 );
   146    184     if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM;
   147    185     memcpy(db->auth.zAuthPW,zPW,nPW);
   148    186     db->auth.nAuthPW = nPW;
   149    187     rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel);
   150    188     db->auth.authLevel = authLevel;
          189  +  sqlite3ExpirePreparedStatements(db);
   151    190     if( rc ){
   152    191       return rc;           /* OOM error, I/O error, etc. */
   153    192     }
   154    193     if( authLevel<UAUTH_User ){
   155    194       return SQLITE_AUTH;  /* Incorrect username and/or password */
   156    195     }
   157    196     return SQLITE_OK;      /* Successful login */
................................................................................
   168    207   ** non-admin user results in an error.
   169    208   */
   170    209   int sqlite3_user_add(
   171    210     sqlite3 *db,           /* Database connection */
   172    211     const char *zUsername, /* Username to be added */
   173    212     int isAdmin,           /* True to give new user admin privilege */
   174    213     int nPW,               /* Number of bytes in aPW[] */
   175         -  const void *aPW        /* Password or credentials */
          214  +  const char *aPW        /* Password or credentials */
   176    215   ){
   177         -  if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_ERROR;
          216  +  sqlite3_stmt *pStmt;
          217  +  int rc;
          218  +  if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH;
          219  +  if( !userTableExists(db, "main") ){
          220  +    if( !isAdmin ) return SQLITE_AUTH;
          221  +    pStmt = sqlite3UserAuthPrepare(db, 
          222  +              "CREATE TABLE sqlite_user(\n"
          223  +              "  uname TEXT PRIMARY KEY,\n"
          224  +              "  isAdmin BOOLEAN,\n"
          225  +              "  pw BLOB\n"
          226  +              ") WITHOUT ROWID;");
          227  +    if( pStmt==0 ) return SQLITE_NOMEM;
          228  +    sqlite3_step(pStmt);
          229  +    rc = sqlite3_finalize(pStmt);
          230  +    if( rc ) return rc;
          231  +  }
          232  +  pStmt = sqlite3UserAuthPrepare(db, 
          233  +            "INSERT INTO sqlite_user(uname,isAdmin,sqlite_crypt(pw,NULL))"
          234  +            " VALUES(%Q,%d,?1)",
          235  +            zUsername, isAdmin!=0);
          236  +  if( pStmt==0 ) return SQLITE_NOMEM;
          237  +  sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC);
          238  +  sqlite3_step(pStmt);
          239  +  rc = sqlite3_finalize(pStmt);
          240  +  if( rc ) return rc;
          241  +  if( db->auth.zAuthUser==0 ){
          242  +    assert( isAdmin!=0 );
          243  +    sqlite3_user_authenticate(db, zUsername, nPW, aPW);
          244  +  }
   178    245     return SQLITE_OK;
   179    246   }
   180    247   
   181    248   /*
   182    249   ** The sqlite3_user_change() interface can be used to change a users
   183    250   ** login credentials or admin privilege.  Any user can change their own
   184    251   ** login credentials.  Only an admin user can change another users login
................................................................................
   186    253   ** admin privilege setting.
   187    254   */
   188    255   int sqlite3_user_change(
   189    256     sqlite3 *db,           /* Database connection */
   190    257     const char *zUsername, /* Username to change */
   191    258     int isAdmin,           /* Modified admin privilege for the user */
   192    259     int nPW,               /* Number of bytes in aPW[] */
   193         -  const void *aPW        /* Modified password or credentials */
          260  +  const char *aPW        /* Modified password or credentials */
   194    261   ){
   195         -  if( db->auth.authLevel<UAUTH_User ) return SQLITE_ERROR;
          262  +  if( db->auth.authLevel<UAUTH_User ) return SQLITE_AUTH;
   196    263     if( strcmp(db->auth.zAuthUser, zUsername)!=0
   197         -       && db->auth.authLevel<UAUTH_Admin ) return SQLITE_ERROR;
          264  +       && db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH;
   198    265     return SQLITE_OK;
   199    266   }
   200    267   
   201    268   /*
   202    269   ** The sqlite3_user_delete() interface can be used (by an admin user only)
   203    270   ** to delete a user.  The currently logged-in user cannot be deleted,
   204    271   ** which guarantees that there is always an admin user and hence that
................................................................................
   205    272   ** the database cannot be converted into a no-authentication-required
   206    273   ** database.
   207    274   */
   208    275   int sqlite3_user_delete(
   209    276     sqlite3 *db,           /* Database connection */
   210    277     const char *zUsername  /* Username to remove */
   211    278   ){
   212         -  if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_ERROR;
          279  +  if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH;
          280  +  if( strcmp(db->auth.zAuthUser, zUsername)==0 ) return SQLITE_AUTH;
   213    281     return SQLITE_OK;
   214    282   }
   215    283   
   216    284   #endif /* SQLITE_USER_AUTHENTICATION */

Changes to main.mk.

    42     42   # build the SQLite library and testing tools.
    43     43   ################################################################################
    44     44   
    45     45   # This is how we compile
    46     46   #
    47     47   TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 
    48     48   TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
    49         -TCCX += -I$(TOP)/ext/async
           49  +TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth
    50     50   
    51     51   # Object files for the SQLite library.
    52     52   #
    53     53   LIBOBJ+= vdbe.o parse.o \
    54     54            alter.o analyze.o attach.o auth.o \
    55     55            backup.o bitvec.o btmutex.o btree.o build.o \
    56     56            callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
................................................................................
   212    212     $(TOP)/ext/icu/icu.c
   213    213   SRC += \
   214    214     $(TOP)/ext/rtree/sqlite3rtree.h \
   215    215     $(TOP)/ext/rtree/rtree.h \
   216    216     $(TOP)/ext/rtree/rtree.c
   217    217   SRC += \
   218    218     $(TOP)/ext/userauth/userauth.c \
   219         -  $(TOP)/ext/userauth/userauth.h
          219  +  $(TOP)/ext/userauth/sqlite3userauth.h
   220    220   
   221    221   # Generated source code files
   222    222   #
   223    223   SRC += \
   224    224     keywordhash.h \
   225    225     opcodes.c \
   226    226     opcodes.h \
................................................................................
   376    376     $(TOP)/ext/fts3/fts3_hash.h \
   377    377     $(TOP)/ext/fts3/fts3_tokenizer.h
   378    378   EXTHDR += \
   379    379     $(TOP)/ext/rtree/rtree.h
   380    380   EXTHDR += \
   381    381     $(TOP)/ext/icu/sqliteicu.h
   382    382   EXTHDR += \
   383         -  $(TOP)/ext/userauth/userauth.h
          383  +  $(TOP)/ext/userauth/sqlite3userauth.h
   384    384   
   385    385   # This is the default Makefile target.  The objects listed here
   386    386   # are what get build when you type just "make" with no arguments.
   387    387   #
   388    388   all:	sqlite3.h libsqlite3.a sqlite3$(EXE)
   389    389   
   390    390   libsqlite3.a:	$(LIBOBJ)

Changes to src/func.c.

  1691   1691       FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
  1692   1692       VFUNCTION(random,            0, 0, 0, randomFunc       ),
  1693   1693       VFUNCTION(randomblob,        1, 0, 0, randomBlob       ),
  1694   1694       FUNCTION(nullif,             2, 0, 1, nullifFunc       ),
  1695   1695       FUNCTION(sqlite_version,     0, 0, 0, versionFunc      ),
  1696   1696       FUNCTION(sqlite_source_id,   0, 0, 0, sourceidFunc     ),
  1697   1697       FUNCTION(sqlite_log,         2, 0, 0, errlogFunc       ),
         1698  +#if SQLITE_USER_AUTHENTICATION
         1699  +    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
         1700  +#endif
  1698   1701   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
  1699   1702       FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
  1700   1703       FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
  1701   1704   #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
  1702   1705       FUNCTION(quote,              1, 0, 0, quoteFunc        ),
  1703   1706       VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
  1704   1707       VFUNCTION(changes,           0, 0, 0, changes          ),

Changes to src/prepare.c.

   718    718     if( db->auth.authLevel<UAUTH_User ){
   719    719       if( db->auth.authLevel==UAUTH_Unknown ){
   720    720         u8 authLevel = UAUTH_Fail;
   721    721         sqlite3UserAuthCheckLogin(db, "main", &authLevel);
   722    722         db->auth.authLevel = authLevel;
   723    723       }
   724    724       if( db->auth.authLevel<UAUTH_User ){
   725         -      sqlite3ErrorWithMsg(db, SQLITE_ERROR, "user not authenticated");
          725  +      sqlite3ErrorWithMsg(db, SQLITE_AUTH_USER, "user not authenticated");
   726    726         sqlite3_mutex_leave(db->mutex);
   727    727         return SQLITE_ERROR;
   728    728       }
   729    729     }
   730    730   #endif
   731    731     sqlite3BtreeEnterAll(db);
   732    732     rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);

Changes to src/shell.c.

    29     29   #endif
    30     30   
    31     31   #include <stdlib.h>
    32     32   #include <string.h>
    33     33   #include <stdio.h>
    34     34   #include <assert.h>
    35     35   #include "sqlite3.h"
           36  +#if SQLITE_USER_AUTHENTICATION
           37  +# include "sqlite3userauth.h"
           38  +#endif
    36     39   #include <ctype.h>
    37     40   #include <stdarg.h>
    38     41   
    39     42   #if !defined(_WIN32) && !defined(WIN32)
    40     43   # include <signal.h>
    41     44   # if !defined(__RTP__) && !defined(_WRS_KERNEL)
    42     45   #  include <pwd.h>
................................................................................
  3431   3434         sqlite3_trace(p->db, 0, 0);
  3432   3435       }else{
  3433   3436         sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
  3434   3437       }
  3435   3438   #endif
  3436   3439     }else
  3437   3440   
         3441  +#if SQLITE_USER_AUTHENTICATION
         3442  +  if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
         3443  +    if( nArg<2 ){
         3444  +      fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
         3445  +      rc = 1;
         3446  +      goto meta_command_exit;
         3447  +    }
         3448  +    if( strcmp(azArg[1],"login")==0 ){
         3449  +      if( nArg!=4 ){
         3450  +        fprintf(stderr, "Usage: .user login USER PASSWORD\n");
         3451  +        rc = 1;
         3452  +        goto meta_command_exit;
         3453  +      }
         3454  +      rc = sqlite3_user_authenticate(p->db, azArg[2], (int)strlen(azArg[3]), azArg[3]);
         3455  +      if( rc ){
         3456  +        fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
         3457  +        rc = 1;
         3458  +      }
         3459  +    }else if( strcmp(azArg[1],"add")==0 ){
         3460  +      if( nArg!=5 ){
         3461  +        fprintf(stderr, "Usage: .user add USER ISADMIN PASSWORD\n");
         3462  +        rc = 1;
         3463  +        goto meta_command_exit;
         3464  +      }
         3465  +      rc = sqlite3_user_add(p->db, azArg[2], booleanValue(azArg[3]),
         3466  +                            (int)strlen(azArg[4]), azArg[4]);
         3467  +      if( rc ){
         3468  +        fprintf(stderr, "User-Add failed: %d\n", rc);
         3469  +        rc = 1;
         3470  +      }
         3471  +    }else if( strcmp(azArg[1],"edit")==0 ){
         3472  +      if( nArg!=5 ){
         3473  +        fprintf(stderr, "Usage: .user edit USER ISADMIN PASSWORD\n");
         3474  +        rc = 1;
         3475  +        goto meta_command_exit;
         3476  +      }
         3477  +      rc = sqlite3_user_change(p->db, azArg[2], booleanValue(azArg[3]),
         3478  +                              (int)strlen(azArg[4]), azArg[4]);
         3479  +      if( rc ){
         3480  +        fprintf(stderr, "User-Edit failed: %d\n", rc);
         3481  +        rc = 1;
         3482  +      }
         3483  +    }else if( strcmp(azArg[1],"delete")==0 ){
         3484  +      if( nArg!=3 ){
         3485  +        fprintf(stderr, "Usage: .user delete USER\n");
         3486  +        rc = 1;
         3487  +        goto meta_command_exit;
         3488  +      }
         3489  +      rc = sqlite3_user_delete(p->db, azArg[2]);
         3490  +      if( rc ){
         3491  +        fprintf(stderr, "User-Delete failed: %d\n", rc);
         3492  +        rc = 1;
         3493  +      }
         3494  +    }else{
         3495  +      fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
         3496  +      rc = 1;
         3497  +      goto meta_command_exit;
         3498  +    }    
         3499  +  }else
         3500  +#endif /* SQLITE_USER_AUTHENTICATION */
         3501  +
  3438   3502     if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
  3439   3503       fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
  3440   3504           sqlite3_libversion(), sqlite3_sourceid());
  3441   3505     }else
  3442   3506   
  3443   3507     if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
  3444   3508       const char *zDbName = nArg==2 ? azArg[1] : "main";

Changes to src/sqlite.h.in.

   488    488   #define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
   489    489   #define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
   490    490   #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
   491    491   #define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
   492    492   #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
   493    493   #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
   494    494   #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
          495  +#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
   495    496   
   496    497   /*
   497    498   ** CAPI3REF: Flags For File Open Operations
   498    499   **
   499    500   ** These bit values are intended for use in the
   500    501   ** 3rd parameter to the [sqlite3_open_v2()] interface and
   501    502   ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.

Changes to src/sqliteInt.h.

  1006   1006   #define UAUTH_Fail        1     /* User authentication failed */
  1007   1007   #define UAUTH_User        2     /* Authenticated as a normal user */
  1008   1008   #define UAUTH_Admin       3     /* Authenticated as an administrator */
  1009   1009   
  1010   1010   /* Functions used only by user authorization logic */
  1011   1011   int sqlite3UserAuthTable(const char*);
  1012   1012   int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*);
         1013  +void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
         1014  +
  1013   1015   
  1014   1016   #endif /* SQLITE_USER_AUTHENTICATION */
  1015   1017   
  1016   1018   
  1017   1019   /*
  1018   1020   ** Each database connection is an instance of the following structure.
  1019   1021   */