Back to index

glibc  2.9
nis-spwd.c
Go to the documentation of this file.
00001 /* Copyright (C) 1996-1998,2001,2002,2003,2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <nss.h>
00021 #include <ctype.h>
00022 #include <errno.h>
00023 #include <string.h>
00024 /* The following is an ugly trick to avoid a prototype declaration for
00025    _nss_nis_endspent.  */
00026 #define _nss_nis_endspent _nss_nis_endspent_XXX
00027 #include <shadow.h>
00028 #undef _nss_nis_endspent
00029 #include <bits/libc-lock.h>
00030 #include <rpcsvc/yp.h>
00031 #include <rpcsvc/ypclnt.h>
00032 
00033 #include "nss-nis.h"
00034 
00035 /* Get the declaration of the parser function.  */
00036 #define ENTNAME spent
00037 #define STRUCTURE spwd
00038 #define EXTERN_PARSER
00039 #include <nss/nss_files/files-parse.c>
00040 
00041 /* Protect global state against multiple changers */
00042 __libc_lock_define_initialized (static, lock)
00043 
00044 static bool_t new_start = 1;
00045 static char *oldkey;
00046 static int oldkeylen;
00047 
00048 enum nss_status
00049 _nss_nis_setspent (int stayopen)
00050 {
00051   __libc_lock_lock (lock);
00052 
00053   new_start = 1;
00054   free (oldkey);
00055   oldkey = NULL;
00056   oldkeylen = 0;
00057 
00058   __libc_lock_unlock (lock);
00059 
00060   return NSS_STATUS_SUCCESS;
00061 }
00062 /* Make _nss_nis_endspent an alias of _nss_nis_setspent.  We do this
00063    even though the prototypes don't match.  The argument of setspent
00064    is not used so this makes no difference.  */
00065 strong_alias (_nss_nis_setspent, _nss_nis_endspent)
00066 
00067 static enum nss_status
00068 internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
00069                       int *errnop)
00070 {
00071   char *domain;
00072   if (__builtin_expect (yp_get_default_domain (&domain), 0))
00073     return NSS_STATUS_UNAVAIL;
00074 
00075   /* Get the next entry until we found a correct one. */
00076   int parse_res;
00077   do
00078     {
00079       char *result;
00080       char *outkey;
00081       int len;
00082       int keylen;
00083       int yperr;
00084 
00085       if (new_start)
00086         yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
00087                        &len);
00088       else
00089         yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
00090                       &keylen, &result, &len);
00091 
00092       if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
00093         {
00094          enum nss_status retval = yperr2nss (yperr);
00095 
00096          if (retval == NSS_STATUS_TRYAGAIN)
00097            *errnop = errno;
00098           return retval;
00099         }
00100 
00101       if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
00102         {
00103           free (result);
00104          *errnop = ERANGE;
00105           return NSS_STATUS_TRYAGAIN;
00106         }
00107 
00108       char *p = strncpy (buffer, result, len);
00109       buffer[len] = '\0';
00110       while (isspace (*p))
00111         ++p;
00112       free (result);
00113 
00114       parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen,
00115                                      errnop);
00116       if (__builtin_expect  (parse_res == -1, 0))
00117        {
00118          free (outkey);
00119          *errnop = ERANGE;
00120          return NSS_STATUS_TRYAGAIN;
00121        }
00122 
00123       free (oldkey);
00124       oldkey = outkey;
00125       oldkeylen = keylen;
00126       new_start = 0;
00127     }
00128   while (!parse_res);
00129 
00130   return NSS_STATUS_SUCCESS;
00131 }
00132 
00133 enum nss_status
00134 _nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen,
00135                    int *errnop)
00136 {
00137   int status;
00138 
00139   __libc_lock_lock (lock);
00140 
00141   status = internal_nis_getspent_r (result, buffer, buflen, errnop);
00142 
00143   __libc_lock_unlock (lock);
00144 
00145   return status;
00146 }
00147 
00148 enum nss_status
00149 _nss_nis_getspnam_r (const char *name, struct spwd *sp,
00150                    char *buffer, size_t buflen, int *errnop)
00151 {
00152   if (name == NULL)
00153     {
00154       *errnop = EINVAL;
00155       return NSS_STATUS_UNAVAIL;
00156     }
00157 
00158   char *domain;
00159   if (__builtin_expect (yp_get_default_domain (&domain), 0))
00160     return NSS_STATUS_UNAVAIL;
00161 
00162   char *result;
00163   int len;
00164   int yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
00165                      &len);
00166 
00167   if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
00168     {
00169       enum nss_status retval = yperr2nss (yperr);
00170 
00171       if (retval == NSS_STATUS_TRYAGAIN)
00172        *errnop = errno;
00173       return retval;
00174     }
00175 
00176   if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
00177     {
00178       free (result);
00179       *errnop = ERANGE;
00180       return NSS_STATUS_TRYAGAIN;
00181     }
00182 
00183   char *p = strncpy (buffer, result, len);
00184   buffer[len] = '\0';
00185   while (isspace (*p))
00186     ++p;
00187   free (result);
00188 
00189   int parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen,
00190                                      errnop);
00191   if (__builtin_expect (parse_res < 1, 0))
00192     {
00193       if (parse_res == -1)
00194        return NSS_STATUS_TRYAGAIN;
00195       else
00196        return NSS_STATUS_NOTFOUND;
00197     }
00198   return NSS_STATUS_SUCCESS;
00199 }