2.9
[glibc/nacl-glibc.git] / nis / nss_nisplus / nisplus-parser.c
blob1e1a343d522e0658afd02bbf4a35538590f8a29b
1 /* Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <pwd.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <rpcsvc/nis.h>
26 #include "nisplus-parser.h"
28 #define NISENTRYVAL(idx, col, res) \
29 (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
31 #define NISENTRYLEN(idx, col, res) \
32 (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
34 #define NISOBJVAL(col, obj) \
35 ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
37 #define NISOBJLEN(col, obj) \
38 ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
41 int
42 _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
43 char *buffer, size_t buflen, int *errnop)
45 if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
46 || NIS_RES_NUMOBJ (result) != 1
47 || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
48 || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0
49 || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7)
50 return 0;
52 nis_object *obj = NIS_RES_OBJECT (result);
53 char *first_unused = buffer;
54 size_t room_left = buflen;
55 size_t len;
57 if (NISOBJLEN (0, obj) >= room_left)
59 /* The line is too long for our buffer. */
60 no_more_room:
61 *errnop = ERANGE;
62 return -1;
65 strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
66 first_unused[NISOBJLEN (0, obj)] = '\0';
67 len = strlen (first_unused);
68 if (len == 0) /* No name ? Should never happen, database is corrupt */
69 return 0;
70 pw->pw_name = first_unused;
71 room_left -= len + 1;
72 first_unused += len + 1;
74 if (NISOBJLEN (1, obj) >= room_left)
75 goto no_more_room;
77 strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
78 first_unused[NISOBJLEN (1, obj)] = '\0';
79 pw->pw_passwd = first_unused;
80 len = strlen (first_unused);
81 room_left -= len + 1;
82 first_unused += len + 1;
84 char *numstr = NISOBJVAL (2, obj);
85 len = NISOBJLEN (2, obj);
86 if (len == 0 && numstr[len - 1] != '\0')
88 if (len >= room_left)
89 goto no_more_room;
91 strncpy (first_unused, numstr, len);
92 first_unused[len] = '\0';
93 numstr = first_unused;
95 if (numstr[0] == '\0')
96 /* If we don't have a uid, it's an invalid shadow entry. */
97 return 0;
98 pw->pw_uid = strtoul (numstr, NULL, 10);
100 numstr = NISOBJVAL (3, obj);
101 len = NISOBJLEN (3, obj);
102 if (len == 0 && numstr[len - 1] != '\0')
104 if (len >= room_left)
105 goto no_more_room;
107 strncpy (first_unused, numstr, len);
108 first_unused[len] = '\0';
109 numstr = first_unused;
111 if (numstr[0] == '\0')
112 /* If we don't have a gid, it's an invalid shadow entry. */
113 return 0;
114 pw->pw_gid = strtoul (numstr, NULL, 10);
116 if (NISOBJLEN(4, obj) >= room_left)
117 goto no_more_room;
119 strncpy (first_unused, NISOBJVAL (4, obj), NISOBJLEN (4, obj));
120 first_unused[NISOBJLEN (4, obj)] = '\0';
121 pw->pw_gecos = first_unused;
122 len = strlen (first_unused);
123 room_left -= len + 1;
124 first_unused += len + 1;
126 if (NISOBJLEN (5, obj) >= room_left)
127 goto no_more_room;
129 strncpy (first_unused, NISOBJVAL (5, obj), NISOBJLEN (5, obj));
130 first_unused[NISOBJLEN (5, obj)] = '\0';
131 pw->pw_dir = first_unused;
132 len = strlen (first_unused);
133 room_left -= len + 1;
134 first_unused += len + 1;
136 if (NISOBJLEN (6, obj) >= room_left)
137 goto no_more_room;
139 strncpy (first_unused, NISOBJVAL (6, obj), NISOBJLEN (6, obj));
140 first_unused[NISOBJLEN (6, obj)] = '\0';
141 pw->pw_shell = first_unused;
142 len = strlen (first_unused);
143 room_left -= len + 1;
144 first_unused += len + 1;
146 return 1;
151 _nss_nisplus_parse_grent (nis_result *result, struct group *gr,
152 char *buffer, size_t buflen, int *errnop)
154 if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
155 || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
156 || strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "group_tbl") != 0
157 || NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4)
158 return 0;
160 nis_object *obj = NIS_RES_OBJECT (result);
161 char *first_unused = buffer;
162 size_t room_left = buflen;
163 char *line;
164 int count;
165 size_t len;
167 if (NISOBJLEN (0, obj) >= room_left)
169 /* The line is too long for our buffer. */
170 no_more_room:
171 *errnop = ERANGE;
172 return -1;
175 strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
176 first_unused[NISOBJLEN (0, obj)] = '\0';
177 len = strlen (first_unused);
178 if (len == 0) /* group table is corrupt */
179 return 0;
180 gr->gr_name = first_unused;
181 room_left -= len + 1;
182 first_unused += len + 1;
184 if (NISOBJLEN (1, obj) >= room_left)
185 goto no_more_room;
187 strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
188 first_unused[NISOBJLEN (1, obj)] = '\0';
189 gr->gr_passwd = first_unused;
190 len = strlen (first_unused);
191 room_left -= len + 1;
192 first_unused += len + 1;
194 char *numstr = NISOBJVAL (2, obj);
195 len = NISOBJLEN (2, obj);
196 if (len == 0 || numstr[len - 1] != '\0')
198 if (len >= room_left)
199 goto no_more_room;
201 strncpy (first_unused, numstr, len);
202 first_unused[len] = '\0';
203 numstr = first_unused;
205 if (numstr[0] == '\0')
206 /* We should always have a gid. */
207 return 0;
208 gr->gr_gid = strtoul (numstr, NULL, 10);
210 if (NISOBJLEN (3, obj) >= room_left)
211 goto no_more_room;
213 strncpy (first_unused, NISOBJVAL (3, obj), NISOBJLEN (3, obj));
214 first_unused[NISOBJLEN (3, obj)] = '\0';
215 line = first_unused;
216 len = strlen (line);
217 room_left -= len + 1;
218 first_unused += len + 1;
219 /* Adjust the pointer so it is aligned for
220 storing pointers. */
221 size_t adjust = ((__alignof__ (char *)
222 - (first_unused - (char *) 0) % __alignof__ (char *))
223 % __alignof__ (char *));
224 if (room_left < adjust)
225 goto no_more_room;
226 first_unused += adjust;
227 room_left -= adjust;
228 gr->gr_mem = (char **) first_unused;
230 count = 0;
231 while (*line != '\0')
233 /* Skip leading blanks. */
234 while (isspace (*line))
235 ++line;
237 if (*line == '\0')
238 break;
240 if (room_left < sizeof (char *))
241 goto no_more_room;
242 room_left -= sizeof (char *);
243 gr->gr_mem[count++] = line;
245 while (*line != '\0' && *line != ',' && !isspace (*line))
246 ++line;
248 if (*line == ',' || isspace (*line))
250 int is = isspace (*line);
252 *line++ = '\0';
253 if (is)
254 while (*line != '\0' && (*line == ',' || isspace (*line)))
255 ++line;
258 if (room_left < sizeof (char *))
259 goto no_more_room;
260 room_left -= sizeof (char *);
261 gr->gr_mem[count] = NULL;
263 return 1;
268 _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
269 char *buffer, size_t buflen, int *errnop)
271 char *first_unused = buffer;
272 size_t room_left = buflen;
273 size_t len;
275 if (result == NULL)
276 return 0;
278 if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
279 || NIS_RES_NUMOBJ (result) != 1
280 || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
281 || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0
282 || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 8)
283 return 0;
285 if (NISENTRYLEN (0, 0, result) >= room_left)
287 /* The line is too long for our buffer. */
288 no_more_room:
289 *errnop = ERANGE;
290 return -1;
293 strncpy (first_unused, NISENTRYVAL (0, 0, result),
294 NISENTRYLEN (0, 0, result));
295 first_unused[NISENTRYLEN (0, 0, result)] = '\0';
296 len = strlen (first_unused);
297 if (len == 0)
298 return 0;
299 sp->sp_namp = first_unused;
300 room_left -= len + 1;
301 first_unused += len + 1;
303 if (NISENTRYLEN (0, 1, result) >= room_left)
304 goto no_more_room;
306 strncpy (first_unused, NISENTRYVAL (0, 1, result),
307 NISENTRYLEN (0, 1, result));
308 first_unused[NISENTRYLEN (0, 1, result)] = '\0';
309 sp->sp_pwdp = first_unused;
310 len = strlen (first_unused);
311 room_left -= len + 1;
312 first_unused += len + 1;
314 sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact =
315 sp->sp_expire = -1;
316 sp->sp_flag = ~0ul;
318 if (NISENTRYLEN (0, 7, result) > 0)
320 char *line = NISENTRYVAL (0, 7, result);
321 char *cp = strchr (line, ':');
322 if (cp == NULL)
323 return 1;
324 *cp++ = '\0';
325 if (*line)
326 sp->sp_lstchg = atol (line);
328 line = cp;
329 cp = strchr (line, ':');
330 if (cp == NULL)
331 return 1;
332 *cp++ = '\0';
333 if (*line)
334 sp->sp_min = atol (line);
336 line = cp;
337 cp = strchr (line, ':');
338 if (cp == NULL)
339 return 1;
340 *cp++ = '\0';
341 if (*line)
342 sp->sp_max = atol (line);
344 line = cp;
345 cp = strchr (line, ':');
346 if (cp == NULL)
347 return 1;
348 *cp++ = '\0';
349 if (*line)
350 sp->sp_warn = atol (line);
352 line = cp;
353 cp = strchr (line, ':');
354 if (cp == NULL)
355 return 1;
356 *cp++ = '\0';
357 if (*line)
358 sp->sp_inact = atol (line);
360 line = cp;
361 cp = strchr (line, ':');
362 if (cp == NULL)
363 return 1;
364 *cp++ = '\0';
365 if (*line)
366 sp->sp_expire = atol (line);
368 line = cp;
369 if (line == NULL)
370 return 1;
371 if (*line)
372 sp->sp_flag = atol (line);
375 return 1;