1 /* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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/>. */
25 #include <bits/libc-lock.h>
26 #include <rpcsvc/nis.h>
28 #include "nss-nisplus.h"
29 #include "nisplus-parser.h"
31 #include <nis_intern.h>
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)
40 extern nis_name grp_tablename_val attribute_hidden
;
41 extern size_t grp_tablename_len attribute_hidden
;
42 extern enum nss_status
_nss_grp_create_tablename (int *errnop
);
46 _nss_nisplus_initgroups_dyn (const char *user
, gid_t group
, long int *start
,
47 long int *size
, gid_t
**groupsp
, long int limit
,
50 if (grp_tablename_val
== NULL
)
52 enum nss_status status
= _nss_grp_create_tablename (errnop
);
54 if (status
!= NSS_STATUS_SUCCESS
)
59 char buf
[strlen (user
) + 12 + grp_tablename_len
];
61 snprintf (buf
, sizeof (buf
), "[members=%s],%s", user
, grp_tablename_val
);
63 result
= nis_list (buf
, FOLLOW_LINKS
| FOLLOW_PATH
| ALL_RESULTS
, NULL
, NULL
);
68 return NSS_STATUS_TRYAGAIN
;
71 if (__builtin_expect (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
, 0))
73 enum nss_status status
= niserr2nss (result
->status
);
75 nis_freeresult (result
);
79 if (NIS_RES_NUMOBJ (result
) == 0)
82 nis_freeresult (result
);
83 return NSS_STATUS_NOTFOUND
;
86 gid_t
*groups
= *groupsp
;
87 nis_object
*obj
= NIS_RES_OBJECT (result
);
88 for (unsigned int cnt
= 0; cnt
< NIS_RES_NUMOBJ (result
); ++cnt
, ++obj
)
90 if (__type_of (obj
) != NIS_ENTRY_OBJ
91 || strcmp (obj
->EN_data
.en_type
, "group_tbl") != 0
92 || obj
->EN_data
.en_cols
.en_cols_len
< 4)
95 char *numstr
= NISOBJVAL (2, obj
);
96 size_t len
= NISOBJLEN (2, obj
);
97 if (len
== 0 || numstr
[0] == '\0')
102 if (__builtin_expect (numstr
[len
- 1] != '\0', 0))
104 char numstrbuf
[len
+ 1];
105 memcpy (numstrbuf
, numstr
, len
);
106 numstrbuf
[len
] = '\0';
107 gid
= strtoul (numstrbuf
, &endp
, 10);
113 gid
= strtoul (numstr
, &endp
, 10);
121 /* Insert this group. */
124 /* Need a bigger buffer. */
127 if (limit
> 0 && *size
== limit
)
128 /* We reached the maximum. */
134 newsize
= MIN (limit
, 2 * *size
);
136 gid_t
*newgroups
= realloc (groups
, newsize
* sizeof (*groups
));
137 if (newgroups
== NULL
)
139 *groupsp
= groups
= newgroups
;
143 groups
[*start
] = gid
;
147 nis_freeresult (result
);
148 return NSS_STATUS_SUCCESS
;