Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Instead of testing geteuid() == 0, instead, test what we really mean: the package database (local.sqlite) has secure permissions, and the euid of the process as appropriate read / write access (including to create the DB)
Matthew Seaman committed 13 years ago
commit a9e4b39a82f8ee53a810f72a23723fa0904f3eb6
parent 829553b
16 files changed +212 -108
modified pkg/add.c
@@ -66,7 +66,7 @@ exec_add(int argc, char **argv)
	struct sbuf *failedpkgs = NULL;
	char path[MAXPATHLEN + 1];
	char *file;
-
	int retcode = EPKG_OK;
+
	int retcode;
	int i;
	int failedpkgcount = 0;
	struct pkg *p = NULL;
@@ -76,14 +76,18 @@ exec_add(int argc, char **argv)
		return (EX_USAGE);
	}

-
	if (geteuid() != 0) {
-
		warnx("Adding packages can only be done as root");
+
	retcode = pkgdb_access(PKGDB_MODE_READ  |
+
			       PKGDB_MODE_WRITE |
+
			       PKGDB_MODE_CREATE,
+
			       PKGDB_DB_LOCAL);
+
	if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to add packages");
		return (EX_NOPERM);
-
	}
+
	} else if (retcode != EPKG_OK)
+
		return (EX_IOERR);

-
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
+
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
		return (EX_IOERR);
-
	}

	failedpkgs = sbuf_new_auto();
	for (i = 1; i < argc; i++) {
modified pkg/audit.c
@@ -392,16 +392,25 @@ exec_audit(int argc, char **argv)
		goto cleanup;
	}

-
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
-
		/*
-
		 * if the database doesn't exist a normal user can't create it
-
		 * it just means there is no package
-
		 */
-
		if (geteuid() == 0)
-
			return (EX_IOERR);
+
	/*
+
	 * if the database doesn't exist it just means there are no
+
	 * packages to audit.
+
	 */
+

+
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
+
	if (ret == EPKG_ENODB) 
		return (EX_OK);
+
	else if (ret == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to read package database");
+
		return (EX_NOPERM);
+
	} else if (ret != EPKG_OK) {
+
		warnx("Error accessing package database");
+
		return (EX_IOERR);
	}

+
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
+
		return (EX_IOERR);
+

	if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL)
	{
		warnx("cannot query local database");
modified pkg/autoremove.c
@@ -47,7 +47,7 @@ exec_autoremove(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
-
	int retcode = EX_SOFTWARE;
+
	int retcode;
	int ch;
	bool yes = false;
	bool dry_run = false;
@@ -80,9 +80,17 @@ exec_autoremove(int argc, char **argv)
		return (EX_USAGE);
	}

-
	if (geteuid() != 0) {
-
		warnx("autoremove can only be done as root");
+
	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
+
			       PKGDB_DB_LOCAL);
+
	if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to autoremove packages");
		return (EX_NOPERM);
+
	} else if (retcode == EPKG_ENODB) {
+
		warnx("No packages installed.  Nothing to do!");
+
		return (EX_OK);
+
	} else if (retcode != EPKG_OK) {
+
		warnx("Error accessing package database");
+
		return (EX_SOFTWARE);
	}

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
@@ -97,12 +105,13 @@ exec_autoremove(int argc, char **argv)

	pkg_jobs_set_flags(jobs, f);

-
	if ((retcode = pkg_jobs_solve(jobs)) != EPKG_OK)
+
	if ((retcode = pkg_jobs_solve(jobs)) != EPKG_OK) {
+
		retcode = EX_SOFTWARE;
		goto cleanup;
+
	}

	if ((nbactions = pkg_jobs_count(jobs)) == 0) {
		printf("Nothing to do.\n");
-
		retcode = 0;
		goto cleanup;
	}

@@ -115,8 +124,10 @@ exec_autoremove(int argc, char **argv)
		if (dry_run)
			yes = false;
	}
-
	if (!yes || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK)
+
	if (!yes || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK) {
+
		retcode = EX_SOFTWARE;
		goto cleanup;
+
	}

	pkgdb_compact(db);

modified pkg/check.c
@@ -175,8 +175,18 @@ fix_deps(struct pkgdb *db, struct deps_head *dh, int nbpkgs, bool yes)
	if (yes == false)
		yes = query_yesno("\n>>> Try to fix the missing dependencies [y/N]: ");

-
	if (yes == true)
+
	if (yes == true) {
+
		if (pkgdb_access(PKGDB_MODE_WRITE, PKGDB_DB_LOCAL) ==
+
		    EPKG_ENOACCESS) {
+
			warnx("Insufficient privilege to modify package "
+
			      "database");
+
			free(pkgs);
+
			pkg_jobs_free(jobs);
+
			return (EPKG_ENOACCESS);
+
		}
+

		pkg_jobs_apply(jobs);
+
	}

	free(pkgs);
	pkg_jobs_free(jobs);
