libwbclient: add wbcResolveWinsByName() and wbcResolveWinsByIP()
[ira/wip.git] / source3 / nsswitch / libwbclient / wbc_util.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind client API
5
6    Copyright (C) Gerald (Jerry) Carter 2007
7
8
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.
13
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.
18
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/>.
21 */
22
23 /* Required Headers */
24
25 #include "libwbclient.h"
26
27
28
29 /** @brief Ping winbindd to see if the daemon is running
30  *
31  * @return #wbcErr
32  **/
33
34 wbcErr wbcPing(void)
35 {
36         struct winbindd_request request;
37         struct winbindd_response response;
38
39         /* Initialize request */
40
41         ZERO_STRUCT(request);
42         ZERO_STRUCT(response);
43
44         return wbcRequestResponse(WINBINDD_PING, &request, &response);
45 }
46
47 wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
48 {
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;
54
55         /* Initialize request */
56
57         ZERO_STRUCT(request);
58         ZERO_STRUCT(response);
59
60         info = talloc(NULL, struct wbcInterfaceDetails);
61         BAIL_ON_PTR_ERROR(info, wbc_status);
62
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;
67
68         /* then the samba version and the winbind separator */
69         wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response);
70         BAIL_ON_WBC_ERROR(wbc_status);
71
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;
76
77         /* then the local netbios name */
78         wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response);
79         BAIL_ON_WBC_ERROR(wbc_status);
80
81         info->netbios_name = talloc_strdup(info,
82                                            response.data.netbios_name);
83         BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
84
85         /* then the local workgroup name */
86         wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response);
87         BAIL_ON_WBC_ERROR(wbc_status);
88
89         info->netbios_domain = talloc_strdup(info,
90                                         response.data.domain_name);
91         BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
92
93         wbc_status = wbcDomainInfo(info->netbios_domain, &domain);
94         if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
95                 /* maybe it's a standalone server */
96                 domain = NULL;
97                 wbc_status = WBC_ERR_SUCCESS;
98         } else {
99                 BAIL_ON_WBC_ERROR(wbc_status);
100         }
101
102         if (domain) {
103                 info->dns_domain = talloc_strdup(info,
104                                                  domain->dns_name);
105                 wbcFreeMemory(domain);
106                 BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
107         } else {
108                 info->dns_domain = NULL;
109         }
110
111         *_details = info;
112         info = NULL;
113
114         wbc_status = WBC_ERR_SUCCESS;
115
116 done:
117         talloc_free(info);
118         return wbc_status;
119 }
120
121
122 /** @brief Lookup the current status of a trusted domain
123  *
124  * @param domain      Domain to query
125  * @param *dinfo       Pointer to returned domain_info struct
126  *
127  * @return #wbcErr
128  *
129  **/
130
131
132 wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
133 {
134         struct winbindd_request request;
135         struct winbindd_response response;
136         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
137         struct wbcDomainInfo *info = NULL;
138
139         if (!domain || !dinfo) {
140                 wbc_status = WBC_ERR_INVALID_PARAM;
141                 BAIL_ON_WBC_ERROR(wbc_status);
142         }
143
144         /* Initialize request */
145
146         ZERO_STRUCT(request);
147         ZERO_STRUCT(response);
148
149         strncpy(request.domain_name, domain,
150                 sizeof(request.domain_name)-1);
151
152         wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
153                                         &request,
154                                         &response);
155         BAIL_ON_WBC_ERROR(wbc_status);
156
157         info = talloc(NULL, struct wbcDomainInfo);
158         BAIL_ON_PTR_ERROR(info, wbc_status);
159
160         info->short_name = talloc_strdup(info,
161                                          response.data.domain_info.name);
162         BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
163
164         info->dns_name = talloc_strdup(info,
165                                        response.data.domain_info.alt_name);
166         BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
167
168         wbc_status = wbcStringToSid(response.data.domain_info.sid,
169                                     &info->sid);
170         BAIL_ON_WBC_ERROR(wbc_status);
171
172         if (response.data.domain_info.native_mode)
173                 info->flags |= WBC_DOMINFO_NATIVE;
174         if (response.data.domain_info.active_directory)
175                 info->flags |= WBC_DOMINFO_AD;
176         if (response.data.domain_info.primary)
177                 info->flags |= WBC_DOMINFO_PRIMARY;
178
179         *dinfo = info;
180
181         wbc_status = WBC_ERR_SUCCESS;
182
183  done:
184         if (!WBC_ERROR_IS_OK(wbc_status)) {
185                 talloc_free(info);
186         }
187
188         return wbc_status;
189 }
190
191
192 /** @brief Resolve a NetbiosName via WINS
193  *
194  * @param name         Name to resolve
195  * @param *ip          Pointer to the ip address string
196  *
197  * @return #wbcErr
198  *
199  **/
200 wbcErr wbcResolveWinsByName(const char *name, const char **ip)
201 {
202         struct winbindd_request request;
203         struct winbindd_response response;
204         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
205         const char *ipaddr;
206
207         ZERO_STRUCT(request);
208         ZERO_STRUCT(response);
209
210         /* Send request */
211
212         strncpy(request.data.winsreq, name,
213                 sizeof(request.data.winsreq)-1);
214
215         wbc_status = wbcRequestResponse(WINBINDD_WINS_BYNAME,
216                                         &request,
217                                         &response);
218         BAIL_ON_WBC_ERROR(wbc_status);
219
220         /* Display response */
221
222         ipaddr = talloc_strdup(NULL, response.data.winsresp);
223         BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
224
225         *ip = ipaddr;
226         wbc_status = WBC_ERR_SUCCESS;
227
228  done:
229         return wbc_status;
230 }
231
232 /** @brief Resolve an IP address via WINS into a NetbiosName
233  *
234  * @param ip          The ip address string
235  * @param *name       Pointer to the name
236  *
237  * @return #wbcErr
238  *
239  **/
240 wbcErr wbcResolveWinsByIP(const char *ip, const char **name)
241 {
242         struct winbindd_request request;
243         struct winbindd_response response;
244         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
245         const char *name_str;
246
247         ZERO_STRUCT(request);
248         ZERO_STRUCT(response);
249
250         /* Send request */
251
252         strncpy(request.data.winsreq, ip,
253                 sizeof(request.data.winsreq)-1);
254
255         wbc_status = wbcRequestResponse(WINBINDD_WINS_BYIP,
256                                         &request,
257                                         &response);
258         BAIL_ON_WBC_ERROR(wbc_status);
259
260         /* Display response */
261
262         name_str = talloc_strdup(NULL, response.data.winsresp);
263         BAIL_ON_PTR_ERROR(name_str, wbc_status);
264
265         *name = name_str;
266         wbc_status = WBC_ERR_SUCCESS;
267
268  done:
269         return wbc_status;
270 }