Back to index

glibc  2.9
nisplus-netgrp.c
Go to the documentation of this file.
00001 /* Copyright (C) 1997, 2003, 2004, 2005, 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>, 1997.
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 <errno.h>
00022 #include <ctype.h>
00023 #include <netdb.h>
00024 #include <string.h>
00025 #include <netgroup.h>
00026 #include <rpcsvc/nis.h>
00027 
00028 #include "nss-nisplus.h"
00029 
00030 #define NISENTRYVAL(idx, col, res) \
00031         (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
00032 
00033 #define NISENTRYLEN(idx, col, res) \
00034         (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
00035 
00036 enum nss_status
00037 _nss_nisplus_getnetgrent_r (struct __netgrent *result, char *buffer,
00038                          size_t buflen, int *errnop)
00039 {
00040   enum nss_status status;
00041 
00042   /* Some sanity checks.  */
00043   if (result->data == NULL || result->data_size == 0)
00044     return NSS_STATUS_NOTFOUND;
00045 
00046   if (result->position == result->data_size)
00047     return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
00048 
00049   unsigned int entrylen
00050     = NISENTRYLEN (result->position, 1, (nis_result *) result->data);
00051   if (entrylen > 0)
00052     {
00053       /* We have a list of other netgroups.  */
00054 
00055       result->type = group_val;
00056       if (entrylen >= buflen)
00057        {
00058          *errnop = ERANGE;
00059          return NSS_STATUS_TRYAGAIN;
00060        }
00061       strncpy (buffer, NISENTRYVAL (result->position, 1,
00062                                 (nis_result *) result->data),
00063               entrylen);
00064       buffer[entrylen] = '\0';
00065       result->val.group = buffer;
00066       ++result->position;
00067       result->first = 0;
00068 
00069       return NSS_STATUS_SUCCESS;
00070     }
00071 
00072   /* Before we can copy the entry to the private buffer we have to make
00073      sure it is big enough.  */
00074   unsigned int hostlen
00075     = NISENTRYLEN (result->position, 2, (nis_result *) result->data);
00076   unsigned int userlen
00077     = NISENTRYLEN (result->position, 3, (nis_result *) result->data);
00078   unsigned int domainlen
00079     = NISENTRYLEN (result->position, 4, (nis_result *) result->data);
00080   if (hostlen + userlen + domainlen + 6 > buflen)
00081     {
00082       *errnop = ERANGE;
00083       status = NSS_STATUS_TRYAGAIN;
00084     }
00085   else
00086     {
00087       char *cp = buffer;
00088 
00089       result->type = triple_val;
00090 
00091       if (hostlen == 0 ||
00092          NISENTRYVAL (result->position, 2,
00093                      (nis_result *) result->data)[0] == '\0')
00094        result->val.triple.host = NULL;
00095       else
00096        {
00097          result->val.triple.host = cp;
00098          cp = __stpncpy (cp, NISENTRYVAL (result->position, 2,
00099                                       (nis_result *) result->data),
00100                        hostlen);
00101          *cp++ = '\0';
00102        }
00103 
00104       if (userlen == 0 ||
00105          NISENTRYVAL (result->position, 3,
00106                      (nis_result *) result->data)[0] == '\0')
00107        result->val.triple.user = NULL;
00108       else
00109        {
00110          result->val.triple.user = cp;
00111          cp = __stpncpy (cp, NISENTRYVAL (result->position, 3,
00112                                       (nis_result *) result->data),
00113                        userlen);
00114          *cp++ = '\0';
00115        }
00116 
00117       if (domainlen == 0 ||
00118          NISENTRYVAL (result->position, 4,
00119                      (nis_result *) result->data)[0] == '\0')
00120        result->val.triple.domain = NULL;
00121       else
00122        {
00123          result->val.triple.domain = cp;
00124          cp = __stpncpy (cp, NISENTRYVAL (result->position, 4,
00125                                       (nis_result *) result->data),
00126                        domainlen);
00127          *cp = '\0';
00128        }
00129 
00130       status = NSS_STATUS_SUCCESS;
00131 
00132       /* Remember where we stopped reading.  */
00133       ++result->position;
00134 
00135       result->first = 0;
00136     }
00137 
00138   return status;
00139 }
00140 
00141 static void
00142 internal_endnetgrent (struct __netgrent *netgrp)
00143 {
00144   nis_freeresult ((nis_result *) netgrp->data);
00145   netgrp->data = NULL;
00146   netgrp->data_size = 0;
00147   netgrp->position = 0;
00148 }
00149 
00150 enum nss_status
00151 _nss_nisplus_setnetgrent (const char *group, struct __netgrent *netgrp)
00152 {
00153   char buf[strlen (group) + 25];
00154 
00155   if (group == NULL || group[0] == '\0')
00156     return NSS_STATUS_UNAVAIL;
00157 
00158   enum nss_status status = NSS_STATUS_SUCCESS;
00159 
00160   snprintf (buf, sizeof (buf), "[name=%s],netgroup.org_dir", group);
00161 
00162   netgrp->data = (char *) nis_list (buf, EXPAND_NAME, NULL, NULL);
00163 
00164   if (netgrp->data == NULL)
00165     {
00166       __set_errno (ENOMEM);
00167       status = NSS_STATUS_TRYAGAIN;
00168     }
00169   else if (niserr2nss (((nis_result *) netgrp->data)->status)
00170           != NSS_STATUS_SUCCESS)
00171     {
00172       status = niserr2nss (((nis_result *) netgrp->data)->status);
00173 
00174       internal_endnetgrent (netgrp);
00175     }
00176   else
00177     {
00178       netgrp->data_size = ((nis_result *) netgrp->data)->objects.objects_len;
00179       netgrp->position = 0;
00180       netgrp->first = 1;
00181     }
00182 
00183   return status;
00184 }
00185 
00186 enum nss_status
00187 _nss_nisplus_endnetgrent (struct __netgrent *netgrp)
00188 {
00189   internal_endnetgrent (netgrp);
00190 
00191   return NSS_STATUS_SUCCESS;
00192 }