2 Unix SMB/CIFS implementation.
6 Copyright (C) Gerald (Jerry) Carter 2007-2008
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 */
25 #include "libwbclient.h"
29 /** @brief Ping winbindd to see if the daemon is running
36 struct winbindd_request request
;
37 struct winbindd_response response
;
39 /* Initialize request */
42 ZERO_STRUCT(response
);
44 return wbcRequestResponse(WINBINDD_PING
, &request
, &response
);
47 wbcErr
wbcInterfaceDetails(struct wbcInterfaceDetails
**_details
)
49 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
50 struct wbcInterfaceDetails
*info
;
51 struct wbcDomainInfo
*domain
= NULL
;
52 struct winbindd_request request
;
53 struct winbindd_response response
;
55 /* Initialize request */
58 ZERO_STRUCT(response
);
60 info
= talloc(NULL
, struct wbcInterfaceDetails
);
61 BAIL_ON_PTR_ERROR(info
, wbc_status
);
63 /* first the interface version */
64 wbc_status
= wbcRequestResponse(WINBINDD_INTERFACE_VERSION
, NULL
, &response
);
65 BAIL_ON_WBC_ERROR(wbc_status
);
66 info
->interface_version
= response
.data
.interface_version
;
68 /* then the samba version and the winbind separator */
69 wbc_status
= wbcRequestResponse(WINBINDD_INFO
, NULL
, &response
);
70 BAIL_ON_WBC_ERROR(wbc_status
);
72 info
->winbind_version
= talloc_strdup(info
,
73 response
.data
.info
.samba_version
);
74 BAIL_ON_PTR_ERROR(info
->winbind_version
, wbc_status
);
75 info
->winbind_separator
= response
.data
.info
.winbind_separator
;
77 /* then the local netbios name */
78 wbc_status
= wbcRequestResponse(WINBINDD_NETBIOS_NAME
, NULL
, &response
);
79 BAIL_ON_WBC_ERROR(wbc_status
);
81 info
->netbios_name
= talloc_strdup(info
,
82 response
.data
.netbios_name
);
83 BAIL_ON_PTR_ERROR(info
->netbios_name
, wbc_status
);
85 /* then the local workgroup name */
86 wbc_status
= wbcRequestResponse(WINBINDD_DOMAIN_NAME
, NULL
, &response
);
87 BAIL_ON_WBC_ERROR(wbc_status
);
89 info
->netbios_domain
= talloc_strdup(info
,
90 response
.data
.domain_name
);
91 BAIL_ON_PTR_ERROR(info
->netbios_domain
, wbc_status
);
93 wbc_status
= wbcDomainInfo(info
->netbios_domain
, &domain
);
94 if (wbc_status
== WBC_ERR_DOMAIN_NOT_FOUND
) {
95 /* maybe it's a standalone server */
97 wbc_status
= WBC_ERR_SUCCESS
;
99 BAIL_ON_WBC_ERROR(wbc_status
);
103 info
->dns_domain
= talloc_strdup(info
,
105 wbcFreeMemory(domain
);
106 BAIL_ON_PTR_ERROR(info
->dns_domain
, wbc_status
);
108 info
->dns_domain
= NULL
;
114 wbc_status
= WBC_ERR_SUCCESS
;
122 /** @brief Lookup the current status of a trusted domain
124 * @param domain Domain to query
125 * @param *dinfo Pointer to returned domain_info struct
132 wbcErr
wbcDomainInfo(const char *domain
, struct wbcDomainInfo
**dinfo
)
134 struct winbindd_request request
;
135 struct winbindd_response response
;
136 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
137 struct wbcDomainInfo
*info
= NULL
;
139 if (!domain
|| !dinfo
) {
140 wbc_status
= WBC_ERR_INVALID_PARAM
;
141 BAIL_ON_WBC_ERROR(wbc_status
);
144 /* Initialize request */
146 ZERO_STRUCT(request
);
147 ZERO_STRUCT(response
);
149 strncpy(request
.domain_name
, domain
,
150 sizeof(request
.domain_name
)-1);
152 wbc_status
= wbcRequestResponse(WINBINDD_DOMAIN_INFO
,
155 BAIL_ON_WBC_ERROR(wbc_status
);
157 info
= talloc(NULL
, struct wbcDomainInfo
);
158 BAIL_ON_PTR_ERROR(info
, wbc_status
);
160 info
->short_name
= talloc_strdup(info
,
161 response
.data
.domain_info
.name
);
162 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
164 info
->dns_name
= talloc_strdup(info
,
165 response
.data
.domain_info
.alt_name
);
166 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
168 wbc_status
= wbcStringToSid(response
.data
.domain_info
.sid
,
170 BAIL_ON_WBC_ERROR(wbc_status
);
172 if (response
.data
.domain_info
.native_mode
)
173 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_NATIVE
;
174 if (response
.data
.domain_info
.active_directory
)
175 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_AD
;
176 if (response
.data
.domain_info
.primary
)
177 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_PRIMARY
;
181 wbc_status
= WBC_ERR_SUCCESS
;
184 if (!WBC_ERROR_IS_OK(wbc_status
)) {
192 /** @brief Resolve a NetbiosName via WINS
194 * @param name Name to resolve
195 * @param *ip Pointer to the ip address string
200 wbcErr
wbcResolveWinsByName(const char *name
, char **ip
)
202 struct winbindd_request request
;
203 struct winbindd_response response
;
204 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
207 ZERO_STRUCT(request
);
208 ZERO_STRUCT(response
);
212 strncpy(request
.data
.winsreq
, name
,
213 sizeof(request
.data
.winsreq
)-1);
215 wbc_status
= wbcRequestResponse(WINBINDD_WINS_BYNAME
,
218 BAIL_ON_WBC_ERROR(wbc_status
);
220 /* Display response */
222 ipaddr
= talloc_strdup(NULL
, response
.data
.winsresp
);
223 BAIL_ON_PTR_ERROR(ipaddr
, wbc_status
);
226 wbc_status
= WBC_ERR_SUCCESS
;
232 /** @brief Resolve an IP address via WINS into a NetbiosName
234 * @param ip The ip address string
235 * @param *name Pointer to the name
240 wbcErr
wbcResolveWinsByIP(const char *ip
, char **name
)
242 struct winbindd_request request
;
243 struct winbindd_response response
;
244 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
247 ZERO_STRUCT(request
);
248 ZERO_STRUCT(response
);
252 strncpy(request
.data
.winsreq
, ip
,
253 sizeof(request
.data
.winsreq
)-1);
255 wbc_status
= wbcRequestResponse(WINBINDD_WINS_BYIP
,
258 BAIL_ON_WBC_ERROR(wbc_status
);
260 /* Display response */
262 name_str
= talloc_strdup(NULL
, response
.data
.winsresp
);
263 BAIL_ON_PTR_ERROR(name_str
, wbc_status
);
266 wbc_status
= WBC_ERR_SUCCESS
;
275 static wbcErr
process_domain_info_string(TALLOC_CTX
*ctx
,
276 struct wbcDomainInfo
*info
,
279 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
283 if (!info
|| !info_string
) {
284 wbc_status
= WBC_ERR_INVALID_PARAM
;
285 BAIL_ON_WBC_ERROR(wbc_status
);
291 if ((s
= strchr(r
, '\\')) == NULL
) {
292 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
293 BAIL_ON_WBC_ERROR(wbc_status
);
298 info
->short_name
= talloc_strdup(ctx
, r
);
299 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
304 if ((s
= strchr(r
, '\\')) == NULL
) {
305 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
306 BAIL_ON_WBC_ERROR(wbc_status
);
311 info
->dns_name
= talloc_strdup(ctx
, r
);
312 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
316 if ((s
= strchr(r
, '\\')) == NULL
) {
317 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
318 BAIL_ON_WBC_ERROR(wbc_status
);
323 wbc_status
= wbcStringToSid(r
, &info
->sid
);
324 BAIL_ON_WBC_ERROR(wbc_status
);
328 if ((s
= strchr(r
, '\\')) == NULL
) {
329 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
330 BAIL_ON_WBC_ERROR(wbc_status
);
335 if (strcmp(r
, "None") == 0) {
336 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_NONE
;
337 } else if (strcmp(r
, "External") == 0) {
338 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_EXTERNAL
;
339 } else if (strcmp(r
, "Forest") == 0) {
340 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_FOREST
;
341 } else if (strcmp(r
, "In Forest") == 0) {
342 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_IN_FOREST
;
344 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
345 BAIL_ON_WBC_ERROR(wbc_status
);
350 if ((s
= strchr(r
, '\\')) == NULL
) {
351 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
352 BAIL_ON_WBC_ERROR(wbc_status
);
357 if (strcmp(r
, "Yes") == 0) {
358 info
->trust_flags
|= WBC_DOMINFO_TRUST_TRANSITIVE
;
363 if ((s
= strchr(r
, '\\')) == NULL
) {
364 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
365 BAIL_ON_WBC_ERROR(wbc_status
);
370 if (strcmp(r
, "Yes") == 0) {
371 info
->trust_flags
|= WBC_DOMINFO_TRUST_INCOMING
;
376 if ((s
= strchr(r
, '\\')) == NULL
) {
377 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
378 BAIL_ON_WBC_ERROR(wbc_status
);
383 if (strcmp(r
, "Yes") == 0) {
384 info
->trust_flags
|= WBC_DOMINFO_TRUST_OUTGOING
;
387 /* Online/Offline status */
391 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
392 BAIL_ON_WBC_ERROR(wbc_status
);
394 if ( strcmp(r
, "Offline") == 0) {
395 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_OFFLINE
;
398 wbc_status
= WBC_ERR_SUCCESS
;
404 /** @brief Enumerate the domain trusts known by Winbind
406 * @param **domains Pointer to the allocated domain list array
407 * @param *num_domains Pointer to number of domains returned
412 wbcErr
wbcListTrusts(struct wbcDomainInfo
**domains
, size_t *num_domains
)
414 struct winbindd_response response
;
415 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
418 char *extra_data
= NULL
;
420 struct wbcDomainInfo
*d_list
= NULL
;
426 ZERO_STRUCT(response
);
430 wbc_status
= wbcRequestResponse(WINBINDD_LIST_TRUSTDOM
,
433 BAIL_ON_WBC_ERROR(wbc_status
);
435 /* Decode the response */
437 p
= (char *)response
.extra_data
.data
;
439 if (strlen(p
) == 0) {
440 /* We should always at least get back our
443 wbc_status
= WBC_ERR_DOMAIN_NOT_FOUND
;
444 BAIL_ON_WBC_ERROR(wbc_status
);
447 /* Count number of domains */
453 if ((q
= strchr(p
, '\n')) != NULL
)
458 d_list
= talloc_array(NULL
, struct wbcDomainInfo
, count
);
459 BAIL_ON_PTR_ERROR(d_list
, wbc_status
);
461 extra_data
= strdup((char*)response
.extra_data
.data
);
462 BAIL_ON_PTR_ERROR(extra_data
, wbc_status
);
466 /* Outer loop processes the list of domain information */
468 for (i
=0; i
<count
&& p
; i
++) {
469 char *next
= strchr(p
, '\n');
476 wbc_status
= process_domain_info_string(d_list
, &d_list
[i
], p
);
477 BAIL_ON_WBC_ERROR(wbc_status
);
486 if (!WBC_ERROR_IS_OK(wbc_status
)) {