Did more integration of Lukes code ready for the first release.
[kai/samba.git] / source3 / nmbsync.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines to synchronise browse lists
5    Copyright (C) Andrew Tridgell 1994-1995
6    
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.
11    
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.
16    
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.
20    
21 */
22
23 #include "includes.h"
24 #include "loadparm.h"
25 #include "localnet.h"
26
27
28 extern int DEBUGLEVEL;
29
30 extern pstring myname;
31 extern struct in_addr bcast_ip;
32 extern struct in_addr Netmask;
33
34 extern int name_type;
35 extern int max_protocol;
36 extern struct in_addr dest_ip;
37 extern int pid;
38 extern int gid;
39 extern int uid;
40 extern int mid;
41 extern BOOL got_pass;
42 extern BOOL have_ip;
43 extern pstring workgroup;
44 extern pstring service;
45 extern pstring desthost;
46 extern BOOL connect_as_ipc;
47
48 /****************************************************************************
49 fudge for getpass function
50 ****************************************************************************/
51 char *getsmbpass(char *pass)
52 {
53         return "dummy"; /* return anything: it should be ignored anyway */
54 }
55
56 /****************************************************************************
57 adds information retrieved from a NetServerEnum call
58 ****************************************************************************/
59 static BOOL add_info(struct domain_record *d, struct work_record *work, int servertype)
60 {
61   char *rparam = NULL;
62   char *rdata = NULL;
63   int rdrcnt,rprcnt;
64   char *p;
65   pstring param;
66   int uLevel = 1;
67   int count = -1;
68   
69   /* now send a SMBtrans command with api ServerEnum? */
70   p = param;
71   SSVAL(p,0,0x68); /* api number */
72   p += 2;
73   strcpy(p,"WrLehDz");
74   p = skip_string(p,1);
75   
76   strcpy(p,"B16BBDz");
77   
78   p = skip_string(p,1);
79   SSVAL(p,0,uLevel);
80   SSVAL(p,2,0x2000); /* buf length */
81   p += 4;
82   SIVAL(p,0,servertype);
83   p += 4;
84   
85   strcpy(p, work->work_group);
86   p = skip_string(p,1);
87   
88   if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
89                    &rprcnt,&rdrcnt, param,NULL,
90                    &rparam,&rdata))
91     {
92       int res = SVAL(rparam,0);
93       int converter=SVAL(rparam,2);
94       int i;
95       
96       if (res == 0)
97         {
98           count=SVAL(rparam,4);
99           p = rdata;
100           
101           for (i = 0;i < count;i++, p += 26)
102             {
103               char *sname = p;
104               uint32 stype = IVAL(p,18);
105               int comment_offset = IVAL(p,22) & 0xFFFF;
106               char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
107               
108               struct work_record *w = work;
109               
110               DEBUG(4, ("\t%-16.16s     %08x    %s\n", sname, stype, cmnt));
111               
112               if (stype & SV_TYPE_DOMAIN_ENUM)
113                 {
114                   /* creates workgroup on remote subnet */
115                   if ((w = find_workgroupstruct(d,sname, False)))
116                     {
117                       if (ip_equal(bcast_ip, d->bcast_ip))
118                         {
119                           announce_request(w, d->bcast_ip);
120                         }
121                     }
122                 }
123               
124               add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
125             }
126         }
127     }
128   
129   if (rparam) free(rparam);
130   if (rdata) free(rdata);
131   
132   return(True);
133 }
134
135
136 /*******************************************************************
137   synchronise browse lists with another browse server.
138
139   log in on the remote server's SMB port to their IPC$ service,
140   do a NetServerEnum and update our server and workgroup databases.
141   ******************************************************************/
142 void sync_browse_lists(struct work_record *work, char *name, int nm_type,
143                        struct in_addr ip)
144 {
145         struct domain_record *d;
146         pid = getpid();
147         uid = getuid();
148         gid = getgid();
149         mid = pid + 100;
150         name_type = nm_type;
151
152         got_pass = True;
153
154         DEBUG(4, ("sync browse lists with %s for %s %s\n",
155                         work->work_group, name, inet_ntoa(ip)));
156
157         strcpy(workgroup,work->work_group);
158         strcpy(desthost,name);
159         dest_ip = ip;
160
161         if (zero_ip(dest_ip)) return;
162         have_ip = True;
163
164         if (!(d = find_domain(ip))) return;
165
166         connect_as_ipc = True;
167
168         /* connect as server and get domains, then servers */
169
170         sprintf(service,"\\\\%s\\IPC$", name);
171         strupper(service);
172
173         if (cli_open_sockets(SMB_PORT))
174         {
175                 if (cli_send_login(NULL,NULL,True,True))
176                 {
177                         add_info(d, work, SV_TYPE_DOMAIN_ENUM);
178                         add_info(d, work, SV_TYPE_ALL&~SV_TYPE_DOMAIN_ENUM);
179                 }
180
181                 close_sockets();
182         }
183 }