[pacman-dev] [PATCH WIP] Allow pacman to be run as a non-root user

William Giokas 1007380 at gmail.com
Mon Mar 3 19:19:11 EST 2014


In order to run pacman as a non-root user to install packages to
non-system (somewhere in $HOME or something) it was required to fake
your root status using fakeroot. This allows users to specify a config
directive, `NoRoot` to tell pacman that it should not check for root
privileges.

There is also an option in makepkg to allow it to not use root, as
otherwise it will call 'sudo' or 'su' when using pacman to install or
remove installed packages.
---

WIP. I'm intending to use pacman and makepkg as a manager for some game mods,
and this was the only thing really holding it back. I had done some tests using
fakeroot and other ways of getting around these checks, but this is something
that I thought should really go into pacman. Will allow even more people to use
things like pacman and PKGBUILDs for other things, like games and user packages.
Might also let us do some testing without having to fake root.

Because WIP I haven't added docs yet. Just thought I'd get someone to look this
over because I generally don't code in C, and it probably is disgusting. It's
really just a carbon copy of the checkspace stuff, except in util.c.

Thanks for looking it over, and sorry in advance for it being horrible.

Bill Giokas (kaictl)

 lib/libalpm/alpm.h    |  3 +++
 lib/libalpm/handle.c  | 13 +++++++++++++
 lib/libalpm/handle.h  |  1 +
 scripts/makepkg.sh.in | 10 ++++++----
 src/pacman/conf.c     |  3 +++
 src/pacman/conf.h     |  1 +
 src/pacman/util.c     |  3 +++
 7 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index b0adb95..10d38bb 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -675,6 +675,9 @@ int alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio);
 int alpm_option_get_checkspace(alpm_handle_t *handle);
 int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
 
+int alpm_option_get_noroot(alpm_handle_t *handle);
+int alpm_option_set_noroot(alpm_handle_t *handle, int noroot);
+
 alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle);
 int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
 
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 0842d51..c9ad007 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -252,6 +252,12 @@ int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
 	return handle->checkspace;
 }
 
+int SYMEXPORT alpm_option_get_noroot(alpm_handle_t *handle)
+{
+	CHECK_HANDLE(handle, return -1);
+	return handle->noroot;
+}
+
 int SYMEXPORT alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb)
 {
 	CHECK_HANDLE(handle, return -1);
@@ -593,6 +599,13 @@ int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
 	return 0;
 }
 
+int SYMEXPORT alpm_option_set_noroot(alpm_handle_t *handle, int noroot)
+{
+	CHECK_HANDLE(handle, return -1);
+	handle->noroot = noroot;
+	return 0;
+}
+
 int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
 		alpm_siglevel_t level)
 {
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index 27241ea..650fe27 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -89,6 +89,7 @@ struct __alpm_handle_t {
 	double deltaratio;       /* Download deltas if possible; a ratio value */
 	int usesyslog;           /* Use syslog instead of logfile? */ /* TODO move to frontend */
 	int checkspace;          /* Check disk space before installing */
+	int noroot;              /* Don't check for root status when running */
 	alpm_siglevel_t siglevel;   /* Default signature verification level */
 	alpm_siglevel_t localfilesiglevel;  /* Signature verification level for local file
 	                                       upgrade operations */
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index e230c15..dda4644 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -77,6 +77,7 @@ NEEDED=0
 NOBUILD=0
 NODEPS=0
 NOEXTRACT=0
+NOROOT=0
 PKGFUNC=0
 PKGLIST=()
 PKGVERFUNC=0
@@ -1005,7 +1006,7 @@ run_pacman() {
 	else
 		cmd=("$PACMAN_PATH" "$@")
 	fi
-	if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
+	if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]] && (( ! $NOROOT )); then
 		if type -p sudo >/dev/null; then
 			cmd=(sudo "${cmd[@]}")
 		else
@@ -2584,9 +2585,9 @@ ARGLIST=("$@")
 OPT_SHORT="AcCdefFghiLmop:rRsSV"
 OPT_LONG=('allsource' 'asroot' 'check' 'clean' 'cleanbuild' 'config:' 'force' 'geninteg'
           'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'nobuild' 'nocolor'
-          'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'pkg:' 'repackage' 'rmdeps'
-          'sign' 'skipchecksums' 'skipinteg' 'skippgpcheck' 'source' 'syncdeps'
-          'verifysource' 'version')
+          'nocheck' 'nodeps' 'noextract' 'noprepare' 'noroot' 'nosign' 'pkg:'
+					'repackage' 'rmdeps' 'sign' 'skipchecksums' 'skipinteg' 'skippgpcheck'
+					'source' 'syncdeps' 'verifysource' 'version')
 
 # Pacman Options
 OPT_LONG+=('asdeps' 'noconfirm' 'needed' 'noprogressbar')
@@ -2601,6 +2602,7 @@ while true; do
 	case "$1" in
 		# Pacman Options
 		--asdeps)         ASDEPS=1;;
+		--noroot)         NOROOT=1;;
 		--noconfirm)      PACMAN_OPTS+=" --noconfirm" ;;
 		--needed)         NEEDED=1;;
 		--noprogressbar)  PACMAN_OPTS+=" --noprogressbar" ;;
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index f75f3a7..5bea270 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -491,6 +491,8 @@ static int _parse_options(const char *key, char *value,
 			pm_printf(ALPM_LOG_DEBUG, "config: totaldownload\n");
 		} else if(strcmp(key, "CheckSpace") == 0) {
 			config->checkspace = 1;
+		} else if(strcmp(key, "NoRoot") == 0) {
+			config->noroot = 1;
 		} else if(strcmp(key, "Color") == 0) {
 			if(config->color == PM_COLOR_UNSET) {
 				config->color = isatty(fileno(stdout)) ? PM_COLOR_ON : PM_COLOR_OFF;
@@ -734,6 +736,7 @@ static int setup_libalpm(void)
 
 	alpm_option_set_arch(handle, config->arch);
 	alpm_option_set_checkspace(handle, config->checkspace);
+	alpm_option_set_noroot(handle, config->noroot);
 	alpm_option_set_usesyslog(handle, config->usesyslog);
 	alpm_option_set_deltaratio(handle, config->deltaratio);
 
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index e8cac50..a6a87a9 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -45,6 +45,7 @@ typedef struct __config_t {
 	unsigned short logmask;
 	unsigned short print;
 	unsigned short checkspace;
+	unsigned short noroot;
 	unsigned short usesyslog;
 	unsigned short color;
 	double deltaratio;
diff --git a/src/pacman/util.c b/src/pacman/util.c
index d42e27b..d10bc7d 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -102,6 +102,9 @@ int trans_release(void)
 
 int needs_root(void)
 {
+	if(config->noroot == 1) {
+		return 0;
+	}
 	switch(config->op) {
 		case PM_OP_DATABASE:
 			return 1;
-- 
1.9.0



More information about the pacman-dev mailing list