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
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)
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)
52 nis_object
*obj
= NIS_RES_OBJECT (result
);
53 char *first_unused
= buffer
;
54 size_t room_left
= buflen
;
57 if (NISOBJLEN (0, obj
) >= room_left
)
59 /* The line is too long for our buffer. */
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 */
70 pw
->pw_name
= first_unused
;
72 first_unused
+= len
+ 1;
74 if (NISOBJLEN (1, obj
) >= room_left
)
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
);
82 first_unused
+= len
+ 1;
84 char *numstr
= NISOBJVAL (2, obj
);
85 len
= NISOBJLEN (2, obj
);
86 if (len
== 0 && numstr
[len
- 1] != '\0')
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. */
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
)
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. */
114 pw
->pw_gid
= strtoul (numstr
, NULL
, 10);
116 if (NISOBJLEN(4, obj
) >= room_left
)
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
)
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
)
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;
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)
160 nis_object
*obj
= NIS_RES_OBJECT (result
);
161 char *first_unused
= buffer
;
162 size_t room_left
= buflen
;
167 if (NISOBJLEN (0, obj
) >= room_left
)
169 /* The line is too long for our buffer. */
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 */
180 gr
->gr_name
= first_unused
;
181 room_left
-= len
+ 1;
182 first_unused
+= len
+ 1;
184 if (NISOBJLEN (1, obj
) >= room_left
)
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
)
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. */
208 gr
->gr_gid
= strtoul (numstr
, NULL
, 10);
210 if (NISOBJLEN (3, obj
) >= room_left
)
213 strncpy (first_unused
, NISOBJVAL (3, obj
), NISOBJLEN (3, obj
));
214 first_unused
[NISOBJLEN (3, obj
)] = '\0';
217 room_left
-= len
+ 1;
218 first_unused
+= len
+ 1;
219 /* Adjust the pointer so it is aligned for
221 size_t adjust
= ((__alignof__ (char *)
222 - (first_unused
- (char *) 0) % __alignof__ (char *))
223 % __alignof__ (char *));
224 if (room_left
< adjust
)
226 first_unused
+= adjust
;
228 gr
->gr_mem
= (char **) first_unused
;
231 while (*line
!= '\0')
233 /* Skip leading blanks. */
234 while (isspace (*line
))
240 if (room_left
< sizeof (char *))
242 room_left
-= sizeof (char *);
243 gr
->gr_mem
[count
++] = line
;
245 while (*line
!= '\0' && *line
!= ',' && !isspace (*line
))
248 if (*line
== ',' || isspace (*line
))
250 int is
= isspace (*line
);
254 while (*line
!= '\0' && (*line
== ',' || isspace (*line
)))
258 if (room_left
< sizeof (char *))
260 room_left
-= sizeof (char *);
261 gr
->gr_mem
[count
] = NULL
;
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
;
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)
285 if (NISENTRYLEN (0, 0, result
) >= room_left
)
287 /* The line is too long for our buffer. */
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
);
299 sp
->sp_namp
= first_unused
;
300 room_left
-= len
+ 1;
301 first_unused
+= len
+ 1;
303 if (NISENTRYLEN (0, 1, result
) >= room_left
)
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
=
318 if (NISENTRYLEN (0, 7, result
) > 0)
320 char *line
= NISENTRYVAL (0, 7, result
);
321 char *cp
= strchr (line
, ':');
326 sp
->sp_lstchg
= atol (line
);
329 cp
= strchr (line
, ':');
334 sp
->sp_min
= atol (line
);
337 cp
= strchr (line
, ':');
342 sp
->sp_max
= atol (line
);
345 cp
= strchr (line
, ':');
350 sp
->sp_warn
= atol (line
);
353 cp
= strchr (line
, ':');
358 sp
->sp_inact
= atol (line
);
361 cp
= strchr (line
, ':');
366 sp
->sp_expire
= atol (line
);
372 sp
->sp_flag
= atol (line
);