OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / sys / unix / unixres.c
1 /* NetHack 3.6  unixres.c       $NHDT-Date: 1432512788 2015/05/25 00:13:08 $  $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */
2 /* Copyright (c) Slash'EM development team, 2001. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* [ALI] This module defines nh_xxx functions to replace getuid etc which
6  * will hide privileges from the caller if so desired.
7  *
8  * Currently supported UNIX variants:
9  *      Linux version 2.1.44 and above
10  *      FreeBSD (versions unknown)
11  *
12  * Note: SunOS and Solaris have no mechanism for retrieving the saved id,
13  * so temporarily dropping privileges on these systems is sufficient to
14  * hide them.
15  */
16
17 #include "config.h"
18
19 #ifdef GETRES_SUPPORT
20
21 #if defined(LINUX)
22
23 /* requires dynamic linking with libc */
24 #include <dlfcn.h>
25
26 static int
27 real_getresuid(ruid, euid, suid)
28 uid_t *ruid, *euid, *suid;
29 {
30     int (*f)(uid_t *, uid_t *, uid_t *); /* getresuid signature */
31
32     f = dlsym(RTLD_NEXT, "getresuid");
33     if (!f)
34         return -1;
35
36     return (*f)(ruid, euid, suid);
37 }
38
39 static int
40 real_getresgid(rgid, egid, sgid)
41 gid_t *rgid, *egid, *sgid;
42 {
43     int (*f)(gid_t *, gid_t *, gid_t *); /* getresgid signature */
44
45     f = dlsym(RTLD_NEXT, "getresgid");
46     if (!f)
47         return -1;
48
49     return (*f)(rgid, egid, sgid);
50 }
51
52 #else
53 #if defined(BSD) || defined(SVR4)
54
55 #ifdef SYS_getresuid
56
57 static int
58 real_getresuid(ruid, euid, suid)
59 uid_t *ruid, *euid, *suid;
60 {
61     return syscall(SYS_getresuid, ruid, euid, suid);
62 }
63
64 #else /* SYS_getresuid */
65
66 #ifdef SVR4
67 #include <sys/stat.h>
68 #endif /* SVR4 */
69
70 static int
71 real_getresuid(ruid, euid, suid)
72 uid_t *ruid, *euid, *suid;
73 {
74     int retval;
75     int pfd[2];
76     struct stat st;
77
78     if (pipe(pfd))
79         return -1;
80     retval = fstat(pfd[0], &st);
81     close(pfd[0]);
82     close(pfd[1]);
83     if (!retval) {
84         *euid = st.st_uid;
85         *ruid = syscall(SYS_getuid);
86         *suid = *ruid; /* Not supported under SVR4 */
87     }
88     return retval;
89 }
90
91 #endif /* SYS_getresuid */
92
93 #ifdef SYS_getresgid
94
95 static int
96 real_getresgid(rgid, egid, sgid)
97 gid_t *rgid, *egid, *sgid;
98 {
99     return syscall(SYS_getresgid, rgid, egid, sgid);
100 }
101
102 #else /* SYS_getresgid */
103
104 static int
105 real_getresgid(rgid, egid, sgid)
106 gid_t *rgid, *egid, *sgid;
107 {
108     int retval;
109     int pfd[2];
110     struct stat st;
111
112     if (pipe(pfd))
113         return -1;
114     retval = fstat(pfd[0], &st);
115     close(pfd[0]);
116     close(pfd[1]);
117     if (!retval) {
118         *egid = st.st_gid;
119         *rgid = syscall(SYS_getgid);
120         *sgid = *rgid; /* Not supported under SVR4 */
121     }
122     return retval;
123 }
124
125 #endif /* SYS_getresgid */
126 #endif /* BSD || SVR4 */
127 #endif /* LINUX */
128
129 static unsigned int hiding_privileges = 0;
130
131 /*
132  * Note: returns the value _after_ action.
133  */
134
135 int
136 hide_privileges(flag)
137 boolean flag;
138 {
139     if (flag)
140         hiding_privileges++;
141     else if (hiding_privileges)
142         hiding_privileges--;
143     return hiding_privileges;
144 }
145
146 int
147 nh_getresuid(ruid, euid, suid)
148 uid_t *ruid, *euid, *suid;
149 {
150     int retval = real_getresuid(ruid, euid, suid);
151
152     if (!retval && hiding_privileges)
153         *euid = *suid = *ruid;
154     return retval;
155 }
156
157 uid_t
158 nh_getuid()
159 {
160     uid_t ruid, euid, suid;
161
162     (void) real_getresuid(&ruid, &euid, &suid);
163     return ruid;
164 }
165
166 uid_t
167 nh_geteuid()
168 {
169     uid_t ruid, euid, suid;
170
171     (void) real_getresuid(&ruid, &euid, &suid);
172     if (hiding_privileges)
173         euid = ruid;
174     return euid;
175 }
176
177 int
178 nh_getresgid(rgid, egid, sgid)
179 gid_t *rgid, *egid, *sgid;
180 {
181     int retval = real_getresgid(rgid, egid, sgid);
182
183     if (!retval && hiding_privileges)
184         *egid = *sgid = *rgid;
185     return retval;
186 }
187
188 gid_t
189 nh_getgid()
190 {
191     gid_t rgid, egid, sgid;
192
193     (void) real_getresgid(&rgid, &egid, &sgid);
194     return rgid;
195 }
196
197 gid_t
198 nh_getegid()
199 {
200     gid_t rgid, egid, sgid;
201
202     (void) real_getresgid(&rgid, &egid, &sgid);
203     if (hiding_privileges)
204         egid = rgid;
205     return egid;
206 }
207
208 #else /* GETRES_SUPPORT */
209
210 #ifdef GNOME_GRAPHICS
211 int
212 hide_privileges(flag)
213 boolean flag;
214 {
215     return 0;
216 }
217 #endif
218
219 #endif /* GETRES_SUPPORT */