1 |
okoeroo |
1403 |
/**************************************************** |
2 |
|
|
C-GUL |
3 |
|
|
|
4 |
|
|
Generate random characters |
5 |
|
|
|
6 |
|
|
****************************************************/ |
7 |
|
|
|
8 |
|
|
|
9 |
okoeroo |
1404 |
uid_t threadsafe_getuid_from_name (const char * username) |
10 |
|
|
{ |
11 |
|
|
struct passwd * p = NULL; |
12 |
|
|
uid_t uid = -1; |
13 |
|
|
int errno_save = 0; |
14 |
|
|
#define HAVE_GETPWNAM_R |
15 |
|
|
#ifdef HAVE_GETPWNAM_R || defined _LIBC |
16 |
|
|
#ifdef _SC_GETPW_R_SIZE_MAX |
17 |
|
|
size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); |
18 |
|
|
#else |
19 |
|
|
size_t buflen = 128; |
20 |
|
|
#endif |
21 |
|
|
char *pwtmpbuf; |
22 |
|
|
struct passwd pwbuf; |
23 |
okoeroo |
1403 |
|
24 |
|
|
|
25 |
okoeroo |
1404 |
if (buflen == -1) |
26 |
|
|
/* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a |
27 |
|
|
moderate value. */ |
28 |
|
|
buflen = 128; |
29 |
okoeroo |
1403 |
|
30 |
okoeroo |
1404 |
pwtmpbuf = (char *) calloc (1, buflen); |
31 |
|
|
|
32 |
|
|
while (getpwnam_r (username, &pwbuf, pwtmpbuf, buflen, &p) != 0) |
33 |
|
|
{ |
34 |
|
|
if (errno != ERANGE) |
35 |
|
|
{ |
36 |
|
|
p = NULL; |
37 |
|
|
break; |
38 |
|
|
} |
39 |
|
|
buflen *= 2; |
40 |
|
|
free (pwtmpbuf); |
41 |
|
|
|
42 |
|
|
if (!(pwtmpbuf = (char *) calloc (1, buflen))) |
43 |
|
|
{ |
44 |
|
|
if (errno == ENOMEM) |
45 |
|
|
{ |
46 |
|
|
/* No memory available, bail out */ |
47 |
|
|
p = NULL; |
48 |
|
|
errno_save = errno; |
49 |
|
|
break; |
50 |
|
|
} |
51 |
|
|
} |
52 |
|
|
} |
53 |
|
|
#else |
54 |
|
|
p = getpwnam (username); |
55 |
|
|
#endif |
56 |
|
|
|
57 |
|
|
if (p) |
58 |
|
|
{ |
59 |
|
|
uid = p -> pw_uid; |
60 |
|
|
} |
61 |
|
|
|
62 |
|
|
free (pwtmpbuf); |
63 |
|
|
errno = errno_save; |
64 |
|
|
return uid; |
65 |
|
|
} |
66 |
|
|
|
67 |
|
|
|
68 |
|
|
|
69 |
okoeroo |
1403 |
/* When the proxy is located on an NFS mount and on the server side the root squash |
70 |
|
|
* option has been enabled, the effective uid is mapped to user 'nobody' which should |
71 |
|
|
* not be able to read the proxy file. To work around this problem, the effective |
72 |
|
|
* uid of the process is changed to that of the calling user and once glexec is done, |
73 |
|
|
* the saved uid is used to restore the identity of the process, |
74 |
|
|
*/ |
75 |
|
|
#if 0 |
76 |
|
|
Example: |
77 |
|
|
uid_t stored_real_uid = -1; |
78 |
|
|
uid_t stored_eff_uid = -1; |
79 |
|
|
|
80 |
|
|
/* Downgrade effective privileges to cope with NFS mounted file systems with root squashing */ |
81 |
|
|
downgradeEffectiveToRealUid (&stored_real_uid, &stored_eff_uid); |
82 |
|
|
|
83 |
|
|
/* Read PEM string */ |
84 |
|
|
fopen(proxyfile, "r"); |
85 |
|
|
|
86 |
|
|
/* Restore privileges to previous state */ |
87 |
|
|
upgradeEffectiveToRealUid (stored_real_uid, stored_eff_uid); |
88 |
|
|
#endif |
89 |
|
|
int downgradeEffectiveToRealUid (uid_t * real_uid, uid_t * saved_uid) |
90 |
|
|
{ |
91 |
|
|
*real_uid = getuid(); |
92 |
|
|
if (*real_uid != 0) |
93 |
|
|
{ |
94 |
|
|
/* Save it */ |
95 |
|
|
*saved_uid = geteuid(); |
96 |
|
|
if (seteuid(*real_uid)) |
97 |
|
|
{ |
98 |
|
|
fprintf (stderr, "Error on downsizing with seteuid()\n"); |
99 |
|
|
return 1; |
100 |
|
|
} |
101 |
|
|
} |
102 |
|
|
return 0; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
int upgradeEffectiveToRealUid (uid_t real_uid, uid_t saved_uid) |
106 |
|
|
{ |
107 |
|
|
/* Do not forget to put back the original effective uid on the process. */ |
108 |
|
|
if (real_uid != 0) |
109 |
|
|
{ |
110 |
|
|
if (seteuid(saved_uid)) |
111 |
|
|
{ |
112 |
|
|
fprintf (stderr, "Error on returning seteuid()\n"); |
113 |
|
|
return 1; |
114 |
|
|
} |
115 |
|
|
} |
116 |
|
|
return 0; |
117 |
|
|
} |
118 |
|
|
|
119 |
|
|
|
120 |
|
|
|
121 |
|
|
/****************************************************************************** |
122 |
|
|
Function: get_gidlist() |
123 |
|
|
|
124 |
|
|
Description: |
125 |
|
|
Finds the list of gids for user in the group file (/etc/group) |
126 |
|
|
Returns a list of gid_t which should be freed by calling program. |
127 |
|
|
|
128 |
|
|
Parameters: |
129 |
|
|
username: the name of the user |
130 |
|
|
ngroups: ptr to int which will be filled with the number of gids. |
131 |
|
|
group_list: ptr to an array of gid_t. |
132 |
|
|
|
133 |
|
|
Returns: |
134 |
|
|
0 on success. |
135 |
|
|
-1 on realloc failure |
136 |
|
|
-2 on getgrent failure |
137 |
|
|
1 on failure |
138 |
|
|
******************************************************************************/ |
139 |
|
|
int get_gidlist( |
140 |
|
|
const char * username, |
141 |
|
|
int * ngroups, |
142 |
|
|
gid_t ** group_list |
143 |
|
|
) |
144 |
|
|
{ |
145 |
|
|
struct group * group_info = NULL; |
146 |
|
|
gid_t * groups = NULL; |
147 |
|
|
gid_t * newgroups = NULL; |
148 |
|
|
int i = 0; |
149 |
|
|
|
150 |
|
|
/* rewind the file pointer to the beginning of the /etc/group file */ |
151 |
|
|
setgrent(); |
152 |
|
|
|
153 |
|
|
lcmaps_log_debug(2, "\tlcmaps_get_gidlist(): looping through group file\n"); |
154 |
|
|
*ngroups = 0; |
155 |
|
|
while ( ( group_info = getgrent() ) ) |
156 |
|
|
{ |
157 |
|
|
char ** pgr_mem = group_info->gr_mem; |
158 |
|
|
char * gr_mem = NULL; |
159 |
|
|
|
160 |
|
|
lcmaps_log_debug(4, "\tlcmaps_get_gidlist(): group %s\n", group_info->gr_name); |
161 |
|
|
while ( (gr_mem = *pgr_mem) ) |
162 |
|
|
{ |
163 |
|
|
lcmaps_log_debug(4, "\tlcmaps_get_gidlist(): \tgroup member %s\n", gr_mem); |
164 |
|
|
if (strncmp(username, gr_mem, strlen(username))==0) |
165 |
|
|
{ |
166 |
|
|
lcmaps_log_debug(2, "\tlcmaps_get_gidlist(): \t\tfound group %s for %s\n", |
167 |
|
|
group_info->gr_name, username); |
168 |
|
|
(*ngroups)++; |
169 |
|
|
newgroups = (gid_t *) realloc(groups, ((*ngroups) * sizeof(gid_t))); |
170 |
|
|
if (newgroups == NULL) |
171 |
|
|
{ |
172 |
|
|
lcmaps_log(1, "lcmaps_get_gidlist(): cannot realloc\n"); |
173 |
|
|
free(groups); |
174 |
|
|
return -1; |
175 |
|
|
} |
176 |
|
|
groups=newgroups; |
177 |
|
|
groups[(*ngroups)-1] = group_info->gr_gid; |
178 |
|
|
} |
179 |
|
|
++pgr_mem; |
180 |
|
|
} |
181 |
|
|
} |
182 |
|
|
if (errno==ENOMEM) |
183 |
|
|
{ |
184 |
|
|
lcmaps_log(1, "lcmaps_get_gidlist(): Cannot read the group file, %s\n", strerror(errno)); |
185 |
|
|
free(groups); |
186 |
|
|
groups=NULL; |
187 |
|
|
/* Close the group file */ |
188 |
|
|
endgrent(); |
189 |
|
|
return -2; |
190 |
|
|
} |
191 |
|
|
*group_list=groups; |
192 |
|
|
lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): %d groups found for %s\n", *ngroups, username); |
193 |
|
|
for (i = 0; i < *ngroups; i++) |
194 |
|
|
{ |
195 |
|
|
lcmaps_log_debug(4,"\tlcmaps_get_gidlist(): group nr %d ==> gid_t %d\n", i+1, groups[i]); |
196 |
|
|
} |
197 |
|
|
/* Close the group file */ |
198 |
|
|
endgrent(); |
199 |
|
|
return 0; |
200 |
|
|
} |
201 |
|
|
|
202 |
|
|
|