]> andersk Git - nss_nonlocal.git/blame - nonlocal-shadow.c
Use automake’s silent-rules mode if available, for quieter build output.
[nss_nonlocal.git] / nonlocal-shadow.c
CommitLineData
f6903667
AK
1/*
2 * nonlocal-shadow.c
3 * shadow database for nss_nonlocal proxy.
4 *
5 * Copyright © 2007 Anders Kaseorg <andersk@mit.edu>
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use, copy,
11 * modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28#define _GNU_SOURCE
29#include <sys/types.h>
30#include <unistd.h>
31#include <stdlib.h>
32#include <stdint.h>
33#include <string.h>
34#include <dlfcn.h>
35#include <stdio.h>
36#include <errno.h>
37#include <shadow.h>
38#include <nss.h>
39
40#include "nsswitch-internal.h"
41#include "nonlocal.h"
42
43
44static service_user *
45nss_shadow_nonlocal_database(void)
46{
47 static service_user *nip = NULL;
48 if (nip == NULL)
49 __nss_database_lookup("shadow_nonlocal", NULL, "", &nip);
50
51 return nip;
52}
53
54
55static service_user *spent_nip = NULL;
56static void *spent_fct_start;
57static union {
58 enum nss_status (*l)(struct spwd *pwd, char *buffer, size_t buflen,
59 int *errnop);
60 void *ptr;
61} spent_fct;
62static const char *spent_fct_name = "getspent_r";
63
64enum nss_status
65_nss_nonlocal_setspent(int stayopen)
66{
67 static const char *fct_name = "setspent";
68 static void *fct_start = NULL;
69 enum nss_status status;
70 service_user *nip;
71 union {
72 enum nss_status (*l)(int stayopen);
73 void *ptr;
74 } fct;
75
76 nip = nss_shadow_nonlocal_database();
77 if (nip == NULL)
78 return NSS_STATUS_UNAVAIL;
79 if (fct_start == NULL)
80 fct_start = __nss_lookup_function(nip, fct_name);
81 fct.ptr = fct_start;
82 do {
83 if (fct.ptr == NULL)
84 status = NSS_STATUS_UNAVAIL;
85 else
86 status = DL_CALL_FCT(fct.l, (stayopen));
87 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
88 if (status != NSS_STATUS_SUCCESS)
89 return status;
90
91 spent_nip = nip;
92 if (spent_fct_start == NULL)
93 spent_fct_start = __nss_lookup_function(nip, spent_fct_name);
94 spent_fct.ptr = spent_fct_start;
95 return NSS_STATUS_SUCCESS;
96}
97
98enum nss_status
99_nss_nonlocal_endspent(void)
100{
101 static const char *fct_name = "endspent";
102 static void *fct_start = NULL;
103 enum nss_status status;
104 service_user *nip;
105 union {
106 enum nss_status (*l)(void);
107 void *ptr;
108 } fct;
109
110 spent_nip = NULL;
111
112 nip = nss_shadow_nonlocal_database();
113 if (nip == NULL)
114 return NSS_STATUS_UNAVAIL;
115 if (fct_start == NULL)
116 fct_start = __nss_lookup_function(nip, fct_name);
117 fct.ptr = fct_start;
118 do {
119 if (fct.ptr == NULL)
120 status = NSS_STATUS_UNAVAIL;
121 else
122 status = DL_CALL_FCT(fct.l, ());
123 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
124 return status;
125}
126
127enum nss_status
128_nss_nonlocal_getspent_r(struct spwd *pwd, char *buffer, size_t buflen,
129 int *errnop)
130{
131 enum nss_status status;
132 if (spent_nip == NULL) {
133 status = _nss_nonlocal_setspent(0);
134 if (status != NSS_STATUS_SUCCESS)
135 return status;
136 }
137 do {
138 if (spent_fct.ptr == NULL)
139 status = NSS_STATUS_UNAVAIL;
140 else
141 status = DL_CALL_FCT(spent_fct.l, (pwd, buffer, buflen, errnop));
142 if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
143 return status;
144
145 if (status == NSS_STATUS_SUCCESS)
146 return NSS_STATUS_SUCCESS;
147 } while (__nss_next(&spent_nip, spent_fct_name, &spent_fct.ptr, status, 0) == 0);
148
149 spent_nip = NULL;
150 return NSS_STATUS_NOTFOUND;
151}
152
153
154enum nss_status
155_nss_nonlocal_getspnam_r(const char *name, struct spwd *pwd,
156 char *buffer, size_t buflen, int *errnop)
157{
158 static const char *fct_name = "getspnam_r";
159 static void *fct_start = NULL;
160 enum nss_status status;
161 service_user *nip;
162 union {
163 enum nss_status (*l)(const char *name, struct spwd *pwd,
164 char *buffer, size_t buflen, int *errnop);
165 void *ptr;
166 } fct;
167
168 nip = nss_shadow_nonlocal_database();
169 if (nip == NULL)
170 return NSS_STATUS_UNAVAIL;
171 if (fct_start == NULL)
172 fct_start = __nss_lookup_function(nip, fct_name);
173 fct.ptr = fct_start;
174 do {
175 if (fct.ptr == NULL)
176 status = NSS_STATUS_UNAVAIL;
177 else
178 status = DL_CALL_FCT(fct.l, (name, pwd, buffer, buflen, errnop));
179 if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
180 break;
181 } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
182 return status;
183}
This page took 0.066635 seconds and 5 git commands to generate.