1 /* Copyright (C) 1997-2017 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, see
17 <http://www.gnu.org/licenses/>. */
23 #include <rpcsvc/nis.h>
25 #include "nisplus-parser.h"
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)
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)
33 #define NISOBJVAL(col, obj) \
34 ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
36 #define NISOBJLEN(col, obj) \
37 ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
41 _nss_nisplus_parse_pwent (nis_result
*result
, struct passwd
*pw
,
42 char *buffer
, size_t buflen
, int *errnop
)
44 if ((result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_S_SUCCESS
)
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)
51 nis_object
*obj
= NIS_RES_OBJECT (result
);
52 char *first_unused
= buffer
;
53 size_t room_left
= buflen
;
56 if (NISOBJLEN (0, obj
) >= room_left
)
58 /* The line is too long for our buffer. */
64 strncpy (first_unused
, NISOBJVAL (0, obj
), NISOBJLEN (0, obj
));
65 first_unused
[NISOBJLEN (0, obj
)] = '\0';
66 len
= strlen (first_unused
);
67 if (len
== 0) /* No name ? Should never happen, database is corrupt */
69 pw
->pw_name
= first_unused
;
71 first_unused
+= len
+ 1;
73 if (NISOBJLEN (1, obj
) >= room_left
)
76 strncpy (first_unused
, NISOBJVAL (1, obj
), NISOBJLEN (1, obj
));
77 first_unused
[NISOBJLEN (1, obj
)] = '\0';
78 pw
->pw_passwd
= first_unused
;
79 len
= strlen (first_unused
);
81 first_unused
+= len
+ 1;
83 char *numstr
= NISOBJVAL (2, obj
);
84 len
= NISOBJLEN (2, obj
);
85 if (len
== 0 && numstr
[len
- 1] != '\0')
90 strncpy (first_unused
, numstr
, len
);
91 first_unused
[len
] = '\0';
92 numstr
= first_unused
;
94 if (numstr
[0] == '\0')
95 /* If we don't have a uid, it's an invalid shadow entry. */
97 pw
->pw_uid
= strtoul (numstr
, NULL
, 10);
99 numstr
= NISOBJVAL (3, obj
);
100 len
= NISOBJLEN (3, obj
);
101 if (len
== 0 && numstr
[len
- 1] != '\0')
103 if (len
>= room_left
)
106 strncpy (first_unused
, numstr
, len
);
107 first_unused
[len
] = '\0';
108 numstr
= first_unused
;
110 if (numstr
[0] == '\0')
111 /* If we don't have a gid, it's an invalid shadow entry. */
113 pw
->pw_gid
= strtoul (numstr
, NULL
, 10);
115 if (NISOBJLEN(4, obj
) >= room_left
)
118 strncpy (first_unused
, NISOBJVAL (4, obj
), NISOBJLEN (4, obj
));
119 first_unused
[NISOBJLEN (4, obj
)] = '\0';
120 pw
->pw_gecos
= first_unused
;
121 len
= strlen (first_unused
);
122 room_left
-= len
+ 1;
123 first_unused
+= len
+ 1;
125 if (NISOBJLEN (5, obj
) >= room_left
)
128 strncpy (first_unused
, NISOBJVAL (5, obj
), NISOBJLEN (5, obj
));
129 first_unused
[NISOBJLEN (5, obj
)] = '\0';
130 pw
->pw_dir
= first_unused
;
131 len
= strlen (first_unused
);
132 room_left
-= len
+ 1;
133 first_unused
+= len
+ 1;
135 if (NISOBJLEN (6, obj
) >= room_left
)
138 strncpy (first_unused
, NISOBJVAL (6, obj
), NISOBJLEN (6, obj
));
139 first_unused
[NISOBJLEN (6, obj
)] = '\0';
140 pw
->pw_shell
= first_unused
;
141 len
= strlen (first_unused
);
142 room_left
-= len
+ 1;
143 first_unused
+= len
+ 1;
150 _nss_nisplus_parse_grent (nis_result
*result
, struct group
*gr
,
151 char *buffer
, size_t buflen
, int *errnop
)
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)
159 nis_object
*obj
= NIS_RES_OBJECT (result
);
160 char *first_unused
= buffer
;
161 size_t room_left
= buflen
;
166 if (NISOBJLEN (0, obj
) >= room_left
)
168 /* The line is too long for our buffer. */
174 strncpy (first_unused
, NISOBJVAL (0, obj
), NISOBJLEN (0, obj
));
175 first_unused
[NISOBJLEN (0, obj
)] = '\0';
176 len
= strlen (first_unused
);
177 if (len
== 0) /* group table is corrupt */
179 gr
->gr_name
= first_unused
;
180 room_left
-= len
+ 1;
181 first_unused
+= len
+ 1;
183 if (NISOBJLEN (1, obj
) >= room_left
)
186 strncpy (first_unused
, NISOBJVAL (1, obj
), NISOBJLEN (1, obj
));
187 first_unused
[NISOBJLEN (1, obj
)] = '\0';
188 gr
->gr_passwd
= first_unused
;
189 len
= strlen (first_unused
);
190 room_left
-= len
+ 1;
191 first_unused
+= len
+ 1;
193 char *numstr
= NISOBJVAL (2, obj
);
194 len
= NISOBJLEN (2, obj
);
195 if (len
== 0 || numstr
[len
- 1] != '\0')
197 if (len
>= room_left
)
200 strncpy (first_unused
, numstr
, len
);
201 first_unused
[len
] = '\0';
202 numstr
= first_unused
;
204 if (numstr
[0] == '\0')
205 /* We should always have a gid. */
207 gr
->gr_gid
= strtoul (numstr
, NULL
, 10);
209 if (NISOBJLEN (3, obj
) >= room_left
)
212 strncpy (first_unused
, NISOBJVAL (3, obj
), NISOBJLEN (3, obj
));
213 first_unused
[NISOBJLEN (3, obj
)] = '\0';
216 room_left
-= len
+ 1;
217 first_unused
+= len
+ 1;
218 /* Adjust the pointer so it is aligned for
220 size_t adjust
= ((__alignof__ (char *)
221 - (first_unused
- (char *) 0) % __alignof__ (char *))
222 % __alignof__ (char *));
223 if (room_left
< adjust
)
225 first_unused
+= adjust
;
227 gr
->gr_mem
= (char **) first_unused
;
230 while (*line
!= '\0')
232 /* Skip leading blanks. */
233 while (isspace (*line
))
239 if (room_left
< sizeof (char *))
241 room_left
-= sizeof (char *);
242 gr
->gr_mem
[count
++] = line
;
244 while (*line
!= '\0' && *line
!= ',' && !isspace (*line
))
247 if (*line
== ',' || isspace (*line
))
249 int is
= isspace (*line
);
253 while (*line
!= '\0' && (*line
== ',' || isspace (*line
)))
257 if (room_left
< sizeof (char *))
259 room_left
-= sizeof (char *);
260 gr
->gr_mem
[count
] = NULL
;
267 _nss_nisplus_parse_spent (nis_result
*result
, struct spwd
*sp
,
268 char *buffer
, size_t buflen
, int *errnop
)
270 char *first_unused
= buffer
;
271 size_t room_left
= buflen
;
277 if ((result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_S_SUCCESS
)
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)
284 if (NISENTRYLEN (0, 0, result
) >= room_left
)
286 /* The line is too long for our buffer. */
292 strncpy (first_unused
, NISENTRYVAL (0, 0, result
),
293 NISENTRYLEN (0, 0, result
));
294 first_unused
[NISENTRYLEN (0, 0, result
)] = '\0';
295 len
= strlen (first_unused
);
298 sp
->sp_namp
= first_unused
;
299 room_left
-= len
+ 1;
300 first_unused
+= len
+ 1;
302 if (NISENTRYLEN (0, 1, result
) >= room_left
)
305 strncpy (first_unused
, NISENTRYVAL (0, 1, result
),
306 NISENTRYLEN (0, 1, result
));
307 first_unused
[NISENTRYLEN (0, 1, result
)] = '\0';
308 sp
->sp_pwdp
= first_unused
;
309 len
= strlen (first_unused
);
310 room_left
-= len
+ 1;
311 first_unused
+= len
+ 1;
313 sp
->sp_lstchg
= sp
->sp_min
= sp
->sp_max
= sp
->sp_warn
= sp
->sp_inact
=
317 if (NISENTRYLEN (0, 7, result
) > 0)
319 char *line
= NISENTRYVAL (0, 7, result
);
320 char *cp
= strchr (line
, ':');
325 sp
->sp_lstchg
= atol (line
);
328 cp
= strchr (line
, ':');
333 sp
->sp_min
= atol (line
);
336 cp
= strchr (line
, ':');
341 sp
->sp_max
= atol (line
);
344 cp
= strchr (line
, ':');
349 sp
->sp_warn
= atol (line
);
352 cp
= strchr (line
, ':');
357 sp
->sp_inact
= atol (line
);
360 cp
= strchr (line
, ':');
365 sp
->sp_expire
= atol (line
);
371 sp
->sp_flag
= atol (line
);