#include <string.h>
#include <sys/param.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <grp.h>
#include <limits.h>
#include "iolib.h"
#include "freedt.h"
#include "config.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";

int main(int argc, char **argv) {
	struct passwd *p;
	int use_supp = 0;

	while (1) {
		int c = getopt(argc, argv, "+V?s");
		if (c == -1)
			break;

		switch (c) {
		case 's':
			use_supp = 1;
			break;
		case 'V':
			version();
		default:
			help();
		}
	}

	if ((argc - optind) < 2)
		help();

	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 */
}



syntax highlighted by Code2HTML, v. 0.9.1