Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Winbind client API
5 :
6 : Copyright (C) Gerald (Jerry) Carter 2007
7 : Copyright (C) Matthew Newton 2015
8 :
9 :
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.
14 :
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.
19 :
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/>.
22 : */
23 :
24 : /* Required Headers */
25 :
26 : #include "replace.h"
27 : #include "libwbclient.h"
28 :
29 : /* From wb_common.c */
30 :
31 : struct winbindd_context;
32 :
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);
43 :
44 : /* Global context used for non-Ctx functions */
45 :
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
52 : };
53 :
54 : /*
55 : result == NSS_STATUS_UNAVAIL: winbind not around
56 : result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
57 :
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.
63 :
64 : --Volker
65 : */
66 :
67 901189 : 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))
75 : {
76 901189 : wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
77 4243 : NSS_STATUS nss_status;
78 :
79 : /* for some calls the request and/or response can be NULL */
80 :
81 905432 : nss_status = fn(wbctx, cmd, request, response);
82 :
83 901188 : switch (nss_status) {
84 433379 : case NSS_STATUS_SUCCESS:
85 433379 : wbc_status = WBC_ERR_SUCCESS;
86 433379 : break;
87 456634 : case NSS_STATUS_UNAVAIL:
88 456634 : wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
89 456634 : break;
90 6932 : case NSS_STATUS_NOTFOUND:
91 6932 : wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
92 6932 : break;
93 0 : default:
94 0 : wbc_status = WBC_ERR_NSS_ERROR;
95 0 : break;
96 : }
97 :
98 901188 : return wbc_status;
99 : }
100 :
101 : /**
102 : * @brief Wrapper around Winbind's send/receive API call
103 : *
104 : * @param ctx Context
105 : * @param cmd Winbind command operation to perform
106 : * @param request Send structure
107 : * @param response Receive structure
108 : *
109 : * @return #wbcErr
110 : */
111 : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
112 881225 : wbcErr wbcRequestResponse(struct wbcContext *ctx, int cmd,
113 : struct winbindd_request *request,
114 : struct winbindd_response *response)
115 : {
116 881225 : struct winbindd_context *wbctx = NULL;
117 :
118 881225 : if (ctx) {
119 1224 : wbctx = ctx->winbindd_ctx;
120 : }
121 :
122 881225 : return wbcRequestResponseInt(wbctx, cmd, request, response,
123 : winbindd_request_response);
124 : }
125 :
126 : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
127 19964 : wbcErr wbcRequestResponsePriv(struct wbcContext *ctx, int cmd,
128 : struct winbindd_request *request,
129 : struct winbindd_response *response)
130 : {
131 19964 : struct winbindd_context *wbctx = NULL;
132 :
133 19964 : if (ctx) {
134 0 : wbctx = ctx->winbindd_ctx;
135 : }
136 :
137 19964 : return wbcRequestResponseInt(wbctx, cmd, request, response,
138 : winbindd_priv_request_response);
139 : }
140 :
141 : /** @brief Translate an error value into a string
142 : *
143 : * @param error
144 : *
145 : * @return a pointer to a static string
146 : **/
147 : _PUBLIC_
148 414 : const char *wbcErrorString(wbcErr error)
149 : {
150 414 : switch (error) {
151 220 : case WBC_ERR_SUCCESS:
152 220 : return "WBC_ERR_SUCCESS";
153 0 : case WBC_ERR_NOT_IMPLEMENTED:
154 0 : return "WBC_ERR_NOT_IMPLEMENTED";
155 0 : case WBC_ERR_UNKNOWN_FAILURE:
156 0 : return "WBC_ERR_UNKNOWN_FAILURE";
157 0 : case WBC_ERR_NO_MEMORY:
158 0 : return "WBC_ERR_NO_MEMORY";
159 0 : case WBC_ERR_INVALID_SID:
160 0 : return "WBC_ERR_INVALID_SID";
161 0 : case WBC_ERR_INVALID_PARAM:
162 0 : return "WBC_ERR_INVALID_PARAM";
163 12 : case WBC_ERR_WINBIND_NOT_AVAILABLE:
164 12 : return "WBC_ERR_WINBIND_NOT_AVAILABLE";
165 106 : case WBC_ERR_DOMAIN_NOT_FOUND:
166 106 : return "WBC_ERR_DOMAIN_NOT_FOUND";
167 0 : case WBC_ERR_INVALID_RESPONSE:
168 0 : return "WBC_ERR_INVALID_RESPONSE";
169 0 : case WBC_ERR_NSS_ERROR:
170 0 : return "WBC_ERR_NSS_ERROR";
171 0 : case WBC_ERR_UNKNOWN_USER:
172 0 : return "WBC_ERR_UNKNOWN_USER";
173 0 : case WBC_ERR_UNKNOWN_GROUP:
174 0 : return "WBC_ERR_UNKNOWN_GROUP";
175 76 : case WBC_ERR_AUTH_ERROR:
176 76 : return "WBC_ERR_AUTH_ERROR";
177 0 : case WBC_ERR_PWD_CHANGE_FAILED:
178 0 : return "WBC_ERR_PWD_CHANGE_FAILED";
179 : }
180 :
181 0 : return "unknown wbcErr value";
182 : }
183 :
184 : #define WBC_MAGIC (0x7a2b0e1e)
185 : #define WBC_MAGIC_FREE (0x875634fe)
186 :
187 : struct wbcMemPrefix {
188 : uint32_t magic;
189 : void (*destructor)(void *ptr);
190 : };
191 :
192 463141 : static size_t wbcPrefixLen(void)
193 : {
194 463157 : size_t result = sizeof(struct wbcMemPrefix);
195 463141 : return (result + 15) & ~15;
196 : }
197 :
198 153755 : static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
199 : {
200 153755 : return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
201 : }
202 :
203 : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
204 154701 : void *wbcAllocateMemory(size_t nelem, size_t elsize,
205 : void (*destructor)(void *ptr))
206 : {
207 6 : struct wbcMemPrefix *result;
208 :
209 154701 : if (nelem >= (2<<24)/elsize) {
210 : /* basic protection against integer wrap */
211 0 : return NULL;
212 : }
213 :
214 154701 : result = (struct wbcMemPrefix *)calloc(
215 154701 : 1, nelem*elsize + wbcPrefixLen());
216 154701 : if (result == NULL) {
217 0 : return NULL;
218 : }
219 154701 : result->magic = WBC_MAGIC;
220 154701 : result->destructor = destructor;
221 154701 : return ((char *)result) + wbcPrefixLen();
222 : }
223 :
224 : /* Free library allocated memory */
225 : _PUBLIC_
226 166161 : void wbcFreeMemory(void *p)
227 : {
228 8 : struct wbcMemPrefix *wbcMem;
229 :
230 166161 : if (p == NULL) {
231 12402 : return;
232 : }
233 153755 : wbcMem = wbcMemToPrefix(p);
234 153755 : if (wbcMem->magic != WBC_MAGIC) {
235 0 : return;
236 : }
237 :
238 : /* paranoid check to ensure we don't double free */
239 153755 : wbcMem->magic = WBC_MAGIC_FREE;
240 :
241 153755 : if (wbcMem->destructor != NULL) {
242 149211 : wbcMem->destructor(p);
243 : }
244 153755 : free(wbcMem);
245 153755 : return;
246 : }
247 :
248 : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
249 1918 : char *wbcStrDup(const char *str)
250 : {
251 0 : char *result;
252 0 : size_t len;
253 :
254 1918 : len = strlen(str);
255 1918 : result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
256 1918 : if (result == NULL) {
257 0 : return NULL;
258 : }
259 1918 : memcpy(result, str, len+1);
260 1918 : return result;
261 : }
262 :
263 72 : static void wbcStringArrayDestructor(void *ptr)
264 : {
265 72 : char **p = (char **)ptr;
266 6560 : while (*p != NULL) {
267 6488 : free(*p);
268 6488 : p += 1;
269 : }
270 72 : }
271 :
272 : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
273 72 : const char **wbcAllocateStringArray(int num_strings)
274 : {
275 144 : return (const char **)wbcAllocateMemory(
276 72 : num_strings + 1, sizeof(const char *),
277 : wbcStringArrayDestructor);
278 : }
279 :
280 : _PUBLIC_
281 4 : wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
282 : {
283 0 : struct wbcLibraryDetails *info;
284 :
285 4 : info = (struct wbcLibraryDetails *)wbcAllocateMemory(
286 : 1, sizeof(struct wbcLibraryDetails), NULL);
287 :
288 4 : if (info == NULL) {
289 0 : return WBC_ERR_NO_MEMORY;
290 : }
291 :
292 4 : info->major_version = WBCLIENT_MAJOR_VERSION;
293 4 : info->minor_version = WBCLIENT_MINOR_VERSION;
294 4 : info->vendor_version = WBCLIENT_VENDOR_VERSION;
295 :
296 4 : *_details = info;
297 4 : return WBC_ERR_SUCCESS;
298 : }
299 :
300 : /* Context handling functions */
301 :
302 266 : static void wbcContextDestructor(void *ptr)
303 : {
304 266 : struct wbcContext *ctx = (struct wbcContext *)ptr;
305 :
306 266 : winbindd_ctx_free(ctx->winbindd_ctx);
307 266 : }
308 :
309 : _PUBLIC_
310 266 : struct wbcContext *wbcCtxCreate(void)
311 : {
312 0 : struct wbcContext *ctx;
313 0 : struct winbindd_context *wbctx;
314 :
315 266 : ctx = (struct wbcContext *)wbcAllocateMemory(
316 : 1, sizeof(struct wbcContext), wbcContextDestructor);
317 :
318 266 : if (!ctx) {
319 0 : return NULL;
320 : }
321 :
322 266 : wbctx = winbindd_ctx_create();
323 :
324 266 : if (!wbctx) {
325 0 : wbcFreeMemory(ctx);
326 0 : return NULL;
327 : }
328 :
329 266 : ctx->winbindd_ctx = wbctx;
330 :
331 266 : return ctx;
332 : }
333 :
334 : _PUBLIC_
335 266 : void wbcCtxFree(struct wbcContext *ctx)
336 : {
337 266 : wbcFreeMemory(ctx);
338 266 : }
339 :
340 : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
341 0 : struct wbcContext *wbcGetGlobalCtx(void)
342 : {
343 0 : return &wbcGlobalCtx;
344 : }
|