summaryrefslogtreecommitdiffstats
path: root/driver/test-uid.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/test-uid.c')
-rw-r--r--driver/test-uid.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/driver/test-uid.c b/driver/test-uid.c
new file mode 100644
index 0000000..6a1f9cc
--- /dev/null
+++ b/driver/test-uid.c
@@ -0,0 +1,209 @@
+/* test-uid.c --- playing with setuid.
+ * xscreensaver, Copyright (c) 1998, 2005 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+
+static void
+print(void)
+{
+ int uid = getuid();
+ int gid = getgid();
+ int euid = geteuid();
+ int egid = getegid();
+ struct passwd *p = 0;
+ struct group *g = 0;
+ gid_t groups[1024];
+ int n, size;
+
+ p = getpwuid (uid);
+ g = getgrgid (gid);
+ fprintf(stderr, "real user/group: %ld/%ld (%s/%s)\n", (long) uid, (long) gid,
+ (p && p->pw_name ? p->pw_name : "???"),
+ (g && g->gr_name ? g->gr_name : "???"));
+
+ p = getpwuid (euid);
+ g = getgrgid (egid);
+ fprintf(stderr, "eff. user/group: %ld/%ld (%s/%s)\n", (long)euid, (long)egid,
+ (p && p->pw_name ? p->pw_name : "???"),
+ (g && g->gr_name ? g->gr_name : "???"));
+
+ size = sizeof(groups) / sizeof(gid_t);
+ n = getgroups(size - 1, groups);
+ if (n < 0)
+ perror("getgroups failed");
+ else
+ {
+ int i;
+ fprintf (stderr, "eff. group list: [");
+ for (i = 0; i < n; i++)
+ {
+ g = getgrgid (groups[i]);
+ fprintf(stderr, "%s%s=%ld", (i == 0 ? "" : ", "),
+ (g->gr_name ? g->gr_name : "???"),
+ (long) groups[i]);
+ }
+ fprintf (stderr, "]\n");
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ struct passwd *p = 0;
+ struct group *g = 0;
+
+ if (argc <= 1)
+ {
+ fprintf(stderr,
+ "usage: %s [ user/group ... ]\n"
+ "\tEach argument may be a user name, or user/group.\n"
+ "\tThis program will attempt to setuid/setgid to each\n"
+ "\tin turn, and report the results. The user and group\n"
+ "\tnames may be strings, or numeric.\n",
+ argv[0]);
+ exit(1);
+ }
+
+ print();
+ for (i = 1; i < argc; i++)
+ {
+ char *user = argv[i];
+ char *group = strchr(user, '/');
+ if (!group)
+ group = strchr(user, '.');
+ if (group)
+ *group++ = 0;
+
+ if (group && *group)
+ {
+ long gid = 0;
+ int was_numeric = 0;
+
+ g = 0;
+ if (*group == '-' || (*group >= '0' && *group <= '9'))
+ if (1 == sscanf(group, "%ld", &gid))
+ {
+ g = getgrgid (gid);
+ was_numeric = 1;
+ }
+
+ if (!g)
+ g = getgrnam(group);
+
+ if (g)
+ {
+ gid = g->gr_gid;
+ group = g->gr_name;
+ }
+ else
+ {
+ if (was_numeric)
+ {
+ fprintf(stderr, "no group numbered %s.\n", group);
+ group = "";
+ }
+ else
+ {
+ fprintf(stderr, "no group named %s.\n", group);
+ goto NOGROUP;
+ }
+ }
+
+ fprintf(stderr, "setgroups(1, [%ld]) \"%s\"", gid, group);
+ {
+ gid_t g2 = gid;
+ if (setgroups(1, &g2) == 0)
+ fprintf(stderr, " succeeded.\n");
+ else
+ perror(" failed");
+ }
+
+ fprintf(stderr, "setgid(%ld) \"%s\"", gid, group);
+ if (setgid(gid) == 0)
+ fprintf(stderr, " succeeded.\n");
+ else
+ perror(" failed");
+
+ NOGROUP: ;
+ }
+
+ if (user && *user)
+ {
+ long uid = 0;
+ int was_numeric = 0;
+
+ p = 0;
+ if (*user == '-' || (*user >= '0' && *user <= '9'))
+ if (1 == sscanf(user, "%ld", &uid))
+ {
+ p = getpwuid (uid);
+ was_numeric = 1;
+ }
+
+ if (!p)
+ p = getpwnam(user);
+
+ if (p)
+ {
+ uid = p->pw_uid;
+ user = p->pw_name;
+ }
+ else
+ {
+ if (was_numeric)
+ {
+ fprintf(stderr, "no user numbered \"%s\".\n", user);
+ user = "";
+ }
+ else
+ {
+ fprintf(stderr, "no user named %s.\n", user);
+ goto NOUSER;
+ }
+ }
+
+ fprintf(stderr, "setuid(%ld) \"%s\"", uid, user);
+ if (setuid(uid) == 0)
+ fprintf(stderr, " succeeded.\n");
+ else
+ perror(" failed");
+ NOUSER: ;
+ }
+ print();
+ }
+
+ fprintf(stderr,
+ "running \"whoami\" and \"groups\" in a sub-process reports:\n");
+ fflush(stdout);
+ fflush(stderr);
+ system ("/bin/sh -c 'echo \"`whoami` / `groups`\"'");
+
+ fflush(stdout);
+ fflush(stderr);
+ exit(0);
+}