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