s4:lib/tls: add support for gnutls_certificate_set_x509_{system_trust,trust_dir}()
[Samba.git] / nsswitch / libwbclient / wbclient.c
blob4562046a9fe98229a30c54aa4f2437a85aea863b
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind client API
6 Copyright (C) Gerald (Jerry) Carter 2007
7 Copyright (C) Matthew Newton 2015
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.
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.
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/>.
24 /* Required Headers */
26 #include "replace.h"
27 #include "libwbclient.h"
29 /* From wb_common.c */
31 struct winbindd_context;
33 NSS_STATUS winbindd_request_response(struct winbindd_context *wbctx,
34 int req_type,
35 struct winbindd_request *request,
36 struct winbindd_response *response);
37 NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx,
38 int req_type,
39 struct winbindd_request *request,
40 struct winbindd_response *response);
41 struct winbindd_context *winbindd_ctx_create(void);
42 void winbindd_ctx_free(struct winbindd_context *ctx);
44 /* Global context used for non-Ctx functions */
46 static 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
55 result == NSS_STATUS_UNAVAIL: winbind not around
56 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
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.
64 --Volker
67 static 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))
76 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
77 NSS_STATUS nss_status;
79 /* for some calls the request and/or response can be NULL */
81 nss_status = fn(wbctx, cmd, request, response);
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;
98 return wbc_status;
102 * @brief Wrapper around Winbind's send/receive API call
104 * @param ctx Context
105 * @param cmd Winbind command operation to perform
106 * @param request Send structure
107 * @param response Receive structure
109 * @return #wbcErr
111 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
112 wbcErr wbcRequestResponse(struct wbcContext *ctx, int cmd,
113 struct winbindd_request *request,
114 struct winbindd_response *response)
116 struct winbindd_context *wbctx = NULL;
118 if (ctx) {
119 wbctx = ctx->winbindd_ctx;
122 return wbcRequestResponseInt(wbctx, cmd, request, response,
123 winbindd_request_response);
126 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
127 wbcErr wbcRequestResponsePriv(struct wbcContext *ctx, int cmd,
128 struct winbindd_request *request,
129 struct winbindd_response *response)
131 struct winbindd_context *wbctx = NULL;
133 if (ctx) {
134 wbctx = ctx->winbindd_ctx;
137 return wbcRequestResponseInt(wbctx, cmd, request, response,
138 winbindd_priv_request_response);
141 /** @brief Translate an error value into a string
143 * @param error
145 * @return a pointer to a static string
147 _PUBLIC_
148 const char *wbcErrorString(wbcErr error)
150 switch (error) {
151 case WBC_ERR_SUCCESS:
152 return "WBC_ERR_SUCCESS";
153 case WBC_ERR_NOT_IMPLEMENTED:
154 return "WBC_ERR_NOT_IMPLEMENTED";
155 case WBC_ERR_UNKNOWN_FAILURE:
156 return "WBC_ERR_UNKNOWN_FAILURE";
157 case WBC_ERR_NO_MEMORY:
158 return "WBC_ERR_NO_MEMORY";
159 case WBC_ERR_INVALID_SID:
160 return "WBC_ERR_INVALID_SID";
161 case WBC_ERR_INVALID_PARAM:
162 return "WBC_ERR_INVALID_PARAM";
163 case WBC_ERR_WINBIND_NOT_AVAILABLE:
164 return "WBC_ERR_WINBIND_NOT_AVAILABLE";
165 case WBC_ERR_DOMAIN_NOT_FOUND:
166 return "WBC_ERR_DOMAIN_NOT_FOUND";
167 case WBC_ERR_INVALID_RESPONSE:
168 return "WBC_ERR_INVALID_RESPONSE";
169 case WBC_ERR_NSS_ERROR:
170 return "WBC_ERR_NSS_ERROR";
171 case WBC_ERR_UNKNOWN_USER:
172 return "WBC_ERR_UNKNOWN_USER";
173 case WBC_ERR_UNKNOWN_GROUP:
174 return "WBC_ERR_UNKNOWN_GROUP";
175 case WBC_ERR_AUTH_ERROR:
176 return "WBC_ERR_AUTH_ERROR";
177 case WBC_ERR_PWD_CHANGE_FAILED:
178 return "WBC_ERR_PWD_CHANGE_FAILED";
181 return "unknown wbcErr value";
184 #define WBC_MAGIC (0x7a2b0e1e)
185 #define WBC_MAGIC_FREE (0x875634fe)
187 struct wbcMemPrefix {
188 uint32_t magic;
189 void (*destructor)(void *ptr);
192 static size_t wbcPrefixLen(void)
194 size_t result = sizeof(struct wbcMemPrefix);
195 return (result + 15) & ~15;
198 static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
200 return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
203 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
204 void *wbcAllocateMemory(size_t nelem, size_t elsize,
205 void (*destructor)(void *ptr))
207 struct wbcMemPrefix *result;
209 if (nelem >= (2<<24)/elsize) {
210 /* basic protection against integer wrap */
211 return NULL;
214 result = (struct wbcMemPrefix *)calloc(
215 1, nelem*elsize + wbcPrefixLen());
216 if (result == NULL) {
217 return NULL;
219 result->magic = WBC_MAGIC;
220 result->destructor = destructor;
221 return ((char *)result) + wbcPrefixLen();
224 /* Free library allocated memory */
225 _PUBLIC_
226 void wbcFreeMemory(void *p)
228 struct wbcMemPrefix *wbcMem;
230 if (p == NULL) {
231 return;
233 wbcMem = wbcMemToPrefix(p);
234 if (wbcMem->magic != WBC_MAGIC) {
235 return;
238 /* paranoid check to ensure we don't double free */
239 wbcMem->magic = WBC_MAGIC_FREE;
241 if (wbcMem->destructor != NULL) {
242 wbcMem->destructor(p);
244 free(wbcMem);
245 return;
248 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
249 char *wbcStrDup(const char *str)
251 char *result;
252 size_t len;
254 len = strlen(str);
255 result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
256 if (result == NULL) {
257 return NULL;
259 memcpy(result, str, len+1);
260 return result;
263 static void wbcStringArrayDestructor(void *ptr)
265 char **p = (char **)ptr;
266 while (*p != NULL) {
267 free(*p);
268 p += 1;
272 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
273 const char **wbcAllocateStringArray(int num_strings)
275 return (const char **)wbcAllocateMemory(
276 num_strings + 1, sizeof(const char *),
277 wbcStringArrayDestructor);
280 _PUBLIC_
281 wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
283 struct wbcLibraryDetails *info;
285 info = (struct wbcLibraryDetails *)wbcAllocateMemory(
286 1, sizeof(struct wbcLibraryDetails), NULL);
288 if (info == NULL) {
289 return WBC_ERR_NO_MEMORY;
292 info->major_version = WBCLIENT_MAJOR_VERSION;
293 info->minor_version = WBCLIENT_MINOR_VERSION;
294 info->vendor_version = WBCLIENT_VENDOR_VERSION;
296 *_details = info;
297 return WBC_ERR_SUCCESS;
300 /* Context handling functions */
302 static void wbcContextDestructor(void *ptr)
304 struct wbcContext *ctx = (struct wbcContext *)ptr;
306 winbindd_ctx_free(ctx->winbindd_ctx);
309 _PUBLIC_
310 struct wbcContext *wbcCtxCreate(void)
312 struct wbcContext *ctx;
313 struct winbindd_context *wbctx;
315 ctx = (struct wbcContext *)wbcAllocateMemory(
316 1, sizeof(struct wbcContext), wbcContextDestructor);
318 if (!ctx) {
319 return NULL;
322 wbctx = winbindd_ctx_create();
324 if (!wbctx) {
325 wbcFreeMemory(ctx);
326 return NULL;
329 ctx->winbindd_ctx = wbctx;
331 return ctx;
334 _PUBLIC_
335 void wbcCtxFree(struct wbcContext *ctx)
337 wbcFreeMemory(ctx);
340 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
341 struct wbcContext *wbcGetGlobalCtx(void)
343 return &wbcGlobalCtx;