aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sqlite3.go8
-rw-r--r--sqlite3_opt_userauth.go34
-rw-r--r--sqlite3_opt_userauth_omit.go5
-rw-r--r--sqlite3_opt_userauth_test.go54
4 files changed, 86 insertions, 15 deletions
diff --git a/sqlite3.go b/sqlite3.go
index 56cb262..79b96ab 100644
--- a/sqlite3.go
+++ b/sqlite3.go
@@ -1308,7 +1308,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
//
// If the SQLITE_USER table is not present in the database file, then
// this interface is a harmless no-op returnning SQLITE_OK.
- if err := conn.RegisterFunc("authenticate", conn.Authenticate, true); err != nil {
+ if err := conn.RegisterFunc("authenticate", conn.Authenticate, false); err != nil {
return nil, err
}
//
@@ -1321,7 +1321,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// The AuthUserAdd only works for the "main" database, not
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
// non-admin user results in an error.
- if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, true); err != nil {
+ if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, false); err != nil {
return nil, err
}
//
@@ -1330,7 +1330,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// 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.
- if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, true); err != nil {
+ if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, false); err != nil {
return nil, err
}
//
@@ -1339,7 +1339,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// which guarantees that there is always an admin user and hence that
// the database cannot be converted into a no-authentication-required
// database.
- if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, true); err != nil {
+ if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, false); err != nil {
return nil, err
}
diff --git a/sqlite3_opt_userauth.go b/sqlite3_opt_userauth.go
index 2f5da0e..197938b 100644
--- a/sqlite3_opt_userauth.go
+++ b/sqlite3_opt_userauth.go
@@ -60,6 +60,7 @@ _sqlite3_auth_is_enabled(sqlite3* db)
*/
import "C"
import (
+ "errors"
"unsafe"
)
@@ -67,6 +68,11 @@ const (
SQLITE_AUTH = C.SQLITE_AUTH
)
+var (
+ ErrUnauthorized = errors.New("SQLITE_AUTH: Unauthorized")
+ ErrAdminRequired = errors.New("SQLITE_AUTH: Unauthorized; Admin Privileges Required")
+)
+
// Authenticate will perform an authentication of the provided username
// and password against the database.
//
@@ -92,6 +98,9 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
}()
rv := C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password)))
+ if rv == C.SQLITE_AUTH {
+ return ErrUnauthorized
+ }
if rv != C.SQLITE_OK {
return c.lastError()
}
@@ -113,6 +122,18 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
isAdmin = 1
}
+ rv := c.authUserAdd(username, password, isAdmin)
+ switch rv {
+ case C.SQLITE_AUTH:
+ return ErrAdminRequired
+ case C.SQLITE_OK:
+ return nil
+ default:
+ return c.lastError()
+ }
+}
+
+func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// Allocate C Variables
cuser := C.CString(username)
cpass := C.CString(password)
@@ -123,12 +144,7 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
C.free(unsafe.Pointer(cpass))
}()
- rv := C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
- if rv != C.SQLITE_OK {
- return c.lastError()
- }
-
- return nil
+ return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
}
// AuthUserChange can be used to change a users
@@ -153,6 +169,9 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
}()
rv := C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
+ if rv == C.SQLITE_AUTH {
+ return ErrAdminRequired
+ }
if rv != C.SQLITE_OK {
return c.lastError()
}
@@ -175,6 +194,9 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
}()
rv := C._sqlite3_user_delete(c.db, cuser)
+ if rv == SQLITE_AUTH {
+ return ErrAdminRequired
+ }
if rv != C.SQLITE_OK {
return c.lastError()
}
diff --git a/sqlite3_opt_userauth_omit.go b/sqlite3_opt_userauth_omit.go
index 0ae92da..3d1c758 100644
--- a/sqlite3_opt_userauth_omit.go
+++ b/sqlite3_opt_userauth_omit.go
@@ -62,4 +62,9 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
return nil
}
+// Check is database is protected by user authentication
+func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
+ return
+}
+
// EOF
diff --git a/sqlite3_opt_userauth_test.go b/sqlite3_opt_userauth_test.go
index 649d10e..fcbcd56 100644
--- a/sqlite3_opt_userauth_test.go
+++ b/sqlite3_opt_userauth_test.go
@@ -9,6 +9,7 @@ package sqlite3
import (
"database/sql"
+ "fmt"
"os"
"testing"
)
@@ -23,11 +24,6 @@ func TestAuthCreateDatabase(t *testing.T) {
}
defer db.Close()
- // Ping database
- if err := db.Ping(); err != nil {
- t.Fatal(err)
- }
-
var exists bool
err = db.QueryRow("select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';").Scan(&exists)
if err != nil {
@@ -38,3 +34,51 @@ func TestAuthCreateDatabase(t *testing.T) {
t.Fatal("failed to enable User Authentication")
}
}
+
+func TestAuthorization(t *testing.T) {
+ tempFilename := TempFilename(t)
+ fmt.Println(tempFilename)
+ //defer os.Remove(tempFilename)
+
+ db, err := sql.Open("sqlite3", "file:"+tempFilename+"?_auth&_auth_user=admin&_auth_pass=admin")
+ if err != nil {
+ t.Fatal("Failed to open database:", err)
+ }
+
+ if _, err := db.Exec("select auth_user_add('user', 'user', false);"); err != nil {
+ t.Fatal(err)
+ }
+
+ var uname string
+ if err := db.QueryRow("select uname from sqlite_user where uname = 'user';").Scan(&uname); err != nil {
+ t.Fatal(err)
+ }
+
+ if uname != "user" {
+ t.Fatal("Failed to create normal user")
+ }
+ db.Close()
+
+ // Re-Open Database as User
+ // Add User should now fail because we are not admin
+ db, err = sql.Open("sqlite3", "file:"+tempFilename+"?_auth_user=user&_auth_pass=user")
+ if err != nil {
+ t.Fatal("Failed to open database:", err)
+ }
+ defer db.Close()
+
+ // Try to create normal user
+ var rv string
+ if err := db.QueryRow("select auth_user_add('user2', 'user2', false);").Scan(&rv); err != nil {
+ t.Fatal(err)
+ }
+ fmt.Printf("RV: %v\n", rv)
+ // if rv != SQLITE_AUTH {
+ // t.Fatal("Succeeded creating user while not admin")
+ // }
+
+ // // Try to create admin user
+ // if _, err := db.Exec("select auth_user_add('admin2', 'admin2', true);"); err != nil {
+ // t.Fatal(err)
+ // }
+}