2 Unix SMB/CIFS implementation.
4 Winbind daemon - WINS related functions
6 Copyright (C) Andrew Tridgell 1999
7 Copyright (C) Herb Lewis 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program 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
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "libsmb/nmblib.h"
28 #define DBGC_CLASS DBGC_WINBIND
30 static struct node_status
*lookup_byaddr_backend(TALLOC_CTX
*mem_ctx
,
31 const char *addr
, int *count
)
33 struct sockaddr_storage ss
;
34 struct nmb_name nname
;
35 struct node_status
*result
;
38 make_nmb_name(&nname
, "*", 0);
39 if (!interpret_string_addr(&ss
, addr
, AI_NUMERICHOST
)) {
42 status
= node_status_query(mem_ctx
, &nname
, &ss
,
43 &result
, count
, NULL
);
44 if (!NT_STATUS_IS_OK(status
)) {
50 static struct sockaddr_storage
*lookup_byname_backend(TALLOC_CTX
*mem_ctx
,
54 struct ip_service
*ret
= NULL
;
55 struct sockaddr_storage
*return_ss
= NULL
;
61 /* always try with wins first */
62 if (NT_STATUS_IS_OK(resolve_wins(name
,0x20,&ret
,count
))) {
65 return_ss
= TALLOC_ARRAY(mem_ctx
, struct sockaddr_storage
,
67 if (return_ss
== NULL
) {
72 /* copy the IP addresses */
73 for ( i
=0; i
<(*count
); i
++ )
74 return_ss
[i
] = ret
[i
].ss
;
80 /* uggh, we have to broadcast to each interface in turn */
81 for (j
=iface_count() - 1;
84 const struct sockaddr_storage
*bcast_ss
= iface_n_bcast(j
);
88 status
= name_query(name
, 0x20, True
, True
,bcast_ss
,
89 mem_ctx
, &return_ss
, count
, NULL
);
90 if (NT_STATUS_IS_OK(status
)) {
98 /* Get hostname from IP */
100 void winbindd_wins_byip(struct winbindd_cli_state
*state
)
103 int i
, count
, maxlen
, size
;
104 struct node_status
*status
;
106 /* Ensure null termination */
107 state
->request
->data
.winsreq
[sizeof(state
->request
->data
.winsreq
)-1]='\0';
109 DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state
->pid
,
110 state
->request
->data
.winsreq
));
113 maxlen
= sizeof(response
) - 1;
115 if ((status
= lookup_byaddr_backend(
116 state
->mem_ctx
, state
->request
->data
.winsreq
, &count
))) {
117 size
= strlen(state
->request
->data
.winsreq
);
120 request_error(state
);
123 fstrcat(response
,state
->request
->data
.winsreq
);
124 fstrcat(response
,"\t");
125 for (i
= 0; i
< count
; i
++) {
126 /* ignore group names */
127 if (status
[i
].flags
& 0x80) continue;
128 if (status
[i
].type
== 0x20) {
129 size
= sizeof(status
[i
].name
) + strlen(response
);
132 request_error(state
);
135 fstrcat(response
, status
[i
].name
);
136 fstrcat(response
, " ");
139 /* make last character a newline */
140 response
[strlen(response
)-1] = '\n';
143 fstrcpy(state
->response
->data
.winsresp
,response
);
147 /* Get IP from hostname */
149 void winbindd_wins_byname(struct winbindd_cli_state
*state
)
151 struct sockaddr_storage
*ip_list
= NULL
;
152 int i
, count
, maxlen
, size
;
154 char addr
[INET6_ADDRSTRLEN
];
156 /* Ensure null termination */
157 state
->request
->data
.winsreq
[sizeof(state
->request
->data
.winsreq
)-1]='\0';
159 DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state
->pid
,
160 state
->request
->data
.winsreq
));
163 maxlen
= sizeof(response
) - 1;
165 ip_list
= lookup_byname_backend(
166 state
->mem_ctx
, state
->request
->data
.winsreq
, &count
);
167 if (ip_list
!= NULL
){
168 for (i
= count
; i
; i
--) {
169 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
-1]);
172 TALLOC_FREE(ip_list
);
173 request_error(state
);
177 /* Clear out the newline character */
178 /* But only if there is something in there,
179 otherwise we clobber something in the stack */
180 if (strlen(response
)) {
181 response
[strlen(response
)-1] = ' ';
184 fstrcat(response
,addr
);
185 fstrcat(response
,"\t");
187 size
= strlen(state
->request
->data
.winsreq
) + strlen(response
);
189 TALLOC_FREE(ip_list
);
190 request_error(state
);
193 fstrcat(response
,state
->request
->data
.winsreq
);
194 fstrcat(response
,"\n");
195 TALLOC_FREE(ip_list
);
197 request_error(state
);
201 fstrcpy(state
->response
->data
.winsresp
,response
);