]>
git.ipfire.org Git - thirdparty/glibc.git/blob - inet/getnetgrent_r.c
52a90d055ce03fd073c1ce044309717705647d64
1 /* Copyright (C) 1996 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
19 #include <libc-lock.h>
25 /* Protect above variable against multiple uses at the same time. */
26 __libc_lock_define_initialized (static, lock
)
28 /* This handle for the NSS data base is shared between all
29 set/get/endXXXent functions. */
30 static service_user
*nip
;
31 /* Remember the first service_entry, it's always the same. */
32 static service_user
*startp
;
35 /* The lookup function for the first entry of this service. */
36 extern int __nss_netgroup_lookup (service_user
**nip
, const char *name
,
39 /* Set up NIP to run through the services. If ALL is zero, use NIP's
40 current location if it's not nil. Return nonzero if there are no
42 static enum nss_status
43 setup (void **fctp
, const char *func_name
, int all
)
48 no_more
= __nss_netgroup_lookup (&nip
, func_name
, fctp
);
49 startp
= no_more
? (service_user
*) -1 : nip
;
51 else if (startp
== (service_user
*) -1)
52 /* No services at all. */
57 /* Reset to the beginning of the service list. */
59 /* Look up the first function. */
60 no_more
= __nss_lookup (&nip
, func_name
, fctp
);
66 setnetgrent (const char *group
)
68 enum nss_status (*fct
) (const char *);
69 enum nss_status status
= NSS_STATUS_UNAVAIL
;
72 __libc_lock_lock (lock
);
74 /* Cycle through all the services and run their setnetgrent functions. */
75 no_more
= setup ((void **) &fct
, "setnetgrent", 1);
78 /* Ignore status, we force check in __NSS_NEXT. */
79 status
= (*fct
) (group
);
81 no_more
= __nss_next (&nip
, "setnetgrent", (void **) &fct
, status
, 0);
84 __libc_lock_unlock (lock
);
86 return status
== NSS_STATUS_SUCCESS
;
93 service_user
*old_nip
;
94 enum nss_status (*fct
) (void);
97 __libc_lock_lock (lock
);
99 /* Remember which was the last used service. */
102 /* Cycle through all the services and run their setnetgrent functions. */
103 no_more
= setup ((void **) &fct
, "endnetgrent", 1);
106 /* Ignore status, we force check in __NSS_NEXT. */
109 no_more
= (nip
== old_nip
110 || __nss_next (&nip
, "endnetgrent", (void **) &fct
, 0, 1));
113 __libc_lock_unlock (lock
);
118 __getnetgrent_r (char **hostp
, char **userp
, char **domainp
,
119 char *buffer
, int buflen
)
121 enum nss_status (*fct
) (struct __netgrent
*, char *, int);
122 struct __netgrent result
;
125 /* Initialize status to return if no more functions are found. */
126 enum nss_status status
= NSS_STATUS_NOTFOUND
;
128 __libc_lock_lock (lock
);
130 /* Run through available functions, starting with the same function last
131 run. We will repeat each function as long as it succeeds, and then go
132 on to the next service action. */
133 no_more
= setup ((void **) &fct
, "getnetgrent_r", 0);
136 status
= (*fct
) (&result
, buffer
, buflen
);
138 no_more
= __nss_next (&nip
, "getnetgrent_r", (void **) &fct
, status
, 0);
141 if (status
== NSS_STATUS_SUCCESS
)
143 *hostp
= result
.host
;
144 *userp
= result
.user
;
145 *domainp
= result
.domain
;
148 __libc_lock_unlock (lock
);
150 return status
== NSS_STATUS_SUCCESS
? 1 : 0;
152 weak_alias (__getnetgrent_r
, getnetgrent_r
)
154 /* Test whether given (host,user,domain) triple is in NETGROUP. */
156 innetgr (const char *netgroup
, const char *host
, const char *user
,
159 int (*setfct
) (const char *);
160 void (*endfct
) (void);
161 int (*getfct
) (struct __netgrent
*, char *, int);
165 __libc_lock_lock (lock
);
167 /* Walk through the services until we found an answer or we shall
168 not work further. We can do some optimization here. Since all
169 services must provide the `setnetgrent' function we can do all
170 the work during one walk through the service list. */
171 no_more
= setup ((void **) &setfct
, "setnetgrent", 1);
174 enum nss_status status
;
177 status
= (*setfct
) (netgroup
);
178 if (status
== NSS_STATUS_SUCCESS
179 && __nss_lookup (&nip
, "getnetgrent_r", (void **) &getfct
) == 0)
182 struct __netgrent entry
;
184 while ((*getfct
) (&entry
, buffer
, sizeof buffer
)
185 == NSS_STATUS_SUCCESS
)
187 if ((entry
.host
== NULL
|| host
== NULL
188 || strcmp (entry
.host
, host
) == 0)
189 && (entry
.user
== NULL
|| user
== NULL
190 || strcmp (entry
.user
, user
) == 0)
191 && (entry
.domain
== NULL
|| domain
== NULL
192 || strcmp (entry
.domain
, domain
) == 0))
202 /* If we found one service which does know the given
203 netgroup we don't try further. */
204 status
= NSS_STATUS_RETURN
;
207 /* Free all resources of the service. */
208 if (__nss_lookup (&nip
, "endnetgrent", (void **) &endfct
) == 0)
211 /* Look for the next service. */
212 no_more
= __nss_next (&nip
, "setnetgrent", (void **) &setfct
, status
, 0);
215 __libc_lock_unlock (lock
);