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/>.
27 #define DBGC_CLASS DBGC_WINBIND
29 static struct node_status
*lookup_byaddr_backend(TALLOC_CTX
*mem_ctx
,
30 const char *addr
, int *count
)
32 struct sockaddr_storage ss
;
33 struct nmb_name nname
;
34 struct node_status
*result
;
37 make_nmb_name(&nname
, "*", 0);
38 if (!interpret_string_addr(&ss
, addr
, AI_NUMERICHOST
)) {
41 status
= node_status_query(mem_ctx
, &nname
, &ss
,
42 &result
, count
, NULL
);
43 if (!NT_STATUS_IS_OK(status
)) {
49 static struct sockaddr_storage
*lookup_byname_backend(TALLOC_CTX
*mem_ctx
,
53 struct ip_service
*ret
= NULL
;
54 struct sockaddr_storage
*return_ss
= NULL
;
60 /* always try with wins first */
61 if (NT_STATUS_IS_OK(resolve_wins(name
,0x20,&ret
,count
))) {
64 return_ss
= TALLOC_ARRAY(mem_ctx
, struct sockaddr_storage
,
66 if (return_ss
== NULL
) {
71 /* copy the IP addresses */
72 for ( i
=0; i
<(*count
); i
++ )
73 return_ss
[i
] = ret
[i
].ss
;
79 /* uggh, we have to broadcast to each interface in turn */
80 for (j
=iface_count() - 1;
83 const struct sockaddr_storage
*bcast_ss
= iface_n_bcast(j
);
87 status
= name_query(name
, 0x20, True
, True
,bcast_ss
,
88 mem_ctx
, &return_ss
, count
, NULL
);
89 if (NT_STATUS_IS_OK(status
)) {
97 /* Get hostname from IP */
99 void winbindd_wins_byip(struct winbindd_cli_state
*state
)
102 int i
, count
, maxlen
, size
;
103 struct node_status
*status
;
105 /* Ensure null termination */
106 state
->request
->data
.winsreq
[sizeof(state
->request
->data
.winsreq
)-1]='\0';
108 DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state
->pid
,
109 state
->request
->data
.winsreq
));
112 maxlen
= sizeof(response
) - 1;
114 if ((status
= lookup_byaddr_backend(
115 state
->mem_ctx
, state
->request
->data
.winsreq
, &count
))) {
116 size
= strlen(state
->request
->data
.winsreq
);
119 request_error(state
);
122 fstrcat(response
,state
->request
->data
.winsreq
);
123 fstrcat(response
,"\t");
124 for (i
= 0; i
< count
; i
++) {
125 /* ignore group names */
126 if (status
[i
].flags
& 0x80) continue;
127 if (status
[i
].type
== 0x20) {
128 size
= sizeof(status
[i
].name
) + strlen(response
);
131 request_error(state
);
134 fstrcat(response
, status
[i
].name
);
135 fstrcat(response
, " ");
138 /* make last character a newline */
139 response
[strlen(response
)-1] = '\n';
142 fstrcpy(state
->response
->data
.winsresp
,response
);
146 /* Get IP from hostname */
148 void winbindd_wins_byname(struct winbindd_cli_state
*state
)
150 struct sockaddr_storage
*ip_list
= NULL
;
151 int i
, count
, maxlen
, size
;
153 char addr
[INET6_ADDRSTRLEN
];
155 /* Ensure null termination */
156 state
->request
->data
.winsreq
[sizeof(state
->request
->data
.winsreq
)-1]='\0';
158 DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state
->pid
,
159 state
->request
->data
.winsreq
));
162 maxlen
= sizeof(response
) - 1;
164 ip_list
= lookup_byname_backend(
165 state
->mem_ctx
, state
->request
->data
.winsreq
, &count
);
166 if (ip_list
!= NULL
){
167 for (i
= count
; i
; i
--) {
168 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
-1]);
171 TALLOC_FREE(ip_list
);
172 request_error(state
);
176 /* Clear out the newline character */
177 /* But only if there is something in there,
178 otherwise we clobber something in the stack */
179 if (strlen(response
)) {
180 response
[strlen(response
)-1] = ' ';
183 fstrcat(response
,addr
);
184 fstrcat(response
,"\t");
186 size
= strlen(state
->request
->data
.winsreq
) + strlen(response
);
188 TALLOC_FREE(ip_list
);
189 request_error(state
);
192 fstrcat(response
,state
->request
->data
.winsreq
);
193 fstrcat(response
,"\n");
194 TALLOC_FREE(ip_list
);
196 request_error(state
);
200 fstrcpy(state
->response
->data
.winsresp
,response
);