@@ -237,7 +247,7 @@ exec_check(int argc, char **argv)
	int flags = PKG_LOAD_BASIC;
	int ret;
	int ch;
-
	bool yes = false;
+
	bool yes;
	bool dcheck = false;
	bool checksums = false;
	bool recompute = false;
@@ -247,6 +257,8 @@ exec_check(int argc, char **argv)
	int i;
	int verbose = 0;

+
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+

	struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh);

	while ((ch = getopt(argc, argv, "yagdBxsrv")) != -1) {
@@ -282,9 +294,6 @@ exec_check(int argc, char **argv)
		case 'r':
			recompute = true;
			flags |= PKG_LOAD_FILES;
-
			if (geteuid() != 0)
-
				errx(EX_USAGE, "recomputing the checksums"
-
				    " and size can only be done as root");
			break;
		case 'v':
			verbose = 1;
@@ -305,14 +314,24 @@ exec_check(int argc, char **argv)
		return (EX_USAGE);
	}

-
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
-
	if (ret == EPKG_ENODB) {
-
		if (geteuid() == 0)
-
			return (EX_IOERR);
+
	if (recompute || reanalyse_shlibs)
+
		ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
+
				   PKGDB_DB_LOCAL);
+
	else
+
		ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);

+
	if (ret == EPKG_ENODB) {
+
		warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
+
	} else if (ret == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to access package database");
+
		return (EX_NOPERM);
+
	} else if (ret != EPKG_OK) {
+
		warnx("Error accessing package database");
+
		return (EX_SOFTWARE);
	}

+
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

@@ -350,12 +369,10 @@ exec_check(int argc, char **argv)
			}
		}

-
		if (geteuid() == 0 && nbpkgs > 0) {
-
			if (yes == false)
-
				pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
-

+
		if (dcheck && nbpkgs > 0 ) {
			printf("\n>>> Missing package dependencies were detected.\n");
			printf(">>> Found %d issue(s) in total with your package database.\n\n", nbpkgs);
+

			ret = fix_deps(db, &dh, nbpkgs, yes);
			if (ret == EPKG_OK)
				check_summary(db, &dh);
modified pkg/delete.c
@@ -104,14 +104,21 @@ exec_delete(int argc, char **argv)
		return (EX_USAGE);
	}

-
	if (geteuid() != 0) {
-
		warnx("deleting packages can only be done as root");
+
	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
+
			       PKGDB_DB_LOCAL);
+
	if (retcode == EPKG_ENODB) {
+
		warnx("No packages installed.  Nothing to do!");
+
		return (EX_OK);
+
	} else if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to delete packages");
		return (EX_NOPERM);
+
	} else if (retcode != EPKG_OK) {
+
		warnx("Error accessing package database");
+
		return (EX_SOFTWARE);
	}
-
	
-
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
-
		return (EPKG_FATAL);
-
	}
+

+
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
+
		return (EX_IOERR);

	if (pkg_jobs_new(&jobs, PKG_JOBS_DEINSTALL, db) != EPKG_OK) {
		pkgdb_close(db);
modified pkg/event.c
@@ -213,9 +213,7 @@ event_callback(void *data, struct pkg_event *ev)
		    getprogname());
		break;
	case PKG_EVENT_NOLOCALDB:
-
		/* only cares if run as root */
-
		if (geteuid() == 0)
-
			fprintf(stderr, "Unable to create local database!\n");
+
		fprintf(stderr, "Local package database nonexistent!\n");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		printf("New version of pkg detected; it needs to be "
modified pkg/fetch.c
@@ -55,12 +55,14 @@ exec_fetch(int argc, char **argv)
	int retcode = EX_SOFTWARE;
	int ch;
	bool force = false;
-
	bool yes = false;
+
	bool yes;
	bool auto_update;
+
	unsigned mode;
	match_t match = MATCH_EXACT;
	pkg_flags f = PKG_FLAG_NONE;

	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
+
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);

	while ((ch = getopt(argc, argv, "ygxr:qaLd")) != -1) {
		switch (ch) {
@@ -102,11 +104,20 @@ exec_fetch(int argc, char **argv)
		return (EX_USAGE);
	}

-
	/* TODO: Allow the user to specify an output directory via -o outdir */
-
	if (geteuid() != 0) {
-
		warnx("Fetching packages can only be done as root");
+
	/* TODO: Allow the user to specify an output directory via -o
+
	   outdir */
+

+
	if (auto_update)
+
		mode = PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE;
+
	else
+
		mode = PKGDB_MODE_READ;
+

+
	retcode = pkgdb_access(mode, PKGDB_DB_REPO);
+
	if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to access repo catalogue");
		return (EX_NOPERM);
-
	}
+
	} else if (retcode != EPKG_OK)
