2 Unix SMB/Netbios implementation.
4 NBT netbios routines to synchronise browse lists
5 Copyright (C) Andrew Tridgell 1994-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL;
29 struct server_record *add_server_entry(char *name,int servertype,
30 int ttl,char *comment,BOOL replace);
33 /****************************************************************************
35 ****************************************************************************/
36 static BOOL call_remote_api(int fd,int cnum,int uid,int timeout,
37 char *inbuf,char *outbuf,
39 int mprcnt,int mdrcnt,
40 int *rprcnt,int *rdrcnt,
41 char *param,char *data,
42 char **rparam,char **rdata)
46 /* send a SMBtrans command */
47 bzero(outbuf,smb_size);
48 set_message(outbuf,14,0,True);
49 CVAL(outbuf,smb_com) = SMBtrans;
50 SSVAL(outbuf,smb_tid,cnum);
51 SSVAL(outbuf,smb_uid,uid);
54 strcpy(p1,"\\PIPE\\LANMAN");
55 p1 = skip_string(p1,1);
59 memcpy(p1,param,prcnt);
61 memcpy(p2,data,drcnt);
63 SSVAL(outbuf,smb_vwv0,prcnt); /* param count */
64 SSVAL(outbuf,smb_vwv1,drcnt); /* data count */
65 SSVAL(outbuf,smb_vwv2,mprcnt); /* mprcnt */
66 SSVAL(outbuf,smb_vwv3,mdrcnt); /* mdrcnt */
67 SSVAL(outbuf,smb_vwv4,0); /* msrcnt */
68 SSVAL(outbuf,smb_vwv5,0); /* flags */
69 SSVAL(outbuf,smb_vwv9,prcnt); /* pscnt */
70 SSVAL(outbuf,smb_vwv10,smb_offset(p1,outbuf)); /* psoff */
71 SSVAL(outbuf,smb_vwv11,drcnt); /* dscnt */
72 SSVAL(outbuf,smb_vwv12,smb_offset(p2,outbuf)); /* dsoff */
73 CVAL(outbuf,smb_vwv13) = 0; /* suwcnt */
75 set_message(outbuf,14,PTR_DIFF(p2+drcnt,smb_buf(outbuf)),False);
79 if (receive_smb(fd,inbuf,timeout) &&
80 CVAL(inbuf,smb_rcls) == 0)
83 *rparam = inbuf+4 + SVAL(inbuf,smb_vwv4);
85 *rdata = inbuf+4 + SVAL(inbuf,smb_vwv7);
87 *rprcnt = SVAL(inbuf,smb_vwv3);
89 *rdrcnt = SVAL(inbuf,smb_vwv6);
97 /*******************************************************************
98 synchronise browse lists with another browse server
99 ******************************************************************/
100 void sync_browse_lists(char *name,int name_type,char *myname,
101 char *domain,struct in_addr ip)
103 char *protocol = "LM1.2X002";
104 char *service = "IPC$";
115 int fd = open_socket_out(SOCK_STREAM, &ip, SMB_PORT);
117 DEBUG(3,("Failed to connect to %s at %s\n",name,inet_ntoa(ip)));
121 if (!(inbuf = (char *)malloc(0xFFFF+1024))) return;
123 /* put in the destination name */
126 name_mangle(name,p,name_type);
131 name_mangle(myname,p,0x20);
134 _smb_setlen(outbuf,len);
135 CVAL(outbuf,0) = 0x81;
138 receive_smb(fd,inbuf,5000);
140 bzero(outbuf,smb_size);
142 /* setup the protocol string */
143 set_message(outbuf,0,strlen(protocol)+2,True);
148 CVAL(outbuf,smb_com) = SMBnegprot;
149 CVAL(outbuf,smb_flg) = 0x8;
150 SSVAL(outbuf,smb_flg2,0x1);
153 bzero(inbuf,smb_size);
154 ret = receive_smb(fd,inbuf,timeout);
156 if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) {
157 DEBUG(3,("%s rejected the protocol\n",name));
159 if (inbuf) free(inbuf);
163 sesskey = IVAL(inbuf,smb_vwv6);
165 bzero(outbuf,smb_size);
166 set_message(outbuf,10,2,True);
167 CVAL(outbuf,smb_com) = SMBsesssetupX;
169 CVAL(outbuf,smb_vwv0) = 0xFF;
170 SSVAL(outbuf,smb_vwv2,0xFFFF);
171 SSVAL(outbuf,smb_vwv3,2);
172 SSVAL(outbuf,smb_vwv4,1);
173 SIVAL(outbuf,smb_vwv5,sesskey);
174 SSVAL(outbuf,smb_vwv7,1);
177 bzero(inbuf,smb_size);
178 ret = receive_smb(fd,inbuf,timeout);
179 if (!ret || CVAL(inbuf,smb_rcls)) {
180 DEBUG(3,("%s rejected session setup\n",name));
182 if (inbuf) free(inbuf);
186 uid = SVAL(inbuf,smb_uid);
188 bzero(outbuf,smb_size);
189 set_message(outbuf,4,2 + (2 + strlen(name) + 1 + strlen(service)) +
190 1 + strlen(dev),True);
191 CVAL(outbuf,smb_com) = SMBtconX;
192 SSVAL(outbuf,smb_uid,uid);
194 SSVAL(outbuf,smb_vwv0,0xFF);
195 SSVAL(outbuf,smb_vwv3,1);
197 p = smb_buf(outbuf) + 1;
202 p = skip_string(p,1);
206 bzero(inbuf,smb_size);
207 ret = receive_smb(fd,inbuf,timeout);
208 if (!ret || CVAL(inbuf,smb_rcls)) {
209 DEBUG(3,("%s rejected IPC connect (%d,%d)\n",name,
210 CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err)));
212 if (inbuf) free(inbuf);
216 cnum = SVAL(inbuf,smb_tid);
218 /* now I need to send a NetServerEnum */
225 SSVAL(p,0,0x68); /* api number */
228 p = skip_string(p,1);
232 p = skip_string(p,1);
233 SSVAL(p,0,1); /* level 1 */
234 SSVAL(p,2,0xFFFF - 500); /* buf length */
240 p = skip_string(p,1);
242 SIVAL(typep,0,0x80000000); /* domain list */
244 if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
249 &rparam,&rdata) && SVAL(rparam,0)==0)
251 int converter=SVAL(rparam,2);
252 int count=SVAL(rparam,4);
255 for (i=0;i<count;i++) {
257 uint32 type = IVAL(p2,18);
258 int comment_offset = IVAL(p2,22) & 0xFFFF;
259 char *comment = comment_offset?(rdata+comment_offset-converter):"";
261 add_server_entry(sname,type,lp_max_ttl(),comment,False);
266 SIVAL(typep,0,0xFFFFFFFF); /* server list */
268 if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
273 &rparam,&rdata) && SVAL(rparam,0)==0)
275 int converter=SVAL(rparam,2);
276 int count=SVAL(rparam,4);
280 for (i=0;i<count;i++) {
282 uint32 type = IVAL(p,18);
283 int comment_offset = IVAL(p,22) & 0xFFFF;
284 char *comment = comment_offset?(rdata+comment_offset-converter):"";
286 add_server_entry(sname,type,lp_max_ttl(),comment,False);
293 bzero(outbuf,smb_size);
294 set_message(outbuf,0,0,True);
295 CVAL(outbuf,smb_com) = SMBtdis;
296 SSVAL(outbuf,smb_uid,uid);
297 SSVAL(outbuf,smb_tid,cnum);
299 receive_smb(fd,inbuf,1000);
302 if (inbuf) free(inbuf);