source: vendor/current/nsswitch/libwbclient/wbclient.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 7.6 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Winbind client API
5
6 Copyright (C) Gerald (Jerry) Carter 2007
7 Copyright (C) Matthew Newton 2015
8
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24/* Required Headers */
25
26#include "replace.h"
27#include "libwbclient.h"
28
29/* From wb_common.c */
30
31struct winbindd_context;
32
33NSS_STATUS winbindd_request_response(struct winbindd_context *wbctx,
34 int req_type,
35 struct winbindd_request *request,
36 struct winbindd_response *response);
37NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx,
38 int req_type,
39 struct winbindd_request *request,
40 struct winbindd_response *response);
41struct winbindd_context *winbindd_ctx_create(void);
42void winbindd_ctx_free(struct winbindd_context *ctx);
43
44/* Global context used for non-Ctx functions */
45
46static struct wbcContext wbcGlobalCtx = {
47 .winbindd_ctx = NULL,
48 .pw_cache_size = 0,
49 .pw_cache_idx = 0,
50 .gr_cache_size = 0,
51 .gr_cache_idx = 0
52};
53
54/*
55 result == NSS_STATUS_UNAVAIL: winbind not around
56 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
57
58 Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off
59 and when winbind return WINBINDD_ERROR. So the semantics of this
60 routine depends on winbind_on. Grepping for winbind_off I just
61 found 3 places where winbind is turned off, and this does not conflict
62 (as far as I have seen) with the callers of is_trusted_domains.
63
64 --Volker
65*/
66
67static wbcErr wbcRequestResponseInt(
68 struct winbindd_context *wbctx,
69 int cmd,
70 struct winbindd_request *request,
71 struct winbindd_response *response,
72 NSS_STATUS (*fn)(struct winbindd_context *wbctx, int req_type,
73 struct winbindd_request *request,
74 struct winbindd_response *response))
75{
76 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
77 NSS_STATUS nss_status;
78
79 /* for some calls the request and/or response can be NULL */
80
81 nss_status = fn(wbctx, cmd, request, response);
82
83 switch (nss_status) {
84 case NSS_STATUS_SUCCESS:
85 wbc_status = WBC_ERR_SUCCESS;
86 break;
87 case NSS_STATUS_UNAVAIL:
88 wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
89 break;
90 case NSS_STATUS_NOTFOUND:
91 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
92 break;
93 default:
94 wbc_status = WBC_ERR_NSS_ERROR;
95 break;
96 }
97
98 return wbc_status;
99}
100
101/**
102 * @brief Wrapper around Winbind's send/receive API call
103 *
104 * @param ctx Context
105 * @param cmd Winbind command operation to perform
106 * @param request Send structure
107 * @param response Receive structure
108 *
109 * @return #wbcErr
110 */
111wbcErr wbcRequestResponse(struct wbcContext *ctx, int cmd,
112 struct winbindd_request *request,
113 struct winbindd_response *response)
114{
115 struct winbindd_context *wbctx = NULL;
116
117 if (ctx) {
118 wbctx = ctx->winbindd_ctx;
119 }
120
121 return wbcRequestResponseInt(wbctx, cmd, request, response,
122 winbindd_request_response);
123}
124
125wbcErr wbcRequestResponsePriv(struct wbcContext *ctx, int cmd,
126 struct winbindd_request *request,
127 struct winbindd_response *response)
128{
129 struct winbindd_context *wbctx = NULL;
130
131 if (ctx) {
132 wbctx = ctx->winbindd_ctx;
133 }
134
135 return wbcRequestResponseInt(wbctx, cmd, request, response,
136 winbindd_priv_request_response);
137}
138
139/** @brief Translate an error value into a string
140 *
141 * @param error
142 *
143 * @return a pointer to a static string
144 **/
145const char *wbcErrorString(wbcErr error)
146{
147 switch (error) {
148 case WBC_ERR_SUCCESS:
149 return "WBC_ERR_SUCCESS";
150 case WBC_ERR_NOT_IMPLEMENTED:
151 return "WBC_ERR_NOT_IMPLEMENTED";
152 case WBC_ERR_UNKNOWN_FAILURE:
153 return "WBC_ERR_UNKNOWN_FAILURE";
154 case WBC_ERR_NO_MEMORY:
155 return "WBC_ERR_NO_MEMORY";
156 case WBC_ERR_INVALID_SID:
157 return "WBC_ERR_INVALID_SID";
158 case WBC_ERR_INVALID_PARAM:
159 return "WBC_ERR_INVALID_PARAM";
160 case WBC_ERR_WINBIND_NOT_AVAILABLE:
161 return "WBC_ERR_WINBIND_NOT_AVAILABLE";
162 case WBC_ERR_DOMAIN_NOT_FOUND:
163 return "WBC_ERR_DOMAIN_NOT_FOUND";
164 case WBC_ERR_INVALID_RESPONSE:
165 return "WBC_ERR_INVALID_RESPONSE";
166 case WBC_ERR_NSS_ERROR:
167 return "WBC_ERR_NSS_ERROR";
168 case WBC_ERR_UNKNOWN_USER:
169 return "WBC_ERR_UNKNOWN_USER";
170 case WBC_ERR_UNKNOWN_GROUP:
171 return "WBC_ERR_UNKNOWN_GROUP";
172 case WBC_ERR_AUTH_ERROR:
173 return "WBC_ERR_AUTH_ERROR";
174 case WBC_ERR_PWD_CHANGE_FAILED:
175 return "WBC_ERR_PWD_CHANGE_FAILED";
176 }
177
178 return "unknown wbcErr value";
179}
180
181#define WBC_MAGIC (0x7a2b0e1e)
182#define WBC_MAGIC_FREE (0x875634fe)
183
184struct wbcMemPrefix {
185 uint32_t magic;
186 void (*destructor)(void *ptr);
187};
188
189static size_t wbcPrefixLen(void)
190{
191 size_t result = sizeof(struct wbcMemPrefix);
192 return (result + 15) & ~15;
193}
194
195static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
196{
197 return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
198}
199
200void *wbcAllocateMemory(size_t nelem, size_t elsize,
201 void (*destructor)(void *ptr))
202{
203 struct wbcMemPrefix *result;
204
205 if (nelem >= (2<<24)/elsize) {
206 /* basic protection against integer wrap */
207 return NULL;
208 }
209
210 result = (struct wbcMemPrefix *)calloc(
211 1, nelem*elsize + wbcPrefixLen());
212 if (result == NULL) {
213 return NULL;
214 }
215 result->magic = WBC_MAGIC;
216 result->destructor = destructor;
217 return ((char *)result) + wbcPrefixLen();
218}
219
220/* Free library allocated memory */
221void wbcFreeMemory(void *p)
222{
223 struct wbcMemPrefix *wbcMem;
224
225 if (p == NULL) {
226 return;
227 }
228 wbcMem = wbcMemToPrefix(p);
229 if (wbcMem->magic != WBC_MAGIC) {
230 return;
231 }
232
233 /* paranoid check to ensure we don't double free */
234 wbcMem->magic = WBC_MAGIC_FREE;
235
236 if (wbcMem->destructor != NULL) {
237 wbcMem->destructor(p);
238 }
239 free(wbcMem);
240 return;
241}
242
243char *wbcStrDup(const char *str)
244{
245 char *result;
246 size_t len;
247
248 len = strlen(str);
249 result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
250 if (result == NULL) {
251 return NULL;
252 }
253 memcpy(result, str, len+1);
254 return result;
255}
256
257static void wbcStringArrayDestructor(void *ptr)
258{
259 char **p = (char **)ptr;
260 while (*p != NULL) {
261 free(*p);
262 p += 1;
263 }
264}
265
266const char **wbcAllocateStringArray(int num_strings)
267{
268 return (const char **)wbcAllocateMemory(
269 num_strings + 1, sizeof(const char *),
270 wbcStringArrayDestructor);
271}
272
273wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
274{
275 struct wbcLibraryDetails *info;
276
277 info = (struct wbcLibraryDetails *)wbcAllocateMemory(
278 1, sizeof(struct wbcLibraryDetails), NULL);
279
280 if (info == NULL) {
281 return WBC_ERR_NO_MEMORY;
282 }
283
284 info->major_version = WBCLIENT_MAJOR_VERSION;
285 info->minor_version = WBCLIENT_MINOR_VERSION;
286 info->vendor_version = WBCLIENT_VENDOR_VERSION;
287
288 *_details = info;
289 return WBC_ERR_SUCCESS;
290}
291
292/* Context handling functions */
293
294static void wbcContextDestructor(void *ptr)
295{
296 struct wbcContext *ctx = (struct wbcContext *)ptr;
297
298 winbindd_ctx_free(ctx->winbindd_ctx);
299}
300
301struct wbcContext *wbcCtxCreate(void)
302{
303 struct wbcContext *ctx;
304 struct winbindd_context *wbctx;
305
306 ctx = (struct wbcContext *)wbcAllocateMemory(
307 1, sizeof(struct wbcContext), wbcContextDestructor);
308
309 if (!ctx) {
310 return NULL;
311 }
312
313 wbctx = winbindd_ctx_create();
314
315 if (!wbctx) {
316 wbcFreeMemory(ctx);
317 return NULL;
318 }
319
320 ctx->winbindd_ctx = wbctx;
321
322 return ctx;
323}
324
325void wbcCtxFree(struct wbcContext *ctx)
326{
327 wbcFreeMemory(ctx);
328}
329
330struct wbcContext *wbcGetGlobalCtx(void)
331{
332 return &wbcGlobalCtx;
333}
Note: See TracBrowser for help on using the repository browser.