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