From a2c1623827406667a4f2f058c24f1d971f6627f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 06:42:03 +0000 Subject: a huge pile of changes :-) The biggest thing is the integration of Lukes new nmbd. Its still largely untested, so we will really need some feedback I've also added auto prototype generation and cleaned up a lot of minor things as a result (This used to be commit 0d8dcfa13c527ec2c8aca39ba49c09e4e694b26c) --- source3/nmbsync.c | 408 +++++++++++++++++++----------------------------------- 1 file changed, 144 insertions(+), 264 deletions(-) (limited to 'source3/nmbsync.c') diff --git a/source3/nmbsync.c b/source3/nmbsync.c index 5a77d6cc48..5a6c07086a 100644 --- a/source3/nmbsync.c +++ b/source3/nmbsync.c @@ -22,282 +22,162 @@ #include "includes.h" #include "loadparm.h" -#include "nameserv.h" +#include "localnet.h" + extern int DEBUGLEVEL; -struct server_record *add_server_entry(char *name,int servertype, - int ttl,char *comment,BOOL replace); +extern pstring myname; +extern struct in_addr bcast_ip; +extern struct in_addr Netmask; + +extern int name_type; +extern int max_protocol; +extern struct in_addr dest_ip; +extern int pid; +extern int gid; +extern int uid; +extern int mid; +extern BOOL got_pass; +extern BOOL have_ip; +extern pstring workgroup; +extern pstring service; +extern pstring desthost; +extern BOOL connect_as_ipc; +/**************************************************************************** +fudge for getpass function +****************************************************************************/ +char *getsmbpass(char *pass) +{ + return "dummy"; /* return anything: it should be ignored anyway */ +} /**************************************************************************** -call a remote api +adds information retrieved from a NetServerEnum call ****************************************************************************/ -static BOOL call_remote_api(int fd,int cnum,int uid,int timeout, - char *inbuf,char *outbuf, - int prcnt,int drcnt, - int mprcnt,int mdrcnt, - int *rprcnt,int *rdrcnt, - char *param,char *data, - char **rparam,char **rdata) +static BOOL add_info(struct domain_record *d, struct work_record *work, int servertype) { - char *p1,*p2; - - /* send a SMBtrans command */ - bzero(outbuf,smb_size); - set_message(outbuf,14,0,True); - CVAL(outbuf,smb_com) = SMBtrans; - SSVAL(outbuf,smb_tid,cnum); - SSVAL(outbuf,smb_uid,uid); - - p1 = smb_buf(outbuf); - strcpy(p1,"\\PIPE\\LANMAN"); - p1 = skip_string(p1,1); - p2 = p1 + prcnt; - - if (prcnt > 0) - memcpy(p1,param,prcnt); - if (drcnt > 0) - memcpy(p2,data,drcnt); - - SSVAL(outbuf,smb_vwv0,prcnt); /* param count */ - SSVAL(outbuf,smb_vwv1,drcnt); /* data count */ - SSVAL(outbuf,smb_vwv2,mprcnt); /* mprcnt */ - SSVAL(outbuf,smb_vwv3,mdrcnt); /* mdrcnt */ - SSVAL(outbuf,smb_vwv4,0); /* msrcnt */ - SSVAL(outbuf,smb_vwv5,0); /* flags */ - SSVAL(outbuf,smb_vwv9,prcnt); /* pscnt */ - SSVAL(outbuf,smb_vwv10,smb_offset(p1,outbuf)); /* psoff */ - SSVAL(outbuf,smb_vwv11,drcnt); /* dscnt */ - SSVAL(outbuf,smb_vwv12,smb_offset(p2,outbuf)); /* dsoff */ - CVAL(outbuf,smb_vwv13) = 0; /* suwcnt */ - - set_message(outbuf,14,PTR_DIFF(p2+drcnt,smb_buf(outbuf)),False); - - send_smb(fd,outbuf); - - if (receive_smb(fd,inbuf,timeout) && - CVAL(inbuf,smb_rcls) == 0) - { - if (rparam) - *rparam = inbuf+4 + SVAL(inbuf,smb_vwv4); - if (rdata) - *rdata = inbuf+4 + SVAL(inbuf,smb_vwv7); - if (rprcnt) - *rprcnt = SVAL(inbuf,smb_vwv3); - if (rdrcnt) - *rdrcnt = SVAL(inbuf,smb_vwv6); - return(True); - } - - return(False); + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + pstring param; + int uLevel = 1; + int count = -1; + + /* now send a SMBtrans command with api ServerEnum? */ + p = param; + SSVAL(p,0,0x68); /* api number */ + p += 2; + strcpy(p,"WrLehDz"); + p = skip_string(p,1); + + strcpy(p,"B16BBDz"); + + p = skip_string(p,1); + SSVAL(p,0,uLevel); + SSVAL(p,2,0x2000); /* buf length */ + p += 4; + SIVAL(p,0,servertype); + p += 4; + + strcpy(p, work->work_group); + p = skip_string(p,1); + + if (cli_call_api(PTR_DIFF(p,param),0, 8,10000, + &rprcnt,&rdrcnt, param,NULL, + &rparam,&rdata)) + { + int res = SVAL(rparam,0); + int converter=SVAL(rparam,2); + int i; + + if (res == 0) + { + count=SVAL(rparam,4); + p = rdata; + + for (i = 0;i < count;i++, p += 26) + { + char *sname = p; + uint32 stype = IVAL(p,18); + int comment_offset = IVAL(p,22) & 0xFFFF; + char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + + struct work_record *w = work; + + DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt)); + + if (stype & SV_TYPE_DOMAIN_ENUM) + { + /* creates workgroup on remote subnet */ + if ((w = find_workgroupstruct(d,sname, False))) + { + if (ip_equal(bcast_ip, d->bcast_ip)) + { + announce_request(w, d->bcast_ip); + } + } + } + + add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False); + } + } + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return(True); } /******************************************************************* - synchronise browse lists with another browse server + synchronise browse lists with another browse server. + + log in on the remote server's SMB port to their IPC$ service, + do a NetServerEnum and update our server and workgroup databases. ******************************************************************/ -void sync_browse_lists(char *name,int name_type,char *myname, - char *domain,struct in_addr ip) +void sync_browse_lists(struct work_record *work, char *name, int nm_type, + struct in_addr ip) { - char *protocol = "LM1.2X002"; - char *service = "IPC$"; - char *dev = "IPC"; - int timeout=2000; - char *inbuf=NULL; - pstring outbuf; - char *p; - int len; - uint32 sesskey; - int cnum,uid; - BOOL ret; - - int fd = open_socket_out(SOCK_STREAM, &ip, SMB_PORT); - if (fd < 0) { - DEBUG(3,("Failed to connect to %s at %s\n",name,inet_ntoa(ip))); - return; - } - - if (!(inbuf = (char *)malloc(0xFFFF+1024))) return; - - /* put in the destination name */ - len = 4; - p = outbuf+len; - name_mangle(name,p,name_type); - len += name_len(p); - - /* and my name */ - p = outbuf+len; - name_mangle(myname,p,0x20); - len += name_len(p); - - _smb_setlen(outbuf,len); - CVAL(outbuf,0) = 0x81; - - send_smb(fd,outbuf); - receive_smb(fd,inbuf,5000); - - bzero(outbuf,smb_size); - - /* setup the protocol string */ - set_message(outbuf,0,strlen(protocol)+2,True); - p = smb_buf(outbuf); - *p++ = 2; - strcpy(p,protocol); - - CVAL(outbuf,smb_com) = SMBnegprot; - CVAL(outbuf,smb_flg) = 0x8; - SSVAL(outbuf,smb_flg2,0x1); - - send_smb(fd,outbuf); - bzero(inbuf,smb_size); - ret = receive_smb(fd,inbuf,timeout); - - if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) { - DEBUG(3,("%s rejected the protocol\n",name)); - close(fd); - if (inbuf) free(inbuf); - return; - } - - sesskey = IVAL(inbuf,smb_vwv6); - - bzero(outbuf,smb_size); - set_message(outbuf,10,2,True); - CVAL(outbuf,smb_com) = SMBsesssetupX; - - CVAL(outbuf,smb_vwv0) = 0xFF; - SSVAL(outbuf,smb_vwv2,0xFFFF); - SSVAL(outbuf,smb_vwv3,2); - SSVAL(outbuf,smb_vwv4,1); - SIVAL(outbuf,smb_vwv5,sesskey); - SSVAL(outbuf,smb_vwv7,1); - - send_smb(fd,outbuf); - bzero(inbuf,smb_size); - ret = receive_smb(fd,inbuf,timeout); - if (!ret || CVAL(inbuf,smb_rcls)) { - DEBUG(3,("%s rejected session setup\n",name)); - close(fd); - if (inbuf) free(inbuf); - return; - } - - uid = SVAL(inbuf,smb_uid); - - bzero(outbuf,smb_size); - set_message(outbuf,4,2 + (2 + strlen(name) + 1 + strlen(service)) + - 1 + strlen(dev),True); - CVAL(outbuf,smb_com) = SMBtconX; - SSVAL(outbuf,smb_uid,uid); - - SSVAL(outbuf,smb_vwv0,0xFF); - SSVAL(outbuf,smb_vwv3,1); - - p = smb_buf(outbuf) + 1; - strcpy(p, "\\\\"); - strcat(p, name); - strcat(p, "\\"); - strcat(p,service); - p = skip_string(p,1); - strcpy(p,dev); - - send_smb(fd,outbuf); - bzero(inbuf,smb_size); - ret = receive_smb(fd,inbuf,timeout); - if (!ret || CVAL(inbuf,smb_rcls)) { - DEBUG(3,("%s rejected IPC connect (%d,%d)\n",name, - CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err))); - close(fd); - if (inbuf) free(inbuf); - return; - } - - cnum = SVAL(inbuf,smb_tid); - - /* now I need to send a NetServerEnum */ - { - fstring param; - uint32 *typep; - char *rparam,*rdata; - - p = param; - SSVAL(p,0,0x68); /* api number */ - p += 2; - strcpy(p,"WrLehDz"); - p = skip_string(p,1); - - strcpy(p,"B16BBDz"); - - p = skip_string(p,1); - SSVAL(p,0,1); /* level 1 */ - SSVAL(p,2,0xFFFF - 500); /* buf length */ - p += 4; - typep = (uint32 *)p; - p += 4; - strcpy(p,domain); - strupper(p); - p = skip_string(p,1); - - SIVAL(typep,0,0x80000000); /* domain list */ - - if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf, - PTR_DIFF(p,param),0, - 8,0xFFFF - 500, - NULL,NULL, - param,NULL, - &rparam,&rdata) && SVAL(rparam,0)==0) - { - int converter=SVAL(rparam,2); - int count=SVAL(rparam,4); - int i; - char *p2 = rdata; - for (i=0;iwork_group, name, inet_ntoa(ip))); + + strcpy(workgroup,work->work_group); + strcpy(desthost,name); + dest_ip = ip; + + if (zero_ip(dest_ip)) return; + have_ip = True; + + if (!(d = find_domain(ip))) return; + + connect_as_ipc = True; + + /* connect as server and get domains, then servers */ + + sprintf(service,"\\\\%s\\IPC$", name); + strupper(service); + + if (cli_open_sockets(SMB_PORT)) + { + if (cli_send_login(NULL,NULL,True,True)) + { + add_info(d, work, SV_TYPE_DOMAIN_ENUM); + add_info(d, work, SV_TYPE_ALL&~SV_TYPE_DOMAIN_ENUM); + } + + close_sockets(); + } } -- cgit