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";
181 return "unknown wbcErr value";
184 #define WBC_MAGIC (0x7a2b0e1e)
185 #define WBC_MAGIC_FREE (0x875634fe)
187 struct wbcMemPrefix
{
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 */
214 result
= (struct wbcMemPrefix
*)calloc(
215 1, nelem
*elsize
+ wbcPrefixLen());
216 if (result
== NULL
) {
219 result
->magic
= WBC_MAGIC
;
220 result
->destructor
= destructor
;
221 return ((char *)result
) + wbcPrefixLen();
224 /* Free library allocated memory */
226 void wbcFreeMemory(void *p
)
228 struct wbcMemPrefix
*wbcMem
;
233 wbcMem
= wbcMemToPrefix(p
);
234 if (wbcMem
->magic
!= WBC_MAGIC
) {
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
);
248 _PUBLIC_
/* this is internal to wbclient_internal.h, but part of the ABI */
249 char *wbcStrDup(const char *str
)
255 result
= (char *)wbcAllocateMemory(len
+1, sizeof(char), NULL
);
256 if (result
== NULL
) {
259 memcpy(result
, str
, len
+1);
263 static void wbcStringArrayDestructor(void *ptr
)
265 char **p
= (char **)ptr
;
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
);
281 wbcErr
wbcLibraryDetails(struct wbcLibraryDetails
**_details
)
283 struct wbcLibraryDetails
*info
;
285 info
= (struct wbcLibraryDetails
*)wbcAllocateMemory(
286 1, sizeof(struct wbcLibraryDetails
), 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
;
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
);
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
);
322 wbctx
= winbindd_ctx_create();
329 ctx
->winbindd_ctx
= wbctx
;
335 void wbcCtxFree(struct wbcContext
*ctx
)
340 _PUBLIC_
/* this is internal to wbclient_internal.h, but part of the ABI */
341 struct wbcContext
*wbcGetGlobalCtx(void)
343 return &wbcGlobalCtx
;