1 /* Copyright (c) 2014, Vsevolod Stakhov
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 *
12 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 */
23
24 #include <sys/param.h>
25 #include <sys/mount.h>
26
27 #include <assert.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <regex.h>
31 #include <grp.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <stdbool.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <libgen.h>
38
39 #include <sqlite3.h>
40
41 #include <bsd_compat.h>
42
43 #include "pkg.h"
44 #include "private/event.h"
45 #include "private/pkg.h"
46 #include "private/pkgdb.h"
47 #include "private/utils.h"
48 #include "binary.h"
49 #include "binary_private.h"
50
51 extern struct pkg_ctx ctx;
52
53 static void
sqlite_file_exists(sqlite3_context * ctx,int argc,sqlite3_value ** argv)54 sqlite_file_exists(sqlite3_context *ctx, int argc, sqlite3_value **argv)
55 {
56 char fpath[MAXPATHLEN];
57 sqlite3 *db = sqlite3_context_db_handle(ctx);
58 char *path = get_dirname(xstrdup(sqlite3_db_filename(db, "main")));
59 char *cksum;
60
61 if (argc != 2) {
62 sqlite3_result_error(ctx, "file_exists needs two argument", -1);
63 return;
64 }
65
66 snprintf(fpath, sizeof(fpath), "%s/%s", path, sqlite3_value_text(argv[0]));
67
68 if (access(fpath, R_OK) == 0) {
69 cksum = pkg_checksum_file(fpath, PKG_HASH_TYPE_SHA256_HEX);
70 if (cksum && strcmp(cksum, sqlite3_value_text(argv[1])) == 0)
71 sqlite3_result_int(ctx, 1);
72 else
73 sqlite3_result_int(ctx, 0);
74 free(cksum);
75 } else {
76 sqlite3_result_int(ctx, 0);
77 }
78 free(path);
79 }
80
81 static int
pkg_repo_binary_get_user_version(sqlite3 * sqlite,int * reposcver)82 pkg_repo_binary_get_user_version(sqlite3 *sqlite, int *reposcver)
83 {
84 sqlite3_stmt *stmt;
85 int retcode;
86 const char *sql = "PRAGMA user_version;";
87
88 if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
89 ERROR_SQLITE(sqlite, sql);
90 return (EPKG_FATAL);
91 }
92
93 if (sqlite3_step(stmt) == SQLITE_ROW) {
94 *reposcver = sqlite3_column_int64(stmt, 0);
95 retcode = EPKG_OK;
96 } else {
97 *reposcver = -1;
98 retcode = EPKG_FATAL;
99 }
100 sqlite3_finalize(stmt);
101 return (retcode);
102 }
103
104 static int
pkg_repo_binary_set_version(sqlite3 * sqlite,int reposcver)105 pkg_repo_binary_set_version(sqlite3 *sqlite, int reposcver)
106 {
107 const char *sql = "PRAGMA user_version = %d;";
108
109 if (sql_exec(sqlite, sql, reposcver) != EPKG_OK) {
110 ERROR_SQLITE(sqlite, sql);
111 return (EPKG_FATAL);
112 }
113
114 return (EPKG_OK);
115 }
116
117 static int
pkg_repo_binary_apply_change(struct pkg_repo * repo,sqlite3 * sqlite,const struct repo_changes * repo_changes,const char * updown,int version,int * next_version)118 pkg_repo_binary_apply_change(struct pkg_repo *repo, sqlite3 *sqlite,
119 const struct repo_changes *repo_changes, const char *updown,
120 int version, int *next_version)
121 {
122 const struct repo_changes *change;
123 bool found = false, in_trans = false;
124 int ret = EPKG_OK;
125 char *errmsg;
126
127 for (change = repo_changes; change->version != -1; change++) {
128 if (change->version == version) {
129 found = true;
130 break;
131 }
132 }
133 if (!found) {
134 pkg_emit_error("Unable to %s \"%s\" repo schema "
135 "version %d (target version %d) "
136 "-- change not found", updown, repo->name, version,
137 REPO_SCHEMA_VERSION);
138 return (EPKG_FATAL);
139 }
140
141 /* begin transaction */
142 if ((ret = pkgdb_transaction_begin_sqlite(sqlite, "SCHEMA")) == EPKG_OK)
143 in_trans = true;
144
145 /* apply change */
146 if (ret == EPKG_OK) {
147 pkg_debug(4, "Pkgdb: running '%s'", change->sql);
148 ret = sqlite3_exec(sqlite, change->sql, NULL, NULL, &errmsg);
149 if (ret != SQLITE_OK) {
150 pkg_emit_error("sqlite: %s", errmsg);
151 sqlite3_free(errmsg);
152 ret = EPKG_FATAL;
153 }
154 }
155
156 /* update repo user_version */
157 if (ret == EPKG_OK) {
158 *next_version = change->next_version;
159 ret = pkg_repo_binary_set_version(sqlite, *next_version);
160 }
161
162 /* commit or rollback */
163 if (in_trans) {
164 if (ret != EPKG_OK)
165 pkgdb_transaction_rollback_sqlite(sqlite, "SCHEMA");
166
167 if (pkgdb_transaction_commit_sqlite(sqlite, "SCHEMA") != EPKG_OK)
168 ret = EPKG_FATAL;
169 }
170
171 if (ret == EPKG_OK) {
172 pkg_emit_notice("Repo \"%s\" %s schema %d to %d: %s",
173 repo->name, updown, version,
174 change->next_version, change->message);
175 }
176
177 return (ret);
178 }
179
180 static int
pkg_repo_binary_upgrade(struct pkg_repo * repo,sqlite3 * sqlite,int current_version)181 pkg_repo_binary_upgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version)
182 {
183 int version;
184 int next_version;
185 int ret = EPKG_OK;
186
187 for (version = current_version;
188 version < REPO_SCHEMA_VERSION;
189 version = next_version) {
190 ret = pkg_repo_binary_apply_change(repo, sqlite, repo_upgrades,
191 "upgrade", version, &next_version);
192 if (ret != EPKG_OK)
193 break;
194 pkg_debug(1, "Upgrading repo database schema from %d to %d",
195 version, next_version);
196 }
197 return (ret);
198 }
199
200 static int
pkg_repo_binary_downgrade(struct pkg_repo * repo,sqlite3 * sqlite,int current_version)201 pkg_repo_binary_downgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version)
202 {
203 int version;
204 int next_version;
205 int ret = EPKG_OK;
206
207 for (version = current_version;
208 version > REPO_SCHEMA_VERSION;
209 version = next_version) {
210
211 ret = pkg_repo_binary_apply_change(repo, sqlite, repo_downgrades,
212 "downgrade", version, &next_version);
213 if (ret != EPKG_OK)
214 break;
215 pkg_debug(1, "Downgrading repo database schema from %d to %d",
216 version, next_version);
217 }
218 return (ret);
219 }
220
221 int
pkg_repo_binary_check_version(struct pkg_repo * repo,sqlite3 * sqlite)222 pkg_repo_binary_check_version(struct pkg_repo *repo, sqlite3 *sqlite)
223 {
224 int reposcver;
225 int repomajor;
226 int ret;
227
228 if ((ret = pkg_repo_binary_get_user_version(sqlite, &reposcver))
229 != EPKG_OK)
230 return (ret); /* sqlite error */
231
232 /*
233 * If the local pkgng uses a repo schema behind that used to
234 * create the repo, we may still be able use it for reading
235 * (ie pkg install), but pkg repo can't do an incremental
236 * update unless the actual schema matches the compiled in
237 * schema version.
238 *
239 * Use a major - minor version schema: as the user_version
240 * PRAGMA takes an integer version, encode this as MAJOR *
241 * 1000 + MINOR.
242 *
243 * So long as the major versions are the same, the local pkgng
244 * should be compatible with any repo created by a more recent
245 * pkgng, although it may need some modification of the repo
246 * schema
247 */
248
249 /* --- Temporary ---- Grandfather in the old repo schema
250 version so this patch doesn't immediately invalidate all
251 the repos out there */
252
253 if (reposcver == 2)
254 reposcver = 2000;
255 if (reposcver == 3)
256 reposcver = 2001;
257
258 repomajor = reposcver / 1000;
259
260 if (repomajor < REPO_SCHEMA_MAJOR) {
261 pkg_emit_error("Repo %s (schema version %d) is too old - "
262 "need at least schema %d", repo->name, reposcver,
263 REPO_SCHEMA_MAJOR * 1000);
264 return (EPKG_REPOSCHEMA);
265 }
266
267 if (repomajor > REPO_SCHEMA_MAJOR) {
268 pkg_emit_error("Repo %s (schema version %d) is too new - "
269 "we can accept at most schema %d", repo->name, reposcver,
270 ((REPO_SCHEMA_MAJOR + 1) * 1000) - 1);
271 return (EPKG_REPOSCHEMA);
272 }
273
274 /* This is a repo schema version we can work with */
275
276 ret = EPKG_OK;
277
278 if (reposcver < REPO_SCHEMA_VERSION) {
279 if (sqlite3_db_readonly(sqlite, "main")) {
280 pkg_emit_error("Repo %s needs schema upgrade from "
281 "%d to %d but it is opened readonly", repo->name,
282 reposcver, REPO_SCHEMA_VERSION);
283 ret = EPKG_FATAL;
284 } else
285 ret = pkg_repo_binary_upgrade(repo, sqlite, reposcver);
286 } else if (reposcver > REPO_SCHEMA_VERSION) {
287 if (sqlite3_db_readonly(sqlite, "main")) {
288 pkg_emit_error("Repo %s needs schema downgrade from "
289 "%d to %d but it is opened readonly", repo->name,
290 reposcver, REPO_SCHEMA_VERSION
291 );
292 ret = EPKG_FATAL;
293 } else
294 ret = pkg_repo_binary_downgrade(repo, sqlite, reposcver);
295 }
296
297 return (ret);
298 }
299
300 int
pkg_repo_binary_open(struct pkg_repo * repo,unsigned mode)301 pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode)
302 {
303 char filepath[MAXPATHLEN];
304 sqlite3 *sqlite = NULL;
305 int flags, dbdirfd, fd;
306 int64_t res;
307 struct pkg_repo_it *it;
308 struct pkg *pkg = NULL;
309
310 sqlite3_initialize();
311
312 pkgdb_syscall_overload();
313
314 dbdirfd = pkg_get_dbdirfd();
315 snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));
316
317 /* Open metafile */
318 if ((fd = openat(dbdirfd, filepath, O_RDONLY)) != -1) {
319 if (pkg_repo_meta_load(fd, &repo->meta) != EPKG_OK) {
320 pkg_emit_error("Repository %s load error: "
321 "meta cannot be loaded %s", pkg_repo_name(repo),
322 strerror(errno));
323 close(fd);
324 return (EPKG_FATAL);
325 }
326 close(fd);
327 }
328
329 snprintf(filepath, sizeof(filepath), "%s",
330 pkg_repo_binary_get_filename(pkg_repo_name(repo)));
331
332 /* Always want read mode here */
333 if (faccessat(dbdirfd, filepath, R_OK | mode, 0) != 0) {
334 return (EPKG_ENOACCESS);
335 }
336
337 flags = (mode & W_OK) != 0 ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
338 if (sqlite3_open_v2(filepath, &sqlite, flags, NULL) != SQLITE_OK) {
339 pkgdb_nfs_corruption(sqlite);
340 pkg_emit_error("Repository %s load error: "
341 "cannot open sqlite3 db: %s", pkg_repo_name(repo),
342 strerror(errno));
343 return (EPKG_FATAL);
344 }
345
346 /* Sanitise sqlite database */
347 if (get_pragma(sqlite, "SELECT count(name) FROM sqlite_master "
348 "WHERE type='table' AND name='repodata';", &res, false) != EPKG_OK) {
349 pkg_emit_error("Repository %s load error: "
350 "unable to query db: %s", pkg_repo_name(repo),
351 strerror(errno));
352 sqlite3_close(sqlite);
353 return (EPKG_FATAL);
354 }
355
356 if (res != 1) {
357 pkg_emit_error("Repository %s contains no repodata table, "
358 "need to re-create database", repo->name);
359 sqlite3_close(sqlite);
360 return (EPKG_FATAL);
361 }
362
363 /* Check package site */
364 char *req = sqlite3_mprintf("select count(key) from repodata "
365 "WHERE key = \"packagesite\" and value = '%q'", pkg_repo_url(repo));
366
367 res = 0;
368 get_pragma(sqlite, req, &res, true);
369 sqlite3_free(req);
370 if (res != 1) {
371 pkg_emit_error("Repository %s has a wrong packagesite, need to "
372 "re-create database", repo->name);
373 sqlite3_close(sqlite);
374 return (EPKG_FATAL);
375 }
376
377 /* Check version */
378 if (pkg_repo_binary_check_version(repo, sqlite) != EPKG_OK) {
379 pkg_emit_error("need to re-create repo %s to upgrade schema version",
380 repo->name);
381 sqlite3_close(sqlite);
382 if (mode & W_OK)
383 unlink(filepath);
384 return (EPKG_REPOSCHEMA);
385 }
386
387 repo->priv = sqlite;
388 /* Check digests format */
389 if ((it = pkg_repo_binary_query(repo, NULL, NULL, MATCH_ALL)) == NULL)
390 return (EPKG_OK);
391
392 if (it->ops->next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) {
393 it->ops->free(it);
394 return (EPKG_OK);
395 }
396 it->ops->free(it);
397 if (pkg->digest == NULL || !pkg_checksum_is_valid(pkg->digest, strlen(pkg->digest))) {
398 pkg_emit_error("Repository %s has incompatible checksum format, need to "
399 "re-create database", repo->name);
400 pkg_free(pkg);
401 sqlite3_close(sqlite);
402 repo->priv = NULL;
403 return (EPKG_FATAL);
404 }
405 pkg_free(pkg);
406
407 return (EPKG_OK);
408 }
409
410 int
pkg_repo_binary_create(struct pkg_repo * repo)411 pkg_repo_binary_create(struct pkg_repo *repo)
412 {
413 char filepath[MAXPATHLEN];
414 sqlite3 *sqlite = NULL;
415 int retcode, dbdirfd;
416
417 sqlite3_initialize();
418
419 dbdirfd = pkg_get_dbdirfd();
420 snprintf(filepath, sizeof(filepath), "%s",
421 pkg_repo_binary_get_filename(pkg_repo_name(repo)));
422 /* Should never ever happen */
423 if (faccessat(dbdirfd, filepath, R_OK, 0) == 0)
424 return (EPKG_CONFLICT);
425
426 pkgdb_syscall_overload();
427
428 /* Open for read/write/create */
429 if (sqlite3_open(filepath, &sqlite) != SQLITE_OK) {
430 pkgdb_nfs_corruption(sqlite);
431 return (EPKG_FATAL);
432 }
433
434 retcode = sql_exec(sqlite, binary_repo_initsql, REPO_SCHEMA_VERSION);
435
436 if (retcode == EPKG_OK) {
437 sqlite3_stmt *stmt;
438 const char sql[] = ""
439 "INSERT OR REPLACE INTO repodata (key, value) "
440 "VALUES (\"packagesite\", ?1);";
441
442 /* register the packagesite */
443 if (sql_exec(sqlite, "CREATE TABLE IF NOT EXISTS repodata ("
444 " key TEXT UNIQUE NOT NULL,"
445 " value TEXT NOT NULL"
446 ");") != EPKG_OK) {
447 pkg_emit_error("Unable to register the packagesite in the "
448 "database");
449 retcode = EPKG_FATAL;
450 goto cleanup;
451 }
452
453 if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
454 ERROR_SQLITE(sqlite, sql);
455 retcode = EPKG_FATAL;
456 goto cleanup;
457 }
458
459 sqlite3_bind_text(stmt, 1, pkg_repo_url(repo), -1, SQLITE_STATIC);
460
461 if (sqlite3_step(stmt) != SQLITE_DONE) {
462 ERROR_STMT_SQLITE(sqlite, stmt);
463 sqlite3_finalize(stmt);
464 retcode = EPKG_FATAL;
465 goto cleanup;
466 }
467
468 sqlite3_finalize(stmt);
469 }
470
471 cleanup:
472 sqlite3_close(sqlite);
473
474 return (retcode);
475 }
476
477 int
pkg_repo_binary_init(struct pkg_repo * repo)478 pkg_repo_binary_init(struct pkg_repo *repo)
479 {
480 int retcode = EPKG_OK;
481 sqlite3 *sqlite = PRIV_GET(repo);
482
483 sqlite3_create_function(sqlite, "file_exists", 2, SQLITE_ANY, NULL,
484 sqlite_file_exists, NULL, NULL);
485 retcode = sql_exec(sqlite, "PRAGMA synchronous=default");
486 if (retcode != EPKG_OK)
487 return (retcode);
488
489 retcode = sql_exec(sqlite, "PRAGMA foreign_keys=on");
490 if (retcode != EPKG_OK)
491 return (retcode);
492 sql_exec(sqlite, "PRAGMA mmap_size=268435456;");
493
494
495 pkgdb_sqlcmd_init(sqlite, NULL, NULL);
496
497 retcode = pkg_repo_binary_init_prstatements(sqlite);
498 if (retcode != EPKG_OK)
499 return (retcode);
500
501 repo->priv = sqlite;
502
503 return (EPKG_OK);
504 }
505
506 int
pkg_repo_binary_close(struct pkg_repo * repo,bool commit)507 pkg_repo_binary_close(struct pkg_repo *repo, bool commit)
508 {
509 int retcode = EPKG_OK;
510 sqlite3 *sqlite = PRIV_GET(repo);
511
512 if (sqlite == NULL)
513 return (retcode);
514
515 if (commit) {
516 if (pkgdb_transaction_commit_sqlite(sqlite, NULL) != SQLITE_OK)
517 retcode = EPKG_FATAL;
518 }
519
520 pkg_repo_binary_finalize_prstatements();
521 sqlite3_close(sqlite);
522
523 repo->priv = NULL;
524
525 return (retcode);
526 }
527
528 int
pkg_repo_binary_access(struct pkg_repo * repo,unsigned mode)529 pkg_repo_binary_access(struct pkg_repo *repo, unsigned mode)
530 {
531 int ret = EPKG_OK;
532
533 ret = pkgdb_check_access(mode,
534 pkg_repo_binary_get_filename(pkg_repo_name(repo)));
535
536 return (ret);
537 }
538