]>
git.ipfire.org Git - thirdparty/glibc.git/blob - nis/nss_nis/nis-initgroups.c
1 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
26 #include <rpcsvc/yp.h>
27 #include <rpcsvc/ypclnt.h>
28 #include <sys/param.h>
32 /* Get the declaration of the parser function. */
34 #define STRUCTURE group
36 #include <nss/nss_files/files-parse.c>
41 struct response_t
*next
;
46 struct response_t
*start
;
47 struct response_t
*next
;
49 typedef struct intern_t intern_t
;
52 saveit (int instatus
, char *inkey
, int inkeylen
, char *inval
,
53 int invallen
, char *indata
)
55 intern_t
*intern
= (intern_t
*) indata
;
57 if (instatus
!= YP_TRUE
)
60 if (inkey
&& inkeylen
> 0 && inval
&& invallen
> 0)
62 if (intern
->start
== NULL
)
64 intern
->start
= malloc (sizeof (struct response_t
));
65 if (intern
->start
== NULL
)
67 intern
->next
= intern
->start
;
71 intern
->next
->next
= malloc (sizeof (struct response_t
));
72 if (intern
->next
->next
== NULL
)
74 intern
->next
= intern
->next
->next
;
76 intern
->next
->next
= NULL
;
77 intern
->next
->val
= malloc (invallen
+ 1);
78 if (intern
->next
->val
== NULL
)
80 strncpy (intern
->next
->val
, inval
, invallen
);
81 intern
->next
->val
[invallen
] = '\0';
87 static enum nss_status
88 internal_setgrent (intern_t
*intern
)
91 struct ypall_callback ypcb
;
92 enum nss_status status
;
94 if (yp_get_default_domain (&domainname
))
95 return NSS_STATUS_UNAVAIL
;
99 ypcb
.foreach
= saveit
;
100 ypcb
.data
= (char *) intern
;
101 status
= yperr2nss (yp_all (domainname
, "group.byname", &ypcb
));
102 intern
->next
= intern
->start
;
107 static enum nss_status
108 internal_getgrent_r (struct group
*grp
, char *buffer
, size_t buflen
,
109 int *errnop
, intern_t
*intern
)
111 struct parser_data
*data
= (void *) buffer
;
115 if (intern
->start
== NULL
)
116 internal_setgrent (intern
);
118 /* Get the next entry until we found a correct one. */
121 if (intern
->next
== NULL
)
124 return NSS_STATUS_NOTFOUND
;
126 p
= strncpy (buffer
, intern
->next
->val
, buflen
);
130 parse_res
= _nss_files_parse_grent (p
, grp
, data
, buflen
, errnop
);
132 return NSS_STATUS_TRYAGAIN
;
133 intern
->next
= intern
->next
->next
;
137 return NSS_STATUS_SUCCESS
;
141 _nss_nis_initgroups_dyn (const char *user
, gid_t group
, long int *start
,
142 long int *size
, gid_t
**groupsp
, long int limit
,
145 struct group grpbuf
, *g
;
146 size_t buflen
= sysconf (_SC_GETPW_R_SIZE_MAX
);
148 enum nss_status status
;
149 intern_t intern
= { NULL
, NULL
};
150 gid_t
*groups
= *groupsp
;
152 status
= internal_setgrent (&intern
);
153 if (status
!= NSS_STATUS_SUCCESS
)
156 tmpbuf
= __alloca (buflen
);
161 internal_getgrent_r (&grpbuf
, tmpbuf
, buflen
, errnop
,
162 &intern
)) == NSS_STATUS_TRYAGAIN
163 && *errnop
== ERANGE
)
166 tmpbuf
= __alloca (buflen
);
169 if (status
!= NSS_STATUS_SUCCESS
)
174 if (g
->gr_gid
!= group
)
178 for (m
= g
->gr_mem
; *m
!= NULL
; ++m
)
179 if (strcmp (*m
, user
) == 0)
181 /* Matches user. Insert this group. */
184 /* Need a bigger buffer. */
188 if (limit
> 0 && *size
== limit
)
189 /* We reached the maximum. */
195 newsize
= MIN (limit
, 2 * *size
);
197 newgroups
= realloc (groups
, newsize
* sizeof (*groups
));
198 if (newgroups
== NULL
)
200 *groupsp
= groups
= newgroups
;
204 groups
[*start
] = g
->gr_gid
;
211 while (status
== NSS_STATUS_SUCCESS
);
214 while (intern
.start
!= NULL
)
216 if (intern
.start
->val
!= NULL
)
217 free (intern
.start
->val
);
218 intern
.next
= intern
.start
;
219 intern
.start
= intern
.start
->next
;
223 return NSS_STATUS_SUCCESS
;