]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * tclXid.c -- | |
3 | * | |
4 | * Tcl commands to access getuid, setuid, getgid, setgid and friends. | |
5 | *--------------------------------------------------------------------------- | |
6 | * Copyright 1992 Karl Lehenbauer and Mark Diekhans. | |
7 | * | |
8 | * Permission to use, copy, modify, and distribute this software and its | |
9 | * documentation for any purpose and without fee is hereby granted, provided | |
10 | * that the above copyright notice appear in all copies. Karl Lehenbauer and | |
11 | * Mark Diekhans make no representations about the suitability of this | |
12 | * software for any purpose. It is provided "as is" without express or | |
13 | * implied warranty. | |
14 | *----------------------------------------------------------------------------- | |
15 | * $Id: tclXid.c,v 2.0 1992/10/16 04:50:51 markd Rel $ | |
16 | *----------------------------------------------------------------------------- | |
17 | */ | |
18 | ||
19 | #include "tclxint.h" | |
20 | ||
21 | /* | |
22 | * Prototypes of internal functions. | |
23 | */ | |
24 | static int | |
25 | UseridToUsernameResult _ANSI_ARGS_((Tcl_Interp *interp, | |
26 | int userId)); | |
27 | ||
28 | static int | |
29 | UsernameToUseridResult _ANSI_ARGS_((Tcl_Interp *interp, | |
30 | char *userName)); | |
31 | ||
32 | static int | |
33 | GroupidToGroupnameResult _ANSI_ARGS_((Tcl_Interp *interp, | |
34 | int groupId)); | |
35 | ||
36 | static int | |
37 | GroupnameToGroupidResult _ANSI_ARGS_((Tcl_Interp *interp, | |
38 | char *groupName)); | |
39 | ||
40 | \f | |
41 | /* | |
42 | *----------------------------------------------------------------------------- | |
43 | * | |
44 | * Tcl_IdCmd -- | |
45 | * Implements the TCL id command: | |
46 | * | |
47 | * id user [name] | |
48 | * id convert user <name> | |
49 | * | |
50 | * id userid [uid] | |
51 | * id convert userid <uid> | |
52 | * | |
53 | * id group [name] | |
54 | * id convert group <name> | |
55 | * | |
56 | * id groupid [gid] | |
57 | * id convert groupid <gid> | |
58 | * | |
59 | * id process | |
60 | * id process parent | |
61 | * id process group | |
62 | * id process group set | |
63 | * | |
64 | * id effective user | |
65 | * id effective userid | |
66 | * | |
67 | * id effective group | |
68 | * id effective groupid | |
69 | * | |
70 | * Results: | |
71 | * Standard TCL results, may return the UNIX system error message. | |
72 | * | |
73 | *----------------------------------------------------------------------------- | |
74 | */ | |
75 | ||
76 | static int | |
77 | UseridToUsernameResult (interp, userId) | |
78 | Tcl_Interp *interp; | |
79 | int userId; | |
80 | { | |
81 | struct passwd *pw = getpwuid (userId); | |
82 | if (pw == NULL) { | |
83 | char numBuf [32]; | |
84 | ||
85 | sprintf (numBuf, "%d", userId); | |
86 | Tcl_AppendResult (interp, "unknown user id: ", numBuf, (char *) NULL); | |
87 | return TCL_ERROR; | |
88 | } | |
89 | strcpy (interp->result, pw->pw_name); | |
90 | return TCL_OK; | |
91 | } | |
92 | ||
93 | static int | |
94 | UsernameToUseridResult (interp, userName) | |
95 | Tcl_Interp *interp; | |
96 | char *userName; | |
97 | { | |
98 | struct passwd *pw = getpwnam (userName); | |
99 | if (pw == NULL) { | |
100 | Tcl_AppendResult (interp, "unknown user id: ", userName, | |
101 | (char *) NULL); | |
102 | return TCL_ERROR; | |
103 | } | |
104 | sprintf (interp->result, "%d", pw->pw_uid); | |
105 | return TCL_OK; | |
106 | } | |
107 | ||
108 | static int | |
109 | GroupidToGroupnameResult (interp, groupId) | |
110 | Tcl_Interp *interp; | |
111 | int groupId; | |
112 | { | |
113 | struct group *grp = getgrgid (groupId); | |
114 | if (grp == NULL) { | |
115 | char numBuf [32]; | |
116 | ||
117 | sprintf (numBuf, "%d", groupId); | |
118 | Tcl_AppendResult (interp, "unknown group id: ", numBuf, (char *) NULL); | |
119 | return TCL_ERROR; | |
120 | } | |
121 | strcpy (interp->result, grp->gr_name); | |
122 | return TCL_OK; | |
123 | } | |
124 | ||
125 | static int | |
126 | GroupnameToGroupidResult (interp, groupName) | |
127 | Tcl_Interp *interp; | |
128 | char *groupName; | |
129 | { | |
130 | struct group *grp = getgrnam (groupName); | |
131 | if (grp == NULL) { | |
132 | Tcl_AppendResult (interp, "unknown group id: ", groupName, | |
133 | (char *) NULL); | |
134 | return TCL_ERROR; | |
135 | } | |
136 | sprintf (interp->result, "%d", grp->gr_gid); | |
137 | return TCL_OK; | |
138 | } | |
139 | ||
140 | int | |
141 | Tcl_IdCmd (clientData, interp, argc, argv) | |
142 | ClientData clientData; | |
143 | Tcl_Interp *interp; | |
144 | int argc; | |
145 | char **argv; | |
146 | { | |
147 | struct passwd *pw; | |
148 | struct group *grp; | |
149 | int uid, gid; | |
150 | ||
151 | if (argc < 2) | |
152 | goto bad_args; | |
153 | ||
154 | /* | |
155 | * If the first argument is "convert", handle the conversion. | |
156 | */ | |
157 | if (STREQU (argv[1], "convert")) { | |
158 | if (argc != 4) { | |
159 | Tcl_AppendResult (interp, tclXWrongArgs, argv [0], | |
160 | " convert arg arg", (char *) NULL); | |
161 | return TCL_ERROR; | |
162 | } | |
163 | ||
164 | if (STREQU (argv[2], "user")) | |
165 | return UsernameToUseridResult (interp, argv[3]); | |
166 | ||
167 | if (STREQU (argv[2], "userid")) { | |
168 | if (Tcl_GetInt (interp, argv[3], &uid) != TCL_OK) | |
169 | return TCL_ERROR; | |
170 | return UseridToUsernameResult (interp, uid); | |
171 | } | |
172 | ||
173 | if (STREQU (argv[2], "group")) | |
174 | return GroupnameToGroupidResult (interp, argv[3]); | |
175 | ||
176 | if (STREQU (argv[2], "groupid")) { | |
177 | if (Tcl_GetInt (interp, argv[3], &gid) != TCL_OK) return TCL_ERROR; | |
178 | return GroupidToGroupnameResult (interp, gid); | |
179 | ||
180 | } | |
181 | goto bad_three_arg; | |
182 | } | |
183 | ||
184 | /* | |
185 | * If the first argument is "effective", return the effective user ID, | |
186 | * name, group ID or name. | |
187 | */ | |
188 | if (STREQU (argv[1], "effective")) { | |
189 | if (argc != 3) { | |
190 | Tcl_AppendResult (interp, tclXWrongArgs, argv [0], | |
191 | " effective arg", (char *) NULL); | |
192 | return TCL_ERROR; | |
193 | } | |
194 | ||
195 | if (STREQU (argv[2], "user")) | |
196 | return UseridToUsernameResult (interp, geteuid ()); | |
197 | ||
198 | if (STREQU (argv[2], "userid")) { | |
199 | sprintf (interp->result, "%d", geteuid ()); | |
200 | return TCL_OK; | |
201 | } | |
202 | ||
203 | if (STREQU (argv[2], "group")) | |
204 | return GroupidToGroupnameResult (interp, getegid ()); | |
205 | ||
206 | if (STREQU (argv[2], "groupid")) { | |
207 | sprintf (interp->result, "%d", getegid ()); | |
208 | return TCL_OK; | |
209 | } | |
210 | goto bad_three_arg; | |
211 | } | |
212 | ||
213 | /* | |
214 | * If the first argument is "process", return the process ID, parent's | |
215 | * process ID, process group or set the process group depending on args. | |
216 | */ | |
217 | if (STREQU (argv[1], "process")) { | |
218 | if (argc == 2) { | |
219 | sprintf (interp->result, "%d", getpid ()); | |
220 | return TCL_OK; | |
221 | } | |
222 | ||
223 | if (STREQU (argv[2], "parent")) { | |
224 | if (argc != 3) { | |
225 | Tcl_AppendResult (interp, tclXWrongArgs, argv [0], | |
226 | " process parent", (char *) NULL); | |
227 | return TCL_ERROR; | |
228 | } | |
229 | sprintf (interp->result, "%d", getppid ()); | |
230 | return TCL_OK; | |
231 | } | |
232 | if (STREQU (argv[2], "group")) { | |
233 | if (argc == 3) { | |
234 | sprintf (interp->result, "%d", getpgrp ()); | |
235 | return TCL_OK; | |
236 | } | |
237 | if ((argc != 4) || !STREQU (argv[3], "set")) { | |
238 | Tcl_AppendResult (interp, tclXWrongArgs, argv [0], | |
239 | " process group [set]", (char *) NULL); | |
240 | return TCL_ERROR; | |
241 | } | |
242 | setpgid(getpid(), getpid()); | |
243 | return TCL_OK; | |
244 | } | |
245 | Tcl_AppendResult (interp, tclXWrongArgs, argv [0], | |
246 | " process [parent|group|group set]", (char *) NULL); | |
247 | return TCL_ERROR; | |
248 | } | |
249 | ||
250 | /* | |
251 | * Handle setting or returning the user ID or group ID (by name or number). | |
252 | */ | |
253 | if (argc > 3) | |
254 | goto bad_args; | |
255 | ||
256 | if (STREQU (argv[1], "user")) { | |
257 | if (argc == 2) { | |
258 | return UseridToUsernameResult (interp, getuid ()); | |
259 | } else { | |
260 | pw = getpwnam (argv[2]); | |
261 | if (pw == NULL) | |
262 | goto name_doesnt_exist; | |
263 | if (setuid (pw->pw_uid) < 0) | |
264 | goto cannot_set_name; | |
265 | return TCL_OK; | |
266 | } | |
267 | } | |
268 | ||
269 | if (STREQU (argv[1], "userid")) { | |
270 | if (argc == 2) { | |
271 | sprintf (interp->result, "%d", getuid ()); | |
272 | return TCL_OK; | |
273 | } else { | |
274 | if (Tcl_GetInt (interp, argv[2], &uid) != TCL_OK) | |
275 | return TCL_ERROR; | |
276 | if (setuid (uid) < 0) | |
277 | goto cannot_set_name; | |
278 | return TCL_OK; | |
279 | } | |
280 | } | |
281 | ||
282 | if (STREQU (argv[1], "group")) { | |
283 | if (argc == 2) { | |
284 | return GroupidToGroupnameResult (interp, getgid ()); | |
285 | } else { | |
286 | grp = getgrnam (argv[2]); | |
287 | if (grp == NULL) | |
288 | goto name_doesnt_exist; | |
289 | if (setgid (grp->gr_gid) < 0) | |
290 | goto cannot_set_name; | |
291 | return TCL_OK; | |
292 | } | |
293 | } | |
294 | ||
295 | if (STREQU (argv[1], "groupid")) { | |
296 | if (argc == 2) { | |
297 | sprintf (interp->result, "%d", getgid ()); | |
298 | return TCL_OK; | |
299 | } else { | |
300 | if (Tcl_GetInt (interp, argv[2], &gid) != TCL_OK) | |
301 | return TCL_ERROR; | |
302 | if (setgid (gid) < 0) | |
303 | goto cannot_set_name; | |
304 | return TCL_OK; | |
305 | } | |
306 | } | |
307 | Tcl_AppendResult (interp, "bad arg: ", argv [0], | |
308 | " second arg must be convert, effective, process, ", | |
309 | "user, userid, group or groupid", (char *) NULL); | |
310 | return TCL_ERROR; | |
311 | ||
312 | ||
313 | bad_three_arg: | |
314 | Tcl_AppendResult (interp, "bad arg: ", argv [0], ": ", argv[1], | |
315 | ": third arg must be user, userid, group or groupid", | |
316 | (char *) NULL); | |
317 | return TCL_ERROR; | |
318 | bad_args: | |
319 | Tcl_AppendResult (interp, tclXWrongArgs, argv [0], " arg [arg..]", | |
320 | (char *) NULL); | |
321 | return TCL_ERROR; | |
322 | ||
323 | name_doesnt_exist: | |
324 | Tcl_AppendResult (interp, " \"", argv[2], "\" does not exists", | |
325 | (char *) NULL); | |
326 | return TCL_ERROR; | |
327 | ||
328 | cannot_set_name: | |
329 | interp->result = Tcl_UnixError (interp); | |
330 | return TCL_ERROR; | |
331 | } |