1 /* Copyright (C) 1997-2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
24 #include <bits/libc-lock.h>
25 #include <rpcsvc/nis.h>
27 #include "nss-nisplus.h"
28 #include "nisplus-parser.h"
30 #include <nis_intern.h>
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)
39 extern nis_name grp_tablename_val attribute_hidden
;
40 extern size_t grp_tablename_len attribute_hidden
;
41 extern enum nss_status
_nss_grp_create_tablename (int *errnop
);
45 _nss_nisplus_initgroups_dyn (const char *user
, gid_t group
, long int *start
,
46 long int *size
, gid_t
**groupsp
, long int limit
,
49 if (grp_tablename_val
== NULL
)
51 enum nss_status status
= _nss_grp_create_tablename (errnop
);
53 if (status
!= NSS_STATUS_SUCCESS
)
58 char buf
[strlen (user
) + 12 + grp_tablename_len
];
60 snprintf (buf
, sizeof (buf
), "[members=%s],%s", user
, grp_tablename_val
);
62 result
= nis_list (buf
, FOLLOW_LINKS
| FOLLOW_PATH
| ALL_RESULTS
, NULL
, NULL
);
67 return NSS_STATUS_TRYAGAIN
;
70 if (__glibc_unlikely (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
))
72 enum nss_status status
= niserr2nss (result
->status
);
74 nis_freeresult (result
);
78 if (NIS_RES_NUMOBJ (result
) == 0)
81 nis_freeresult (result
);
82 return NSS_STATUS_NOTFOUND
;
85 gid_t
*groups
= *groupsp
;
86 nis_object
*obj
= NIS_RES_OBJECT (result
);
87 for (unsigned int cnt
= 0; cnt
< NIS_RES_NUMOBJ (result
); ++cnt
, ++obj
)
89 if (__type_of (obj
) != NIS_ENTRY_OBJ
90 || strcmp (obj
->EN_data
.en_type
, "group_tbl") != 0
91 || obj
->EN_data
.en_cols
.en_cols_len
< 4)
94 char *numstr
= NISOBJVAL (2, obj
);
95 size_t len
= NISOBJLEN (2, obj
);
96 if (len
== 0 || numstr
[0] == '\0')
101 if (__glibc_unlikely (numstr
[len
- 1] != '\0'))
103 char numstrbuf
[len
+ 1];
104 memcpy (numstrbuf
, numstr
, len
);
105 numstrbuf
[len
] = '\0';
106 gid
= strtoul (numstrbuf
, &endp
, 10);
112 gid
= strtoul (numstr
, &endp
, 10);
120 /* Insert this group. */
123 /* Need a bigger buffer. */
126 if (limit
> 0 && *size
== limit
)
127 /* We reached the maximum. */
133 newsize
= MIN (limit
, 2 * *size
);
135 gid_t
*newgroups
= realloc (groups
, newsize
* sizeof (*groups
));
136 if (newgroups
== NULL
)
138 *groupsp
= groups
= newgroups
;
142 groups
[*start
] = gid
;
146 nis_freeresult (result
);
147 return NSS_STATUS_SUCCESS
;