+
		return (EX_IOERR);

	/* first update the remote repositories if needed */
	if (auto_update && (retcode = pkgcli_update(false)) != EPKG_OK)
@@ -131,9 +142,7 @@ exec_fetch(int argc, char **argv)

	if (!quiet) {
		print_jobs_summary(jobs, "The following packages will be fetched:\n\n");
-
		
-
		if (!yes)
-
			pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+

		if (!yes)
			yes = query_yesno("\nProceed with fetching packages [y/N]: ");
	}
modified pkg/info.c
@@ -193,20 +193,20 @@ exec_info(int argc, char **argv)
		return (0);
	}

-
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
-
	if (ret == EPKG_ENODB) {
-
		if (geteuid() == 0)
-
			return (EX_IOERR);
-

+
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
+
	if (ret == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to query package database");
+
		return (EX_NOPERM);
+
	} else if (ret == EPKG_ENODB) {
		if (match == MATCH_ALL)
			return (EX_OK);
-

		if (!quiet)
-
			printf("No packages installed.\n");
-

+
			warnx("No packages installed");
		return (EX_UNAVAILABLE);
-
	}
-

+
	} else if (ret != EPKG_OK)
+
		return (EX_IOERR);
+
		
+
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

modified pkg/install.c
@@ -55,7 +55,7 @@ exec_install(int argc, char **argv)
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
	const char *reponame = NULL;
-
	int retcode = EX_SOFTWARE;
+
	int retcode;
	int updcode = EPKG_OK;
	int ch;
	bool yes;
@@ -114,22 +114,28 @@ exec_install(int argc, char **argv)
		return (EX_USAGE);
	}

-
	if (geteuid() != 0) {
-
		warnx("Installing packages can only be done as root");
+
	retcode = pkgdb_access(PKGDB_MODE_READ  |
+
			       PKGDB_MODE_WRITE |
+
			       PKGDB_MODE_CREATE,
+
			       PKGDB_DB_LOCAL   |
+
			       PKGDB_DB_REPO);
+
	if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to install packages");
		return (EX_NOPERM);
-
	}
+
	} else if (retcode != EPKG_OK)
+
		return (EX_IOERR);
+
	else
+
		retcode = EX_SOFTWARE;

	/* first update the remote repositories if needed */
	if (auto_update && (updcode = pkgcli_update(false)) != EPKG_OK)
		return (updcode);

-
	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
+
	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK)
		return (EX_IOERR);
-
	}

-
	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) {
+
	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK)
		goto cleanup;
-
	}

	pkg_jobs_set_flags(jobs, f);

modified pkg/lock.c
@@ -172,21 +172,23 @@ exec_lock_unlock(int argc, char **argv, enum action action)
	else
		pkgname = argv[0];

-
	if (geteuid() != 0) {
-
		warnx("lock and unlock can only be done as root");
-
		return (EX_NOPERM);
-
	}
-

-
	retcode = pkgdb_open(&db, PKGDB_DEFAULT);
+
	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
+
			       PKGDB_DB_LOCAL);
	if (retcode == EPKG_ENODB) {
		if (match == MATCH_ALL)
			return (EX_OK);
-

		if (!quiet)
-
			printf("No packages installed.\n");
-

-
		return (EX_NOINPUT);
+
			warnx("No packages installed.  Nothing to do!");
+
		return (EX_OK);
+
	} else if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to modify package database");
+
		return (EX_NOPERM);
+
	} else if (retcode != EPKG_OK) {
+
		warnx("Error accessing package database");
+
		return (EX_SOFTWARE);
	}
+

+
	retcode = pkgdb_open(&db, PKGDB_DEFAULT);
	if (retcode != EPKG_OK)
		return (EX_IOERR);

modified pkg/query.c
@@ -30,6 +30,7 @@
#include <sys/sbuf.h>

#include <ctype.h>
+
#include <err.h>
#include <inttypes.h>
#include <libutil.h>
#include <pkg.h>
@@ -818,7 +819,7 @@ exec_query(int argc, char **argv)
	int query_flags = PKG_LOAD_BASIC;
	match_t match = MATCH_EXACT;
	int ch;
-
	int ret = EPKG_OK;
+
	int ret;
	int retcode = EX_OK;
	int i;
	char multiline = 0;
@@ -888,15 +889,18 @@ exec_query(int argc, char **argv)
		sbuf_finish(sqlcond);
	}

-
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
-
	if (ret == EPKG_ENODB) {
-
		if (geteuid() == 0)
-
			return (EX_IOERR);
-

-
		/* do not fail if run as a user */
+
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
+
	if (ret == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to query package database");
+
		return (EX_NOPERM);
+
	} else if (ret == EPKG_ENODB) {
+
		if (!quiet)
+
			warnx("No packages installed");
		return (EX_OK);
-
	}
+
	} else if (ret != EPKG_OK)
