Back to index

glibc  2.9
nisplus-parser.c
Go to the documentation of this file.
00001 /* Copyright (C) 1997, 1999, 2004, 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 <pwd.h>
00021 #include <ctype.h>
00022 #include <errno.h>
00023 #include <string.h>
00024 #include <rpcsvc/nis.h>
00025 
00026 #include "nisplus-parser.h"
00027 
00028 #define NISENTRYVAL(idx, col, res) \
00029         (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
00030 
00031 #define NISENTRYLEN(idx, col, res) \
00032         (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
00033 
00034 #define NISOBJVAL(col, obj) \
00035   ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
00036 
00037 #define NISOBJLEN(col, obj) \
00038   ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
00039 
00040 
00041 int
00042 _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
00043                        char *buffer, size_t buflen, int *errnop)
00044 {
00045   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
00046       || NIS_RES_NUMOBJ (result) != 1
00047       || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
00048       || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0
00049       || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7)
00050     return 0;
00051 
00052   nis_object *obj = NIS_RES_OBJECT (result);
00053   char *first_unused = buffer;
00054   size_t room_left = buflen;
00055   size_t len;
00056 
00057   if (NISOBJLEN (0, obj) >= room_left)
00058     {
00059       /* The line is too long for our buffer.  */
00060     no_more_room:
00061       *errnop = ERANGE;
00062       return -1;
00063     }
00064 
00065   strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
00066   first_unused[NISOBJLEN (0, obj)] = '\0';
00067   len = strlen (first_unused);
00068   if (len == 0) /* No name ? Should never happen, database is corrupt */
00069     return 0;
00070   pw->pw_name = first_unused;
00071   room_left -= len + 1;
00072   first_unused += len + 1;
00073 
00074   if (NISOBJLEN (1, obj) >= room_left)
00075     goto no_more_room;
00076 
00077   strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
00078   first_unused[NISOBJLEN (1, obj)] = '\0';
00079   pw->pw_passwd = first_unused;
00080   len = strlen (first_unused);
00081   room_left -= len + 1;
00082   first_unused += len + 1;
00083 
00084   char *numstr = NISOBJVAL (2, obj);
00085   len = NISOBJLEN (2, obj);
00086   if (len == 0 && numstr[len - 1] != '\0')
00087     {
00088       if (len >= room_left)
00089        goto no_more_room;
00090 
00091       strncpy (first_unused, numstr, len);
00092       first_unused[len] = '\0';
00093       numstr = first_unused;
00094     }
00095   if (numstr[0] == '\0')
00096     /* If we don't have a uid, it's an invalid shadow entry.  */
00097     return 0;
00098   pw->pw_uid = strtoul (numstr, NULL, 10);
00099 
00100   numstr = NISOBJVAL (3, obj);
00101   len = NISOBJLEN (3, obj);
00102   if (len == 0 && numstr[len - 1] != '\0')
00103     {
00104       if (len >= room_left)
00105        goto no_more_room;
00106 
00107       strncpy (first_unused, numstr, len);
00108       first_unused[len] = '\0';
00109       numstr = first_unused;
00110     }
00111   if (numstr[0] == '\0')
00112     /* If we don't have a gid, it's an invalid shadow entry.  */
00113     return 0;
00114   pw->pw_gid = strtoul (numstr, NULL, 10);
00115 
00116   if (NISOBJLEN(4, obj) >= room_left)
00117     goto no_more_room;
00118 
00119   strncpy (first_unused, NISOBJVAL (4, obj), NISOBJLEN (4, obj));
00120   first_unused[NISOBJLEN (4, obj)] = '\0';
00121   pw->pw_gecos = first_unused;
00122   len = strlen (first_unused);
00123   room_left -= len + 1;
00124   first_unused += len + 1;
00125 
00126   if (NISOBJLEN (5, obj) >= room_left)
00127     goto no_more_room;
00128 
00129   strncpy (first_unused, NISOBJVAL (5, obj), NISOBJLEN (5, obj));
00130   first_unused[NISOBJLEN (5, obj)] = '\0';
00131   pw->pw_dir = first_unused;
00132   len = strlen (first_unused);
00133   room_left -= len + 1;
00134   first_unused += len + 1;
00135 
00136   if (NISOBJLEN (6, obj) >= room_left)
00137     goto no_more_room;
00138 
00139   strncpy (first_unused, NISOBJVAL (6, obj), NISOBJLEN (6, obj));
00140   first_unused[NISOBJLEN (6, obj)] = '\0';
00141   pw->pw_shell = first_unused;
00142   len = strlen (first_unused);
00143   room_left -= len + 1;
00144   first_unused += len + 1;
00145 
00146   return 1;
00147 }
00148 
00149 
00150 int
00151 _nss_nisplus_parse_grent (nis_result *result, struct group *gr,
00152                        char *buffer, size_t buflen, int *errnop)
00153 {
00154   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
00155       || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
00156       || strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "group_tbl") != 0
00157       || NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4)
00158     return 0;
00159 
00160   nis_object *obj = NIS_RES_OBJECT (result);
00161   char *first_unused = buffer;
00162   size_t room_left = buflen;
00163   char *line;
00164   int count;
00165   size_t len;
00166 
00167   if (NISOBJLEN (0, obj) >= room_left)
00168     {
00169       /* The line is too long for our buffer.  */
00170     no_more_room:
00171       *errnop = ERANGE;
00172       return -1;
00173     }
00174 
00175   strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
00176   first_unused[NISOBJLEN (0, obj)] = '\0';
00177   len = strlen (first_unused);
00178   if (len == 0) /* group table is corrupt */
00179     return 0;
00180   gr->gr_name = first_unused;
00181   room_left -= len + 1;
00182   first_unused += len + 1;
00183 
00184   if (NISOBJLEN (1, obj) >= room_left)
00185     goto no_more_room;
00186 
00187   strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
00188   first_unused[NISOBJLEN (1, obj)] = '\0';
00189   gr->gr_passwd = first_unused;
00190   len = strlen (first_unused);
00191   room_left -= len + 1;
00192   first_unused += len + 1;
00193 
00194   char *numstr = NISOBJVAL (2, obj);
00195   len = NISOBJLEN (2, obj);
00196   if (len == 0 || numstr[len - 1] != '\0')
00197     {
00198       if (len >= room_left)
00199        goto no_more_room;
00200 
00201       strncpy (first_unused, numstr, len);
00202       first_unused[len] = '\0';
00203       numstr = first_unused;
00204     }
00205   if (numstr[0] == '\0')
00206     /* We should always have a gid.  */
00207     return 0;
00208   gr->gr_gid = strtoul (numstr, NULL, 10);
00209 
00210   if (NISOBJLEN (3, obj) >= room_left)
00211     goto no_more_room;
00212 
00213   strncpy (first_unused, NISOBJVAL (3, obj), NISOBJLEN (3, obj));
00214   first_unused[NISOBJLEN (3, obj)] = '\0';
00215   line = first_unused;
00216   len = strlen (line);
00217   room_left -= len + 1;
00218   first_unused += len + 1;
00219   /* Adjust the pointer so it is aligned for
00220      storing pointers.  */
00221   size_t adjust = ((__alignof__ (char *)
00222                   - (first_unused - (char *) 0) % __alignof__ (char *))
00223                  % __alignof__ (char *));
00224   if (room_left < adjust)
00225     goto no_more_room;
00226   first_unused += adjust;
00227   room_left -= adjust;
00228   gr->gr_mem = (char **) first_unused;
00229 
00230   count = 0;
00231   while (*line != '\0')
00232     {
00233       /* Skip leading blanks.  */
00234       while (isspace (*line))
00235        ++line;
00236 
00237       if (*line == '\0')
00238        break;
00239 
00240       if (room_left < sizeof (char *))
00241        goto no_more_room;
00242       room_left -= sizeof (char *);
00243       gr->gr_mem[count++] = line;
00244 
00245       while (*line != '\0' && *line != ',' && !isspace (*line))
00246        ++line;
00247 
00248       if (*line == ',' || isspace (*line))
00249        {
00250          int is = isspace (*line);
00251 
00252          *line++ = '\0';
00253          if (is)
00254            while (*line != '\0' && (*line == ',' || isspace (*line)))
00255              ++line;
00256        }
00257     }
00258   if (room_left < sizeof (char *))
00259     goto no_more_room;
00260   room_left -= sizeof (char *);
00261   gr->gr_mem[count] = NULL;
00262 
00263   return 1;
00264 }
00265 
00266 
00267 int
00268 _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
00269                        char *buffer, size_t buflen, int *errnop)
00270 {
00271   char *first_unused = buffer;
00272   size_t room_left = buflen;
00273   size_t len;
00274 
00275   if (result == NULL)
00276     return 0;
00277 
00278   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
00279       || NIS_RES_NUMOBJ (result) != 1
00280       || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
00281       || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0
00282       || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 8)
00283     return 0;
00284 
00285   if (NISENTRYLEN (0, 0, result) >= room_left)
00286     {
00287       /* The line is too long for our buffer.  */
00288     no_more_room:
00289       *errnop = ERANGE;
00290       return -1;
00291     }
00292 
00293   strncpy (first_unused, NISENTRYVAL (0, 0, result),
00294           NISENTRYLEN (0, 0, result));
00295   first_unused[NISENTRYLEN (0, 0, result)] = '\0';
00296   len = strlen (first_unused);
00297   if (len == 0)
00298     return 0;
00299   sp->sp_namp = first_unused;
00300   room_left -= len + 1;
00301   first_unused += len + 1;
00302 
00303   if (NISENTRYLEN (0, 1, result) >= room_left)
00304     goto no_more_room;
00305 
00306   strncpy (first_unused, NISENTRYVAL (0, 1, result),
00307           NISENTRYLEN (0, 1, result));
00308   first_unused[NISENTRYLEN (0, 1, result)] = '\0';
00309   sp->sp_pwdp = first_unused;
00310   len = strlen (first_unused);
00311   room_left -= len + 1;
00312   first_unused += len + 1;
00313 
00314   sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact =
00315     sp->sp_expire = -1;
00316   sp->sp_flag = ~0ul;
00317 
00318   if (NISENTRYLEN (0, 7, result) > 0)
00319     {
00320       char *line = NISENTRYVAL (0, 7, result);
00321       char *cp = strchr (line, ':');
00322       if (cp == NULL)
00323        return 1;
00324       *cp++ = '\0';
00325       if (*line)
00326        sp->sp_lstchg = atol (line);
00327 
00328       line = cp;
00329       cp = strchr (line, ':');
00330       if (cp == NULL)
00331        return 1;
00332       *cp++ = '\0';
00333       if (*line)
00334        sp->sp_min = atol (line);
00335 
00336       line = cp;
00337       cp = strchr (line, ':');
00338       if (cp == NULL)
00339        return 1;
00340       *cp++ = '\0';
00341       if (*line)
00342        sp->sp_max = atol (line);
00343 
00344       line = cp;
00345       cp = strchr (line, ':');
00346       if (cp == NULL)
00347        return 1;
00348       *cp++ = '\0';
00349       if (*line)
00350        sp->sp_warn = atol (line);
00351 
00352       line = cp;
00353       cp = strchr (line, ':');
00354       if (cp == NULL)
00355        return 1;
00356       *cp++ = '\0';
00357       if (*line)
00358        sp->sp_inact = atol (line);
00359 
00360       line = cp;
00361       cp = strchr (line, ':');
00362       if (cp == NULL)
00363        return 1;
00364       *cp++ = '\0';
00365       if (*line)
00366        sp->sp_expire = atol (line);
00367 
00368       line = cp;
00369       if (line == NULL)
00370        return 1;
00371       if (*line)
00372        sp->sp_flag = atol (line);
00373     }
00374 
00375   return 1;
00376 }