ftp://ftp.smr.ru/pub/0/FreeBSD/releases/distfiles/xscreensaver-3.16.tar.gz
[xscreensaver] / driver / test-uid.c
1 /* test-uid.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 <stdlib.h>
18 #ifdef HAVE_UNISTD_H
19 # include <unistd.h>
20 #endif
21
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <pwd.h>
28 #include <grp.h>
29
30 static void
31 print(void)
32 {
33   int uid = getuid();
34   int gid = getgid();
35   int euid = geteuid();
36   int egid = getegid();
37   struct passwd *p = 0;
38   struct group *g = 0;
39
40   p = getpwuid (uid);
41   g = getgrgid (gid);
42   fprintf(stderr, "real user/group: %ld/%ld (%s/%s)\n", (long) uid, (long) gid,
43           (p && p->pw_name ? p->pw_name : "???"),
44           (g && g->gr_name ? g->gr_name : "???"));
45
46   p = getpwuid (euid);
47   g = getgrgid (egid);
48   fprintf(stderr, "eff. user/group: %ld/%ld (%s/%s)\n", (long)euid, (long)egid,
49           (p && p->pw_name ? p->pw_name : "???"),
50           (g && g->gr_name ? g->gr_name : "???"));
51 }
52
53 int
54 main (int argc, char **argv)
55 {
56   int i;
57   struct passwd *p = 0;
58   struct group *g = 0;
59
60   if (argc <= 1)
61     {
62       fprintf(stderr,
63               "usage: %s [ user/group ... ]\n"
64               "\tEach argument may be a user name, or user/group.\n"
65               "\tThis program will attempt to setuid/setgid to each\n"
66               "\tin turn, and report the results.  The user and group\n"
67               "\tnames may be strings, or numeric.\n",
68               argv[0]);
69       exit(1);
70     }
71
72   print();
73   for (i = 1; i < argc; i++)
74     {
75       char *user = argv[i];
76       char *group = strchr(user, '/');
77       if (!group)
78         group = strchr(user, '.');
79       if (group)
80         *group++ = 0;
81
82       if (group && *group)
83         {
84           long gid = 0;
85           int was_numeric = 0;
86
87           g = 0;
88           if (*group == '-' || (*group >= '0' && *group <= '9'))
89             if (1 == sscanf(group, "%ld", &gid))
90               {
91                 g = getgrgid (gid);
92                 was_numeric = 1;
93               }
94
95           if (!g)
96             g = getgrnam(group);
97
98           if (g)
99             {
100               gid = g->gr_gid;
101               group = g->gr_name;
102             }
103           else
104             {
105               if (was_numeric)
106                 {
107                   fprintf(stderr, "no group numbered %s.\n", group);
108                   group = "";
109                 }
110               else
111                 {
112                   fprintf(stderr, "no group named %s.\n", group);
113                   goto NOGROUP;
114                 }
115             }
116
117           fprintf(stderr, "setgid(%ld) \"%s\"", gid, group);
118           if (setgid(gid) == 0)
119             fprintf(stderr, " succeeded.\n");
120           else
121             perror(" failed");
122
123         NOGROUP: ;
124         }
125
126       if (user && *user)
127         {
128           long uid = 0;
129           int was_numeric = 0;
130
131           p = 0;
132           if (*user == '-' || (*user >= '0' && *user <= '9'))
133             if (1 == sscanf(user, "%ld", &uid))
134               {
135                 p = getpwuid (uid);
136                 was_numeric = 1;
137               }
138
139           if (!p)
140             p = getpwnam(user);
141
142           if (p)
143             {
144               uid = p->pw_uid;
145               user = p->pw_name;
146             }
147           else
148             {
149               if (was_numeric)
150                 {
151                   fprintf(stderr, "no user numbered \"%s\".\n", user);
152                   user = "";
153                 }
154               else
155                 {
156                   fprintf(stderr, "no user named %s.\n", user);
157                   goto NOUSER;
158                 }
159             }
160
161           fprintf(stderr, "setuid(%ld) \"%s\"", uid, user);
162           if (setuid(uid) == 0)
163             fprintf(stderr, " succeeded.\n");
164           else
165             perror(" failed");
166         NOUSER: ;
167         }
168       print();
169     }
170
171   fprintf(stderr,
172           "running \"whoami\" and \"groups\" in a sub-process reports:\n");
173   fflush(stdout);
174   fflush(stderr);
175   system ("/bin/sh -c 'echo \"`whoami` / `groups`\"'");
176
177   fflush(stdout);
178   fflush(stderr);
179   exit(0);
180 }