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 wbcErr
wbcRequestResponse(struct wbcContext
*ctx
, int cmd
,
112 struct winbindd_request
*request
,
113 struct winbindd_response
*response
)
115 struct winbindd_context
*wbctx
= NULL
;
118 wbctx
= ctx
->winbindd_ctx
;
121 return wbcRequestResponseInt(wbctx
, cmd
, request
, response
,
122 winbindd_request_response
);
125 wbcErr
wbcRequestResponsePriv(struct wbcContext
*ctx
, int cmd
,
126 struct winbindd_request
*request
,
127 struct winbindd_response
*response
)
129 struct winbindd_context
*wbctx
= NULL
;
132 wbctx
= ctx
->winbindd_ctx
;
135 return wbcRequestResponseInt(wbctx
, cmd
, request
, response
,
136 winbindd_priv_request_response
);
139 /** @brief Translate an error value into a string
143 * @return a pointer to a static string
145 const char *wbcErrorString(wbcErr 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";
178 return "unknown wbcErr value";
181 #define WBC_MAGIC (0x7a2b0e1e)
182 #define WBC_MAGIC_FREE (0x875634fe)
184 struct wbcMemPrefix
{
186 void (*destructor
)(void *ptr
);
189 static size_t wbcPrefixLen(void)
191 size_t result
= sizeof(struct wbcMemPrefix
);
192 return (result
+ 15) & ~15;
195 static struct wbcMemPrefix
*wbcMemToPrefix(void *ptr
)
197 return (struct wbcMemPrefix
*)(((char *)ptr
) - wbcPrefixLen());
200 void *wbcAllocateMemory(size_t nelem
, size_t elsize
,
201 void (*destructor
)(void *ptr
))
203 struct wbcMemPrefix
*result
;
205 if (nelem
>= (2<<24)/elsize
) {
206 /* basic protection against integer wrap */
210 result
= (struct wbcMemPrefix
*)calloc(
211 1, nelem
*elsize
+ wbcPrefixLen());
212 if (result
== NULL
) {
215 result
->magic
= WBC_MAGIC
;
216 result
->destructor
= destructor
;
217 return ((char *)result
) + wbcPrefixLen();
220 /* Free library allocated memory */
221 void wbcFreeMemory(void *p
)
223 struct wbcMemPrefix
*wbcMem
;
228 wbcMem
= wbcMemToPrefix(p
);
229 if (wbcMem
->magic
!= WBC_MAGIC
) {
233 /* paranoid check to ensure we don't double free */
234 wbcMem
->magic
= WBC_MAGIC_FREE
;
236 if (wbcMem
->destructor
!= NULL
) {
237 wbcMem
->destructor(p
);
243 char *wbcStrDup(const char *str
)
249 result
= (char *)wbcAllocateMemory(len
+1, sizeof(char), NULL
);
250 if (result
== NULL
) {
253 memcpy(result
, str
, len
+1);
257 static void wbcStringArrayDestructor(void *ptr
)
259 char **p
= (char **)ptr
;
266 const char **wbcAllocateStringArray(int num_strings
)
268 return (const char **)wbcAllocateMemory(
269 num_strings
+ 1, sizeof(const char *),
270 wbcStringArrayDestructor
);
273 wbcErr
wbcLibraryDetails(struct wbcLibraryDetails
**_details
)
275 struct wbcLibraryDetails
*info
;
277 info
= (struct wbcLibraryDetails
*)wbcAllocateMemory(
278 1, sizeof(struct wbcLibraryDetails
), NULL
);
281 return WBC_ERR_NO_MEMORY
;
284 info
->major_version
= WBCLIENT_MAJOR_VERSION
;
285 info
->minor_version
= WBCLIENT_MINOR_VERSION
;
286 info
->vendor_version
= WBCLIENT_VENDOR_VERSION
;
289 return WBC_ERR_SUCCESS
;
292 /* Context handling functions */
294 static void wbcContextDestructor(void *ptr
)
296 struct wbcContext
*ctx
= (struct wbcContext
*)ptr
;
298 winbindd_ctx_free(ctx
->winbindd_ctx
);
301 struct wbcContext
*wbcCtxCreate(void)
303 struct wbcContext
*ctx
;
304 struct winbindd_context
*wbctx
;
306 ctx
= (struct wbcContext
*)wbcAllocateMemory(
307 1, sizeof(struct wbcContext
), wbcContextDestructor
);
313 wbctx
= winbindd_ctx_create();
320 ctx
->winbindd_ctx
= wbctx
;
325 void wbcCtxFree(struct wbcContext
*ctx
)
330 struct wbcContext
*wbcGetGlobalCtx(void)
332 return &wbcGlobalCtx
;