http://ftp.aanet.ru/pub/Linux/X11/apps/xscreensaver-2.31.tar.gz
[xscreensaver] / driver / test-uid.c
1 /* uid-test.c --- playing with setuid.
2  * xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@jwz.org>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include <ctype.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <pwd.h>
23 #include <grp.h>
24
25 static void
26 print(void)
27 {
28   int uid = getuid();
29   int gid = getgid();
30   int euid = geteuid();
31   int egid = getegid();
32   struct passwd *p = 0;
33   struct group *g = 0;
34
35   p = getpwuid (uid);
36   g = getgrgid (gid);
37   fprintf(stderr, "real user/group: %ld/%ld (%s/%s)\n", uid, gid,
38           (p && p->pw_name ? p->pw_name : "???"),
39           (g && g->gr_name ? g->gr_name : "???"));
40
41   p = getpwuid (euid);
42   g = getgrgid (egid);
43   fprintf(stderr, "eff. user/group: %ld/%ld (%s/%s)\n", euid, egid,
44           (p && p->pw_name ? p->pw_name : "???"),
45           (g && g->gr_name ? g->gr_name : "???"));
46 }
47
48 int
49 main (int argc, char **argv)
50 {
51   int i;
52   struct passwd *p = 0;
53   struct group *g = 0;
54
55   if (argc <= 1)
56     {
57       fprintf(stderr,
58               "usage: %s [ user/group ... ]\n"
59               "\tEach argument may be a user name, or user/group.\n"
60               "\tThis program will attempt to setuid/setgid to each\n"
61               "\tin turn, and report the results.  The user and group\n"
62               "\tnames may be strings, or numeric.\n",
63               argv[0]);
64       exit(1);
65     }
66
67   print();
68   for (i = 1; i < argc; i++)
69     {
70       char *user = argv[i];
71       char *group = strchr(user, '/');
72       if (group)
73         *group++ = 0;
74
75       if (group && *group)
76         {
77           long gid = 0;
78           int was_numeric = 0;
79
80           g = 0;
81           if (*group == '-' || (*group >= '0' && *group <= '9'))
82             if (1 == sscanf(group, "%ld", &gid))
83               {
84                 g = getgrgid (gid);
85                 was_numeric = 1;
86               }
87
88           if (!g)
89             g = getgrnam(group);
90
91           if (g)
92             {
93               gid = g->gr_gid;
94               group = g->gr_name;
95             }
96           else
97             {
98               if (was_numeric)
99                 {
100                   fprintf(stderr, "no group numbered %s.\n", group);
101                   group = "";
102                 }
103               else
104                 {
105                   fprintf(stderr, "no group named %s.\n", group);
106                   goto NOGROUP;
107                 }
108             }
109
110           fprintf(stderr, "setgid(%ld) \"%s\"", gid, group);
111           if (setgid(gid) == 0)
112             fprintf(stderr, " succeeded.\n");
113           else
114             perror(" failed");
115
116         NOGROUP: ;
117         }
118
119       if (user && *user)
120         {
121           long uid = 0;
122           int was_numeric = 0;
123
124           p = 0;
125           if (*user == '-' || (*user >= '0' && *user <= '9'))
126             if (1 == sscanf(user, "%ld", &uid))
127               {
128                 p = getpwuid (uid);
129                 was_numeric = 1;
130               }
131
132           if (!p)
133             p = getpwnam(user);
134
135           if (p)
136             {
137               uid = p->pw_uid;
138               user = p->pw_name;
139             }
140           else
141             {
142               if (was_numeric)
143                 {
144                   fprintf(stderr, "no user numbered \"%s\".\n", user);
145                   user = "";
146                 }
147               else
148                 {
149                   fprintf(stderr, "no user named %s.\n", user);
150                   goto NOUSER;
151                 }
152             }
153
154           fprintf(stderr, "setuid(%ld) \"%s\"", uid, user);
155           if (setuid(uid) == 0)
156             fprintf(stderr, " succeeded.\n");
157           else
158             perror(" failed");
159         NOUSER: ;
160         }
161       print();
162     }
163
164   fprintf(stderr,
165           "running \"whoami\" and \"groups\" in a sub-process reports:\n");
166   fflush(stdout);
167   fflush(stderr);
168   system ("/bin/sh -c 'echo \"`whoami` / `groups`\"'");
169
170   fflush(stdout);
171   fflush(stderr);
172   exit(0);
173 }