1 /* Prototype for the setgrent functions we use here. */
2 typedef enum nss_status (*set_function
) (void);
4 /* Prototype for the endgrent functions we use here. */
5 typedef enum nss_status (*end_function
) (void);
7 /* Prototype for the setgrent functions we use here. */
8 typedef enum nss_status (*get_function
) (struct group
*, char *,
11 static enum nss_status
12 compat_call (service_user
*nip
, const char *user
, gid_t group
, long int *start
,
13 long int *size
, gid_t
**groupsp
, long int limit
, int *errnop
)
16 size_t buflen
= __sysconf (_SC_GETGR_R_SIZE_MAX
);
18 enum nss_status status
;
19 set_function setgrent_fct
;
20 get_function getgrent_fct
;
21 end_function endgrent_fct
;
22 gid_t
*groups
= *groupsp
;
24 getgrent_fct
= __nss_lookup_function (nip
, "getgrent_r");
25 if (getgrent_fct
== NULL
)
26 return NSS_STATUS_UNAVAIL
;
28 setgrent_fct
= __nss_lookup_function (nip
, "setgrent");
31 status
= DL_CALL_FCT (setgrent_fct
, ());
32 if (status
!= NSS_STATUS_SUCCESS
)
36 endgrent_fct
= __nss_lookup_function (nip
, "endgrent");
38 tmpbuf
= __alloca (buflen
);
42 while ((status
= DL_CALL_FCT (getgrent_fct
,
43 (&grpbuf
, tmpbuf
, buflen
, errnop
)),
44 status
== NSS_STATUS_TRYAGAIN
)
48 tmpbuf
= __alloca (buflen
);
51 if (status
!= NSS_STATUS_SUCCESS
)
54 if (grpbuf
.gr_gid
!= group
)
58 for (m
= grpbuf
.gr_mem
; *m
!= NULL
; ++m
)
59 if (strcmp (*m
, user
) == 0)
61 /* Check whether the group is already on the list. */
63 for (cnt
= 0; cnt
< *start
; ++cnt
)
64 if (groups
[cnt
] == grpbuf
.gr_gid
)
69 /* Matches user and not yet on the list. Insert
71 if (__builtin_expect (*start
== *size
, 0))
73 /* Need a bigger buffer. */
77 if (limit
> 0 && *size
== limit
)
78 /* We reached the maximum. */
84 newsize
= MIN (limit
, 2 * *size
);
86 newgroups
= realloc (groups
,
87 newsize
* sizeof (*groups
));
88 if (newgroups
== NULL
)
90 *groupsp
= groups
= newgroups
;
94 groups
[*start
] = grpbuf
.gr_gid
;
102 while (status
== NSS_STATUS_SUCCESS
);
106 DL_CALL_FCT (endgrent_fct
, ());
108 return NSS_STATUS_SUCCESS
;