+
		return (EX_IOERR);

+
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

modified pkg/register.c
@@ -97,12 +97,19 @@ exec_register(int argc, char **argv)
	bool developer = false;

	int i;
-
	int ret = EPKG_OK, retcode = EX_OK;
-

-
	if (geteuid() != 0) {
-
		warnx("registering packages can only be done as root");
+
	int ret = EPKG_OK, retcode;
+

+
	retcode = pkgdb_access(PKGDB_MODE_READ  |
+
			       PKGDB_MODE_WRITE |
+
			       PKGDB_MODE_CREATE,
+
			       PKGDB_DB_LOCAL);
+
	if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to register packages");
		return (EX_NOPERM);
-
	}
+
	} else if (retcode != EPKG_OK)
+
		return (EX_IOERR);
+
	else
+
		retcode = EX_OK;

	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);

modified pkg/rquery.c
@@ -143,15 +143,16 @@ exec_rquery(int argc, char **argv)
		sbuf_finish(sqlcond);
	}

-
	ret = pkgdb_open(&db, PKGDB_REMOTE);
-
	if (ret == EPKG_ENODB) {
-
		if (geteuid() == 0)
-
			return (EX_IOERR);
-

-
		/* do not fail if run as a user */
+
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
+
	if (ret == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to query package database");
+
		return (EX_NOPERM);
+
	} else if (ret == EPKG_ENODB) {
		return (EX_OK);
-
	}
+
	} else if (ret != EPKG_OK)
+
		return (EX_IOERR);

+
	ret = pkgdb_open(&db, PKGDB_REMOTE);
	if (ret != EPKG_OK)
		return (EX_IOERR);

modified pkg/set.c
@@ -65,6 +65,7 @@ exec_set(int argc, char **argv)
	char *oldorigin = NULL;
	unsigned int loads = PKG_LOAD_BASIC;
	unsigned int sets = 0;
+
	int retcode;

	while ((ch = getopt(argc, argv, "ayA:kxgo:")) != -1) {
		switch (ch) {
@@ -126,9 +127,20 @@ exec_set(int argc, char **argv)
		return (EX_USAGE);
	}

-
	if (geteuid() != 0) {
-
		warnx("Modifying local database can only be done as root");
+
	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
+
			       PKGDB_DB_LOCAL);
+
	if (retcode == EPKG_ENODB) {
+
		if (match == MATCH_ALL)
+
			return (EX_OK);
+
		if (!quiet)
+
			warnx("No packages installed.  Nothing to do!");
+
		return (EX_OK);
+
	} else if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to modify package database");
		return (EX_NOPERM);
+
	} else if (retcode != EPKG_OK) {
+
		warnx("Error accessing package database");
+
		return (EX_SOFTWARE);
	}

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
modified pkg/update.c
@@ -132,10 +132,14 @@ exec_update(int argc, char **argv)
		return (EX_USAGE);
	}

-
	if (geteuid() != 0) {
-
		warnx("Updating repository catalogues can only be done as root");
+
	ret = pkgdb_access(PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
+
			   PKGDB_DB_REPO);
+
	if (ret == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to update repository "
+
		      "catalogue");
		return (EX_NOPERM);
-
	}
+
	} else if (ret != EPKG_OK)
+
		return (EX_IOERR);

	ret = pkgcli_update(force);

modified pkg/upgrade.c
@@ -47,7 +47,7 @@ exec_upgrade(int argc, char **argv)
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
	const char *reponame = NULL;
-
	int retcode = 1;
+
	int retcode;
	int updcode;
	int ch;
	bool yes;
@@ -90,16 +90,29 @@ exec_upgrade(int argc, char **argv)
	argc -= optind;
	argv += optind;

-
	if (!dry_run && geteuid() != 0) {
-
		warnx("Upgrading can only be done as root");
-
		return (EX_NOPERM);
-
	}
-

	if (argc != 0) {
		usage_upgrade();
		return (EX_USAGE);
	}

+

+
	if (dry_run)
+
		retcode = pkgdb_access(PKGDB_MODE_READ,
+
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
+
	else
+
		retcode = pkgdb_access(PKGDB_MODE_READ  |
+
				       PKGDB_MODE_WRITE |
+
				       PKGDB_MODE_CREATE,
+
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
+

+
	if (retcode == EPKG_ENOACCESS) {
+
		warnx("Insufficient privilege to upgrade packages");
+
		return (EX_NOPERM);
+
	} else if (retcode != EPKG_OK)
+
		return (EX_IOERR);
+
	else
+
		retcode = EX_SOFTWARE;
+
	
	/* first update the remote repositories if needed */
	if (!dry_run && auto_update && 
	    (updcode = pkgcli_update(false)) != EPKG_OK)