2 Unix SMB/CIFS implementation.
6 Copyright (C) Gerald (Jerry) Carter 2007
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 3 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* Required Headers */
26 #include "libwbclient.h"
28 /* From wb_common.c */
30 NSS_STATUS winbindd_request_response(struct winbindd_context *wbctx,
32 struct winbindd_request *request,
33 struct winbindd_response *response);
34 NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx,
36 struct winbindd_request *request,
37 struct winbindd_response *response);
40 result == NSS_STATUS_UNAVAIL: winbind not around
41 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
43 Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off
44 and when winbind return WINBINDD_ERROR. So the semantics of this
45 routine depends on winbind_on. Grepping for winbind_off I just
46 found 3 places where winbind is turned off, and this does not conflict
47 (as far as I have seen) with the callers of is_trusted_domains.
52 static wbcErr wbcRequestResponseInt(
54 struct winbindd_request *request,
55 struct winbindd_response *response,
56 NSS_STATUS (*fn)(struct winbindd_context *wbctx, int req_type,
57 struct winbindd_request *request,
58 struct winbindd_response *response))
60 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
61 NSS_STATUS nss_status;
63 /* for some calls the request and/or response can be NULL */
65 nss_status = fn(NULL, cmd, request, response);
68 case NSS_STATUS_SUCCESS:
69 wbc_status = WBC_ERR_SUCCESS;
71 case NSS_STATUS_UNAVAIL:
72 wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
74 case NSS_STATUS_NOTFOUND:
75 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
78 wbc_status = WBC_ERR_NSS_ERROR;
86 * @brief Wrapper around Winbind's send/receive API call
88 * @param cmd Winbind command operation to perform
89 * @param request Send structure
90 * @param response Receive structure
94 wbcErr wbcRequestResponse(int cmd,
95 struct winbindd_request *request,
96 struct winbindd_response *response)
98 return wbcRequestResponseInt(cmd, request, response,
99 winbindd_request_response);
102 wbcErr wbcRequestResponsePriv(int cmd,
103 struct winbindd_request *request,
104 struct winbindd_response *response)
106 return wbcRequestResponseInt(cmd, request, response,
107 winbindd_priv_request_response);
110 /** @brief Translate an error value into a string
114 * @return a pointer to a static string
116 const char *wbcErrorString(wbcErr error)
119 case WBC_ERR_SUCCESS:
120 return "WBC_ERR_SUCCESS";
121 case WBC_ERR_NOT_IMPLEMENTED:
122 return "WBC_ERR_NOT_IMPLEMENTED";
123 case WBC_ERR_UNKNOWN_FAILURE:
124 return "WBC_ERR_UNKNOWN_FAILURE";
125 case WBC_ERR_NO_MEMORY:
126 return "WBC_ERR_NO_MEMORY";
127 case WBC_ERR_INVALID_SID:
128 return "WBC_ERR_INVALID_SID";
129 case WBC_ERR_INVALID_PARAM:
130 return "WBC_ERR_INVALID_PARAM";
131 case WBC_ERR_WINBIND_NOT_AVAILABLE:
132 return "WBC_ERR_WINBIND_NOT_AVAILABLE";
133 case WBC_ERR_DOMAIN_NOT_FOUND:
134 return "WBC_ERR_DOMAIN_NOT_FOUND";
135 case WBC_ERR_INVALID_RESPONSE:
136 return "WBC_ERR_INVALID_RESPONSE";
137 case WBC_ERR_NSS_ERROR:
138 return "WBC_ERR_NSS_ERROR";
139 case WBC_ERR_UNKNOWN_USER:
140 return "WBC_ERR_UNKNOWN_USER";
141 case WBC_ERR_UNKNOWN_GROUP:
142 return "WBC_ERR_UNKNOWN_GROUP";
143 case WBC_ERR_AUTH_ERROR:
144 return "WBC_ERR_AUTH_ERROR";
145 case WBC_ERR_PWD_CHANGE_FAILED:
146 return "WBC_ERR_PWD_CHANGE_FAILED";
149 return "unknown wbcErr value";
152 #define WBC_MAGIC (0x7a2b0e1e)
153 #define WBC_MAGIC_FREE (0x875634fe)
155 struct wbcMemPrefix {
157 void (*destructor)(void *ptr);
160 static size_t wbcPrefixLen(void)
162 size_t result = sizeof(struct wbcMemPrefix);
163 return (result + 15) & ~15;
166 static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
168 return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
171 void *wbcAllocateMemory(size_t nelem, size_t elsize,
172 void (*destructor)(void *ptr))
174 struct wbcMemPrefix *result;
176 if (nelem >= (2<<24)/elsize) {
177 /* basic protection against integer wrap */
181 result = (struct wbcMemPrefix *)calloc(
182 1, nelem*elsize + wbcPrefixLen());
183 if (result == NULL) {
186 result->magic = WBC_MAGIC;
187 result->destructor = destructor;
188 return ((char *)result) + wbcPrefixLen();
191 /* Free library allocated memory */
192 void wbcFreeMemory(void *p)
194 struct wbcMemPrefix *wbcMem;
199 wbcMem = wbcMemToPrefix(p);
200 if (wbcMem->magic != WBC_MAGIC) {
204 /* paranoid check to ensure we don't double free */
205 wbcMem->magic = WBC_MAGIC_FREE;
207 if (wbcMem->destructor != NULL) {
208 wbcMem->destructor(p);
214 char *wbcStrDup(const char *str)
220 result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
221 if (result == NULL) {
224 memcpy(result, str, len+1);
228 static void wbcStringArrayDestructor(void *ptr)
230 char **p = (char **)ptr;
237 const char **wbcAllocateStringArray(int num_strings)
239 return (const char **)wbcAllocateMemory(
240 num_strings + 1, sizeof(const char *),
241 wbcStringArrayDestructor);
244 wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
246 struct wbcLibraryDetails *info;
248 info = (struct wbcLibraryDetails *)wbcAllocateMemory(
249 1, sizeof(struct wbcLibraryDetails), NULL);
252 return WBC_ERR_NO_MEMORY;
255 info->major_version = WBCLIENT_MAJOR_VERSION;
256 info->minor_version = WBCLIENT_MINOR_VERSION;
257 info->vendor_version = WBCLIENT_VENDOR_VERSION;
260 return WBC_ERR_SUCCESS;