1 /* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
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. */
29 #include "nss_hesiod.h"
31 /* Get the declaration of the parser function. */
33 #define STRUCTURE group
35 #include <nss/nss_files/files-parse.c>
38 _nss_hesiod_setgrent (void)
40 return NSS_STATUS_SUCCESS;
44 _nss_hesiod_endgrent (void)
46 return NSS_STATUS_SUCCESS;
49 static enum nss_status
50 lookup (const char *name, const char *type, struct group *grp,
51 char *buffer, size_t buflen, int *errnop)
53 struct parser_data *data = (void *) buffer;
60 context = _nss_hesiod_init ();
62 return NSS_STATUS_UNAVAIL;
64 list = hesiod_resolve (context, name, type);
68 return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
71 linebuflen = buffer + buflen - data->linebuffer;
72 len = strlen (*list) + 1;
75 hesiod_free_list (context, list);
78 return NSS_STATUS_TRYAGAIN;
81 memcpy (data->linebuffer, *list, len);
82 hesiod_free_list (context, list);
85 parse_res = _nss_files_parse_grent (buffer, grp, data, buflen, errnop);
87 return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
89 return NSS_STATUS_SUCCESS;
93 _nss_hesiod_getgrnam_r (const char *name, struct group *grp,
94 char *buffer, size_t buflen, int *errnop)
96 return lookup (name, "group", grp, buffer, buflen, errnop);
100 _nss_hesiod_getgrgid_r (gid_t gid, struct group *grp,
101 char *buffer, size_t buflen, int *errnop)
103 char gidstr[21]; /* We will probably never have a gid_t with more
106 snprintf (gidstr, sizeof gidstr, "%d", gid);
108 return lookup (gidstr, "gid", grp, buffer, buflen, errnop);
112 internal_gid_in_list (const gid_t *list, const gid_t g, long int len)
124 static enum nss_status
125 internal_gid_from_group (void *context, const char *groupname, gid_t *group)
128 enum nss_status status = NSS_STATUS_NOTFOUND;
130 grp_res = hesiod_resolve (context, groupname, "group");
131 if (grp_res != NULL && *grp_res != NULL)
135 while (*p != '\0' && *p != ':')
137 while (*p != '\0' && *p == ':')
139 while (*p != '\0' && *p != ':')
141 while (*p != '\0' && *p == ':')
150 while (*q != '\0' && *q != ':')
153 val = strtol (p, &endp, 10);
154 if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
157 if (endp == q && endp != p)
158 status = NSS_STATUS_SUCCESS;
161 hesiod_free_list (context, grp_res);
167 _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
168 long int *size, gid_t **groupsp, int *errnop)
170 enum nss_status status = NSS_STATUS_SUCCESS;
174 gid_t *groups = *groupsp;
176 context = _nss_hesiod_init ();
178 return NSS_STATUS_UNAVAIL;
180 list = hesiod_resolve (context, user, "grplist");
184 hesiod_end (context);
185 return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
188 if (!internal_gid_in_list (groups, group, *start))
190 if (__builtin_expect (*start == *size, 0))
192 /* Need a bigger buffer. */
194 newgroups = realloc (groups, 2 * *size * sizeof (*groups));
195 if (newgroups == NULL)
197 *groupsp = groups = newgroups;
201 groups[(*start)++] = group;
211 status = NSS_STATUS_NOTFOUND;
214 while (*q != '\0' && *q != ':')
220 val = strtol (p, &endp, 10);
221 if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
223 if (*endp == '\0' && endp != p)
224 status = NSS_STATUS_SUCCESS;
226 status = internal_gid_from_group (context, p, &group);
228 if (status == NSS_STATUS_SUCCESS
229 && !internal_gid_in_list (groups, group, *start))
231 if (__builtin_expect (*start == *size, 0))
233 /* Need a bigger buffer. */
235 newgroups = realloc (groups, 2 * *size * sizeof (*groups));
236 if (newgroups == NULL)
238 *groupsp = groups = newgroups;
242 groups[(*start)++] = group;
250 hesiod_free_list (context, list);
251 hesiod_end (context);
253 return NSS_STATUS_SUCCESS;