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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 #include <bits/libc-lock.h>
27 #include <rpcsvc/nis.h>
29 #include "nss-nisplus.h"
30 #include "nisplus-parser.h"
32 #include <nis_intern.h>
35 #define NISOBJVAL(col, obj) \
36 ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
38 #define NISOBJLEN(col, obj) \
39 ((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
41 extern nis_name grp_tablename_val attribute_hidden
;
42 extern size_t grp_tablename_len attribute_hidden
;
43 extern enum nss_status
_nss_grp_create_tablename (int *errnop
);
47 _nss_nisplus_initgroups_dyn (const char *user
, gid_t group
, long int *start
,
48 long int *size
, gid_t
**groupsp
, long int limit
,
51 if (grp_tablename_val
== NULL
)
53 enum nss_status status
= _nss_grp_create_tablename (errnop
);
55 if (status
!= NSS_STATUS_SUCCESS
)
60 char buf
[strlen (user
) + 12 + grp_tablename_len
];
62 snprintf (buf
, sizeof (buf
), "[members=%s],%s", user
, grp_tablename_val
);
64 result
= nis_list (buf
, FOLLOW_LINKS
| FOLLOW_PATH
| ALL_RESULTS
, NULL
, NULL
);
69 return NSS_STATUS_TRYAGAIN
;
72 if (__builtin_expect (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
, 0))
74 enum nss_status status
= niserr2nss (result
->status
);
76 nis_freeresult (result
);
80 if (NIS_RES_NUMOBJ (result
) == 0)
83 nis_freeresult (result
);
84 return NSS_STATUS_NOTFOUND
;
87 gid_t
*groups
= *groupsp
;
88 nis_object
*obj
= NIS_RES_OBJECT (result
);
89 for (unsigned int cnt
= 0; cnt
< NIS_RES_NUMOBJ (result
); ++cnt
, ++obj
)
91 if (__type_of (obj
) != NIS_ENTRY_OBJ
92 || strcmp (obj
->EN_data
.en_type
, "group_tbl") != 0
93 || obj
->EN_data
.en_cols
.en_cols_len
< 4)
96 char *numstr
= NISOBJVAL (2, obj
);
97 size_t len
= NISOBJLEN (2, obj
);
98 if (len
== 0 || numstr
[0] == '\0')
103 if (__builtin_expect (numstr
[len
- 1] != '\0', 0))
105 char numstrbuf
[len
+ 1];
106 memcpy (numstrbuf
, numstr
, len
);
107 numstrbuf
[len
] = '\0';
108 gid
= strtoul (numstrbuf
, &endp
, 10);
114 gid
= strtoul (numstr
, &endp
, 10);
122 /* Insert this group. */
125 /* Need a bigger buffer. */
128 if (limit
> 0 && *size
== limit
)
129 /* We reached the maximum. */
135 newsize
= MIN (limit
, 2 * *size
);
137 gid_t
*newgroups
= realloc (groups
, newsize
* sizeof (*groups
));
138 if (newgroups
== NULL
)
140 *groupsp
= groups
= newgroups
;
144 groups
[*start
] = gid
;
148 nis_freeresult (result
);
149 return NSS_STATUS_SUCCESS
;