12e322d37SHiroki Sato /*-
28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni *
42e322d37SHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc.
52e322d37SHiroki Sato * All rights reserved.
6e8636dfdSBill Paul *
72e322d37SHiroki Sato * Redistribution and use in source and binary forms, with or without
82e322d37SHiroki Sato * modification, are permitted provided that the following conditions are met:
92e322d37SHiroki Sato * - Redistributions of source code must retain the above copyright notice,
102e322d37SHiroki Sato * this list of conditions and the following disclaimer.
112e322d37SHiroki Sato * - Redistributions in binary form must reproduce the above copyright notice,
122e322d37SHiroki Sato * this list of conditions and the following disclaimer in the documentation
132e322d37SHiroki Sato * and/or other materials provided with the distribution.
142e322d37SHiroki Sato * - Neither the name of Sun Microsystems, Inc. nor the names of its
152e322d37SHiroki Sato * contributors may be used to endorse or promote products derived
162e322d37SHiroki Sato * from this software without specific prior written permission.
17e8636dfdSBill Paul *
182e322d37SHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
192e322d37SHiroki Sato * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
202e322d37SHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
212e322d37SHiroki Sato * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
222e322d37SHiroki Sato * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
232e322d37SHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
242e322d37SHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
252e322d37SHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
262e322d37SHiroki Sato * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
272e322d37SHiroki Sato * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
282e322d37SHiroki Sato * POSSIBILITY OF SUCH DAMAGE.
29e8636dfdSBill Paul */
30a986ef57SDavid E. O'Brien
31e8636dfdSBill Paul /*
32e8636dfdSBill Paul * netname utility routines convert from unix names to network names and
33e8636dfdSBill Paul * vice-versa This module is operating system dependent! What we define here
34e8636dfdSBill Paul * will work with any unix system that has adopted the sun NIS domain
35e8636dfdSBill Paul * architecture.
36e8636dfdSBill Paul */
378360efbdSAlfred Perlstein #include "namespace.h"
38e8636dfdSBill Paul #include <sys/param.h>
39e8636dfdSBill Paul #include <rpc/rpc.h>
40e8636dfdSBill Paul #include <rpc/rpc_com.h>
41e8636dfdSBill Paul #ifdef YP
42e8636dfdSBill Paul #include <rpcsvc/yp_prot.h>
43e8636dfdSBill Paul #include <rpcsvc/ypclnt.h>
44e8636dfdSBill Paul #endif
45e8636dfdSBill Paul #include <ctype.h>
46e8636dfdSBill Paul #include <stdio.h>
47e8636dfdSBill Paul #include <grp.h>
48e8636dfdSBill Paul #include <pwd.h>
49e8636dfdSBill Paul #include <string.h>
50e8636dfdSBill Paul #include <stdlib.h>
51e8636dfdSBill Paul #include <unistd.h>
528360efbdSAlfred Perlstein #include "un-namespace.h"
53e8636dfdSBill Paul
54e8636dfdSBill Paul static char *OPSYS = "unix";
556c58990dSBjoern A. Zeeb #ifdef YP
56e8636dfdSBill Paul static char *NETID = "netid.byname";
576c58990dSBjoern A. Zeeb #endif
58e8636dfdSBill Paul static char *NETIDFILE = "/etc/netid";
59e8636dfdSBill Paul
60c05ac53bSDavid E. O'Brien static int getnetid( char *, char * );
61*a2e41a58SJohn Baldwin static int _getgroups( char *, gid_t [NGRPS] );
62e8636dfdSBill Paul
63e8636dfdSBill Paul /*
64e8636dfdSBill Paul * Convert network-name into unix credential
65e8636dfdSBill Paul */
66e8636dfdSBill Paul int
netname2user(char netname[MAXNETNAMELEN+1],uid_t * uidp,gid_t * gidp,int * gidlenp,gid_t * gidlist)67587cf682SCraig Rodrigues netname2user(char netname[MAXNETNAMELEN + 1], uid_t *uidp, gid_t *gidp,
68587cf682SCraig Rodrigues int *gidlenp, gid_t *gidlist)
69e8636dfdSBill Paul {
70e8636dfdSBill Paul char *p;
71e8636dfdSBill Paul int gidlen;
72e8636dfdSBill Paul uid_t uid;
732a29b52bSBruce Evans long luid;
74e8636dfdSBill Paul struct passwd *pwd;
75e8636dfdSBill Paul char val[1024];
76e8636dfdSBill Paul char *val1, *val2;
77e8636dfdSBill Paul char *domain;
78e8636dfdSBill Paul int vallen;
79e8636dfdSBill Paul int err;
80e8636dfdSBill Paul
81e8636dfdSBill Paul if (getnetid(netname, val)) {
8267ab6e98SAndrey A. Chernov char *res = val;
8367ab6e98SAndrey A. Chernov
8467ab6e98SAndrey A. Chernov p = strsep(&res, ":");
85e8636dfdSBill Paul if (p == NULL)
86e8636dfdSBill Paul return (0);
8767ab6e98SAndrey A. Chernov *uidp = (uid_t) atol(p);
8867ab6e98SAndrey A. Chernov p = strsep(&res, "\n,");
89e8636dfdSBill Paul if (p == NULL) {
90e8636dfdSBill Paul return (0);
91e8636dfdSBill Paul }
9267ab6e98SAndrey A. Chernov *gidp = (gid_t) atol(p);
93838d9858SBrooks Davis for (gidlen = 0; gidlen < NGRPS; gidlen++) {
9467ab6e98SAndrey A. Chernov p = strsep(&res, "\n,");
95e8636dfdSBill Paul if (p == NULL)
96e8636dfdSBill Paul break;
97e8636dfdSBill Paul gidlist[gidlen] = (gid_t) atol(p);
98e8636dfdSBill Paul }
99e8636dfdSBill Paul *gidlenp = gidlen;
100e8636dfdSBill Paul
101e8636dfdSBill Paul return (1);
102e8636dfdSBill Paul }
103e8636dfdSBill Paul val1 = strchr(netname, '.');
104e8636dfdSBill Paul if (val1 == NULL)
105e8636dfdSBill Paul return (0);
106e8636dfdSBill Paul if (strncmp(netname, OPSYS, (val1-netname)))
107e8636dfdSBill Paul return (0);
108e8636dfdSBill Paul val1++;
109e8636dfdSBill Paul val2 = strchr(val1, '@');
110e8636dfdSBill Paul if (val2 == NULL)
111e8636dfdSBill Paul return (0);
112e8636dfdSBill Paul vallen = val2 - val1;
113e8636dfdSBill Paul if (vallen > (1024 - 1))
114e8636dfdSBill Paul vallen = 1024 - 1;
115e8636dfdSBill Paul (void) strncpy(val, val1, 1024);
116e8636dfdSBill Paul val[vallen] = 0;
117e8636dfdSBill Paul
1188d630135SAlfred Perlstein err = __rpc_get_default_domain(&domain); /* change to rpc */
119e8636dfdSBill Paul if (err)
120e8636dfdSBill Paul return (0);
121e8636dfdSBill Paul
122e8636dfdSBill Paul if (strcmp(val2 + 1, domain))
123e8636dfdSBill Paul return (0); /* wrong domain */
124e8636dfdSBill Paul
1252a29b52bSBruce Evans if (sscanf(val, "%ld", &luid) != 1)
126e8636dfdSBill Paul return (0);
1272a29b52bSBruce Evans uid = luid;
1282a29b52bSBruce Evans
129e8636dfdSBill Paul /* use initgroups method */
130e8636dfdSBill Paul pwd = getpwuid(uid);
131e8636dfdSBill Paul if (pwd == NULL)
132e8636dfdSBill Paul return (0);
133e8636dfdSBill Paul *uidp = pwd->pw_uid;
134e8636dfdSBill Paul *gidp = pwd->pw_gid;
135e8636dfdSBill Paul *gidlenp = _getgroups(pwd->pw_name, gidlist);
136e8636dfdSBill Paul return (1);
137e8636dfdSBill Paul }
138e8636dfdSBill Paul
139e8636dfdSBill Paul /*
140e8636dfdSBill Paul * initgroups
141e8636dfdSBill Paul */
142e8636dfdSBill Paul
143e8636dfdSBill Paul static int
_getgroups(char * uname,gid_t groups[NGRPS])144587cf682SCraig Rodrigues _getgroups(char *uname, gid_t groups[NGRPS])
145e8636dfdSBill Paul {
146e8636dfdSBill Paul gid_t ngroups = 0;
1478fb3f3f6SDavid E. O'Brien struct group *grp;
1488fb3f3f6SDavid E. O'Brien int i;
1498fb3f3f6SDavid E. O'Brien int j;
150e8636dfdSBill Paul int filter;
151e8636dfdSBill Paul
152e8636dfdSBill Paul setgrent();
153e8636dfdSBill Paul while ((grp = getgrent())) {
154e8636dfdSBill Paul for (i = 0; grp->gr_mem[i]; i++)
155e8636dfdSBill Paul if (!strcmp(grp->gr_mem[i], uname)) {
156838d9858SBrooks Davis if (ngroups == NGRPS) {
157e8636dfdSBill Paul #ifdef DEBUG
158e8636dfdSBill Paul fprintf(stderr,
159e8636dfdSBill Paul "initgroups: %s is in too many groups\n", uname);
160e8636dfdSBill Paul #endif
161e8636dfdSBill Paul goto toomany;
162e8636dfdSBill Paul }
163e8636dfdSBill Paul /* filter out duplicate group entries */
164e8636dfdSBill Paul filter = 0;
165e8636dfdSBill Paul for (j = 0; j < ngroups; j++)
166e8636dfdSBill Paul if (groups[j] == grp->gr_gid) {
167e8636dfdSBill Paul filter++;
168e8636dfdSBill Paul break;
169e8636dfdSBill Paul }
170e8636dfdSBill Paul if (!filter)
171e8636dfdSBill Paul groups[ngroups++] = grp->gr_gid;
172e8636dfdSBill Paul }
173e8636dfdSBill Paul }
174e8636dfdSBill Paul toomany:
175e8636dfdSBill Paul endgrent();
176e8636dfdSBill Paul return (ngroups);
177e8636dfdSBill Paul }
178e8636dfdSBill Paul
179e8636dfdSBill Paul /*
180e8636dfdSBill Paul * Convert network-name to hostname
181e8636dfdSBill Paul */
182e8636dfdSBill Paul int
netname2host(char netname[MAXNETNAMELEN+1],char * hostname,int hostlen)183587cf682SCraig Rodrigues netname2host(char netname[MAXNETNAMELEN + 1], char *hostname, int hostlen)
184e8636dfdSBill Paul {
185e8636dfdSBill Paul int err;
186e8636dfdSBill Paul char valbuf[1024];
187e8636dfdSBill Paul char *val;
188e8636dfdSBill Paul char *val2;
189e8636dfdSBill Paul int vallen;
190e8636dfdSBill Paul char *domain;
191e8636dfdSBill Paul
192e8636dfdSBill Paul if (getnetid(netname, valbuf)) {
193e8636dfdSBill Paul val = valbuf;
194e8636dfdSBill Paul if ((*val == '0') && (val[1] == ':')) {
195e8636dfdSBill Paul (void) strncpy(hostname, val + 2, hostlen);
196e8636dfdSBill Paul return (1);
197e8636dfdSBill Paul }
198e8636dfdSBill Paul }
199e8636dfdSBill Paul val = strchr(netname, '.');
200e8636dfdSBill Paul if (val == NULL)
201e8636dfdSBill Paul return (0);
202e8636dfdSBill Paul if (strncmp(netname, OPSYS, (val - netname)))
203e8636dfdSBill Paul return (0);
204e8636dfdSBill Paul val++;
205e8636dfdSBill Paul val2 = strchr(val, '@');
206e8636dfdSBill Paul if (val2 == NULL)
207e8636dfdSBill Paul return (0);
208e8636dfdSBill Paul vallen = val2 - val;
209e8636dfdSBill Paul if (vallen > (hostlen - 1))
210e8636dfdSBill Paul vallen = hostlen - 1;
211e8636dfdSBill Paul (void) strncpy(hostname, val, vallen);
212e8636dfdSBill Paul hostname[vallen] = 0;
213e8636dfdSBill Paul
2148d630135SAlfred Perlstein err = __rpc_get_default_domain(&domain); /* change to rpc */
215e8636dfdSBill Paul if (err)
216e8636dfdSBill Paul return (0);
217e8636dfdSBill Paul
218e8636dfdSBill Paul if (strcmp(val2 + 1, domain))
219e8636dfdSBill Paul return (0); /* wrong domain */
220e8636dfdSBill Paul else
221e8636dfdSBill Paul return (1);
222e8636dfdSBill Paul }
223e8636dfdSBill Paul
224e8636dfdSBill Paul /*
225e8636dfdSBill Paul * reads the file /etc/netid looking for a + to optionally go to the
226e8636dfdSBill Paul * network information service.
227e8636dfdSBill Paul */
228e8636dfdSBill Paul int
getnetid(char * key,char * ret)229587cf682SCraig Rodrigues getnetid(char *key, char *ret)
230e8636dfdSBill Paul {
231e8636dfdSBill Paul char buf[1024]; /* big enough */
232e8636dfdSBill Paul char *res;
233e8636dfdSBill Paul char *mkey;
234e8636dfdSBill Paul char *mval;
235e8636dfdSBill Paul FILE *fd;
236e8636dfdSBill Paul #ifdef YP
237e8636dfdSBill Paul char *domain;
238e8636dfdSBill Paul int err;
239e8636dfdSBill Paul char *lookup;
240e8636dfdSBill Paul int len;
241e8636dfdSBill Paul #endif
24299d49860SEnji Cooper int rv;
24399d49860SEnji Cooper
24499d49860SEnji Cooper rv = 0;
245e8636dfdSBill Paul
246e8636dfdSBill Paul fd = fopen(NETIDFILE, "r");
24767ab6e98SAndrey A. Chernov if (fd == NULL) {
248e8636dfdSBill Paul #ifdef YP
249e8636dfdSBill Paul res = "+";
250e8636dfdSBill Paul goto getnetidyp;
251e8636dfdSBill Paul #else
252e8636dfdSBill Paul return (0);
253e8636dfdSBill Paul #endif
254e8636dfdSBill Paul }
25599d49860SEnji Cooper while (fd != NULL) {
25667ab6e98SAndrey A. Chernov res = fgets(buf, sizeof(buf), fd);
25767ab6e98SAndrey A. Chernov if (res == NULL) {
25899d49860SEnji Cooper rv = 0;
25999d49860SEnji Cooper goto done;
260e8636dfdSBill Paul }
261e8636dfdSBill Paul if (res[0] == '#')
262e8636dfdSBill Paul continue;
263e8636dfdSBill Paul else if (res[0] == '+') {
264e8636dfdSBill Paul #ifdef YP
265e8636dfdSBill Paul getnetidyp:
266e8636dfdSBill Paul err = yp_get_default_domain(&domain);
267e8636dfdSBill Paul if (err) {
268e8636dfdSBill Paul continue;
269e8636dfdSBill Paul }
270e8636dfdSBill Paul lookup = NULL;
271e8636dfdSBill Paul err = yp_match(domain, NETID, key,
272e8636dfdSBill Paul strlen(key), &lookup, &len);
273e8636dfdSBill Paul if (err) {
274e8636dfdSBill Paul #ifdef DEBUG
275e8636dfdSBill Paul fprintf(stderr, "match failed error %d\n", err);
276e8636dfdSBill Paul #endif
277e8636dfdSBill Paul continue;
278e8636dfdSBill Paul }
279e8636dfdSBill Paul lookup[len] = 0;
280e8636dfdSBill Paul strcpy(ret, lookup);
281e8636dfdSBill Paul free(lookup);
28299d49860SEnji Cooper rv = 2;
28399d49860SEnji Cooper goto done;
284e8636dfdSBill Paul #else /* YP */
285e8636dfdSBill Paul #ifdef DEBUG
286e8636dfdSBill Paul fprintf(stderr,
287e8636dfdSBill Paul "Bad record in %s '+' -- NIS not supported in this library copy\n",
288e8636dfdSBill Paul NETIDFILE);
289e8636dfdSBill Paul #endif
290e8636dfdSBill Paul continue;
291e8636dfdSBill Paul #endif /* YP */
292e8636dfdSBill Paul } else {
29367ab6e98SAndrey A. Chernov mkey = strsep(&res, "\t ");
294e8636dfdSBill Paul if (mkey == NULL) {
295e8636dfdSBill Paul fprintf(stderr,
296e8636dfdSBill Paul "Bad record in %s -- %s", NETIDFILE, buf);
297e8636dfdSBill Paul continue;
298e8636dfdSBill Paul }
29967ab6e98SAndrey A. Chernov do {
30067ab6e98SAndrey A. Chernov mval = strsep(&res, " \t#\n");
30167ab6e98SAndrey A. Chernov } while (mval != NULL && !*mval);
302e8636dfdSBill Paul if (mval == NULL) {
303e8636dfdSBill Paul fprintf(stderr,
304e8636dfdSBill Paul "Bad record in %s val problem - %s", NETIDFILE, buf);
305e8636dfdSBill Paul continue;
306e8636dfdSBill Paul }
307e8636dfdSBill Paul if (strcmp(mkey, key) == 0) {
308e8636dfdSBill Paul strcpy(ret, mval);
30999d49860SEnji Cooper rv = 1;
31099d49860SEnji Cooper goto done;
31199d49860SEnji Cooper }
31299d49860SEnji Cooper }
31399d49860SEnji Cooper }
314e8636dfdSBill Paul
31599d49860SEnji Cooper done:
31699d49860SEnji Cooper if (fd != NULL)
31799d49860SEnji Cooper fclose(fd);
31899d49860SEnji Cooper return (rv);
319e8636dfdSBill Paul }
320