/* Copyright (c) 1997-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <sys/types.h> #include <rpc/rpc.h> #include <rpcsvc/nis.h> #define DEFAULT_TTL 43200 /* ** Some functions for parsing the -D param and NIS_DEFAULTS Environ */ static nis_name searchXYX (char *str, const char *what) { assert (strlen (what) == 6); assert (strncmp (str, what, 6) == 0); str += 6; /* Points to the begin of the parameters. */ int i = 0; while (str[i] != '\0' && str[i] != ':') ++i; if (i == 0) /* only "<WHAT>=" ? */ return strdup (""); return strndup (str, i); } static nis_name searchgroup (char *str) { return searchXYX (str, "group="); } static nis_name searchowner (char *str) { return searchXYX (str, "owner="); } static uint32_t searchttl (char *str) { char buf[strlen (str) + 1]; char *cptr, *dptr; uint32_t time; int i; dptr = strstr (str, "ttl="); if (dptr == NULL) /* should (could) not happen */ return DEFAULT_TTL;; dptr += 4; /* points to the begin of the new ttl */ i = 0; while (dptr[i] != '\0' && dptr[i] != ':') i++; if (i == 0) /* only "ttl=" ? */ return DEFAULT_TTL; strncpy (buf, dptr, i); buf[i] = '\0'; time = 0; dptr = buf; cptr = strchr (dptr, 'd'); if (cptr != NULL) { *cptr = '\0'; cptr++; time += atoi (dptr) * 60 * 60 * 24; dptr = cptr; } cptr = strchr (dptr, 'h'); if (cptr != NULL) { *cptr = '\0'; cptr++; time += atoi (dptr) * 60 * 60; dptr = cptr; } cptr = strchr (dptr, 'm'); if (cptr != NULL) { *cptr = '\0'; cptr++; time += atoi (dptr) * 60; dptr = cptr; } cptr = strchr (dptr, 's'); if (cptr != NULL) *cptr = '\0'; time += atoi (dptr); return time; } static unsigned int searchaccess (char *str, unsigned int access) { char buf[strlen (str) + 1]; char *cptr; unsigned int result = access; int i; int n, o, g, w; cptr = strstr (str, "access="); if (cptr == NULL) return 0; cptr += 7; /* points to the begin of the access string */ i = 0; while (cptr[i] != '\0' && cptr[i] != ':') i++; if (i == 0) /* only "access=" ? */ return 0; strncpy (buf, cptr, i); buf[i] = '\0'; n = o = g = w = 0; cptr = buf; if (*cptr == ',') /* Fix for stupid Solaris scripts */ ++cptr; while (*cptr != '\0') { switch (*cptr) { case 'n': n = 1; break; case 'o': o = 1; break; case 'g': g = 1; break; case 'w': w = 1; break; case 'a': o = g = w = 1; break; case '-': cptr++; /* Remove "-" from beginning */ while (*cptr != '\0' && *cptr != ',') { switch (*cptr) { case 'r': if (n) result = result & ~(NIS_READ_ACC << 24); if (o) result = result & ~(NIS_READ_ACC << 16); if (g) result = result & ~(NIS_READ_ACC << 8); if (w) result = result & ~(NIS_READ_ACC); break; case 'm': if (n) result = result & ~(NIS_MODIFY_ACC << 24); if (o) result = result & ~(NIS_MODIFY_ACC << 16); if (g) result = result & ~(NIS_MODIFY_ACC << 8); if (w) result = result & ~(NIS_MODIFY_ACC); break; case 'c': if (n) result = result & ~(NIS_CREATE_ACC << 24); if (o) result = result & ~(NIS_CREATE_ACC << 16); if (g) result = result & ~(NIS_CREATE_ACC << 8); if (w) result = result & ~(NIS_CREATE_ACC); break; case 'd': if (n) result = result & ~(NIS_DESTROY_ACC << 24); if (o) result = result & ~(NIS_DESTROY_ACC << 16); if (g) result = result & ~(NIS_DESTROY_ACC << 8); if (w) result = result & ~(NIS_DESTROY_ACC); break; default: return (~0U); } cptr++; } n = o = g = w = 0; break; case '+': cptr++; /* Remove "+" from beginning */ while (*cptr != '\0' && *cptr != ',') { switch (*cptr) { case 'r': if (n) result = result | (NIS_READ_ACC << 24); if (o) result = result | (NIS_READ_ACC << 16); if (g) result = result | (NIS_READ_ACC << 8); if (w) result = result | (NIS_READ_ACC); break; case 'm': if (n) result = result | (NIS_MODIFY_ACC << 24); if (o) result = result | (NIS_MODIFY_ACC << 16); if (g) result = result | (NIS_MODIFY_ACC << 8); if (w) result = result | (NIS_MODIFY_ACC); break; case 'c': if (n) result = result | (NIS_CREATE_ACC << 24); if (o) result = result | (NIS_CREATE_ACC << 16); if (g) result = result | (NIS_CREATE_ACC << 8); if (w) result = result | (NIS_CREATE_ACC); break; case 'd': if (n) result = result | (NIS_DESTROY_ACC << 24); if (o) result = result | (NIS_DESTROY_ACC << 16); if (g) result = result | (NIS_DESTROY_ACC << 8); if (w) result = result | (NIS_DESTROY_ACC); break; default: return (~0U); } cptr++; } n = o = g = w = 0; break; case '=': cptr++; /* Remove "=" from beginning */ /* Clear */ if (n) result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC + NIS_DESTROY_ACC) << 24); if (o) result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC + NIS_DESTROY_ACC) << 16); if (g) result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC + NIS_DESTROY_ACC) << 8); if (w) result = result & ~(NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC + NIS_DESTROY_ACC); while (*cptr != '\0' && *cptr != ',') { switch (*cptr) { case 'r': if (n) result = result | (NIS_READ_ACC << 24); if (o) result = result | (NIS_READ_ACC << 16); if (g) result = result | (NIS_READ_ACC << 8); if (w) result = result | (NIS_READ_ACC); break; case 'm': if (n) result = result | (NIS_MODIFY_ACC << 24); if (o) result = result | (NIS_MODIFY_ACC << 16); if (g) result = result | (NIS_MODIFY_ACC << 8); if (w) result = result | (NIS_MODIFY_ACC); break; case 'c': if (n) result = result | (NIS_CREATE_ACC << 24); if (o) result = result | (NIS_CREATE_ACC << 16); if (g) result = result | (NIS_CREATE_ACC << 8); if (w) result = result | (NIS_CREATE_ACC); break; case 'd': if (n) result = result | (NIS_DESTROY_ACC << 24); if (o) result = result | (NIS_DESTROY_ACC << 16); if (g) result = result | (NIS_DESTROY_ACC << 8); if (w) result = result | (NIS_DESTROY_ACC); break; default: return result = (~0U); } cptr++; } n = o = g = w = 0; break; default: return result = (~0U); } if (*cptr != '\0') cptr++; } return result; } nis_name __nis_default_owner (char *defaults) { char *default_owner = NULL; char *cptr = defaults; if (cptr == NULL) cptr = getenv ("NIS_DEFAULTS"); if (cptr != NULL) { char *dptr = strstr (cptr, "owner="); if (dptr != NULL) { char *p = searchowner (dptr); if (p == NULL) return NULL; default_owner = strdupa (p); free (p); } } return strdup (default_owner ?: nis_local_principal ()); } libnsl_hidden_def (__nis_default_owner) nis_name __nis_default_group (char *defaults) { char *default_group = NULL; char *cptr = defaults; if (cptr == NULL) cptr = getenv ("NIS_DEFAULTS"); if (cptr != NULL) { char *dptr = strstr (cptr, "group="); if (dptr != NULL) { char *p = searchgroup (dptr); if (p == NULL) return NULL; default_group = strdupa (p); free (p); } } return strdup (default_group ?: nis_local_group ()); } libnsl_hidden_def (__nis_default_group) uint32_t __nis_default_ttl (char *defaults) { char *cptr, *dptr; if (defaults != NULL) { dptr = strstr (defaults, "ttl="); if (dptr != NULL) return searchttl (defaults); } cptr = getenv ("NIS_DEFAULTS"); if (cptr == NULL) return DEFAULT_TTL; dptr = strstr (cptr, "ttl="); if (dptr == NULL) return DEFAULT_TTL; return searchttl (cptr); } /* Default access rights are ----rmcdr---r---, but we could change this with the NIS_DEFAULTS variable. */ unsigned int __nis_default_access (char *param, unsigned int defaults) { unsigned int result; char *cptr; if (defaults == 0) result = 0 | OWNER_DEFAULT | GROUP_DEFAULT | WORLD_DEFAULT; else result = defaults; if (param != NULL && strstr (param, "access=") != NULL) result = searchaccess (param, result); else { cptr = getenv ("NIS_DEFAULTS"); if (cptr != NULL && strstr (cptr, "access=") != NULL) result = searchaccess (cptr, result); } return result; } libnsl_hidden_def (__nis_default_access)