sqlite3_opt_userauth.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. //go:build sqlite_userauth
  6. // +build sqlite_userauth
  7. package sqlite3
  8. /*
  9. #cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION
  10. #cgo LDFLAGS: -lm
  11. #ifndef USE_LIBSQLITE3
  12. #include "sqlite3-binding.h"
  13. #else
  14. #include <sqlite3.h>
  15. #endif
  16. #include <stdlib.h>
  17. static int
  18. _sqlite3_user_authenticate(sqlite3* db, const char* zUsername, const char* aPW, int nPW)
  19. {
  20. return sqlite3_user_authenticate(db, zUsername, aPW, nPW);
  21. }
  22. static int
  23. _sqlite3_user_add(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
  24. {
  25. return sqlite3_user_add(db, zUsername, aPW, nPW, isAdmin);
  26. }
  27. static int
  28. _sqlite3_user_change(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
  29. {
  30. return sqlite3_user_change(db, zUsername, aPW, nPW, isAdmin);
  31. }
  32. static int
  33. _sqlite3_user_delete(sqlite3* db, const char* zUsername)
  34. {
  35. return sqlite3_user_delete(db, zUsername);
  36. }
  37. static int
  38. _sqlite3_auth_enabled(sqlite3* db)
  39. {
  40. int exists = -1;
  41. sqlite3_stmt *stmt;
  42. sqlite3_prepare_v2(db, "select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';", -1, &stmt, NULL);
  43. while ( sqlite3_step(stmt) == SQLITE_ROW) {
  44. exists = sqlite3_column_int(stmt, 0);
  45. }
  46. sqlite3_finalize(stmt);
  47. return exists;
  48. }
  49. */
  50. import "C"
  51. import (
  52. "errors"
  53. "unsafe"
  54. )
  55. const (
  56. SQLITE_AUTH = C.SQLITE_AUTH
  57. )
  58. var (
  59. ErrUnauthorized = errors.New("SQLITE_AUTH: Unauthorized")
  60. ErrAdminRequired = errors.New("SQLITE_AUTH: Unauthorized; Admin Privileges Required")
  61. )
  62. // Authenticate will perform an authentication of the provided username
  63. // and password against the database.
  64. //
  65. // If a database contains the SQLITE_USER table, then the
  66. // call to Authenticate must be invoked with an
  67. // appropriate username and password prior to enable read and write
  68. // access to the database.
  69. //
  70. // Return SQLITE_OK on success or SQLITE_ERROR if the username/password
  71. // combination is incorrect or unknown.
  72. //
  73. // If the SQLITE_USER table is not present in the database file, then
  74. // this interface is a harmless no-op returnning SQLITE_OK.
  75. func (c *SQLiteConn) Authenticate(username, password string) error {
  76. rv := c.authenticate(username, password)
  77. switch rv {
  78. case C.SQLITE_ERROR, C.SQLITE_AUTH:
  79. return ErrUnauthorized
  80. case C.SQLITE_OK:
  81. return nil
  82. default:
  83. return c.lastError()
  84. }
  85. }
  86. // authenticate provides the actual authentication to SQLite.
  87. // This is not exported for usage in Go.
  88. // It is however exported for usage within SQL by the user.
  89. //
  90. // Returns:
  91. //
  92. // C.SQLITE_OK (0)
  93. // C.SQLITE_ERROR (1)
  94. // C.SQLITE_AUTH (23)
  95. func (c *SQLiteConn) authenticate(username, password string) int {
  96. // Allocate C Variables
  97. cuser := C.CString(username)
  98. cpass := C.CString(password)
  99. // Free C Variables
  100. defer func() {
  101. C.free(unsafe.Pointer(cuser))
  102. C.free(unsafe.Pointer(cpass))
  103. }()
  104. return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))))
  105. }
  106. // AuthUserAdd can be used (by an admin user only)
  107. // to create a new user. When called on a no-authentication-required
  108. // database, this routine converts the database into an authentication-
  109. // required database, automatically makes the added user an
  110. // administrator, and logs in the current connection as that user.
  111. // The AuthUserAdd only works for the "main" database, not
  112. // for any ATTACH-ed databases. Any call to AuthUserAdd by a
  113. // non-admin user results in an error.
  114. func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
  115. isAdmin := 0
  116. if admin {
  117. isAdmin = 1
  118. }
  119. rv := c.authUserAdd(username, password, isAdmin)
  120. switch rv {
  121. case C.SQLITE_ERROR, C.SQLITE_AUTH:
  122. return ErrAdminRequired
  123. case C.SQLITE_OK:
  124. return nil
  125. default:
  126. return c.lastError()
  127. }
  128. }
  129. // authUserAdd enables the User Authentication if not enabled.
  130. // Otherwise it will add a user.
  131. //
  132. // When user authentication is already enabled then this function
  133. // can only be called by an admin.
  134. //
  135. // This is not exported for usage in Go.
  136. // It is however exported for usage within SQL by the user.
  137. //
  138. // Returns:
  139. //
  140. // C.SQLITE_OK (0)
  141. // C.SQLITE_ERROR (1)
  142. // C.SQLITE_AUTH (23)
  143. func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
  144. // Allocate C Variables
  145. cuser := C.CString(username)
  146. cpass := C.CString(password)
  147. // Free C Variables
  148. defer func() {
  149. C.free(unsafe.Pointer(cuser))
  150. C.free(unsafe.Pointer(cpass))
  151. }()
  152. return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
  153. }
  154. // AuthUserChange can be used to change a users
  155. // login credentials or admin privilege. Any user can change their own
  156. // login credentials. Only an admin user can change another users login
  157. // credentials or admin privilege setting. No user may change their own
  158. // admin privilege setting.
  159. func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error {
  160. isAdmin := 0
  161. if admin {
  162. isAdmin = 1
  163. }
  164. rv := c.authUserChange(username, password, isAdmin)
  165. switch rv {
  166. case C.SQLITE_ERROR, C.SQLITE_AUTH:
  167. return ErrAdminRequired
  168. case C.SQLITE_OK:
  169. return nil
  170. default:
  171. return c.lastError()
  172. }
  173. }
  174. // authUserChange allows to modify a user.
  175. // Users can change their own password.
  176. //
  177. // Only admins can change passwords for other users
  178. // and modify the admin flag.
  179. //
  180. // The admin flag of the current logged in user cannot be changed.
  181. // THis ensures that their is always an admin.
  182. //
  183. // This is not exported for usage in Go.
  184. // It is however exported for usage within SQL by the user.
  185. //
  186. // Returns:
  187. //
  188. // C.SQLITE_OK (0)
  189. // C.SQLITE_ERROR (1)
  190. // C.SQLITE_AUTH (23)
  191. func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
  192. // Allocate C Variables
  193. cuser := C.CString(username)
  194. cpass := C.CString(password)
  195. // Free C Variables
  196. defer func() {
  197. C.free(unsafe.Pointer(cuser))
  198. C.free(unsafe.Pointer(cpass))
  199. }()
  200. return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
  201. }
  202. // AuthUserDelete can be used (by an admin user only)
  203. // to delete a user. The currently logged-in user cannot be deleted,
  204. // which guarantees that there is always an admin user and hence that
  205. // the database cannot be converted into a no-authentication-required
  206. // database.
  207. func (c *SQLiteConn) AuthUserDelete(username string) error {
  208. rv := c.authUserDelete(username)
  209. switch rv {
  210. case C.SQLITE_ERROR, C.SQLITE_AUTH:
  211. return ErrAdminRequired
  212. case C.SQLITE_OK:
  213. return nil
  214. default:
  215. return c.lastError()
  216. }
  217. }
  218. // authUserDelete can be used to delete a user.
  219. //
  220. // This function can only be executed by an admin.
  221. //
  222. // This is not exported for usage in Go.
  223. // It is however exported for usage within SQL by the user.
  224. //
  225. // Returns:
  226. //
  227. // C.SQLITE_OK (0)
  228. // C.SQLITE_ERROR (1)
  229. // C.SQLITE_AUTH (23)
  230. func (c *SQLiteConn) authUserDelete(username string) int {
  231. // Allocate C Variables
  232. cuser := C.CString(username)
  233. // Free C Variables
  234. defer func() {
  235. C.free(unsafe.Pointer(cuser))
  236. }()
  237. return int(C._sqlite3_user_delete(c.db, cuser))
  238. }
  239. // AuthEnabled checks if the database is protected by user authentication
  240. func (c *SQLiteConn) AuthEnabled() (exists bool) {
  241. rv := c.authEnabled()
  242. if rv == 1 {
  243. exists = true
  244. }
  245. return
  246. }
  247. // authEnabled perform the actual check for user authentication.
  248. //
  249. // This is not exported for usage in Go.
  250. // It is however exported for usage within SQL by the user.
  251. //
  252. // Returns:
  253. //
  254. // 0 - Disabled
  255. // 1 - Enabled
  256. func (c *SQLiteConn) authEnabled() int {
  257. return int(C._sqlite3_auth_enabled(c.db))
  258. }
  259. // EOF