1*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
2*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
3*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
4*2d543d20SAndroid Build Coastguard Worker #include <string.h>
5*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
6*2d543d20SAndroid Build Coastguard Worker #include <stdio_ext.h>
7*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
8*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
9*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
10*2d543d20SAndroid Build Coastguard Worker
11*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
12*2d543d20SAndroid Build Coastguard Worker #include <selinux/context.h>
13*2d543d20SAndroid Build Coastguard Worker
14*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
15*2d543d20SAndroid Build Coastguard Worker #include "callbacks.h"
16*2d543d20SAndroid Build Coastguard Worker
17*2d543d20SAndroid Build Coastguard Worker /* Process line from seusers.conf and split into its fields.
18*2d543d20SAndroid Build Coastguard Worker Returns 0 on success, -1 on comments, and -2 on error. */
process_seusers(const char * buffer,char ** luserp,char ** seuserp,char ** levelp,int mls_enabled)19*2d543d20SAndroid Build Coastguard Worker static int process_seusers(const char *buffer,
20*2d543d20SAndroid Build Coastguard Worker char **luserp,
21*2d543d20SAndroid Build Coastguard Worker char **seuserp, char **levelp, int mls_enabled)
22*2d543d20SAndroid Build Coastguard Worker {
23*2d543d20SAndroid Build Coastguard Worker char *newbuf = strdup(buffer);
24*2d543d20SAndroid Build Coastguard Worker char *luser = NULL, *seuser = NULL, *level = NULL;
25*2d543d20SAndroid Build Coastguard Worker char *start, *end;
26*2d543d20SAndroid Build Coastguard Worker int mls_found = 1;
27*2d543d20SAndroid Build Coastguard Worker
28*2d543d20SAndroid Build Coastguard Worker if (!newbuf)
29*2d543d20SAndroid Build Coastguard Worker goto err;
30*2d543d20SAndroid Build Coastguard Worker
31*2d543d20SAndroid Build Coastguard Worker start = newbuf;
32*2d543d20SAndroid Build Coastguard Worker while (isspace((unsigned char)*start))
33*2d543d20SAndroid Build Coastguard Worker start++;
34*2d543d20SAndroid Build Coastguard Worker if (*start == '#' || *start == 0) {
35*2d543d20SAndroid Build Coastguard Worker free(newbuf);
36*2d543d20SAndroid Build Coastguard Worker return -1; /* Comment or empty line, skip over */
37*2d543d20SAndroid Build Coastguard Worker }
38*2d543d20SAndroid Build Coastguard Worker end = strchr(start, ':');
39*2d543d20SAndroid Build Coastguard Worker if (!end)
40*2d543d20SAndroid Build Coastguard Worker goto err;
41*2d543d20SAndroid Build Coastguard Worker *end = 0;
42*2d543d20SAndroid Build Coastguard Worker
43*2d543d20SAndroid Build Coastguard Worker luser = strdup(start);
44*2d543d20SAndroid Build Coastguard Worker if (!luser)
45*2d543d20SAndroid Build Coastguard Worker goto err;
46*2d543d20SAndroid Build Coastguard Worker
47*2d543d20SAndroid Build Coastguard Worker start = end + 1;
48*2d543d20SAndroid Build Coastguard Worker end = strchr(start, ':');
49*2d543d20SAndroid Build Coastguard Worker if (!end) {
50*2d543d20SAndroid Build Coastguard Worker mls_found = 0;
51*2d543d20SAndroid Build Coastguard Worker
52*2d543d20SAndroid Build Coastguard Worker end = start;
53*2d543d20SAndroid Build Coastguard Worker while (*end && !isspace((unsigned char)*end))
54*2d543d20SAndroid Build Coastguard Worker end++;
55*2d543d20SAndroid Build Coastguard Worker }
56*2d543d20SAndroid Build Coastguard Worker *end = 0;
57*2d543d20SAndroid Build Coastguard Worker
58*2d543d20SAndroid Build Coastguard Worker seuser = strdup(start);
59*2d543d20SAndroid Build Coastguard Worker if (!seuser)
60*2d543d20SAndroid Build Coastguard Worker goto err;
61*2d543d20SAndroid Build Coastguard Worker
62*2d543d20SAndroid Build Coastguard Worker if (!strcmp(seuser, ""))
63*2d543d20SAndroid Build Coastguard Worker goto err;
64*2d543d20SAndroid Build Coastguard Worker
65*2d543d20SAndroid Build Coastguard Worker /* Skip MLS if disabled, or missing. */
66*2d543d20SAndroid Build Coastguard Worker if (!mls_enabled || !mls_found)
67*2d543d20SAndroid Build Coastguard Worker goto out;
68*2d543d20SAndroid Build Coastguard Worker
69*2d543d20SAndroid Build Coastguard Worker start = ++end;
70*2d543d20SAndroid Build Coastguard Worker while (*end && !isspace((unsigned char)*end))
71*2d543d20SAndroid Build Coastguard Worker end++;
72*2d543d20SAndroid Build Coastguard Worker *end = 0;
73*2d543d20SAndroid Build Coastguard Worker
74*2d543d20SAndroid Build Coastguard Worker level = strdup(start);
75*2d543d20SAndroid Build Coastguard Worker if (!level)
76*2d543d20SAndroid Build Coastguard Worker goto err;
77*2d543d20SAndroid Build Coastguard Worker
78*2d543d20SAndroid Build Coastguard Worker if (!strcmp(level, ""))
79*2d543d20SAndroid Build Coastguard Worker goto err;
80*2d543d20SAndroid Build Coastguard Worker
81*2d543d20SAndroid Build Coastguard Worker out:
82*2d543d20SAndroid Build Coastguard Worker free(newbuf);
83*2d543d20SAndroid Build Coastguard Worker *luserp = luser;
84*2d543d20SAndroid Build Coastguard Worker *seuserp = seuser;
85*2d543d20SAndroid Build Coastguard Worker *levelp = level;
86*2d543d20SAndroid Build Coastguard Worker return 0;
87*2d543d20SAndroid Build Coastguard Worker err:
88*2d543d20SAndroid Build Coastguard Worker free(newbuf);
89*2d543d20SAndroid Build Coastguard Worker free(luser);
90*2d543d20SAndroid Build Coastguard Worker free(seuser);
91*2d543d20SAndroid Build Coastguard Worker free(level);
92*2d543d20SAndroid Build Coastguard Worker return -2; /* error */
93*2d543d20SAndroid Build Coastguard Worker }
94*2d543d20SAndroid Build Coastguard Worker
95*2d543d20SAndroid Build Coastguard Worker int require_seusers = 0;
96*2d543d20SAndroid Build Coastguard Worker
97*2d543d20SAndroid Build Coastguard Worker #include <pwd.h>
98*2d543d20SAndroid Build Coastguard Worker #include <grp.h>
99*2d543d20SAndroid Build Coastguard Worker
get_default_gid(const char * name)100*2d543d20SAndroid Build Coastguard Worker static gid_t get_default_gid(const char *name) {
101*2d543d20SAndroid Build Coastguard Worker struct passwd pwstorage, *pwent = NULL;
102*2d543d20SAndroid Build Coastguard Worker gid_t gid = (gid_t)-1;
103*2d543d20SAndroid Build Coastguard Worker /* Allocate space for the getpwnam_r buffer */
104*2d543d20SAndroid Build Coastguard Worker char *rbuf = NULL;
105*2d543d20SAndroid Build Coastguard Worker long rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
106*2d543d20SAndroid Build Coastguard Worker if (rbuflen <= 0)
107*2d543d20SAndroid Build Coastguard Worker rbuflen = 1024;
108*2d543d20SAndroid Build Coastguard Worker
109*2d543d20SAndroid Build Coastguard Worker for (;;) {
110*2d543d20SAndroid Build Coastguard Worker int rc;
111*2d543d20SAndroid Build Coastguard Worker
112*2d543d20SAndroid Build Coastguard Worker rbuf = malloc(rbuflen);
113*2d543d20SAndroid Build Coastguard Worker if (rbuf == NULL)
114*2d543d20SAndroid Build Coastguard Worker break;
115*2d543d20SAndroid Build Coastguard Worker
116*2d543d20SAndroid Build Coastguard Worker rc = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent);
117*2d543d20SAndroid Build Coastguard Worker if (rc == ERANGE && rbuflen < LONG_MAX / 2) {
118*2d543d20SAndroid Build Coastguard Worker free(rbuf);
119*2d543d20SAndroid Build Coastguard Worker rbuflen *= 2;
120*2d543d20SAndroid Build Coastguard Worker continue;
121*2d543d20SAndroid Build Coastguard Worker }
122*2d543d20SAndroid Build Coastguard Worker if (rc == 0 && pwent)
123*2d543d20SAndroid Build Coastguard Worker gid = pwent->pw_gid;
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker break;
126*2d543d20SAndroid Build Coastguard Worker }
127*2d543d20SAndroid Build Coastguard Worker
128*2d543d20SAndroid Build Coastguard Worker free(rbuf);
129*2d543d20SAndroid Build Coastguard Worker return gid;
130*2d543d20SAndroid Build Coastguard Worker }
131*2d543d20SAndroid Build Coastguard Worker
check_group(const char * group,const char * name,const gid_t gid)132*2d543d20SAndroid Build Coastguard Worker static int check_group(const char *group, const char *name, const gid_t gid) {
133*2d543d20SAndroid Build Coastguard Worker int match = 0;
134*2d543d20SAndroid Build Coastguard Worker int i, ng = 0;
135*2d543d20SAndroid Build Coastguard Worker gid_t *groups = NULL;
136*2d543d20SAndroid Build Coastguard Worker struct group gbuf, *grent = NULL;
137*2d543d20SAndroid Build Coastguard Worker
138*2d543d20SAndroid Build Coastguard Worker long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
139*2d543d20SAndroid Build Coastguard Worker if (rbuflen <= 0)
140*2d543d20SAndroid Build Coastguard Worker rbuflen = 1024;
141*2d543d20SAndroid Build Coastguard Worker char *rbuf;
142*2d543d20SAndroid Build Coastguard Worker
143*2d543d20SAndroid Build Coastguard Worker while(1) {
144*2d543d20SAndroid Build Coastguard Worker rbuf = malloc(rbuflen);
145*2d543d20SAndroid Build Coastguard Worker if (rbuf == NULL)
146*2d543d20SAndroid Build Coastguard Worker return 0;
147*2d543d20SAndroid Build Coastguard Worker int retval = getgrnam_r(group, &gbuf, rbuf,
148*2d543d20SAndroid Build Coastguard Worker rbuflen, &grent);
149*2d543d20SAndroid Build Coastguard Worker if (retval == ERANGE && rbuflen < LONG_MAX / 2)
150*2d543d20SAndroid Build Coastguard Worker {
151*2d543d20SAndroid Build Coastguard Worker free(rbuf);
152*2d543d20SAndroid Build Coastguard Worker rbuflen = rbuflen * 2;
153*2d543d20SAndroid Build Coastguard Worker } else if ( retval != 0 || grent == NULL )
154*2d543d20SAndroid Build Coastguard Worker {
155*2d543d20SAndroid Build Coastguard Worker goto done;
156*2d543d20SAndroid Build Coastguard Worker } else
157*2d543d20SAndroid Build Coastguard Worker {
158*2d543d20SAndroid Build Coastguard Worker break;
159*2d543d20SAndroid Build Coastguard Worker }
160*2d543d20SAndroid Build Coastguard Worker }
161*2d543d20SAndroid Build Coastguard Worker
162*2d543d20SAndroid Build Coastguard Worker if (getgrouplist(name, gid, NULL, &ng) < 0) {
163*2d543d20SAndroid Build Coastguard Worker if (ng == 0)
164*2d543d20SAndroid Build Coastguard Worker goto done;
165*2d543d20SAndroid Build Coastguard Worker groups = calloc(ng, sizeof(*groups));
166*2d543d20SAndroid Build Coastguard Worker if (!groups)
167*2d543d20SAndroid Build Coastguard Worker goto done;
168*2d543d20SAndroid Build Coastguard Worker if (getgrouplist(name, gid, groups, &ng) < 0)
169*2d543d20SAndroid Build Coastguard Worker goto done;
170*2d543d20SAndroid Build Coastguard Worker } else {
171*2d543d20SAndroid Build Coastguard Worker /* WTF? ng was 0 and we didn't fail? Are we in 0 groups? */
172*2d543d20SAndroid Build Coastguard Worker goto done;
173*2d543d20SAndroid Build Coastguard Worker }
174*2d543d20SAndroid Build Coastguard Worker
175*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < ng; i++) {
176*2d543d20SAndroid Build Coastguard Worker if (grent->gr_gid == groups[i]) {
177*2d543d20SAndroid Build Coastguard Worker match = 1;
178*2d543d20SAndroid Build Coastguard Worker goto done;
179*2d543d20SAndroid Build Coastguard Worker }
180*2d543d20SAndroid Build Coastguard Worker }
181*2d543d20SAndroid Build Coastguard Worker
182*2d543d20SAndroid Build Coastguard Worker done:
183*2d543d20SAndroid Build Coastguard Worker free(groups);
184*2d543d20SAndroid Build Coastguard Worker free(rbuf);
185*2d543d20SAndroid Build Coastguard Worker return match;
186*2d543d20SAndroid Build Coastguard Worker }
187*2d543d20SAndroid Build Coastguard Worker
getseuserbyname(const char * name,char ** r_seuser,char ** r_level)188*2d543d20SAndroid Build Coastguard Worker int getseuserbyname(const char *name, char **r_seuser, char **r_level)
189*2d543d20SAndroid Build Coastguard Worker {
190*2d543d20SAndroid Build Coastguard Worker FILE *cfg = NULL;
191*2d543d20SAndroid Build Coastguard Worker size_t size = 0;
192*2d543d20SAndroid Build Coastguard Worker char *buffer = NULL;
193*2d543d20SAndroid Build Coastguard Worker int rc;
194*2d543d20SAndroid Build Coastguard Worker unsigned long lineno = 0;
195*2d543d20SAndroid Build Coastguard Worker int mls_enabled = is_selinux_mls_enabled();
196*2d543d20SAndroid Build Coastguard Worker
197*2d543d20SAndroid Build Coastguard Worker char *username = NULL;
198*2d543d20SAndroid Build Coastguard Worker char *seuser = NULL;
199*2d543d20SAndroid Build Coastguard Worker char *level = NULL;
200*2d543d20SAndroid Build Coastguard Worker char *groupseuser = NULL;
201*2d543d20SAndroid Build Coastguard Worker char *grouplevel = NULL;
202*2d543d20SAndroid Build Coastguard Worker char *defaultseuser = NULL;
203*2d543d20SAndroid Build Coastguard Worker char *defaultlevel = NULL;
204*2d543d20SAndroid Build Coastguard Worker
205*2d543d20SAndroid Build Coastguard Worker gid_t gid = get_default_gid(name);
206*2d543d20SAndroid Build Coastguard Worker
207*2d543d20SAndroid Build Coastguard Worker cfg = fopen(selinux_usersconf_path(), "re");
208*2d543d20SAndroid Build Coastguard Worker if (!cfg)
209*2d543d20SAndroid Build Coastguard Worker goto nomatch;
210*2d543d20SAndroid Build Coastguard Worker
211*2d543d20SAndroid Build Coastguard Worker __fsetlocking(cfg, FSETLOCKING_BYCALLER);
212*2d543d20SAndroid Build Coastguard Worker while (getline(&buffer, &size, cfg) > 0) {
213*2d543d20SAndroid Build Coastguard Worker ++lineno;
214*2d543d20SAndroid Build Coastguard Worker rc = process_seusers(buffer, &username, &seuser, &level,
215*2d543d20SAndroid Build Coastguard Worker mls_enabled);
216*2d543d20SAndroid Build Coastguard Worker if (rc == -1)
217*2d543d20SAndroid Build Coastguard Worker continue; /* comment, skip */
218*2d543d20SAndroid Build Coastguard Worker if (rc == -2) {
219*2d543d20SAndroid Build Coastguard Worker selinux_log(SELINUX_ERROR, "%s: error on line %lu, skipping...\n",
220*2d543d20SAndroid Build Coastguard Worker selinux_usersconf_path(), lineno);
221*2d543d20SAndroid Build Coastguard Worker continue;
222*2d543d20SAndroid Build Coastguard Worker }
223*2d543d20SAndroid Build Coastguard Worker
224*2d543d20SAndroid Build Coastguard Worker if (!strcmp(username, name))
225*2d543d20SAndroid Build Coastguard Worker break;
226*2d543d20SAndroid Build Coastguard Worker
227*2d543d20SAndroid Build Coastguard Worker if (username[0] == '%' &&
228*2d543d20SAndroid Build Coastguard Worker !groupseuser &&
229*2d543d20SAndroid Build Coastguard Worker check_group(&username[1], name, gid)) {
230*2d543d20SAndroid Build Coastguard Worker groupseuser = seuser;
231*2d543d20SAndroid Build Coastguard Worker grouplevel = level;
232*2d543d20SAndroid Build Coastguard Worker } else {
233*2d543d20SAndroid Build Coastguard Worker if (!defaultseuser &&
234*2d543d20SAndroid Build Coastguard Worker !strcmp(username, "__default__")) {
235*2d543d20SAndroid Build Coastguard Worker defaultseuser = seuser;
236*2d543d20SAndroid Build Coastguard Worker defaultlevel = level;
237*2d543d20SAndroid Build Coastguard Worker } else {
238*2d543d20SAndroid Build Coastguard Worker free(seuser);
239*2d543d20SAndroid Build Coastguard Worker free(level);
240*2d543d20SAndroid Build Coastguard Worker }
241*2d543d20SAndroid Build Coastguard Worker }
242*2d543d20SAndroid Build Coastguard Worker free(username);
243*2d543d20SAndroid Build Coastguard Worker username = NULL;
244*2d543d20SAndroid Build Coastguard Worker seuser = NULL;
245*2d543d20SAndroid Build Coastguard Worker }
246*2d543d20SAndroid Build Coastguard Worker
247*2d543d20SAndroid Build Coastguard Worker free(buffer);
248*2d543d20SAndroid Build Coastguard Worker fclose(cfg);
249*2d543d20SAndroid Build Coastguard Worker
250*2d543d20SAndroid Build Coastguard Worker if (seuser) {
251*2d543d20SAndroid Build Coastguard Worker free(username);
252*2d543d20SAndroid Build Coastguard Worker free(defaultseuser);
253*2d543d20SAndroid Build Coastguard Worker free(defaultlevel);
254*2d543d20SAndroid Build Coastguard Worker free(groupseuser);
255*2d543d20SAndroid Build Coastguard Worker free(grouplevel);
256*2d543d20SAndroid Build Coastguard Worker *r_seuser = seuser;
257*2d543d20SAndroid Build Coastguard Worker *r_level = level;
258*2d543d20SAndroid Build Coastguard Worker return 0;
259*2d543d20SAndroid Build Coastguard Worker }
260*2d543d20SAndroid Build Coastguard Worker
261*2d543d20SAndroid Build Coastguard Worker if (groupseuser) {
262*2d543d20SAndroid Build Coastguard Worker free(defaultseuser);
263*2d543d20SAndroid Build Coastguard Worker free(defaultlevel);
264*2d543d20SAndroid Build Coastguard Worker *r_seuser = groupseuser;
265*2d543d20SAndroid Build Coastguard Worker *r_level = grouplevel;
266*2d543d20SAndroid Build Coastguard Worker return 0;
267*2d543d20SAndroid Build Coastguard Worker }
268*2d543d20SAndroid Build Coastguard Worker
269*2d543d20SAndroid Build Coastguard Worker if (defaultseuser) {
270*2d543d20SAndroid Build Coastguard Worker *r_seuser = defaultseuser;
271*2d543d20SAndroid Build Coastguard Worker *r_level = defaultlevel;
272*2d543d20SAndroid Build Coastguard Worker return 0;
273*2d543d20SAndroid Build Coastguard Worker }
274*2d543d20SAndroid Build Coastguard Worker
275*2d543d20SAndroid Build Coastguard Worker nomatch:
276*2d543d20SAndroid Build Coastguard Worker if (require_seusers)
277*2d543d20SAndroid Build Coastguard Worker return -1;
278*2d543d20SAndroid Build Coastguard Worker
279*2d543d20SAndroid Build Coastguard Worker /* Fall back to the Linux username and no level. */
280*2d543d20SAndroid Build Coastguard Worker *r_seuser = strdup(name);
281*2d543d20SAndroid Build Coastguard Worker if (!(*r_seuser))
282*2d543d20SAndroid Build Coastguard Worker return -1;
283*2d543d20SAndroid Build Coastguard Worker *r_level = NULL;
284*2d543d20SAndroid Build Coastguard Worker return 0;
285*2d543d20SAndroid Build Coastguard Worker }
286*2d543d20SAndroid Build Coastguard Worker
getseuser(const char * username,const char * service,char ** r_seuser,char ** r_level)287*2d543d20SAndroid Build Coastguard Worker int getseuser(const char *username, const char *service,
288*2d543d20SAndroid Build Coastguard Worker char **r_seuser, char **r_level) {
289*2d543d20SAndroid Build Coastguard Worker int ret = -1;
290*2d543d20SAndroid Build Coastguard Worker int len = 0;
291*2d543d20SAndroid Build Coastguard Worker char *seuser = NULL;
292*2d543d20SAndroid Build Coastguard Worker char *level = NULL;
293*2d543d20SAndroid Build Coastguard Worker char *buffer = NULL;
294*2d543d20SAndroid Build Coastguard Worker size_t size = 0;
295*2d543d20SAndroid Build Coastguard Worker char *rec = NULL;
296*2d543d20SAndroid Build Coastguard Worker char *path = NULL;
297*2d543d20SAndroid Build Coastguard Worker FILE *fp = NULL;
298*2d543d20SAndroid Build Coastguard Worker if (asprintf(&path,"%s/logins/%s", selinux_policy_root(), username) < 0)
299*2d543d20SAndroid Build Coastguard Worker goto err;
300*2d543d20SAndroid Build Coastguard Worker fp = fopen(path, "re");
301*2d543d20SAndroid Build Coastguard Worker free(path);
302*2d543d20SAndroid Build Coastguard Worker if (fp == NULL) goto err;
303*2d543d20SAndroid Build Coastguard Worker __fsetlocking(fp, FSETLOCKING_BYCALLER);
304*2d543d20SAndroid Build Coastguard Worker while (getline(&buffer, &size, fp) > 0) {
305*2d543d20SAndroid Build Coastguard Worker if (strncmp(buffer, "*:", 2) == 0) {
306*2d543d20SAndroid Build Coastguard Worker free(rec);
307*2d543d20SAndroid Build Coastguard Worker rec = strdup(buffer);
308*2d543d20SAndroid Build Coastguard Worker continue;
309*2d543d20SAndroid Build Coastguard Worker }
310*2d543d20SAndroid Build Coastguard Worker if (!service)
311*2d543d20SAndroid Build Coastguard Worker continue;
312*2d543d20SAndroid Build Coastguard Worker len = strlen(service);
313*2d543d20SAndroid Build Coastguard Worker if ((strncmp(buffer, service, len) == 0) &&
314*2d543d20SAndroid Build Coastguard Worker (buffer[len] == ':')) {
315*2d543d20SAndroid Build Coastguard Worker free(rec);
316*2d543d20SAndroid Build Coastguard Worker rec = strdup(buffer);
317*2d543d20SAndroid Build Coastguard Worker break;
318*2d543d20SAndroid Build Coastguard Worker }
319*2d543d20SAndroid Build Coastguard Worker }
320*2d543d20SAndroid Build Coastguard Worker
321*2d543d20SAndroid Build Coastguard Worker if (! rec) goto err;
322*2d543d20SAndroid Build Coastguard Worker seuser = strchr(rec, ':');
323*2d543d20SAndroid Build Coastguard Worker if (! seuser) goto err;
324*2d543d20SAndroid Build Coastguard Worker
325*2d543d20SAndroid Build Coastguard Worker seuser++;
326*2d543d20SAndroid Build Coastguard Worker level = strchr(seuser, ':');
327*2d543d20SAndroid Build Coastguard Worker if (! level) goto err;
328*2d543d20SAndroid Build Coastguard Worker *level = 0;
329*2d543d20SAndroid Build Coastguard Worker level++;
330*2d543d20SAndroid Build Coastguard Worker *r_seuser = strdup(seuser);
331*2d543d20SAndroid Build Coastguard Worker if (! *r_seuser) goto err;
332*2d543d20SAndroid Build Coastguard Worker
333*2d543d20SAndroid Build Coastguard Worker len = strlen(level);
334*2d543d20SAndroid Build Coastguard Worker if (len && level[len-1] == '\n')
335*2d543d20SAndroid Build Coastguard Worker level[len-1] = 0;
336*2d543d20SAndroid Build Coastguard Worker
337*2d543d20SAndroid Build Coastguard Worker *r_level = strdup(level);
338*2d543d20SAndroid Build Coastguard Worker if (! *r_level) {
339*2d543d20SAndroid Build Coastguard Worker free(*r_seuser);
340*2d543d20SAndroid Build Coastguard Worker goto err;
341*2d543d20SAndroid Build Coastguard Worker }
342*2d543d20SAndroid Build Coastguard Worker ret = 0;
343*2d543d20SAndroid Build Coastguard Worker
344*2d543d20SAndroid Build Coastguard Worker err:
345*2d543d20SAndroid Build Coastguard Worker free(buffer);
346*2d543d20SAndroid Build Coastguard Worker if (fp) fclose(fp);
347*2d543d20SAndroid Build Coastguard Worker free(rec);
348*2d543d20SAndroid Build Coastguard Worker
349*2d543d20SAndroid Build Coastguard Worker return (ret ? getseuserbyname(username, r_seuser, r_level) : ret);
350*2d543d20SAndroid Build Coastguard Worker }
351