2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1999
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nsswitch/winbind_client.h"
23 #include "nsswitch/libwbclient/wbclient.h"
24 #include "lib/util/string_wrappers.h"
28 #include <ns_daemon.h>
36 static pthread_mutex_t wins_nss_mutex
= PTHREAD_MUTEX_INITIALIZER
;
43 #ifndef NETDB_INTERNAL
44 #define NETDB_INTERNAL -1
48 #define NETDB_SUCCESS 0
52 NSS_STATUS
_nss_wins_gethostbyname_r(const char *hostname
,
58 NSS_STATUS
_nss_wins_gethostbyname2_r(const char *name
,
66 static char *lookup_byname_backend(const char *name
)
73 nbt_len
= strlen(name
);
74 if (nbt_len
> MAX_NETBIOSNAME_LEN
- 1) {
77 p
= strchr(name
, '.');
82 wbcSetClientProcessName("nss_wins");
83 result
= wbcResolveWinsByName(name
, &ip
);
84 if (result
!= WBC_ERR_SUCCESS
) {
88 ipp
= strchr(ip
, '\t');
98 static char *lookup_byaddr_backend(const char *ip
)
103 wbcSetClientProcessName("nss_wins");
104 result
= wbcResolveWinsByIP(ip
, &name
);
105 if (result
!= WBC_ERR_SUCCESS
) {
118 nsd_logprintf(NSD_LOG_MIN
, "entering init (wins)\n");
120 ok
= nss_wins_init();
128 int lookup(nsd_file_t
*rq
)
133 int i
, count
, len
, size
;
137 nsd_logprintf(NSD_LOG_MIN
, "entering lookup (wins)\n");
141 map
= nsd_attr_fetch_string(rq
->f_attrs
, "table", (char*)0);
143 rq
->f_status
= NS_FATAL
;
147 key
= nsd_attr_fetch_string(rq
->f_attrs
, "key", (char*)0);
148 if (! key
|| ! *key
) {
149 rq
->f_status
= NS_FATAL
;
154 len
= sizeof(response
) - 2;
157 * response needs to be a string of the following format
158 * ip_address[ ip_address]*\tname[ alias]*
160 if (strcasecmp_m(map
,"hosts.byaddr") == 0) {
163 name
= lookup_byaddr_backend(key
);
165 size
= strlen(key
) + 1;
170 strncat(response
,key
,size
);
171 strncat(response
,"\t",1);
173 size
= strlen(name
) + 1;
178 strncat(response
, name
, size
);
179 strncat(response
, " ", 1);
182 response
[strlen(response
)-1] = '\n';
183 } else if (strcasecmp_m(map
,"hosts.byname") == 0) {
186 ip
= lookup_byname_backend(key
);
188 size
= strlen(ip
) + 1;
194 strncat(response
,ip
,size
);
195 strncat(response
,"\t",1);
196 size
= strlen(key
) + 1;
201 strncat(response
,key
,size
);
202 strncat(response
,"\n",1);
209 nsd_logprintf(NSD_LOG_LOW
, "lookup (wins %s) %s\n",map
,response
);
210 nsd_set_result(rq
,NS_SUCCESS
,response
,strlen(response
),VOLATILE
);
213 nsd_logprintf(NSD_LOG_LOW
, "lookup (wins) not found\n");
214 rq
->f_status
= NS_NOTFOUND
;
220 /* Allocate some space from the nss static buffer. The buffer and buflen
221 are the pointers passed in by the C library to the _nss_*_*
224 static char *get_static(char **buffer
, size_t *buflen
, size_t len
)
228 /* Error check. We return false if things aren't set up right, or
229 there isn't enough buffer space left. */
231 if ((buffer
== NULL
) || (buflen
== NULL
) || (*buflen
< len
)) {
235 /* Return an index into the static buffer */
244 /****************************************************************************
245 gethostbyname() - we ignore any domain portion of the name and only
246 handle names that are at most 15 characters long
247 **************************************************************************/
250 _nss_wins_gethostbyname_r(const char *hostname
,
257 NSS_STATUS nss_status
= NSS_STATUS_SUCCESS
;
266 pthread_mutex_lock(&wins_nss_mutex
);
269 memset(he
, '\0', sizeof(*he
));
270 fstrcpy(name
, hostname
);
274 ip
= lookup_byname_backend(name
);
276 *h_errnop
= HOST_NOT_FOUND
;
277 nss_status
= NSS_STATUS_NOTFOUND
;
281 rc
= inet_pton(AF_INET
, ip
, &in
);
285 *h_errnop
= NETDB_INTERNAL
;
286 nss_status
= NSS_STATUS_TRYAGAIN
;
292 namelen
= strlen(name
) + 1;
294 if ((he
->h_name
= get_static(&buffer
, &buflen
, namelen
)) == NULL
) {
296 *h_errnop
= NETDB_INTERNAL
;
297 nss_status
= NSS_STATUS_TRYAGAIN
;
301 memcpy(he
->h_name
, name
, namelen
);
303 /* Copy h_addr_list, align to pointer boundary first */
305 if ((i
= (unsigned long)(buffer
) % sizeof(char*)) != 0)
306 i
= sizeof(char*) - i
;
308 if (get_static(&buffer
, &buflen
, i
) == NULL
) {
310 *h_errnop
= NETDB_INTERNAL
;
311 nss_status
= NSS_STATUS_TRYAGAIN
;
315 if ((he
->h_addr_list
= (char **)get_static(
316 &buffer
, &buflen
, 2 * sizeof(char *))) == NULL
) {
318 *h_errnop
= NETDB_INTERNAL
;
319 nss_status
= NSS_STATUS_TRYAGAIN
;
323 if ((he
->h_addr_list
[0] = get_static(&buffer
, &buflen
,
324 INADDRSZ
)) == NULL
) {
326 *h_errnop
= NETDB_INTERNAL
;
327 nss_status
= NSS_STATUS_TRYAGAIN
;
331 memcpy(he
->h_addr_list
[0], &in
, INADDRSZ
);
333 he
->h_addr_list
[1] = NULL
;
335 /* Set h_addr_type and h_length */
337 he
->h_addrtype
= AF_INET
;
338 he
->h_length
= INADDRSZ
;
342 if ((i
= (unsigned long)(buffer
) % sizeof(char*)) != 0)
343 i
= sizeof(char*) - i
;
345 if (get_static(&buffer
, &buflen
, i
) == NULL
) {
347 *h_errnop
= NETDB_INTERNAL
;
348 nss_status
= NSS_STATUS_TRYAGAIN
;
352 if ((he
->h_aliases
= (char **)get_static(
353 &buffer
, &buflen
, sizeof(char *))) == NULL
) {
355 *h_errnop
= NETDB_INTERNAL
;
356 nss_status
= NSS_STATUS_TRYAGAIN
;
360 he
->h_aliases
[0] = NULL
;
362 *h_errnop
= NETDB_SUCCESS
;
363 nss_status
= NSS_STATUS_SUCCESS
;
368 pthread_mutex_unlock(&wins_nss_mutex
);
376 _nss_wins_gethostbyname2_r(const char *name
,
384 NSS_STATUS nss_status
;
387 *errnop
= EAFNOSUPPORT
;
389 nss_status
= NSS_STATUS_UNAVAIL
;
391 nss_status
= _nss_wins_gethostbyname_r(name
,