ctdb-scripts: Improve update and listing code
[samba4-gss.git] / nsswitch / libwbclient / wbclient.c
blobb6816ccd57090b28e52a32828cbeaf573b3d8841
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";
179 case WBC_ERR_NOT_MAPPED:
180 return "WBC_ERR_NOT_MAPPED";
183 return "unknown wbcErr value";
186 #define WBC_MAGIC (0x7a2b0e1e)
187 #define WBC_MAGIC_FREE (0x875634fe)
189 struct wbcMemPrefix {
190 uint32_t magic;
191 void (*destructor)(void *ptr);
194 static size_t wbcPrefixLen(void)
196 size_t result = sizeof(struct wbcMemPrefix);
197 return (result + 15) & ~15;
200 static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
202 return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
205 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
206 void *wbcAllocateMemory(size_t nelem, size_t elsize,
207 void (*destructor)(void *ptr))
209 struct wbcMemPrefix *result;
211 if (nelem >= (2<<24)/elsize) {
212 /* basic protection against integer wrap */
213 return NULL;
216 result = (struct wbcMemPrefix *)calloc(
217 1, nelem*elsize + wbcPrefixLen());
218 if (result == NULL) {
219 return NULL;
221 result->magic = WBC_MAGIC;
222 result->destructor = destructor;
223 return ((char *)result) + wbcPrefixLen();
226 /* Free library allocated memory */
227 _PUBLIC_
228 void wbcFreeMemory(void *p)
230 struct wbcMemPrefix *wbcMem;
232 if (p == NULL) {
233 return;
235 wbcMem = wbcMemToPrefix(p);
236 if (wbcMem->magic != WBC_MAGIC) {
237 return;
240 /* paranoid check to ensure we don't double free */
241 wbcMem->magic = WBC_MAGIC_FREE;
243 if (wbcMem->destructor != NULL) {
244 wbcMem->destructor(p);
246 free(wbcMem);
247 return;
250 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
251 char *wbcStrDup(const char *str)
253 char *result;
254 size_t len;
256 len = strlen(str);
257 result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
258 if (result == NULL) {
259 return NULL;
261 memcpy(result, str, len+1);
262 return result;
265 static void wbcStringArrayDestructor(void *ptr)
267 char **p = (char **)ptr;
268 while (*p != NULL) {
269 free(*p);
270 p += 1;
274 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
275 const char **wbcAllocateStringArray(int num_strings)
277 return (const char **)wbcAllocateMemory(
278 num_strings + 1, sizeof(const char *),
279 wbcStringArrayDestructor);
282 _PUBLIC_
283 wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
285 struct wbcLibraryDetails *info;
287 info = (struct wbcLibraryDetails *)wbcAllocateMemory(
288 1, sizeof(struct wbcLibraryDetails), NULL);
290 if (info == NULL) {
291 return WBC_ERR_NO_MEMORY;
294 info->major_version = WBCLIENT_MAJOR_VERSION;
295 info->minor_version = WBCLIENT_MINOR_VERSION;
296 info->vendor_version = WBCLIENT_VENDOR_VERSION;
298 *_details = info;
299 return WBC_ERR_SUCCESS;
302 /* Context handling functions */
304 static void wbcContextDestructor(void *ptr)
306 struct wbcContext *ctx = (struct wbcContext *)ptr;
308 winbindd_ctx_free(ctx->winbindd_ctx);
311 _PUBLIC_
312 struct wbcContext *wbcCtxCreate(void)
314 struct wbcContext *ctx;
315 struct winbindd_context *wbctx;
317 ctx = (struct wbcContext *)wbcAllocateMemory(
318 1, sizeof(struct wbcContext), wbcContextDestructor);
320 if (!ctx) {
321 return NULL;
324 wbctx = winbindd_ctx_create();
326 if (!wbctx) {
327 wbcFreeMemory(ctx);
328 return NULL;
331 ctx->winbindd_ctx = wbctx;
333 return ctx;
336 _PUBLIC_
337 void wbcCtxFree(struct wbcContext *ctx)
339 wbcFreeMemory(ctx);
342 _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
343 struct wbcContext *wbcGetGlobalCtx(void)
345 return &wbcGlobalCtx;