2 Unix SMB/CIFS implementation.
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 */
27 #include "libwbclient.h"
29 /* From wb_common.c */
31 struct winbindd_context
;
33 NSS_STATUS
winbindd_request_response(struct winbindd_context
*wbctx
,
35 struct winbindd_request
*request
,
36 struct winbindd_response
*response
);
37 NSS_STATUS
winbindd_priv_request_response(struct winbindd_context
*wbctx
,
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
= {
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.
67 static wbcErr
wbcRequestResponseInt(
68 struct winbindd_context
*wbctx
,
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
);
84 case NSS_STATUS_SUCCESS
:
85 wbc_status
= WBC_ERR_SUCCESS
;
87 case NSS_STATUS_UNAVAIL
:
88 wbc_status
= WBC_ERR_WINBIND_NOT_AVAILABLE
;
90 case NSS_STATUS_NOTFOUND
:
91 wbc_status
= WBC_ERR_DOMAIN_NOT_FOUND
;
94 wbc_status
= WBC_ERR_NSS_ERROR
;
102 * @brief Wrapper around Winbind's send/receive API call
105 * @param cmd Winbind command operation to perform
106 * @param request Send structure
107 * @param response Receive structure
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
;
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
;
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
145 * @return a pointer to a static string
148 const char *wbcErrorString(wbcErr 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
{
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 */
216 result
= (struct wbcMemPrefix
*)calloc(
217 1, nelem
*elsize
+ wbcPrefixLen());
218 if (result
== NULL
) {
221 result
->magic
= WBC_MAGIC
;
222 result
->destructor
= destructor
;
223 return ((char *)result
) + wbcPrefixLen();
226 /* Free library allocated memory */
228 void wbcFreeMemory(void *p
)
230 struct wbcMemPrefix
*wbcMem
;
235 wbcMem
= wbcMemToPrefix(p
);
236 if (wbcMem
->magic
!= WBC_MAGIC
) {
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
);
250 _PUBLIC_
/* this is internal to wbclient_internal.h, but part of the ABI */
251 char *wbcStrDup(const char *str
)
257 result
= (char *)wbcAllocateMemory(len
+1, sizeof(char), NULL
);
258 if (result
== NULL
) {
261 memcpy(result
, str
, len
+1);
265 static void wbcStringArrayDestructor(void *ptr
)
267 char **p
= (char **)ptr
;
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
);
283 wbcErr
wbcLibraryDetails(struct wbcLibraryDetails
**_details
)
285 struct wbcLibraryDetails
*info
;
287 info
= (struct wbcLibraryDetails
*)wbcAllocateMemory(
288 1, sizeof(struct wbcLibraryDetails
), 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
;
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
);
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
);
324 wbctx
= winbindd_ctx_create();
331 ctx
->winbindd_ctx
= wbctx
;
337 void wbcCtxFree(struct wbcContext
*ctx
)
342 _PUBLIC_
/* this is internal to wbclient_internal.h, but part of the ABI */
343 struct wbcContext
*wbcGetGlobalCtx(void)
345 return &wbcGlobalCtx
;