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)
36 _nss_nisplus_parse_pwent_chk (nis_result
*result
, struct passwd
*pw
,
37 char *buffer
, size_t buflen
, int *errnop
)
39 if ((result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_S_SUCCESS
)
40 || NIS_RES_NUMOBJ (result
) != 1
41 || __type_of (NIS_RES_OBJECT (result
)) != NIS_ENTRY_OBJ
42 || strcmp (NIS_RES_OBJECT (result
)->EN_data
.en_type
, "passwd_tbl") != 0
43 || NIS_RES_OBJECT (result
)->EN_data
.en_cols
.en_cols_len
< 7)
46 return _nss_nisplus_parse_pwent (result
, 0, pw
, buffer
, buflen
, errnop
);
51 _nss_nisplus_parse_pwent (nis_result
*result
, size_t entry
, struct passwd
*pw
,
52 char *buffer
, size_t buflen
, int *errnop
)
54 char *first_unused
= buffer
;
55 size_t room_left
= buflen
;
58 if (NISENTRYLEN (entry
, 0, result
) >= room_left
)
60 /* The line is too long for our buffer. */
66 strncpy (first_unused
, NISENTRYVAL (entry
, 0, result
),
67 NISENTRYLEN (entry
, 0, result
));
68 first_unused
[NISENTRYLEN (entry
, 0, result
)] = '\0';
69 len
= strlen (first_unused
);
70 if (len
== 0) /* No name ? Should never happen, database is corrupt */
72 pw
->pw_name
= first_unused
;
74 first_unused
+= len
+ 1;
76 if (NISENTRYLEN (entry
, 1, result
) >= room_left
)
79 strncpy (first_unused
, NISENTRYVAL (entry
, 1, result
),
80 NISENTRYLEN (entry
, 1, result
));
81 first_unused
[NISENTRYLEN (entry
, 1, result
)] = '\0';
82 pw
->pw_passwd
= first_unused
;
83 len
= strlen (first_unused
);
85 first_unused
+= len
+ 1;
87 if (NISENTRYLEN (entry
, 2, result
) >= room_left
)
90 strncpy (first_unused
, NISENTRYVAL (entry
, 2, result
),
91 NISENTRYLEN (entry
, 2, result
));
92 first_unused
[NISENTRYLEN (entry
, 2, result
)] = '\0';
93 len
= strlen (first_unused
);
94 if (len
== 0) /* If we don't have a uid, it's an invalid shadow entry */
96 pw
->pw_uid
= strtoul (first_unused
, NULL
, 10);
98 if (NISENTRYLEN (entry
, 3, result
) >= room_left
)
101 strncpy (first_unused
, NISENTRYVAL (entry
, 3, result
),
102 NISENTRYLEN (entry
, 3, result
));
103 first_unused
[NISENTRYLEN (entry
, 3, result
)] = '\0';
104 len
= strlen (first_unused
);
105 if (len
== 0) /* If we don't have a gid, it's an invalid shadow entry */
107 pw
->pw_gid
= strtoul (first_unused
, NULL
, 10);
109 if (NISENTRYLEN(entry
, 4, result
) >= room_left
)
112 strncpy (first_unused
, NISENTRYVAL (entry
, 4, result
),
113 NISENTRYLEN (entry
, 4, result
));
114 first_unused
[NISENTRYLEN (entry
, 4, result
)] = '\0';
115 pw
->pw_gecos
= first_unused
;
116 len
= strlen (first_unused
);
117 room_left
-= len
+ 1;
118 first_unused
+= len
+ 1;
120 if (NISENTRYLEN (entry
, 5, result
) >= room_left
)
123 strncpy (first_unused
, NISENTRYVAL (entry
, 5, result
),
124 NISENTRYLEN (entry
, 5, result
));
125 first_unused
[NISENTRYLEN (entry
, 5, result
)] = '\0';
126 pw
->pw_dir
= first_unused
;
127 len
= strlen (first_unused
);
128 room_left
-= len
+ 1;
129 first_unused
+= len
+ 1;
131 if (NISENTRYLEN (entry
, 6, result
) >= room_left
)
134 strncpy (first_unused
, NISENTRYVAL (entry
, 6, result
),
135 NISENTRYLEN (entry
, 6, result
));
136 first_unused
[NISENTRYLEN (entry
, 6, result
)] = '\0';
137 pw
->pw_shell
= first_unused
;
138 len
= strlen (first_unused
);
139 room_left
-= len
+ 1;
140 first_unused
+= len
+ 1;
147 _nss_nisplus_parse_grent (nis_result
*result
, u_long entry
, struct group
*gr
,
148 char *buffer
, size_t buflen
, int *errnop
)
150 char *first_unused
= buffer
;
151 size_t room_left
= buflen
;
159 if ((result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_S_SUCCESS
)
160 || __type_of(NIS_RES_OBJECT (result
)) != NIS_ENTRY_OBJ
161 || strcmp (NIS_RES_OBJECT (result
)[entry
].EN_data
.en_type
,
163 || NIS_RES_OBJECT (result
)[entry
].EN_data
.en_cols
.en_cols_len
< 4)
166 if (NISENTRYLEN (entry
, 0, result
) >= room_left
)
168 /* The line is too long for our buffer. */
174 strncpy (first_unused
, NISENTRYVAL (entry
, 0, result
),
175 NISENTRYLEN (entry
, 0, result
));
176 first_unused
[NISENTRYLEN (entry
, 0, result
)] = '\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 (NISENTRYLEN (entry
, 1, result
) >= room_left
)
187 strncpy (first_unused
, NISENTRYVAL (entry
, 1, result
),
188 NISENTRYLEN (entry
, 1, result
));
189 first_unused
[NISENTRYLEN (entry
, 1, result
)] = '\0';
190 gr
->gr_passwd
= first_unused
;
191 len
= strlen (first_unused
);
192 room_left
-= (len
+ 1);
193 first_unused
+= (len
+ 1);
195 if (NISENTRYLEN (entry
, 2, result
) >= room_left
)
198 strncpy (first_unused
, NISENTRYVAL (entry
, 2, result
),
199 NISENTRYLEN (entry
, 2, result
));
200 first_unused
[NISENTRYLEN (entry
, 2, result
)] = '\0';
201 len
= strlen (first_unused
);
202 if (len
== 0) /* We should always have a gid */
204 gr
->gr_gid
= strtoul (first_unused
, NULL
, 10);
206 if (NISENTRYLEN (entry
, 3, result
) >= room_left
)
209 strncpy (first_unused
, NISENTRYVAL (entry
, 3, result
),
210 NISENTRYLEN (entry
, 3, result
));
211 first_unused
[NISENTRYLEN (entry
, 3, result
)] = '\0';
214 room_left
-= (len
+ 1);
215 first_unused
+= (len
+ 1);
216 /* Adjust the pointer so it is aligned for
218 size_t adjust
= ((__alignof__ (char *)
219 - (first_unused
- (char *) 0) % __alignof__ (char *))
220 % __alignof__ (char *));
221 if (room_left
< adjust
)
223 first_unused
+= adjust
;
225 gr
->gr_mem
= (char **) first_unused
;
228 while (*line
!= '\0')
230 /* Skip leading blanks. */
231 while (isspace (*line
))
237 if (room_left
< sizeof (char *))
239 room_left
-= sizeof (char *);
240 gr
->gr_mem
[count
++] = line
;
242 while (*line
!= '\0' && *line
!= ',' && !isspace (*line
))
245 if (*line
== ',' || isspace (*line
))
247 int is
= isspace (*line
);
251 while (*line
!= '\0' && (*line
== ',' || isspace (*line
)))
255 if (room_left
< sizeof (char *))
257 room_left
-= sizeof (char *);
258 gr
->gr_mem
[count
] = NULL
;
265 _nss_nisplus_parse_spent (nis_result
*result
, struct spwd
*sp
,
266 char *buffer
, size_t buflen
, int *errnop
)
268 char *first_unused
= buffer
;
269 size_t room_left
= buflen
;
275 if ((result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_S_SUCCESS
)
276 || NIS_RES_NUMOBJ (result
) != 1
277 || __type_of(NIS_RES_OBJECT (result
)) != NIS_ENTRY_OBJ
278 || strcmp (NIS_RES_OBJECT (result
)->EN_data
.en_type
, "passwd_tbl") != 0
279 || NIS_RES_OBJECT (result
)->EN_data
.en_cols
.en_cols_len
< 8)
282 if (NISENTRYLEN (0, 0, result
) >= room_left
)
284 /* The line is too long for our buffer. */
290 strncpy (first_unused
, NISENTRYVAL (0, 0, result
),
291 NISENTRYLEN (0, 0, result
));
292 first_unused
[NISENTRYLEN (0, 0, result
)] = '\0';
293 len
= strlen (first_unused
);
296 sp
->sp_namp
= first_unused
;
297 room_left
-= (len
+ 1);
298 first_unused
+= (len
+ 1);
300 if (NISENTRYLEN (0, 1, result
) >= room_left
)
303 strncpy (first_unused
, NISENTRYVAL (0, 1, result
),
304 NISENTRYLEN (0, 1, result
));
305 first_unused
[NISENTRYLEN (0, 1, result
)] = '\0';
306 sp
->sp_pwdp
= first_unused
;
307 len
= strlen (first_unused
);
308 room_left
-= (len
+ 1);
309 first_unused
+= (len
+ 1);
311 sp
->sp_lstchg
= sp
->sp_min
= sp
->sp_max
= sp
->sp_warn
= sp
->sp_inact
=
315 if (NISENTRYLEN (0, 7, result
) > 0)
317 char *line
= NISENTRYVAL (0, 7, result
);
318 char *cp
= strchr (line
, ':');
323 sp
->sp_lstchg
= atol (line
);
326 cp
= strchr (line
, ':');
331 sp
->sp_min
= atol (line
);
334 cp
= strchr (line
, ':');
339 sp
->sp_max
= atol (line
);
342 cp
= strchr (line
, ':');
347 sp
->sp_warn
= atol (line
);
350 cp
= strchr (line
, ':');
355 sp
->sp_inact
= atol (line
);
358 cp
= strchr (line
, ':');
363 sp
->sp_expire
= atol (line
);
369 sp
->sp_flag
= atol (line
);