SVN: rc-scripts/branches/upstart_native/src: . Makefile.am setuidgid.c
jajcus
jajcus at pld-linux.org
Fri May 7 13:24:41 CEST 2010
Author: jajcus
Date: Fri May 7 13:24:40 2010
New Revision: 11396
Added:
rc-scripts/branches/upstart_native/src/setuidgid.c (contents, props changed)
Modified:
rc-scripts/branches/upstart_native/src/ (props changed)
rc-scripts/branches/upstart_native/src/Makefile.am
Log:
- setuidgid tool added (from freedt) as upstart doesn't provide facilities to
set user id for started jobs, 'su' sucks and using start-stop-daemon for
this purpose would be an overkill.
Modified: rc-scripts/branches/upstart_native/src/Makefile.am
==============================================================================
--- rc-scripts/branches/upstart_native/src/Makefile.am (original)
+++ rc-scripts/branches/upstart_native/src/Makefile.am Fri May 7 13:24:40 2010
@@ -26,6 +26,7 @@
ppp-watch \
start-stop-daemon \
fstab-decode \
+ setuidgid \
usernetctl
EXTRA_PROGRAMS = \
@@ -66,4 +67,6 @@
start_stop_daemon_SOURCES = start-stop-daemon.c
+setuidgid_SOURCES = setuidgid.c
+
fstab_decode_SOURCES = fstab-decode.c
Added: rc-scripts/branches/upstart_native/src/setuidgid.c
==============================================================================
--- (empty file)
+++ rc-scripts/branches/upstart_native/src/setuidgid.c Fri May 7 13:24:40 2010
@@ -0,0 +1,132 @@
+/*
+ Simple wrapper to run a command with different uid/gid.
+
+ Based on the implementation in freedt:
+ Copyright (C) 2003 Adam Sampson <azz at gnu.org>
+
+ 2010-05-07 – Jacek Konieczny <jajcus> updated for standalone compilation
+ and included in PLD rc-scripts
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <string.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <grp.h>
+#include <limits.h>
+
+const char *progname = "setuidgid";
+const char *proghelp =
+ "Usage: setuidgid [OPTIONS] account command ...\n"
+ "Run a command under the uid and gid of an account.\n\n"
+ "-s Also set supplementary groups\n";
+
+void die(const char *msg) {
+ fprintf(stderr, "%s: %s\n", progname, msg);
+ exit(1);
+}
+void die2(const char *msg1, const char *msg2) {
+ fprintf(stderr, "%s: %s: %s\n", progname, msg1, msg2);
+ exit(1);
+}
+void show_version() {
+ fprintf(stderr, "%s $Rev$ (PLD rc-scripts)\n", progname);
+}
+void version() {
+ show_version();
+ exit(0);
+}
+void help(int retval) {
+ show_version();
+ fprintf(stderr, "\n%s"
+ "-V Show version information\n"
+ "-h Show usage information\n", proghelp);
+ exit(retval);
+}
+
+int main(int argc, char **argv) {
+ struct passwd *p;
+ int use_supp = 0;
+
+ while (1) {
+ int c = getopt(argc, argv, "+V?hs");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 's':
+ use_supp = 1;
+ break;
+ case 'V':
+ version();
+ case 'h':
+ case '?':
+ help(0);
+ default:
+ help(1);
+ }
+ }
+
+ if ((argc - optind) < 2)
+ help(1);
+
+ p = getpwnam(argv[optind]);
+ if (!p)
+ die("no such account");
+ if (setgid(p->pw_gid) < 0)
+ die("unable to setgid");
+
+ if (use_supp) {
+ gid_t groups[NGROUPS_MAX];
+ size_t n = 0;
+
+ setgrent();
+ while (1) {
+ char **p;
+ struct group *g = getgrent();
+ if (g == NULL)
+ break;
+
+ for (p = g->gr_mem; *p != NULL; p++) {
+ if (strcmp(*p, argv[optind]) == 0) {
+ if (n >= NGROUPS_MAX)
+ die("too many groups");
+ groups[n++] = g->gr_gid;
+ }
+ }
+ }
+
+ if (setgroups(n, groups) < 0)
+ die("unable to setgroups");
+ } else {
+ if (setgroups(1, &p->pw_gid) < 0)
+ die("unable to setgroups");
+ }
+
+ if (setuid(p->pw_uid) < 0)
+ die("unable to setuid");
+
+ ++optind;
+ execvp(argv[optind], &argv[optind]);
+ die2(argv[optind], "unable to exec");
+
+ return 0; /* NOTREACHED */
+}
+
More information about the pld-cvs-commit
mailing list