/[pdpsoft]/trunk/grid-mw-security/cgul/unixprivs/unixpriv.c
ViewVC logotype

Contents of /trunk/grid-mw-security/cgul/unixprivs/unixpriv.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1988 - (show annotations) (download) (as text)
Fri Oct 1 13:24:56 2010 UTC (11 years, 10 months ago) by aramv
File MIME type: text/x-chdr
File size: 10880 byte(s)
Added some parenthesis around assignments used as boolean values
1 #include "unixpriv.h"
2
3
4 /****************************************************
5 C-GUL
6
7 ****************************************************/
8
9
10 char * cgul_process_identity_oneline(void)
11 {
12 int t = 0;
13 int stored_errno = 0;
14 char * line_buf = NULL;
15 struct passwd * p = NULL;
16 struct group * g = NULL;
17 int ngroups = 0;
18 gid_t * list = NULL;
19
20 uid_t uid = getuid();
21 uid_t euid = geteuid();
22 gid_t gid = getgid();
23 gid_t egid = getegid();
24
25
26 /* Allocate write buffer, must be free'd */
27 if (!(line_buf = calloc (sizeof (char), 1024 + 1)))
28 return NULL;
29
30 /* Real User ID */
31 if((p = getpwuid (uid))){
32 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), "uid=%d(%s)", uid, p -> pw_name);
33 } else {
34 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), "uid=%d", uid);
35 }
36
37 /* Effective User ID */
38 if((p = getpwuid (euid))){
39 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",euid=%d(%s)", euid, p -> pw_name);
40 } else {
41 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",euid=%d", euid);
42 }
43
44 /* Real Group ID */
45 if((g = getgrgid (gid))){
46 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",gid=%d(%s)", gid, g -> gr_name);
47 } else {
48 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",gid=%d", gid);
49 }
50
51 /* Effective Group ID */
52 if((g = getgrgid (egid))){
53 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",egid=%d(%s)", egid, g -> gr_name);
54 } else {
55 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",egid=%d", egid);
56 }
57
58 /* Get the number of secondary group IDs for root */
59 if ((ngroups = getgroups(0, NULL)) < 0)
60 {
61 stored_errno = errno;
62 free (line_buf);
63 errno = stored_errno;
64 return NULL;
65 }
66 list = (gid_t *) malloc(ngroups * sizeof(gid_t));
67
68 /* Get the secondary group IDs for root */
69 if (getgroups(ngroups, list) < 0)
70 {
71 stored_errno = errno;
72 free (line_buf);
73 errno = stored_errno;
74 return NULL;
75 }
76
77 /* Make a oneliner out of all the secondary GIDs */
78 for (t = 0; t < ngroups; t++)
79 {
80 /* Secondary Group ID */
81 if((g = getgrgid (list[t]))){
82 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",sgid=%d(%s)", list[t], g -> gr_name);
83 } else {
84 snprintf (&line_buf[strlen(line_buf)], 1024 - strlen(line_buf), ",sgid=%d", list[t]);
85 }
86 }
87
88 /* Memory liberation */
89 if (list) free(list);
90 list=(gid_t *) NULL;
91
92 return line_buf;
93 }
94
95
96 uid_t threadsafe_getuid_from_name (const char * username)
97 {
98 struct passwd * p = NULL;
99 uid_t uid = -1;
100 int errno_save = 0;
101 #define HAVE_GETPWNAM_R
102 #if defined HAVE_GETPWNAM_R || defined _LIBC
103 char * pwtmpbuf = NULL;
104 struct passwd pwbuf;
105 size_t buflen = 1024;
106 #ifdef _SC_GETPW_R_SIZE_MAX
107 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
108 if ((buflen == -1) && (errno != 0))
109 {
110 buflen = 1024;
111 }
112 #endif
113
114 /* Allocate the buffer for getpwnam_r() */
115 pwtmpbuf = (char *) calloc (1, buflen);
116
117 /* Get Passwd Info for Username */
118 while (getpwnam_r (username, &pwbuf, pwtmpbuf, buflen, &p) != 0)
119 {
120 /* If the errno is anything different then ERANGE, something is wrong or the ID is not available */
121 if (errno != ERANGE)
122 {
123 errno_save = errno;
124 p = NULL;
125 break;
126 }
127
128 /* ERANGE is left over, which means that there is insufficient buffer space. Increasing buffer side and try again */
129 buflen *= 2;
130 free (pwtmpbuf);
131
132 /* Allocate the buffer for getpwnam_r() */
133 if (!(pwtmpbuf = (char *) calloc (1, buflen)))
134 {
135 /* System ran out of memory */
136 if (errno == ENOMEM)
137 {
138 /* No memory available, bail out */
139 p = NULL;
140 errno_save = errno;
141 break;
142 }
143 }
144 }
145 #else
146 p = getpwnam (username);
147 #endif
148
149 /* If there is an entry found, fetch the UID info */
150 if (p)
151 {
152 uid = p -> pw_uid;
153 }
154
155 /* Remove the buffer for the getpwnam_r() */
156 free (pwtmpbuf);
157 errno = errno_save;
158 return uid;
159 }
160
161
162 gid_t threadsafe_getgid_from_name (const char * groupname)
163 {
164 struct group * p = NULL;
165 gid_t gid = -1;
166 int errno_save = 0;
167 #define HAVE_GETPWNAM_R
168 #if defined HAVE_GETPWNAM_R || defined _LIBC
169 char * grtmpbuf = NULL;
170 struct group grbuf;
171 size_t buflen = 1024;
172 #ifdef _SC_GETGR_R_SIZE_MAX
173 buflen = sysconf (_SC_GETGR_R_SIZE_MAX);
174 if ((buflen == -1) && (errno != 0))
175 {
176 buflen = 1024;
177 }
178 #endif
179
180 /* Allocate the buffer for getpwnam_r() */
181 grtmpbuf = (char *) calloc (1, buflen);
182
183 /* Get Passwd Info for Username */
184 while (getgrnam_r (groupname, &grbuf, grtmpbuf, buflen, &p) != 0)
185 {
186 /* If the errno is anything different then ERANGE, something is wrong or the ID is not available */
187 if (errno != ERANGE)
188 {
189 errno_save = errno;
190 p = NULL;
191 break;
192 }
193
194 /* ERANGE is left over, which means that there is insufficient buffer space. Increasing buffer side and try again */
195 buflen *= 2;
196 free (grtmpbuf);
197
198 /* Allocate the buffer for getpwnam_r() */
199 if (!(grtmpbuf = (char *) calloc (1, buflen)))
200 {
201 /* System ran out of memory */
202 if (errno == ENOMEM)
203 {
204 /* No memory available, bail out */
205 p = NULL;
206 errno_save = errno;
207 break;
208 }
209 }
210 }
211 #else
212 /* If the platform doesn't have a getgrnam_r() function */
213 p = getgrnam (username);
214 #endif
215
216 /* If there is an entry found, fetch the GID info */
217 if (p)
218 {
219 gid = p -> gr_gid;
220 }
221
222 /* Remove the buffer for the getgrnam_r() */
223 free (grtmpbuf);
224 errno = errno_save;
225 return gid;
226 }
227
228
229
230
231
232 /* When the proxy is located on an NFS mount and on the server side the root squash
233 * option has been enabled, the effective uid is mapped to user 'nobody' which should
234 * not be able to read the proxy file. To work around this problem, the effective
235 * uid of the process is changed to that of the calling user and once glexec is done,
236 * the saved uid is used to restore the identity of the process,
237 */
238 #if 0
239 Example:
240 uid_t stored_real_uid = -1;
241 uid_t stored_eff_uid = -1;
242
243 /* Downgrade effective privileges to cope with NFS mounted file systems with root squashing */
244 downgradeEffectiveToRealUid (&stored_real_uid, &stored_eff_uid);
245
246 /* Read PEM string */
247 fopen(proxyfile, "r");
248
249 /* Restore privileges to previous state */
250 upgradeEffectiveToRealUid (stored_real_uid, stored_eff_uid);
251 #endif
252 int downgradeEffectiveToRealUid (uid_t * real_uid, uid_t * saved_uid)
253 {
254 *real_uid = getuid();
255 if (*real_uid != 0)
256 {
257 /* Save it */
258 *saved_uid = geteuid();
259 if (seteuid(*real_uid))
260 {
261 fprintf (stderr, "Error on downsizing with seteuid()\n");
262 return 1;
263 }
264 }
265 return 0;
266 }
267
268 int upgradeEffectiveToRealUid (uid_t real_uid, uid_t saved_uid)
269 {
270 /* Do not forget to put back the original effective uid on the process. */
271 if (real_uid != 0)
272 {
273 if (seteuid(saved_uid))
274 {
275 fprintf (stderr, "Error on returning seteuid()\n");
276 return 1;
277 }
278 }
279 return 0;
280 }
281
282
283
284 /******************************************************************************
285 Function: get_gidlist()
286
287 Description:
288 Finds the list of gids for user in the group file (/etc/group)
289 Returns a list of gid_t which should be freed by calling program.
290
291 Parameters:
292 username: the name of the user
293 ngroups: ptr to int which will be filled with the number of gids.
294 group_list: ptr to an array of gid_t.
295
296 Returns:
297 0 on success.
298 -1 on realloc failure
299 -2 on getgrent failure
300 1 on failure
301 ******************************************************************************/
302 int get_gidlist(
303 const char * username,
304 int * ngroups,
305 gid_t ** group_list
306 )
307 {
308 struct group * group_info = NULL;
309 gid_t * groups = NULL;
310 gid_t * newgroups = NULL;
311 int i = 0;
312
313 /* rewind the file pointer to the beginning of the /etc/group file */
314 setgrent();
315
316 lcmaps_log_debug(2, "\tlcmaps_get_gidlist(): looping through group file\n");
317 *ngroups = 0;
318 while ( ( group_info = getgrent() ) )
319 {
320 char ** pgr_mem = group_info->gr_mem;
321 char * gr_mem = NULL;
322
323 lcmaps_log_debug(4, "\tlcmaps_get_gidlist(): group %s\n", group_info->gr_name);
324 while ( (gr_mem = *pgr_mem) )
325 {
326 lcmaps_log_debug(4, "\tlcmaps_get_gidlist(): \tgroup member %s\n", gr_mem);
327 if (strncmp(username, gr_mem, strlen(username))==0)
328 {
329 lcmaps_log_debug(2, "\tlcmaps_get_gidlist(): \t\tfound group %s for %s\n",
330 group_info->gr_name, username);
331 (*ngroups)++;
332 newgroups = (gid_t *) realloc(groups, ((*ngroups) * sizeof(gid_t)));
333 if (newgroups == NULL)
334 {
335 lcmaps_log(1, "lcmaps_get_gidlist(): cannot realloc\n");
336 free(groups);
337 return -1;
338 }
339 groups=newgroups;
340 groups[(*ngroups)-1] = group_info->gr_gid;
341 }
342 ++pgr_mem;
343 }
344 }
345 if (errno==ENOMEM)
346 {
347 lcmaps_log(1, "lcmaps_get_gidlist(): Cannot read the group file, %s\n", strerror(errno));
348 free(groups);
349 groups=NULL;
350 /* Close the group file */
351 endgrent();
352 return -2;
353 }
354 *group_list=groups;
355 lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): %d groups found for %s\n", *ngroups, username);
356 for (i = 0; i < *ngroups; i++)
357 {
358 lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): group nr %d ==> gid_t %d\n", i+1, groups[i]);
359 }
360 /* Close the group file */
361 endgrent();
362 return 0;
363 }
364
365

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28