Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/rpc/netnamer.c
39476 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 2009, Sun Microsystems, Inc.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are met:
9
* - Redistributions of source code must retain the above copyright notice,
10
* this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright notice,
12
* this list of conditions and the following disclaimer in the documentation
13
* and/or other materials provided with the distribution.
14
* - Neither the name of Sun Microsystems, Inc. nor the names of its
15
* contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
* POSSIBILITY OF SUCH DAMAGE.
29
*/
30
31
/*
32
* netname utility routines convert from unix names to network names and
33
* vice-versa This module is operating system dependent! What we define here
34
* will work with any unix system that has adopted the sun NIS domain
35
* architecture.
36
*/
37
#include "namespace.h"
38
#include <sys/param.h>
39
#include <rpc/rpc.h>
40
#include <rpc/rpc_com.h>
41
#ifdef YP
42
#include <rpcsvc/yp_prot.h>
43
#include <rpcsvc/ypclnt.h>
44
#endif
45
#include <ctype.h>
46
#include <stdio.h>
47
#include <grp.h>
48
#include <pwd.h>
49
#include <string.h>
50
#include <stdlib.h>
51
#include <unistd.h>
52
#include "un-namespace.h"
53
54
static char *OPSYS = "unix";
55
#ifdef YP
56
static char *NETID = "netid.byname";
57
#endif
58
static char *NETIDFILE = "/etc/netid";
59
60
static int getnetid( char *, char * );
61
static int _getgroups( char *, gid_t [NGRPS] );
62
63
/*
64
* Convert network-name into unix credential
65
*/
66
int
67
netname2user(char netname[MAXNETNAMELEN + 1], uid_t *uidp, gid_t *gidp,
68
int *gidlenp, gid_t *gidlist)
69
{
70
char *p;
71
int gidlen;
72
uid_t uid;
73
long luid;
74
struct passwd *pwd;
75
char val[1024];
76
char *val1, *val2;
77
char *domain;
78
int vallen;
79
int err;
80
81
if (getnetid(netname, val)) {
82
char *res = val;
83
84
p = strsep(&res, ":");
85
if (p == NULL)
86
return (0);
87
*uidp = (uid_t) atol(p);
88
p = strsep(&res, "\n,");
89
if (p == NULL) {
90
return (0);
91
}
92
*gidp = (gid_t) atol(p);
93
for (gidlen = 0; gidlen < NGRPS; gidlen++) {
94
p = strsep(&res, "\n,");
95
if (p == NULL)
96
break;
97
gidlist[gidlen] = (gid_t) atol(p);
98
}
99
*gidlenp = gidlen;
100
101
return (1);
102
}
103
val1 = strchr(netname, '.');
104
if (val1 == NULL)
105
return (0);
106
if (strncmp(netname, OPSYS, (val1-netname)))
107
return (0);
108
val1++;
109
val2 = strchr(val1, '@');
110
if (val2 == NULL)
111
return (0);
112
vallen = val2 - val1;
113
if (vallen > (1024 - 1))
114
vallen = 1024 - 1;
115
(void) strncpy(val, val1, 1024);
116
val[vallen] = 0;
117
118
err = __rpc_get_default_domain(&domain); /* change to rpc */
119
if (err)
120
return (0);
121
122
if (strcmp(val2 + 1, domain))
123
return (0); /* wrong domain */
124
125
if (sscanf(val, "%ld", &luid) != 1)
126
return (0);
127
uid = luid;
128
129
/* use initgroups method */
130
pwd = getpwuid(uid);
131
if (pwd == NULL)
132
return (0);
133
*uidp = pwd->pw_uid;
134
*gidp = pwd->pw_gid;
135
*gidlenp = _getgroups(pwd->pw_name, gidlist);
136
return (1);
137
}
138
139
/*
140
* initgroups
141
*/
142
143
static int
144
_getgroups(char *uname, gid_t groups[NGRPS])
145
{
146
gid_t ngroups = 0;
147
struct group *grp;
148
int i;
149
int j;
150
int filter;
151
152
setgrent();
153
while ((grp = getgrent())) {
154
for (i = 0; grp->gr_mem[i]; i++)
155
if (!strcmp(grp->gr_mem[i], uname)) {
156
if (ngroups == NGRPS) {
157
#ifdef DEBUG
158
fprintf(stderr,
159
"initgroups: %s is in too many groups\n", uname);
160
#endif
161
goto toomany;
162
}
163
/* filter out duplicate group entries */
164
filter = 0;
165
for (j = 0; j < ngroups; j++)
166
if (groups[j] == grp->gr_gid) {
167
filter++;
168
break;
169
}
170
if (!filter)
171
groups[ngroups++] = grp->gr_gid;
172
}
173
}
174
toomany:
175
endgrent();
176
return (ngroups);
177
}
178
179
/*
180
* Convert network-name to hostname
181
*/
182
int
183
netname2host(char netname[MAXNETNAMELEN + 1], char *hostname, int hostlen)
184
{
185
int err;
186
char valbuf[1024];
187
char *val;
188
char *val2;
189
int vallen;
190
char *domain;
191
192
if (getnetid(netname, valbuf)) {
193
val = valbuf;
194
if ((*val == '0') && (val[1] == ':')) {
195
(void) strncpy(hostname, val + 2, hostlen);
196
return (1);
197
}
198
}
199
val = strchr(netname, '.');
200
if (val == NULL)
201
return (0);
202
if (strncmp(netname, OPSYS, (val - netname)))
203
return (0);
204
val++;
205
val2 = strchr(val, '@');
206
if (val2 == NULL)
207
return (0);
208
vallen = val2 - val;
209
if (vallen > (hostlen - 1))
210
vallen = hostlen - 1;
211
(void) strncpy(hostname, val, vallen);
212
hostname[vallen] = 0;
213
214
err = __rpc_get_default_domain(&domain); /* change to rpc */
215
if (err)
216
return (0);
217
218
if (strcmp(val2 + 1, domain))
219
return (0); /* wrong domain */
220
else
221
return (1);
222
}
223
224
/*
225
* reads the file /etc/netid looking for a + to optionally go to the
226
* network information service.
227
*/
228
int
229
getnetid(char *key, char *ret)
230
{
231
char buf[1024]; /* big enough */
232
char *res;
233
char *mkey;
234
char *mval;
235
FILE *fd;
236
#ifdef YP
237
char *domain;
238
int err;
239
char *lookup;
240
int len;
241
#endif
242
int rv;
243
244
rv = 0;
245
246
fd = fopen(NETIDFILE, "r");
247
if (fd == NULL) {
248
#ifdef YP
249
res = "+";
250
goto getnetidyp;
251
#else
252
return (0);
253
#endif
254
}
255
while (fd != NULL) {
256
res = fgets(buf, sizeof(buf), fd);
257
if (res == NULL) {
258
rv = 0;
259
goto done;
260
}
261
if (res[0] == '#')
262
continue;
263
else if (res[0] == '+') {
264
#ifdef YP
265
getnetidyp:
266
err = yp_get_default_domain(&domain);
267
if (err) {
268
continue;
269
}
270
lookup = NULL;
271
err = yp_match(domain, NETID, key,
272
strlen(key), &lookup, &len);
273
if (err) {
274
#ifdef DEBUG
275
fprintf(stderr, "match failed error %d\n", err);
276
#endif
277
continue;
278
}
279
lookup[len] = 0;
280
strcpy(ret, lookup);
281
free(lookup);
282
rv = 2;
283
goto done;
284
#else /* YP */
285
#ifdef DEBUG
286
fprintf(stderr,
287
"Bad record in %s '+' -- NIS not supported in this library copy\n",
288
NETIDFILE);
289
#endif
290
continue;
291
#endif /* YP */
292
} else {
293
mkey = strsep(&res, "\t ");
294
if (mkey == NULL) {
295
fprintf(stderr,
296
"Bad record in %s -- %s", NETIDFILE, buf);
297
continue;
298
}
299
do {
300
mval = strsep(&res, " \t#\n");
301
} while (mval != NULL && !*mval);
302
if (mval == NULL) {
303
fprintf(stderr,
304
"Bad record in %s val problem - %s", NETIDFILE, buf);
305
continue;
306
}
307
if (strcmp(mkey, key) == 0) {
308
strcpy(ret, mval);
309
rv = 1;
310
goto done;
311
}
312
}
313
}
314
315
done:
316
if (fd != NULL)
317
fclose(fd);
318
return (rv);
319
}
320
321