Back to index

glibc  2.9
nisplus-spwd.c
Go to the documentation of this file.
00001 /* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2007
00002    Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <nss.h>
00022 #include <errno.h>
00023 #include <shadow.h>
00024 #include <string.h>
00025 #include <bits/libc-lock.h>
00026 #include <rpcsvc/nis.h>
00027 
00028 #include "nss-nisplus.h"
00029 #include "nisplus-parser.h"
00030 
00031 __libc_lock_define_initialized (static, lock)
00032 
00033 static nis_result *result;
00034 
00035 /* Defined in nisplus-pwd.c.  */
00036 extern nis_name pwd_tablename_val attribute_hidden;
00037 extern size_t pwd_tablename_len attribute_hidden;
00038 extern enum nss_status _nss_pwd_create_tablename (int *errnop);
00039 
00040 
00041 enum nss_status
00042 _nss_nisplus_setspent (int stayopen)
00043 {
00044   enum nss_status status = NSS_STATUS_SUCCESS;
00045   int err;
00046 
00047   __libc_lock_lock (lock);
00048 
00049   if (result != NULL)
00050     {
00051       nis_freeresult (result);
00052       result = NULL;
00053     }
00054 
00055   if (pwd_tablename_val == NULL)
00056     status = _nss_pwd_create_tablename (&err);
00057 
00058   __libc_lock_unlock (lock);
00059 
00060   return NSS_STATUS_SUCCESS;
00061 }
00062 
00063 enum nss_status
00064 _nss_nisplus_endspent (void)
00065 {
00066   __libc_lock_lock (lock);
00067 
00068   if (result != NULL)
00069     {
00070       nis_freeresult (result);
00071       result = NULL;
00072     }
00073 
00074   __libc_lock_unlock (lock);
00075 
00076   return NSS_STATUS_SUCCESS;
00077 }
00078 
00079 static enum nss_status
00080 internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
00081                           int *errnop)
00082 {
00083   int parse_res;
00084 
00085   /* Get the next entry until we found a correct one. */
00086   do
00087     {
00088       nis_result *saved_res;
00089 
00090       if (result == NULL)
00091        {
00092          saved_res = NULL;
00093 
00094           if (pwd_tablename_val == NULL)
00095            {
00096              enum nss_status status = _nss_pwd_create_tablename (errnop);
00097 
00098              if (status != NSS_STATUS_SUCCESS)
00099               return status;
00100            }
00101 
00102          result = nis_first_entry (pwd_tablename_val);
00103          if (result == NULL)
00104            {
00105              *errnop = errno;
00106              return NSS_STATUS_TRYAGAIN;
00107            }
00108          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
00109            return niserr2nss (result->status);
00110        }
00111       else
00112        {
00113          saved_res = result;
00114          result = nis_next_entry (pwd_tablename_val, &result->cookie);
00115          if (result == NULL)
00116            {
00117              *errnop = errno;
00118              return NSS_STATUS_TRYAGAIN;
00119            }
00120          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
00121            {
00122              nis_freeresult (saved_res);
00123              return niserr2nss (result->status);
00124            }
00125        }
00126 
00127       parse_res = _nss_nisplus_parse_spent (result, sp, buffer,
00128                                        buflen, errnop);
00129       if (__builtin_expect (parse_res == -1, 0))
00130        {
00131          nis_freeresult (result);
00132          result = saved_res;
00133          *errnop = ERANGE;
00134          return NSS_STATUS_TRYAGAIN;
00135        }
00136 
00137       if (saved_res != NULL)
00138        nis_freeresult (saved_res);
00139     }
00140   while (!parse_res);
00141 
00142   return NSS_STATUS_SUCCESS;
00143 }
00144 
00145 enum nss_status
00146 _nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen,
00147                       int *errnop)
00148 {
00149   int status;
00150 
00151   __libc_lock_lock (lock);
00152 
00153   status = internal_nisplus_getspent_r (result, buffer, buflen, errnop);
00154 
00155   __libc_lock_unlock (lock);
00156 
00157   return status;
00158 }
00159 
00160 enum nss_status
00161 _nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
00162                    char *buffer, size_t buflen, int *errnop)
00163 {
00164   int parse_res;
00165 
00166   if (pwd_tablename_val == NULL)
00167     {
00168       enum nss_status status = _nss_pwd_create_tablename (errnop);
00169 
00170       if (status != NSS_STATUS_SUCCESS)
00171        return status;
00172     }
00173 
00174   if (name == NULL)
00175     {
00176       *errnop = EINVAL;
00177       return NSS_STATUS_NOTFOUND;
00178     }
00179 
00180   nis_result *result;
00181   char buf[strlen (name) + 9 + pwd_tablename_len];
00182   int olderr = errno;
00183 
00184   snprintf (buf, sizeof (buf), "[name=%s],%s", name, pwd_tablename_val);
00185 
00186   result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL);
00187 
00188   if (result == NULL)
00189     {
00190       *errnop = ENOMEM;
00191       return NSS_STATUS_TRYAGAIN;
00192     }
00193 
00194   if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
00195     {
00196       enum nss_status status = niserr2nss (result->status);
00197 
00198       __set_errno (olderr);
00199 
00200       nis_freeresult (result);
00201       return status;
00202     }
00203 
00204   parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen, errnop);
00205   nis_freeresult (result);
00206 
00207   if (__builtin_expect (parse_res < 1, 0))
00208     {
00209       if (parse_res == -1)
00210        {
00211          *errnop = ERANGE;
00212          return NSS_STATUS_TRYAGAIN;
00213        }
00214       else
00215        {
00216          __set_errno (olderr);
00217          return NSS_STATUS_NOTFOUND;
00218        }
00219     }
00220 
00221   return NSS_STATUS_SUCCESS;
00222 }