]>
Commit | Line | Data |
---|---|---|
b168057a | 1 | /* Copyright (C) 1997-2015 Free Software Foundation, Inc. |
2d7da676 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
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. | |
2d7da676 UD |
9 | |
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 | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
2d7da676 | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
2d7da676 UD |
18 | |
19 | #include <pwd.h> | |
20 | #include <ctype.h> | |
21 | #include <errno.h> | |
22 | #include <string.h> | |
23 | #include <rpcsvc/nis.h> | |
24 | ||
25 | #include "nisplus-parser.h" | |
26 | ||
5b4f9fad UD |
27 | #define NISENTRYVAL(idx, col, res) \ |
28 | (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) | |
2d7da676 | 29 | |
5b4f9fad UD |
30 | #define NISENTRYLEN(idx, col, res) \ |
31 | (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) | |
2d7da676 | 32 | |
a17fa610 UD |
33 | #define NISOBJVAL(col, obj) \ |
34 | ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) | |
35 | ||
36 | #define NISOBJLEN(col, obj) \ | |
37 | ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) | |
38 | ||
2d7da676 UD |
39 | |
40 | int | |
a17fa610 UD |
41 | _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw, |
42 | char *buffer, size_t buflen, int *errnop) | |
2d7da676 | 43 | { |
a334319f | 44 | if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) |
0433a350 UD |
45 | || NIS_RES_NUMOBJ (result) != 1 |
46 | || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ | |
47 | || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0 | |
48 | || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7) | |
a334319f UD |
49 | return 0; |
50 | ||
a17fa610 | 51 | nis_object *obj = NIS_RES_OBJECT (result); |
d08a1d40 UD |
52 | char *first_unused = buffer; |
53 | size_t room_left = buflen; | |
54 | size_t len; | |
55 | ||
a17fa610 | 56 | if (NISOBJLEN (0, obj) >= room_left) |
2d7da676 UD |
57 | { |
58 | /* The line is too long for our buffer. */ | |
59 | no_more_room: | |
d71b808a | 60 | *errnop = ERANGE; |
60c96635 | 61 | return -1; |
2d7da676 UD |
62 | } |
63 | ||
a17fa610 UD |
64 | strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj)); |
65 | first_unused[NISOBJLEN (0, obj)] = '\0'; | |
7d1de115 UD |
66 | len = strlen (first_unused); |
67 | if (len == 0) /* No name ? Should never happen, database is corrupt */ | |
68 | return 0; | |
2d7da676 | 69 | pw->pw_name = first_unused; |
d08a1d40 UD |
70 | room_left -= len + 1; |
71 | first_unused += len + 1; | |
2d7da676 | 72 | |
a17fa610 | 73 | if (NISOBJLEN (1, obj) >= room_left) |
2d7da676 UD |
74 | goto no_more_room; |
75 | ||
a17fa610 UD |
76 | strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj)); |
77 | first_unused[NISOBJLEN (1, obj)] = '\0'; | |
2d7da676 | 78 | pw->pw_passwd = first_unused; |
7d1de115 | 79 | len = strlen (first_unused); |
d08a1d40 UD |
80 | room_left -= len + 1; |
81 | first_unused += len + 1; | |
2d7da676 | 82 | |
a17fa610 UD |
83 | char *numstr = NISOBJVAL (2, obj); |
84 | len = NISOBJLEN (2, obj); | |
ac053970 UD |
85 | if (len == 0 && numstr[len - 1] != '\0') |
86 | { | |
87 | if (len >= room_left) | |
88 | goto no_more_room; | |
2d7da676 | 89 | |
ac053970 UD |
90 | strncpy (first_unused, numstr, len); |
91 | first_unused[len] = '\0'; | |
92 | numstr = first_unused; | |
93 | } | |
94 | if (numstr[0] == '\0') | |
95 | /* If we don't have a uid, it's an invalid shadow entry. */ | |
7d1de115 | 96 | return 0; |
ac053970 | 97 | pw->pw_uid = strtoul (numstr, NULL, 10); |
2d7da676 | 98 | |
a17fa610 UD |
99 | numstr = NISOBJVAL (3, obj); |
100 | len = NISOBJLEN (3, obj); | |
ac053970 UD |
101 | if (len == 0 && numstr[len - 1] != '\0') |
102 | { | |
103 | if (len >= room_left) | |
104 | goto no_more_room; | |
2d7da676 | 105 | |
ac053970 UD |
106 | strncpy (first_unused, numstr, len); |
107 | first_unused[len] = '\0'; | |
108 | numstr = first_unused; | |
109 | } | |
110 | if (numstr[0] == '\0') | |
111 | /* If we don't have a gid, it's an invalid shadow entry. */ | |
7d1de115 | 112 | return 0; |
ac053970 | 113 | pw->pw_gid = strtoul (numstr, NULL, 10); |
2d7da676 | 114 | |
a17fa610 | 115 | if (NISOBJLEN(4, obj) >= room_left) |
2d7da676 UD |
116 | goto no_more_room; |
117 | ||
a17fa610 UD |
118 | strncpy (first_unused, NISOBJVAL (4, obj), NISOBJLEN (4, obj)); |
119 | first_unused[NISOBJLEN (4, obj)] = '\0'; | |
2d7da676 | 120 | pw->pw_gecos = first_unused; |
7d1de115 | 121 | len = strlen (first_unused); |
d08a1d40 UD |
122 | room_left -= len + 1; |
123 | first_unused += len + 1; | |
2d7da676 | 124 | |
a17fa610 | 125 | if (NISOBJLEN (5, obj) >= room_left) |
2d7da676 UD |
126 | goto no_more_room; |
127 | ||
a17fa610 UD |
128 | strncpy (first_unused, NISOBJVAL (5, obj), NISOBJLEN (5, obj)); |
129 | first_unused[NISOBJLEN (5, obj)] = '\0'; | |
2d7da676 | 130 | pw->pw_dir = first_unused; |
7d1de115 | 131 | len = strlen (first_unused); |
d08a1d40 UD |
132 | room_left -= len + 1; |
133 | first_unused += len + 1; | |
2d7da676 | 134 | |
a17fa610 | 135 | if (NISOBJLEN (6, obj) >= room_left) |
2d7da676 UD |
136 | goto no_more_room; |
137 | ||
a17fa610 UD |
138 | strncpy (first_unused, NISOBJVAL (6, obj), NISOBJLEN (6, obj)); |
139 | first_unused[NISOBJLEN (6, obj)] = '\0'; | |
2d7da676 | 140 | pw->pw_shell = first_unused; |
7d1de115 | 141 | len = strlen (first_unused); |
d08a1d40 UD |
142 | room_left -= len + 1; |
143 | first_unused += len + 1; | |
2d7da676 UD |
144 | |
145 | return 1; | |
146 | } | |
147 | ||
0433a350 | 148 | |
2d7da676 | 149 | int |
a17fa610 | 150 | _nss_nisplus_parse_grent (nis_result *result, struct group *gr, |
d71b808a | 151 | char *buffer, size_t buflen, int *errnop) |
2d7da676 | 152 | { |
a17fa610 UD |
153 | if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) |
154 | || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ | |
155 | || strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "group_tbl") != 0 | |
156 | || NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4) | |
157 | return 0; | |
158 | ||
159 | nis_object *obj = NIS_RES_OBJECT (result); | |
2d7da676 UD |
160 | char *first_unused = buffer; |
161 | size_t room_left = buflen; | |
162 | char *line; | |
163 | int count; | |
7d1de115 | 164 | size_t len; |
2d7da676 | 165 | |
a17fa610 | 166 | if (NISOBJLEN (0, obj) >= room_left) |
2d7da676 UD |
167 | { |
168 | /* The line is too long for our buffer. */ | |
169 | no_more_room: | |
d71b808a | 170 | *errnop = ERANGE; |
60c96635 | 171 | return -1; |
2d7da676 UD |
172 | } |
173 | ||
a17fa610 UD |
174 | strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj)); |
175 | first_unused[NISOBJLEN (0, obj)] = '\0'; | |
7d1de115 UD |
176 | len = strlen (first_unused); |
177 | if (len == 0) /* group table is corrupt */ | |
178 | return 0; | |
2d7da676 | 179 | gr->gr_name = first_unused; |
ac053970 UD |
180 | room_left -= len + 1; |
181 | first_unused += len + 1; | |
2d7da676 | 182 | |
a17fa610 | 183 | if (NISOBJLEN (1, obj) >= room_left) |
2d7da676 UD |
184 | goto no_more_room; |
185 | ||
a17fa610 UD |
186 | strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj)); |
187 | first_unused[NISOBJLEN (1, obj)] = '\0'; | |
2d7da676 | 188 | gr->gr_passwd = first_unused; |
7d1de115 | 189 | len = strlen (first_unused); |
ac053970 UD |
190 | room_left -= len + 1; |
191 | first_unused += len + 1; | |
2d7da676 | 192 | |
a17fa610 UD |
193 | char *numstr = NISOBJVAL (2, obj); |
194 | len = NISOBJLEN (2, obj); | |
195 | if (len == 0 || numstr[len - 1] != '\0') | |
ac053970 UD |
196 | { |
197 | if (len >= room_left) | |
198 | goto no_more_room; | |
2d7da676 | 199 | |
ac053970 UD |
200 | strncpy (first_unused, numstr, len); |
201 | first_unused[len] = '\0'; | |
202 | numstr = first_unused; | |
203 | } | |
204 | if (numstr[0] == '\0') | |
205 | /* We should always have a gid. */ | |
7d1de115 | 206 | return 0; |
ac053970 | 207 | gr->gr_gid = strtoul (numstr, NULL, 10); |
2d7da676 | 208 | |
a17fa610 | 209 | if (NISOBJLEN (3, obj) >= room_left) |
2d7da676 UD |
210 | goto no_more_room; |
211 | ||
a17fa610 UD |
212 | strncpy (first_unused, NISOBJVAL (3, obj), NISOBJLEN (3, obj)); |
213 | first_unused[NISOBJLEN (3, obj)] = '\0'; | |
2d7da676 | 214 | line = first_unused; |
7d1de115 | 215 | len = strlen (line); |
ac053970 UD |
216 | room_left -= len + 1; |
217 | first_unused += len + 1; | |
2d7da676 UD |
218 | /* Adjust the pointer so it is aligned for |
219 | storing pointers. */ | |
3fc044a1 UD |
220 | size_t adjust = ((__alignof__ (char *) |
221 | - (first_unused - (char *) 0) % __alignof__ (char *)) | |
222 | % __alignof__ (char *)); | |
0433a350 UD |
223 | if (room_left < adjust) |
224 | goto no_more_room; | |
3fc044a1 | 225 | first_unused += adjust; |
0433a350 | 226 | room_left -= adjust; |
2d7da676 UD |
227 | gr->gr_mem = (char **) first_unused; |
228 | ||
229 | count = 0; | |
230 | while (*line != '\0') | |
231 | { | |
232 | /* Skip leading blanks. */ | |
233 | while (isspace (*line)) | |
234 | ++line; | |
235 | ||
236 | if (*line == '\0') | |
237 | break; | |
238 | ||
239 | if (room_left < sizeof (char *)) | |
079c00e6 | 240 | goto no_more_room; |
2d7da676 | 241 | room_left -= sizeof (char *); |
079c00e6 | 242 | gr->gr_mem[count++] = line; |
2d7da676 | 243 | |
8f2ece69 | 244 | while (*line != '\0' && *line != ',' && !isspace (*line)) |
2d7da676 UD |
245 | ++line; |
246 | ||
8f2ece69 | 247 | if (*line == ',' || isspace (*line)) |
2d7da676 | 248 | { |
8f2ece69 UD |
249 | int is = isspace (*line); |
250 | ||
0433a350 | 251 | *line++ = '\0'; |
8f2ece69 UD |
252 | if (is) |
253 | while (*line != '\0' && (*line == ',' || isspace (*line))) | |
2d7da676 | 254 | ++line; |
2d7da676 | 255 | } |
2d7da676 UD |
256 | } |
257 | if (room_left < sizeof (char *)) | |
079c00e6 | 258 | goto no_more_room; |
2d7da676 UD |
259 | room_left -= sizeof (char *); |
260 | gr->gr_mem[count] = NULL; | |
261 | ||
262 | return 1; | |
263 | } | |
264 | ||
0433a350 | 265 | |
2d7da676 UD |
266 | int |
267 | _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, | |
d71b808a | 268 | char *buffer, size_t buflen, int *errnop) |
2d7da676 UD |
269 | { |
270 | char *first_unused = buffer; | |
271 | size_t room_left = buflen; | |
7d1de115 | 272 | size_t len; |
8f2ece69 | 273 | |
2d7da676 UD |
274 | if (result == NULL) |
275 | return 0; | |
276 | ||
d71b808a | 277 | if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) |
0433a350 UD |
278 | || NIS_RES_NUMOBJ (result) != 1 |
279 | || __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ | |
280 | || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0 | |
281 | || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 8) | |
2d7da676 UD |
282 | return 0; |
283 | ||
d71b808a | 284 | if (NISENTRYLEN (0, 0, result) >= room_left) |
2d7da676 UD |
285 | { |
286 | /* The line is too long for our buffer. */ | |
287 | no_more_room: | |
d71b808a | 288 | *errnop = ERANGE; |
60c96635 | 289 | return -1; |
2d7da676 UD |
290 | } |
291 | ||
292 | strncpy (first_unused, NISENTRYVAL (0, 0, result), | |
293 | NISENTRYLEN (0, 0, result)); | |
d71b808a | 294 | first_unused[NISENTRYLEN (0, 0, result)] = '\0'; |
7d1de115 UD |
295 | len = strlen (first_unused); |
296 | if (len == 0) | |
297 | return 0; | |
2d7da676 | 298 | sp->sp_namp = first_unused; |
ac053970 UD |
299 | room_left -= len + 1; |
300 | first_unused += len + 1; | |
2d7da676 | 301 | |
d71b808a | 302 | if (NISENTRYLEN (0, 1, result) >= room_left) |
2d7da676 UD |
303 | goto no_more_room; |
304 | ||
305 | strncpy (first_unused, NISENTRYVAL (0, 1, result), | |
306 | NISENTRYLEN (0, 1, result)); | |
d71b808a | 307 | first_unused[NISENTRYLEN (0, 1, result)] = '\0'; |
2d7da676 | 308 | sp->sp_pwdp = first_unused; |
7d1de115 | 309 | len = strlen (first_unused); |
ac053970 UD |
310 | room_left -= len + 1; |
311 | first_unused += len + 1; | |
2d7da676 UD |
312 | |
313 | sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact = | |
b5c6276a UD |
314 | sp->sp_expire = -1; |
315 | sp->sp_flag = ~0ul; | |
2d7da676 UD |
316 | |
317 | if (NISENTRYLEN (0, 7, result) > 0) | |
318 | { | |
0433a350 UD |
319 | char *line = NISENTRYVAL (0, 7, result); |
320 | char *cp = strchr (line, ':'); | |
2d7da676 | 321 | if (cp == NULL) |
b5c6276a | 322 | return 1; |
2d7da676 | 323 | *cp++ = '\0'; |
b5c6276a UD |
324 | if (*line) |
325 | sp->sp_lstchg = atol (line); | |
2d7da676 UD |
326 | |
327 | line = cp; | |
328 | cp = strchr (line, ':'); | |
329 | if (cp == NULL) | |
b5c6276a | 330 | return 1; |
2d7da676 | 331 | *cp++ = '\0'; |
b5c6276a UD |
332 | if (*line) |
333 | sp->sp_min = atol (line); | |
2d7da676 UD |
334 | |
335 | line = cp; | |
336 | cp = strchr (line, ':'); | |
337 | if (cp == NULL) | |
b5c6276a | 338 | return 1; |
2d7da676 | 339 | *cp++ = '\0'; |
b5c6276a UD |
340 | if (*line) |
341 | sp->sp_max = atol (line); | |
2d7da676 UD |
342 | |
343 | line = cp; | |
344 | cp = strchr (line, ':'); | |
345 | if (cp == NULL) | |
b5c6276a | 346 | return 1; |
2d7da676 | 347 | *cp++ = '\0'; |
b5c6276a UD |
348 | if (*line) |
349 | sp->sp_warn = atol (line); | |
2d7da676 UD |
350 | |
351 | line = cp; | |
352 | cp = strchr (line, ':'); | |
353 | if (cp == NULL) | |
b5c6276a | 354 | return 1; |
2d7da676 | 355 | *cp++ = '\0'; |
b5c6276a UD |
356 | if (*line) |
357 | sp->sp_inact = atol (line); | |
2d7da676 UD |
358 | |
359 | line = cp; | |
360 | cp = strchr (line, ':'); | |
361 | if (cp == NULL) | |
b5c6276a | 362 | return 1; |
2d7da676 | 363 | *cp++ = '\0'; |
b5c6276a UD |
364 | if (*line) |
365 | sp->sp_expire = atol (line); | |
2d7da676 UD |
366 | |
367 | line = cp; | |
368 | if (line == NULL) | |
b5c6276a UD |
369 | return 1; |
370 | if (*line) | |
371 | sp->sp_flag = atol (line); | |
2d7da676 UD |
372 | } |
373 | ||
374 | return 1; | |
375 | } |