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 <[email protected]>
+
+    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 */
+}
+
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to