--- Makefile.orig Tue Aug 26 03:52:06 1997 +++ Makefile Mon Sep 1 14:25:10 1997 @@ -634,7 +634,7 @@ SMBDOBJ = predict.o $(SMBDOBJ1) $(SMBDOBJ2) $(VTP_OBJ) NMBDOBJ1 = nmblib.o namepacket.o nameresp.o nmbsync.o nameannounce.o nameelect.o NMBDOBJ2 = namedbresp.o namedbwork.o namedbserver.o namedbsubnet.o namedbname.o -NMBDOBJ3 = nameservresp.o nameservreply.o namelogon.o namebrowse.o namework.o nameserv.o clientutil.o +NMBDOBJ3 = nameservresp.o nameservreply.o namelogon.o namebrowse.o namework.o nameserv.o clientutil.o namelanman.o NMBDOBJ = $(UTILOBJ) $(NMBDOBJ1) $(NMBDOBJ2) $(NMBDOBJ3) .SUFFIXES: .SUFFIXES: .c .o .h --- nameserv.h.orig Thu Jul 31 20:55:17 1997 +++ nameserv.h Mon Sep 1 14:25:10 1997 @@ -82,6 +82,7 @@ /* mail slots */ #define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE" #define NET_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NETLOGON" +#define LANMAN_MAILSLOT "\\MAILSLOT\\LANMAN" enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL}; enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3}; --- proto.h.orig Fri Aug 22 06:35:23 1997 +++ proto.h Mon Sep 1 14:25:10 1997 @@ -188,6 +188,7 @@ int lp_maxdisksize(void); int lp_lpqcachetime(void); int lp_syslog(void); +int lp_lm_announce(void); int lp_client_code_page(void); char *lp_preexec(int ); char *lp_postexec(int ); @@ -447,6 +448,21 @@ void run_elections(time_t t); void process_election(struct packet_struct *p,char *buf); BOOL check_elections(void); + +/*The following definitions come from namelanman.c */ + +void do_announce_lm_host(int command, + char *from_name, int from_type, + struct in_addr from_ip, char *to_name, + int to_type, struct in_addr to_ip, + time_t announce_interval, char *server_name, + int server_type, char *server_comment); +void announce_my_lm_servers_removed(void); +void announce_lm_server(struct subnet_record *d, char *work, + char *name, char *comment, time_t ttl, int server_type); +void announce_lm_host(time_t t); +void process_lanman_packet(struct packet_struct *p,char *buf,int len); + /*The following definitions come from namelogon.c */ --- client.c.orig Tue Aug 26 03:00:09 1997 +++ client.c Mon Sep 1 14:25:10 1997 @@ -1297,6 +1297,11 @@ (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300)))) method = 0; + /* Attempt to detect OS/2 Peer as the server, because it can crash + on a chained readX+close. */ + if (max_xmit == 4356) + method = -1; + /* if we support readraw then use that */ if (method<0 && readbraw_supported) method = 1; --- loadparm.c.orig Wed Aug 13 01:37:22 1997 +++ loadparm.c Mon Sep 1 14:25:11 1997 @@ -153,6 +153,7 @@ int os_level; int max_ttl; int ReadSize; + int lm_announce; int shmem_size; int shmem_hash_size; int client_code_page; @@ -468,6 +469,7 @@ {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL}, {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL}, {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL}, + {"lm announce", P_INTEGER, P_GLOBAL, &Globals.lm_announce, NULL}, {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL}, {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL}, {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL}, @@ -638,6 +640,7 @@ Globals.os_level = 0; Globals.max_ttl = 60*60*4; /* 2 hours default */ Globals.ReadSize = 16*1024; + Globals.lm_announce = 0; Globals.shmem_size = SHMEM_SIZE; Globals.shmem_hash_size = SHMEM_HASH_SIZE; Globals.announce_as = ANNOUNCE_AS_NT; @@ -879,6 +882,7 @@ FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize) FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime) FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog) +FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce) FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page) FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as) --- namelanman.c.orig Mon Sep 1 14:25:11 1997 +++ namelanman.c Mon Sep 1 14:25:11 1997 @@ -0,0 +1,301 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT netbios routines and daemon - version 2 + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Revision History: + + 27 mar 1997: Andreas Degert + Implementation of LAN Manager (LM) announcements. + Samba servers should now be visible to LM clients + (including OS/2 machines). + 14 apr 1997: Jacco de Leeuw + Observed OS/2 machines will be added to the browse list. + All LM routines have been moved to one file. + 5 may 1997: Jacco de Leeuw + Send LM announcements with no services when Samba is killed. + Renamed LM routines to resemble existing name scheme. + 11 aug 1997: Updated for 1.9.17 +*/ + +#include "includes.h" + +extern int ClientDGRAM; +extern pstring myname; +extern struct subnet_record *subnetlist; +extern struct in_addr wins_ip; +extern int DEBUGLEVEL; +extern pstring scope; +extern BOOL updatedlists; + +/**************************************************************************** + send a LAN Manager packet + **************************************************************************/ + +void do_announce_lm_host(int command, + char *from_name, int from_type, + struct in_addr from_ip, char *to_name, + int to_type, struct in_addr to_ip, + time_t announce_interval, char *server_name, + int server_type, char *server_comment) +{ + pstring outbuf; + char *p = outbuf; + + bzero(outbuf,sizeof(outbuf)); + + SSVAL(p,0,command); /* frame type */ + SIVAL(p,2,server_type); /* services offered by this server */ + CVAL(p,6) = lp_major_announce_version(); + CVAL(p,7) = lp_minor_announce_version(); + SSVAL(p,8,announce_interval); /* announcement cycle in seconds */ + p += 10; + strcpy(p,server_name); + strupper(p); + p = skip_string(p,1); + strcpy(p,server_comment); + p = skip_string(p,1); + + debug_browse_data(outbuf, PTR_DIFF(p,outbuf)); + + /* send the announcement */ + send_mailslot_reply(False,LANMAN_MAILSLOT,ClientDGRAM,outbuf, + PTR_DIFF(p,outbuf), + from_name, to_name, + from_type, to_type, + to_ip, from_ip); +} + + +/**************************************************************************** + announce on all subnets that Samba is no longer a LAN Manager server + **************************************************************************/ + +void announce_my_lm_servers_removed(void) +{ + char *work = lp_workgroup(); + int announce_interval = lp_lm_announce(); + struct subnet_record *d; + int server_type; + pstring comment; + + if (announce_interval <=0) return; + + StrnCpy(comment, lp_serverstring(), 43); + + if (myname[0] == '\0') return; + + server_type = 0; /* Going down. There are 'no services'. */ + + for (d = subnetlist; d; d = d->next) + { + if (ip_equal(d->bcast_ip, wins_ip)) continue; + announce_lm_server(d,work,myname,comment, + announce_interval,server_type); + } +} + + +/**************************************************************************** + send a LAN Manager host announcement packet + **************************************************************************/ + +void announce_lm_server(struct subnet_record *d, char *work, + char *name, char *comment, time_t ttl, int server_type) +{ + + do_announce_lm_host(ANN_HostAnnouncement, + name, 0x00, + d->myip, work, + 0x00, d->bcast_ip, + ttl, name, + server_type, comment); +} + + +/**************************************************************************** + announce a LAN Manager server entry on all subnets + **************************************************************************/ + +void announce_lm_host(time_t t) +{ + static time_t lastannounce_time = 0; + char *work = lp_workgroup(); + int announce_interval = lp_lm_announce(); + struct subnet_record *d; + int server_type; + pstring comment; + + if (announce_interval <=0) return; + + StrnCpy(comment, lp_serverstring(), 43); + + if (myname[0] == '\0') return; + + if (lastannounce_time && (t - lastannounce_time) < announce_interval) + return; + + lastannounce_time = t; + server_type = SV_TYPE_WORKSTATION|SV_TYPE_SERVER|SV_TYPE_TIME_SOURCE; + + for (d = subnetlist; d; d = d->next) + { + if (ip_equal(d->bcast_ip, wins_ip)) continue; + announce_lm_server(d,work,myname,comment, + announce_interval,server_type); + } +} + + + /******************************************************************* + process a LAN Manager announcement frame + ******************************************************************/ +static void process_lm_announce(struct packet_struct *p,uint16 command,char *buf) +{ + struct dgram_packet *dgram = &p->packet.dgram; + struct in_addr ip = dgram->header.source_ip; + struct subnet_record *d = find_subnet(ip); + + int ttl = SVAL(buf,8); /* time-to-live for this announcement */ + char *name = buf+10; + int osmajor=CVAL(buf,6); /* major version of node software */ + int osminor=CVAL(buf,7); /* minor version of node software */ + uint32 server_type = IVAL(buf,2); /* services offered by this server */ + char *s = buf+10; + pstring comment; + static int logwarnings=0; + + struct work_record *work; + char *work_name; + char *serv_name = dgram->source_name.name; + BOOL add = False; + + s = skip_string(s,1); + StrnCpy(comment, s, 43); + + DEBUG(4,("LM Announcement(%d) from %s",command,name)); + DEBUG(4,(" on %s ttl=%d OS=(%d,%d) type=%08x comment=%s\n", + namestr(&dgram->dest_name),ttl,osmajor,osminor, + server_type,comment)); + + if (((osmajor > 38) && (osmajor < 36)) || (osminor !=0)) + { + DEBUG(4,("LM Announcement frame discarded: didn't originate from" \ + " OS/2 Warp 4 or Connect\n")); + /* Could have been from a Windows machine (with LM Announce=Yes), + or a Samba server. Then don't disrupt the current browse list. */ + return; + } + + if (!strequal(dgram->dest_name.scope,scope )) return; + + if ((logwarnings < 5) && (lp_lm_announce() <= 0)) + { + logwarnings++; + DEBUG(1, ("OS/2 client(s) detected! " \ + "Please increase the\n'lm announce' " \ + "parameter (see smb.conf.5)...\n")); + } + + /* we need some way of finding out about new workgroups + that appear to be sending packets to us. The name_type checks make + sure we don't add host names as workgroups */ + if (command == ANN_HostAnnouncement && + (dgram->dest_name.name_type == 0x1d || + dgram->dest_name.name_type == 0x1e)) + add = True; + + work_name = dgram->dest_name.name; + if (!(work = find_workgroupstruct(d, work_name,add))) + return; + + DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name)); + + ttl = GET_TTL(ttl); + + /* add them to our browse list, and update the browse.dat file */ + add_server_entry(d,work,name,server_type|SV_TYPE_LOCAL_LIST_ONLY,ttl,comment,True); + updatedlists = True; +} + + +/******************************************************************* + process a LAN Manager announcement request +*******************************************************************/ + +static void process_lm_announce_request(struct packet_struct *p,char *buf) +{ + pstring comment; + uint32 server_type; + int announce_interval = lp_lm_announce(); + + + if (announce_interval <= 0) + { + DEBUG(3,("ignoring LM announcement request from %s\n",buf+2)); + /* The server is configured to not send LM announcements */ + return; + } + + DEBUG(3,("responding to LM announcement request from %s\n",buf+2)); + + server_type = SV_TYPE_WORKSTATION|SV_TYPE_SERVER|SV_TYPE_TIME_SOURCE; + + StrnCpy(comment, lp_serverstring(), 43); + + do_announce_lm_host(ANN_HostAnnouncement, + myname, 0x00, + *iface_ip(p->ip), lp_workgroup(), + 0x00, p->ip, + announce_interval, myname, + server_type, comment); +} + + +/**************************************************************************** + process a LAN Manager browse frame + **************************************************************************/ + +void process_lanman_packet(struct packet_struct *p,char *buf,int len) +{ + int code = SVAL(buf,0); + switch( code ) + { + case ANN_HostAnnouncement: + { + debug_browse_data(buf, len); + process_lm_announce(p, ANN_HostAnnouncement, buf); + break; + } + + case ANN_AnnouncementRequest: + { + debug_browse_data(buf, len); + process_lm_announce_request(p, buf); + break; + } + + default: + { + struct dgram_packet *dgram = &p->packet.dgram; + DEBUG(4,("unknown LM browse packet %d from %s %s to %s\n", + code, namestr(&dgram->source_name), + inet_ntoa(p->ip), namestr(&dgram->dest_name))); + } + } +} --- nmbd.c.orig Thu Jul 31 20:55:19 1997 +++ nmbd.c Mon Sep 1 14:25:11 1997 @@ -71,6 +71,8 @@ /* XXXX don't care if we never receive a response back... yet */ announce_my_servers_removed(); + announce_my_lm_servers_removed(); + /* XXXX other things: if we are a master browser, force an election? */ exit(0); @@ -310,6 +312,7 @@ announce_host(t); announce_master(t); announce_remote(t); + announce_lm_host(t); query_refresh_names(t); --- reply.c.orig Fri Aug 22 06:35:23 1997 +++ reply.c Mon Sep 1 14:25:11 1997 @@ -2105,11 +2105,11 @@ mtime = make_unix_date3(inbuf+smb_vwv1); + close_file(fnum); + /* try and set the date */ set_filetime(Files[fnum].name,mtime); - close_file(fnum); - /* We have a cached error */ if(eclass || err) return(ERROR(eclass,err)); @@ -2153,10 +2153,10 @@ nwritten = write_file(fnum,data,numtowrite); - set_filetime(Files[fnum].name,mtime); - close_file(fnum); + set_filetime(Files[fnum].name,mtime); + DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n", timestring(),fnum,cnum,numtowrite,nwritten, Connections[cnum].num_files_open)); --- server.c.orig Fri Aug 22 06:35:24 1997 +++ server.c Mon Sep 1 14:25:11 1997 @@ -1532,7 +1532,7 @@ if (strstr(fname,".+,;=[].")) { unix_ERR_class = ERRDOS; - unix_ERR_code = ERROR_EAS_NOT_SUPPORTED; + unix_ERR_code = ERRcannotopen; return; } --- trans2.c.orig Tue Aug 26 03:29:20 1997 +++ trans2.c Mon Sep 1 14:27:18 1997 @@ -1301,11 +1301,7 @@ if (total_data > 0 && IVAL(pdata,0) == total_data) { /* uggh, EAs for OS2 */ DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data)); -#ifdef OS2_WPS_FIX /* This may become the main code stream in a later release */ - return(ERROR(ERRDOS,ERRcannotopen)); -#else /* OS2_WPS_FIX */ return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED)); -#endif /* OS2_WPS_FIX */ } switch (info_level)