1/* Copyright (c) 1997-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <stdint.h>
24#include <sys/types.h>
25#include <rpc/rpc.h>
26#include <rpcsvc/nis.h>
27#include <shlib-compat.h>
28
29#define DEFAULT_TTL 43200
30
31/*
32** Some functions for parsing the -D param and NIS_DEFAULTS Environ
33*/
34static nis_name
35searchXYX (char *str, const char *what)
36{
37 assert (strlen (what) == 6);
38 assert (strncmp (str, what, 6) == 0);
39 str += 6; /* Points to the begin of the parameters. */
40
41 int i = 0;
42 while (str[i] != '\0' && str[i] != ':')
43 ++i;
44 if (i == 0) /* only "<WHAT>=" ? */
45 return strdup ("");
46
47 return strndup (str, i);
48}
49
50
51static nis_name
52searchgroup (char *str)
53{
54 return searchXYX (str, "group=");
55}
56
57
58static nis_name
59searchowner (char *str)
60{
61 return searchXYX (str, "owner=");
62}
63
64
65static uint32_t
66searchttl (char *str)
67{
68 char buf[strlen (str) + 1];
69 char *cptr, *dptr;
70 uint32_t time;
71 int i;
72
73 dptr = strstr (str, "ttl=");
74 if (dptr == NULL) /* should (could) not happen */
75 return DEFAULT_TTL;;
76
77 dptr += 4; /* points to the begin of the new ttl */
78 i = 0;
79 while (dptr[i] != '\0' && dptr[i] != ':')
80 i++;
81 if (i == 0) /* only "ttl=" ? */
82 return DEFAULT_TTL;
83
84 strncpy (buf, dptr, i);
85 buf[i] = '\0';
86 time = 0;
87
88 dptr = buf;
89 cptr = strchr (dptr, 'd');
90 if (cptr != NULL)
91 {
92 *cptr = '\0';
93 cptr++;
94 time += atoi (dptr) * 60 * 60 * 24;
95 dptr = cptr;
96 }
97
98 cptr = strchr (dptr, 'h');
99 if (cptr != NULL)
100 {
101 *cptr = '\0';
102 cptr++;
103 time += atoi (dptr) * 60 * 60;
104 dptr = cptr;
105 }
106
107 cptr = strchr (dptr, 'm');
108 if (cptr != NULL)
109 {
110 *cptr = '\0';
111 cptr++;
112 time += atoi (dptr) * 60;
113 dptr = cptr;
114 }
115
116 cptr = strchr (dptr, 's');
117 if (cptr != NULL)
118 *cptr = '\0';
119
120 time += atoi (dptr);
121
122 return time;
123}
124
125static unsigned int
126searchaccess (char *str, unsigned int access)
127{
128 char buf[strlen (str) + 1];
129 char *cptr;
130 unsigned int result = access;
131 int i;
132 int n, o, g, w;
133
134 cptr = strstr (str, "access=");
135 if (cptr == NULL)
136 return 0;
137
138 cptr += 7; /* points to the begin of the access string */
139 i = 0;
140 while (cptr[i] != '\0' && cptr[i] != ':')
141 i++;
142 if (i == 0) /* only "access=" ? */
143 return 0;
144
145 strncpy (buf, cptr, i);
146 buf[i] = '\0';
147
148 n = o = g = w = 0;
149 cptr = buf;
150 if (*cptr == ',') /* Fix for stupid Solaris scripts */
151 ++cptr;
152 while (*cptr != '\0')
153 {
154 switch (*cptr)
155 {
156 case 'n':
157 n = 1;
158 break;
159 case 'o':
160 o = 1;
161 break;
162 case 'g':
163 g = 1;
164 break;
165 case 'w':
166 w = 1;
167 break;
168 case 'a':
169 o = g = w = 1;
170 break;
171 case '-':
172 cptr++; /* Remove "-" from beginning */
173 while (*cptr != '\0' && *cptr != ',')
174 {
175 switch (*cptr)
176 {
177 case 'r':
178 if (n)
179 result = result & ~(NIS_READ_ACC << 24);
180 if (o)
181 result = result & ~(NIS_READ_ACC << 16);
182 if (g)
183 result = result & ~(NIS_READ_ACC << 8);
184 if (w)
185 result = result & ~(NIS_READ_ACC);
186 break;
187 case 'm':
188 if (n)
189 result = result & ~(NIS_MODIFY_ACC << 24);
190 if (o)
191 result = result & ~(NIS_MODIFY_ACC << 16);
192 if (g)
193 result = result & ~(NIS_MODIFY_ACC << 8);
194 if (w)
195 result = result & ~(NIS_MODIFY_ACC);
196 break;
197 case 'c':
198 if (n)
199 result = result & ~(NIS_CREATE_ACC << 24);
200 if (o)
201 result = result & ~(NIS_CREATE_ACC << 16);
202 if (g)
203 result = result & ~(NIS_CREATE_ACC << 8);
204 if (w)
205 result = result & ~(NIS_CREATE_ACC);
206 break;
207 case 'd':
208 if (n)
209 result = result & ~(NIS_DESTROY_ACC << 24);
210 if (o)
211 result = result & ~(NIS_DESTROY_ACC << 16);
212 if (g)
213 result = result & ~(NIS_DESTROY_ACC << 8);
214 if (w)
215 result = result & ~(NIS_DESTROY_ACC);
216 break;
217 default:
218 return (~0U);
219 }
220 cptr++;
221 }
222 n = o = g = w = 0;
223 break;
224 case '+':
225 cptr++; /* Remove "+" from beginning */
226 while (*cptr != '\0' && *cptr != ',')
227 {
228 switch (*cptr)
229 {
230 case 'r':
231 if (n)
232 result = result | (NIS_READ_ACC << 24);
233 if (o)
234 result = result | (NIS_READ_ACC << 16);
235 if (g)
236 result = result | (NIS_READ_ACC << 8);
237 if (w)
238 result = result | (NIS_READ_ACC);
239 break;
240 case 'm':
241 if (n)
242 result = result | (NIS_MODIFY_ACC << 24);
243 if (o)
244 result = result | (NIS_MODIFY_ACC << 16);
245 if (g)
246 result = result | (NIS_MODIFY_ACC << 8);
247 if (w)
248 result = result | (NIS_MODIFY_ACC);
249 break;
250 case 'c':
251 if (n)
252 result = result | (NIS_CREATE_ACC << 24);
253 if (o)
254 result = result | (NIS_CREATE_ACC << 16);
255 if (g)
256 result = result | (NIS_CREATE_ACC << 8);
257 if (w)
258 result = result | (NIS_CREATE_ACC);
259 break;
260 case 'd':
261 if (n)
262 result = result | (NIS_DESTROY_ACC << 24);
263 if (o)
264 result = result | (NIS_DESTROY_ACC << 16);
265 if (g)
266 result = result | (NIS_DESTROY_ACC << 8);
267 if (w)
268 result = result | (NIS_DESTROY_ACC);
269 break;
270 default:
271 return (~0U);
272 }
273 cptr++;
274 }
275 n = o = g = w = 0;
276 break;
277 case '=':
278 cptr++; /* Remove "=" from beginning */
279 /* Clear */
280 if (n)
281 result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC +
282 NIS_CREATE_ACC + NIS_DESTROY_ACC) << 24);
283
284 if (o)
285 result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC +
286 NIS_CREATE_ACC + NIS_DESTROY_ACC) << 16);
287 if (g)
288 result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC +
289 NIS_CREATE_ACC + NIS_DESTROY_ACC) << 8);
290 if (w)
291 result = result & ~(NIS_READ_ACC + NIS_MODIFY_ACC +
292 NIS_CREATE_ACC + NIS_DESTROY_ACC);
293 while (*cptr != '\0' && *cptr != ',')
294 {
295 switch (*cptr)
296 {
297 case 'r':
298 if (n)
299 result = result | (NIS_READ_ACC << 24);
300 if (o)
301 result = result | (NIS_READ_ACC << 16);
302 if (g)
303 result = result | (NIS_READ_ACC << 8);
304 if (w)
305 result = result | (NIS_READ_ACC);
306 break;
307 case 'm':
308 if (n)
309 result = result | (NIS_MODIFY_ACC << 24);
310 if (o)
311 result = result | (NIS_MODIFY_ACC << 16);
312 if (g)
313 result = result | (NIS_MODIFY_ACC << 8);
314 if (w)
315 result = result | (NIS_MODIFY_ACC);
316 break;
317 case 'c':
318 if (n)
319 result = result | (NIS_CREATE_ACC << 24);
320 if (o)
321 result = result | (NIS_CREATE_ACC << 16);
322 if (g)
323 result = result | (NIS_CREATE_ACC << 8);
324 if (w)
325 result = result | (NIS_CREATE_ACC);
326 break;
327 case 'd':
328 if (n)
329 result = result | (NIS_DESTROY_ACC << 24);
330 if (o)
331 result = result | (NIS_DESTROY_ACC << 16);
332 if (g)
333 result = result | (NIS_DESTROY_ACC << 8);
334 if (w)
335 result = result | (NIS_DESTROY_ACC);
336 break;
337 default:
338 return result = (~0U);
339 }
340 cptr++;
341 }
342 n = o = g = w = 0;
343 break;
344 default:
345 return result = (~0U);
346 }
347 if (*cptr != '\0')
348 cptr++;
349 }
350
351 return result;
352}
353
354
355nis_name
356__nis_default_owner (char *defaults)
357{
358 char *default_owner = NULL;
359
360 char *cptr = defaults;
361 if (cptr == NULL)
362 cptr = getenv ("NIS_DEFAULTS");
363
364 if (cptr != NULL)
365 {
366 char *dptr = strstr (cptr, "owner=");
367 if (dptr != NULL)
368 {
369 char *p = searchowner (dptr);
370 if (p == NULL)
371 return NULL;
372 default_owner = strdupa (p);
373 free (p);
374 }
375 }
376
377 return strdup (default_owner ?: nis_local_principal ());
378}
379libnsl_hidden_nolink_def (__nis_default_owner, GLIBC_2_1)
380
381
382nis_name
383__nis_default_group (char *defaults)
384{
385 char *default_group = NULL;
386
387 char *cptr = defaults;
388 if (cptr == NULL)
389 cptr = getenv ("NIS_DEFAULTS");
390
391 if (cptr != NULL)
392 {
393 char *dptr = strstr (cptr, "group=");
394 if (dptr != NULL)
395 {
396 char *p = searchgroup (dptr);
397 if (p == NULL)
398 return NULL;
399 default_group = strdupa (p);
400 free (p);
401 }
402 }
403
404 return strdup (default_group ?: nis_local_group ());
405}
406libnsl_hidden_nolink_def (__nis_default_group, GLIBC_2_1)
407
408
409uint32_t
410__nis_default_ttl (char *defaults)
411{
412 char *cptr, *dptr;
413
414 if (defaults != NULL)
415 {
416 dptr = strstr (defaults, "ttl=");
417 if (dptr != NULL)
418 return searchttl (defaults);
419 }
420
421 cptr = getenv ("NIS_DEFAULTS");
422 if (cptr == NULL)
423 return DEFAULT_TTL;
424
425 dptr = strstr (cptr, "ttl=");
426 if (dptr == NULL)
427 return DEFAULT_TTL;
428
429 return searchttl (cptr);
430}
431libnsl_hidden_nolink_def (__nis_default_ttl, GLIBC_2_1)
432
433/* Default access rights are ----rmcdr---r---, but we could change
434 this with the NIS_DEFAULTS variable. */
435unsigned int
436__nis_default_access (char *param, unsigned int defaults)
437{
438 unsigned int result;
439 char *cptr;
440
441 if (defaults == 0)
442 result = 0 | OWNER_DEFAULT | GROUP_DEFAULT | WORLD_DEFAULT;
443 else
444 result = defaults;
445
446 if (param != NULL && strstr (param, "access=") != NULL)
447 result = searchaccess (param, result);
448 else
449 {
450 cptr = getenv ("NIS_DEFAULTS");
451 if (cptr != NULL && strstr (cptr, "access=") != NULL)
452 result = searchaccess (cptr, result);
453 }
454
455 return result;
456}
457libnsl_hidden_nolink_def (__nis_default_access, GLIBC_2_1)
458