summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source3/client/client.c12
-rw-r--r--source3/client/clientutil.c8
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/proto.h10
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/lib/system.c2
-rw-r--r--source3/lib/util.c23
-rw-r--r--source3/locking/locking.c2
-rw-r--r--source3/nameannounce.c115
-rw-r--r--source3/nameannounce.doc2
-rw-r--r--source3/nameelect.c2
-rw-r--r--source3/namepacket.c37
-rw-r--r--source3/namework.c5
-rw-r--r--source3/nmbd/nmbd.c18
-rw-r--r--source3/param/loadparm.c40
-rw-r--r--source3/printing/printing.c154
-rw-r--r--source3/smbd/pipes.c17
-rw-r--r--source3/smbd/reply.c125
-rw-r--r--source3/smbd/server.c154
-rw-r--r--source3/utils/nmblookup.c2
20 files changed, 351 insertions, 380 deletions
diff --git a/source3/client/client.c b/source3/client/client.c
index b0e4f4a004..6bd94be756 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -33,7 +33,7 @@ pstring cur_dir = "\\";
pstring cd_path = "";
pstring service="";
pstring desthost="";
-pstring myname = "";
+extern pstring myname;
pstring password = "";
pstring username="";
pstring workgroup=WORKGROUP;
@@ -3988,11 +3988,10 @@ static BOOL open_sockets(int port )
strcpy(desthost,host);
}
- if (*myname == 0)
- {
+ if (*myname == 0) {
get_myname(myname,NULL);
- strupper(myname);
- }
+ }
+ strupper(myname);
DEBUG(3,("Opening sockets\n"));
@@ -4008,7 +4007,8 @@ static BOOL open_sockets(int port )
/* Try and resolve the name with the netbios server */
int bcast;
- if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) {
+ if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3,
+ interpret_addr(lp_socket_address()))) != -1) {
set_socket_options(bcast, "SO_BROADCAST");
if (name_query(bcast, host, 0x20, True, True, *iface_bcast(dest_ip),
diff --git a/source3/client/clientutil.c b/source3/client/clientutil.c
index 41c482196a..e684d42612 100644
--- a/source3/client/clientutil.c
+++ b/source3/client/clientutil.c
@@ -31,7 +31,7 @@
pstring service="";
pstring desthost="";
-pstring myname = "";
+extern pstring myname;
pstring password = "";
pstring username="";
pstring workgroup=WORKGROUP;
@@ -819,10 +819,8 @@ BOOL cli_open_sockets(int port)
DEBUG(5,("Opening sockets\n"));
if (*myname == 0)
- {
- get_myname(myname,NULL);
- strupper(myname);
- }
+ get_myname(myname,NULL);
+ strupper(myname);
if (!have_ip)
{
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 35ef18055c..c7acbddc2b 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -220,7 +220,6 @@ Here come some platform specific sections
#define HAVE_BZERO
#define HAVE_MEMMOVE
#define USE_SIGPROCMASK
-#define FAST_SHARE_MODES 1
#if 0
/* SETFS disabled until we can check on some bug reports */
#if _LINUX_C_LIB_VERSION_MAJOR >= 5
diff --git a/source3/include/proto.h b/source3/include/proto.h
index c1697dc641..9ddf7cb1fd 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -143,6 +143,7 @@ char *lp_logon_script(void);
char *lp_remote_announce(void);
char *lp_wins_server(void);
char *lp_interfaces(void);
+char *lp_socket_address(void);
BOOL lp_wins_support(void);
BOOL lp_wins_proxy(void);
BOOL lp_domain_master(void);
@@ -297,7 +298,6 @@ void do_announce_request(char *info, char *to_name, int announce_type,
void sync_server(enum state_type state, char *serv_name, char *work_name,
int name_type,
struct in_addr ip);
-void announce_backup(void);
void do_announce_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,
@@ -305,7 +305,7 @@ void do_announce_host(int command,
char *server_name, int server_type, char *server_comment);
void remove_my_servers(void);
void announce_server(struct subnet_record *d, struct work_record *work,
- char *name, char *comment, time_t ttl, int server_type);
+ char *name, char *comment, time_t ttl, int server_type);
void announce_host(void);
void announce_master(void);
void announce_remote(void);
@@ -686,7 +686,7 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
void exit_server(char *reason);
void standard_sub(int cnum,char *s);
char *smb_fn_name(int type);
-int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
+int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
/*The following definitions come from shmem.c */
@@ -891,9 +891,9 @@ int byte_checksum(char *buf,int len);
char *dirname_dos(char *path,char *buf);
void *Realloc(void *p,int size);
void Abort(void );
-BOOL get_myname(char *myname,struct in_addr *ip);
+BOOL get_myname(char *my_name,struct in_addr *ip);
BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
-int open_socket_in(int type, int port, int dlevel);
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr);
int open_socket_out(int type, struct in_addr *addr, int port );
int interpret_protocol(char *str,int def);
int interpret_security(char *str,int def);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index c9180dd50c..349d406b49 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -796,7 +796,7 @@ enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER};
/* printing types */
enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
- PRINT_QNX,PRINT_PLP};
+ PRINT_QNX,PRINT_PLP,PRINT_LPRNG};
/* case handling */
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 1410b776ab..81e9a6679a 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -98,7 +98,7 @@ int sys_select(fd_set *fds,struct timeval *tval)
do {
if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
errno = 0;
- selrtn = select(16,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
+ selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
} while (selrtn<0 && errno == EINTR);
return(selrtn);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 5ef1d21a7a..2f3ac1bb15 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -48,6 +48,9 @@ struct in_addr lastip;
/* the last port received from */
int lastport=0;
+/* this is used by the chaining code */
+int chain_size = 0;
+
int trans_num = 0;
/*
@@ -73,7 +76,7 @@ fstring remote_proto="UNKNOWN";
pstring myhostname="";
pstring user_socket_options="";
pstring sesssetup_user="";
-
+pstring myname = "";
int smb_read_error = 0;
@@ -1075,7 +1078,7 @@ return the SMB offset into an SMB buffer
********************************************************************/
int smb_offset(char *p,char *buf)
{
- return(PTR_DIFF(p,buf+4));
+ return(PTR_DIFF(p,buf+4) + chain_size);
}
@@ -2696,7 +2699,7 @@ void Abort(void )
/****************************************************************************
get my own name and IP
****************************************************************************/
-BOOL get_myname(char *myname,struct in_addr *ip)
+BOOL get_myname(char *my_name,struct in_addr *ip)
{
struct hostent *hp;
pstring hostname;
@@ -2717,13 +2720,13 @@ BOOL get_myname(char *myname,struct in_addr *ip)
return False;
}
- if (myname)
+ if (my_name)
{
/* split off any parts after an initial . */
char *p = strchr(hostname,'.');
if (p) *p = 0;
- strcpy(myname,hostname);
+ strcpy(my_name,hostname);
}
if (ip)
@@ -2748,7 +2751,7 @@ BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
/****************************************************************************
open a socket of the specified type, port and address for incoming data
****************************************************************************/
-int open_socket_in(int type, int port, int dlevel)
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
{
struct hostent *hp;
struct sockaddr_in sock;
@@ -2773,7 +2776,7 @@ int open_socket_in(int type, int port, int dlevel)
#endif
sock.sin_port = htons( port );
sock.sin_family = hp->h_addrtype;
- sock.sin_addr.s_addr = INADDR_ANY;
+ sock.sin_addr.s_addr = socket_addr;
res = socket(hp->h_addrtype, type, 0);
if (res == -1)
{ DEBUG(0,("socket failed\n")); return -1; }
@@ -2788,15 +2791,15 @@ int open_socket_in(int type, int port, int dlevel)
{
if (port) {
if (port == SMB_PORT || port == NMB_PORT)
- DEBUG(dlevel,("bind failed on port %d (%s)\n",
- port,strerror(errno)));
+ DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
+ port,socket_addr,strerror(errno)));
close(res);
if (dlevel > 0 && port < 1000)
port = 7999;
if (port >= 1000 && port < 9000)
- return(open_socket_in(type,port+1,dlevel));
+ return(open_socket_in(type,port+1,dlevel,socket_addr));
}
return(-1);
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 966bb2253b..04f4a4b197 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -240,6 +240,8 @@ BOOL start_share_mode_mgmt(void)
pstring shmem_file_name;
strcpy(shmem_file_name,lp_lockdir());
+ if (!directory_exist(shmem_file_name,NULL))
+ mkdir(shmem_file_name,0755);
trim_string(shmem_file_name,"","/");
if (!*shmem_file_name) return(False);
strcat(shmem_file_name, "/SHARE_MEM_FILE");
diff --git a/source3/nameannounce.c b/source3/nameannounce.c
index 0127ae03e3..09aade86ef 100644
--- a/source3/nameannounce.c
+++ b/source3/nameannounce.c
@@ -137,102 +137,6 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
/****************************************************************************
- construct a host announcement unicast
-
- this function should not be used heavily, and only when we are _not_
- a master browser and _not_ a primary domain controller.
-
- **************************************************************************/
-void announce_backup(void)
-{
- static time_t lastrun = 0;
- time_t t = time(NULL);
- pstring outbuf;
- char *p;
- struct subnet_record *d1;
- int tok;
- static uint32 id_count = 0;
-
- if (!lastrun) lastrun = t;
-#if 1
- if (t < lastrun + 1 * 60)
-#else
- if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
-#endif
- return;
- lastrun = t;
-
- DEBUG(4,("checking backups...\n"));
-
- for (tok = 0; tok <= workgroup_count; tok++)
- {
- for (d1 = subnetlist; d1; d1 = d1->next)
- {
- struct work_record *work;
- struct subnet_record *d;
-
- /* search for unique workgroup: only the name matters */
- for (work = d1->workgrouplist;
- work && (tok != work->token);
- work = work->next);
-
- if (!work) continue;
-
- if (AM_MASTER(work) && AM_DOMCTL(work)) continue;
-
- /* found one: announce it across all domains */
- for (d = subnetlist; d; d = d->next)
- {
-
- DEBUG(2,("sending announce backup %s workgroup %s(%d)\n",
- inet_ntoa(d->bcast_ip),work->work_group,
- work->token));
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
-
- CVAL(p,0) = ANN_GetBackupListReq;
- CVAL(p,1) = work->token; /* workgroup unique key index */
- SIVAL(p,2,++id_count); /* unique count. not that we use it! */
-
- p += 6;
-
- debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
-
- if (!AM_DOMCTL(work))
- {
- /* only ask for a list of backup domain controllers
- if we are not a domain controller ourselves */
-
- send_mailslot_reply(BROWSE_MAILSLOT,
- ClientDGRAM,outbuf,
- PTR_DIFF(p,outbuf),
- myname, work->work_group,
- 0x0,0x1b,d->bcast_ip,
- *iface_ip(d->bcast_ip));
- }
-
- debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
-
- if (!AM_MASTER(work))
- {
- /* only ask for a list of master browsers if we
- are not a master browser ourselves */
-
- send_mailslot_reply(BROWSE_MAILSLOT,
- ClientDGRAM,outbuf,
- PTR_DIFF(p,outbuf),
- myname, work->work_group,
- 0x0,0x1d,d->bcast_ip,
- *iface_ip(d->bcast_ip));
- }
- }
- }
- }
-}
-
-
-/****************************************************************************
send a host announcement packet
**************************************************************************/
void do_announce_host(int command,
@@ -305,7 +209,7 @@ void remove_my_servers(void)
announce a server entry
****************************************************************************/
void announce_server(struct subnet_record *d, struct work_record *work,
- char *name, char *comment, time_t ttl, int server_type)
+ char *name, char *comment, time_t ttl, int server_type)
{
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
@@ -315,7 +219,8 @@ void announce_server(struct subnet_record *d, struct work_record *work,
/* wins pseudo-ip interface */
if (!AM_MASTER(work))
{
- /* non-master announce by unicast to the domain master */
+ /* non-master announce by unicast to the domain
+ master */
if (!lp_wins_support() && *lp_wins_server())
{
/* look up the domain master with the WINS server */
@@ -441,14 +346,6 @@ void announce_host(void)
work->lastannounce_time = t;
- /*
- if (!d->my_interface) {
- stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
- SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
- SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
- }
- */
-
for (s = work->serverlist; s; s = s->next) {
if (strequal(myname, s->serv.name)) {
announce = True;
@@ -456,9 +353,9 @@ void announce_host(void)
}
}
- if (announce)
- {
- announce_server(d,work,my_name,comment,work->announce_interval,stype);
+ if (announce) {
+ announce_server(d,work,my_name,comment,
+ work->announce_interval,stype);
}
if (work->needannounce)
diff --git a/source3/nameannounce.doc b/source3/nameannounce.doc
index a1e33cb800..e04a59209a 100644
--- a/source3/nameannounce.doc
+++ b/source3/nameannounce.doc
@@ -81,7 +81,7 @@ via name queries will just lead to lag and propogation delays, because
if two parts of the net choose different DMBs then the data will be
very slow to propoogate.
-If a DMB is configured then just sent the master announcemnt to that
+If a DMB is configured then just send the master announcemnt to that
box! Thats all that needs to be done. Just send a udp 138 packet and
forget it. If the recipient is indeed a DMB (as it should be if the
config file is correct) then it should initiate a browse list sync
diff --git a/source3/nameelect.c b/source3/nameelect.c
index 38b4d5d80e..2edc484ba0 100644
--- a/source3/nameelect.c
+++ b/source3/nameelect.c
@@ -502,7 +502,7 @@ void run_elections(void)
work->work_group,inet_ntoa(d->bcast_ip)));
work->RunningElection = False;
- work->state = MST_NONE;
+ work->state = MST_NONE;
become_master(d, work);
}
diff --git a/source3/namepacket.c b/source3/namepacket.c
index a752ef5dfa..4be5a95952 100644
--- a/source3/namepacket.c
+++ b/source3/namepacket.c
@@ -360,7 +360,8 @@ static void process_nmb(struct packet_struct *p)
{
if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
if (nmb->header.response)
- response_netbios_packet(p); /* response to registration dealt with here */
+ response_netbios_packet(p); /* response to registration dealt
+ with here */
else
reply_name_reg(p);
break;
@@ -409,7 +410,8 @@ static void process_nmb(struct packet_struct *p)
}
if (nmb->header.response)
- response_netbios_packet(p); /* response to reply dealt with in here */
+ response_netbios_packet(p); /* response to reply dealt with
+ in here */
else
reply_name_release(p);
break;
@@ -457,10 +459,11 @@ void listen_for_packets(BOOL run_election)
FD_SET(ClientNMB,&fds);
FD_SET(ClientDGRAM,&fds);
- /* during elections and when expecting a netbios response packet we need
- to send election packets at one second intervals.
- XXXX actually, it needs to be the interval (in ms) between time now and the
- time we are expecting the next netbios packet */
+ /* during elections and when expecting a netbios response packet we
+ need to send election packets at tighter intervals
+
+ ideally it needs to be the interval (in ms) between time now and
+ the time we are expecting the next netbios packet */
timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
timeout.tv_usec = 0;
@@ -471,17 +474,14 @@ void listen_for_packets(BOOL run_election)
{
struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
if (packet) {
-#if 1
if (ismyip(packet->ip) &&
(packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- DEBUG(5,("discarding own packet from %s:%d\n",
+ DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
- } else
-#endif
- {
- queue_packet(packet);
- }
+ } else {
+ queue_packet(packet);
+ }
}
}
@@ -489,17 +489,14 @@ void listen_for_packets(BOOL run_election)
{
struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
if (packet) {
-#if 1
if (ismyip(packet->ip) &&
(packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- DEBUG(5,("discarding own packet from %s:%d\n",
+ DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
- } else
-#endif
- {
- queue_packet(packet);
- }
+ } else {
+ queue_packet(packet);
+ }
}
}
}
diff --git a/source3/namework.c b/source3/namework.c
index 74c567fa74..108048d500 100644
--- a/source3/namework.c
+++ b/source3/namework.c
@@ -284,11 +284,12 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
tell_become_backup();
#endif
- /* get the local_only browse list from the local master and add it to ours. */
+ /* get the local_only browse list from the local master and add it
+ to ours. */
if (command == ANN_LocalMasterAnnouncement)
{
add_browser_entry(serv_name,dgram->dest_name.name_type,
- work->work_group,30,ip,True);
+ work->work_group,30,ip,True);
}
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 82ea9550f3..2621be87ee 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -305,14 +305,6 @@ static void process(void)
announce_host();
-#if 0
- /* XXXX what was this stuff supposed to do? It sent
- ANN_GetBackupListReq packets which I think should only be
- sent when trying to find out who to browse with */
-
- announce_backup();
-#endif
-
announce_master();
announce_remote();
@@ -344,11 +336,11 @@ static BOOL open_sockets(BOOL isdaemon, int port)
}
if (isdaemon)
- ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
+ ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()));
else
ClientNMB = 0;
- ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
+ ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,interpret_addr(lp_socket_address()));
if (ClientNMB == -1)
return(False);
@@ -376,8 +368,8 @@ static BOOL init_structs()
strcpy(myname,myhostname);
p = strchr(myname,'.');
if (p) *p = 0;
- strupper(myname);
}
+ strupper(myname);
return True;
}
@@ -490,11 +482,11 @@ static void usage(char *pname)
DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
- init_structs();
-
if (!reload_services(False))
return(-1);
+ init_structs();
+
set_samba_nb_type();
if (!is_daemon && !is_a_socket(0)) {
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 953613fd74..87209d1bb7 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -53,6 +53,7 @@ BOOL bLoaded = False;
extern int DEBUGLEVEL;
extern pstring user_socket_options;
+extern pstring myname;
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
@@ -83,7 +84,8 @@ extern pstring user_socket_options;
/* these are the types of parameter we have */
typedef enum
{
- P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_STRING,P_GSTRING
+ P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
+ P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
} parm_type;
typedef enum
@@ -130,6 +132,7 @@ typedef struct
char *szWINSserver;
char *szInterfaces;
char *szRemoteAnnounce;
+ char *szSocketAddress;
int max_log_size;
int mangled_stack;
int max_xmit;
@@ -371,6 +374,7 @@ struct parm_struct
{"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
+ {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
{"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
{"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
@@ -393,12 +397,13 @@ struct parm_struct
{"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
{"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
{"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
- {"workgroup", P_STRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
+ {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
{"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
{"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
{"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
{"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
{"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
+ {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
{"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
{"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
@@ -525,7 +530,8 @@ static void init_globals(void)
bzero((void *)&Globals,sizeof(Globals));
for (i = 0; parm_table[i].label; i++)
- if (parm_table[i].type == P_STRING &&
+ if ((parm_table[i].type == P_STRING ||
+ parm_table[i].type == P_USTRING) &&
parm_table[i].ptr)
string_init(parm_table[i].ptr,"");
@@ -551,6 +557,7 @@ static void init_globals(void)
string_set(&Globals.szLockDir, LOCKDIR);
string_set(&Globals.szRootdir, "/");
string_set(&Globals.szSmbrun, SMBRUN);
+ string_set(&Globals.szSocketAddress, "0.0.0.0");
sprintf(s,"Samba %s",VERSION);
string_set(&Globals.szServerString,s);
Globals.bLoadPrinters = True;
@@ -611,6 +618,7 @@ static void init_locals(void)
{
case PRINT_BSD:
case PRINT_AIX:
+ case PRINT_LPRNG:
case PRINT_PLP:
string_initial(&sDefault.szLpqcommand,"lpq -P%p");
string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
@@ -735,6 +743,7 @@ FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
+FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
@@ -875,7 +884,9 @@ static void free_service(service *pservice)
return;
for (i=0;parm_table[i].label;i++)
- if (parm_table[i].type == P_STRING && parm_table[i].class == P_LOCAL)
+ if ((parm_table[i].type == P_STRING ||
+ parm_table[i].type == P_STRING) &&
+ parm_table[i].class == P_LOCAL)
string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
}
@@ -1164,6 +1175,11 @@ static void copy_service(service *pserviceDest,
case P_STRING:
string_set(dest_ptr,*(char **)src_ptr);
break;
+
+ case P_USTRING:
+ string_set(dest_ptr,*(char **)src_ptr);
+ strupper(*(char **)dest_ptr);
+ break;
default:
break;
}
@@ -1344,6 +1360,8 @@ static BOOL handle_printing(char *pszParmValue,int *val)
*val = PRINT_QNX;
else if (strequal(pszParmValue,"plp"))
*val = PRINT_PLP;
+ else if (strequal(pszParmValue,"lprng"))
+ *val = PRINT_LPRNG;
return(True);
}
@@ -1526,9 +1544,19 @@ static BOOL do_parameter(char *pszParmName, char *pszParmValue)
string_set(parm_ptr,pszParmValue);
break;
+ case P_USTRING:
+ string_set(parm_ptr,pszParmValue);
+ strupper(*(char **)parm_ptr);
+ break;
+
case P_GSTRING:
strcpy((char *)parm_ptr,pszParmValue);
break;
+
+ case P_UGSTRING:
+ strcpy((char *)parm_ptr,pszParmValue);
+ strupper((char *)parm_ptr);
+ break;
}
return(True);
@@ -1562,11 +1590,13 @@ static void print_parameter(parm_type type,void *ptr)
break;
case P_GSTRING:
+ case P_UGSTRING:
if ((char *)ptr)
printf("%s",(char *)ptr);
break;
case P_STRING:
+ case P_USTRING:
if (*(char **)ptr)
printf("%s",*(char **)ptr);
break;
@@ -1593,6 +1623,7 @@ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
return(*((char *)ptr1) == *((char *)ptr2));
case P_GSTRING:
+ case P_UGSTRING:
{
char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
if (p1 && !*p1) p1 = NULL;
@@ -1600,6 +1631,7 @@ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
return(p1==p2 || strequal(p1,p2));
}
case P_STRING:
+ case P_USTRING:
{
char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
if (p1 && !*p1) p1 = NULL;
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 00df859e0a..d1b702cb0a 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -277,6 +277,157 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
return(True);
}
+/*
+<magnus@hum.auc.dk>
+LPRng_time modifies the current date by inserting the hour and minute from
+the lpq output. The lpq time looks like "23:15:07"
+*/
+static time_t LPRng_time(string tok[],int pos)
+{
+ time_t jobtime;
+ struct tm *t;
+ char tmp_time[9];
+
+ jobtime = time(NULL); /* default case: take current time */
+ t = localtime(&jobtime);
+ t->tm_hour = atoi(tok[pos]);
+ StrnCpy(tmp_time,tok[pos],sizeof(tmp_time));
+ t->tm_min = atoi(tmp_time+3);
+ t->tm_sec = atoi(tmp_time+6);
+ jobtime = mktime(t);
+
+ return jobtime;
+}
+
+
+/****************************************************************************
+ parse a lpq line
+ <magnus@hum.auc.dk>
+ Most of the code is directly reused from parse_lpq_bsd()
+
+here are two examples of lpq output under lprng (LPRng-2.3.0)
+
+Printer: humprn@hum-fak
+ Queue: 1 printable job
+ Server: pid 4840 active, Unspooler: pid 4841 active
+ Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996
+ Rank Owner Class Job Files Size Time
+active magnus@hum-fak A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31
+
+Printer: humprn@hum-fak (printing disabled)
+ Queue: 1 printable job
+ Warning: no server present
+ Status: finished operations at Fri Jun 21 10:10:32 1996
+ Rank Owner Class Job Files Size Time
+1 magnus@hum-fak A 387 /var/spool/smb/netbudget.xls 21230 10:50:53
+
+****************************************************************************/
+static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
+{
+#define LPRNG_RANKTOK 0
+#define LPRNG_USERTOK 1
+#define LPRNG_PRIOTOK 2
+#define LPRNG_JOBTOK 3
+#define LPRNG_FILETOK 4
+#define LPRNG_TOTALTOK 5
+#define LPRNG_TIMETOK 6
+#define LPRNG_NTOK 7
+
+/****************************************************************************
+From lpd_status.c in LPRng source.
+0 1 2 3 4 5 6 7
+12345678901234567890123456789012345678901234567890123456789012345678901234
+" Rank Owner Class Job Files Size Time"
+ plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s",
+ number, line, priority, cfp->number, error );
+ plp_snprintf( msg + len, sizeof(msg)-len, "%4d",
+ cfp->jobsize );
+ plp_snprintf( msg+len, sizeof(msg)-len, " %s",
+ Time_str( 1, cfp->statb.st_ctime ) );
+****************************************************************************/
+ /* The following define's are to be able to adjust the values if the
+LPRng source changes. This is from version 2.3.0. Magnus */
+#define SPACE_W 1
+#define RANK_W 6
+#define OWNER_W 19
+#define CLASS_W 1
+#define JOB_W 3
+#define FILE_W 32
+/* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */
+#define JOBSIZE_W 4
+
+#define RANK_POS 0
+#define OWNER_POS RANK_POS+RANK_W+SPACE_W
+#define CLASS_POS OWNER_POS+OWNER_W+SPACE_W
+#define JOB_POS CLASS_POS+CLASS_W+SPACE_W
+#define FILE_POS JOB_POS+JOB_W+SPACE_W
+#define JOBSIZE_POS FILE_POS+FILE_W
+
+
+ string tok[LPRNG_NTOK];
+ int count=0;
+
+/*
+Need to insert one space in front of the size, to be able to use
+next_token() unchanged. I would have liked to be able to insert a
+space instead, to prevent losing that one char, but perl has spoiled
+me :-\ So I did it the easiest way.
+
+HINT: Use as short a path as possible for the samba spool directory.
+A long spool-path will just waste significant chars of the file name.
+*/
+
+ (char)line[JOBSIZE_POS-1]=' ';
+
+ /* handle the case of "(stdin)" as a filename */
+ string_sub(line,"stdin","STDIN");
+ string_sub(line,"(","\"");
+ string_sub(line,")","\"");
+
+ for (count=0; count<LPRNG_NTOK && next_token(&line,tok[count],NULL); count++) ;
+
+ /* we must get LPRNG_NTOK tokens */
+ if (count < LPRNG_NTOK)
+ return(False);
+
+ /* the Job and Total columns must be integer */
+ if (!isdigit(*tok[LPRNG_JOBTOK]) || !isdigit(*tok[LPRNG_TOTALTOK])) return(False);
+
+ /* if the fname contains a space then use STDIN */
+ /* I do not understand how this would be possible. Magnus. */
+ if (strchr(tok[LPRNG_FILETOK],' '))
+ strcpy(tok[LPRNG_FILETOK],"STDIN");
+
+ /* only take the last part of the filename */
+ {
+ string tmp;
+ char *p = strrchr(tok[LPRNG_FILETOK],'/');
+ if (p)
+ {
+ strcpy(tmp,p+1);
+ strcpy(tok[LPRNG_FILETOK],tmp);
+ }
+ }
+
+
+ buf->job = atoi(tok[LPRNG_JOBTOK]);
+ buf->size = atoi(tok[LPRNG_TOTALTOK]);
+ buf->status = strequal(tok[LPRNG_RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
+ /* buf->time = time(NULL); */
+ buf->time = LPRng_time(tok,LPRNG_TIMETOK);
+DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time)));
+ StrnCpy(buf->user,tok[LPRNG_USERTOK],sizeof(buf->user)-1);
+ StrnCpy(buf->file,tok[LPRNG_FILETOK],sizeof(buf->file)-1);
+#ifdef LPRNG_PRIOTOK
+ /* Here I try to map the CLASS char to a number, but the number
+ is never shown in Print Manager under NT anyway... Magnus. */
+ buf->priority = atoi(tok[LPRNG_PRIOTOK-('A'-1)]);
+#else
+ buf->priority = 1;
+#endif
+ return(True);
+}
+
/*******************************************************************
@@ -695,6 +846,9 @@ static BOOL parse_lpq_entry(int snum,char *line,
case PRINT_QNX:
ret = parse_lpq_qnx(line,buf,first);
break;
+ case PRINT_LPRNG:
+ ret = parse_lpq_lprng(line,buf,first);
+ break;
case PRINT_PLP:
ret = parse_lpq_plp(line,buf,first);
break;
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 724f58e1e2..ffa46083c3 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -35,7 +35,6 @@
/* look in server.c for some explanation of these variables */
extern int Protocol;
extern int DEBUGLEVEL;
-extern int chain_size;
extern int maxxmit;
extern int chain_fnum;
extern char magic_char;
@@ -72,9 +71,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
pstring fname;
int cnum = SVAL(inbuf,smb_tid);
int fnum = -1;
- int outsize = 0;
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
#if 0
@@ -149,8 +145,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
}
/* Prepare the reply */
- outsize = set_message(outbuf,15,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
+ set_message(outbuf,15,0,True);
/* Put things back the way they were. */
Connections[cnum].read_only = 1;
@@ -164,7 +159,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
rmode = 1;
}
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
SSVAL(outbuf,smb_vwv2,fnum);
SSVAL(outbuf,smb_vwv3,fmode);
put_dos_date3(outbuf,smb_vwv4,mtime);
@@ -174,17 +168,10 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
fname, fnum, Files[fnum].name));
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 3c2e91d5f5..a84a9af0c1 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -30,7 +30,6 @@
/* look in server.c for some explanation of these variables */
extern int Protocol;
extern int DEBUGLEVEL;
-extern int chain_size;
extern int maxxmit;
extern int chain_fnum;
extern char magic_char;
@@ -178,11 +177,8 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
pstring password;
pstring devicename;
int connection_num;
- int outsize = 0;
int uid = SVAL(inbuf,smb_uid);
int vuid;
- int smb_com2 = SVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int passlen = SVAL(inbuf,smb_vwv3);
*service = *user = *password = *devicename = 0;
@@ -221,7 +217,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (connection_num < 0)
return(connection_error(inbuf,outbuf,connection_num));
- outsize = set_message(outbuf,2,strlen(devicename)+1,True);
+ set_message(outbuf,2,strlen(devicename)+1,True);
DEBUG(3,("%s tconX service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
@@ -229,17 +225,9 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
SSVAL(inbuf,smb_tid,connection_num);
SSVAL(outbuf,smb_tid,connection_num);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size + outsize)-4);
-
strcpy(smb_buf(outbuf),devicename);
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -278,11 +266,8 @@ reply to a session setup command
****************************************************************************/
int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- int outsize = 0;
int sess_uid;
int gid;
- int smb_com2;
- int smb_off2;
int smb_bufsize;
int smb_mpxmax;
int smb_vc_num;
@@ -299,8 +284,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
*smb_apasswd = 0;
sess_uid = SVAL(inbuf,smb_uid);
- smb_com2 = CVAL(inbuf,smb_vwv0);
- smb_off2 = SVAL(inbuf,smb_vwv1);
smb_bufsize = SVAL(inbuf,smb_vwv2);
smb_mpxmax = SVAL(inbuf,smb_vwv3);
smb_vc_num = SVAL(inbuf,smb_vwv4);
@@ -424,15 +407,15 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
/* it's ok - setup a reply */
if (Protocol < PROTOCOL_NT1) {
- outsize = set_message(outbuf,3,0,True);
+ set_message(outbuf,3,0,True);
} else {
char *p;
- outsize = set_message(outbuf,3,3,True);
+ set_message(outbuf,3,3,True);
p = smb_buf(outbuf);
strcpy(p,"Unix"); p = skip_string(p,1);
strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
strcpy(p,lp_workgroup()); p = skip_string(p,1);
- outsize = set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
+ set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
/* perhaps grab OS version here?? */
}
@@ -451,9 +434,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
SSVAL(inbuf,smb_uid,(uint16)pw->pw_uid);
}
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
-
if (guest && !computer_id)
SSVAL(outbuf,smb_vwv2,1);
@@ -463,12 +443,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
maxxmit = MIN(maxxmit,smb_bufsize);
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -973,10 +948,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
pstring fname;
int cnum = SVAL(inbuf,smb_tid);
int fnum = -1;
- int outsize = 0;
int openmode = 0;
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
#if 0
@@ -1033,9 +1005,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
return(ERROR(ERRDOS,ERRnoaccess));
}
- outsize = set_message(outbuf,15,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
+ set_message(outbuf,15,0,True);
SSVAL(outbuf,smb_vwv2,fnum);
SSVAL(outbuf,smb_vwv3,fmode);
put_dos_date3(outbuf,smb_vwv4,mtime);
@@ -1045,14 +1015,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1061,26 +1024,15 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
****************************************************************************/
int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
{
- int outsize = 0;
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int uid = SVAL(inbuf,smb_uid);
invalidate_uid(uid);
- outsize = set_message(outbuf,2,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
+ set_message(outbuf,2,0,True);
DEBUG(3,("%s ulogoffX uid=%d\n",timestring(),uid));
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1486,8 +1438,6 @@ int reply_read(char *inbuf,char *outbuf)
****************************************************************************/
int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int fnum = GETFNUM(inbuf,smb_vwv2);
uint32 smb_offs = IVAL(inbuf,smb_vwv3);
int smb_maxcnt = SVAL(inbuf,smb_vwv5);
@@ -1495,7 +1445,6 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
int cnum;
int nread = -1;
char *data;
- int outsize = 0;
BOOL ok = False;
cnum = SVAL(inbuf,smb_tid);
@@ -1504,7 +1453,7 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
CHECK_READ(fnum);
CHECK_ERROR(fnum);
- outsize = set_message(outbuf,12,0,True);
+ set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
if (is_locked(fnum,cnum,smb_maxcnt,smb_offs))
@@ -1515,27 +1464,17 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
- outsize += nread;
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
SSVAL(outbuf,smb_vwv5,nread);
- SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf) + chain_size);
+ SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
SSVAL(smb_buf(outbuf),-2,nread);
- DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d com2=%d off2=%d\n",
+ DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d\n",
timestring(),fnum,cnum,
- smb_mincnt,smb_maxcnt,nread,smb_com2,smb_off2));
+ smb_mincnt,smb_maxcnt,nread));
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1767,8 +1706,6 @@ int reply_write(char *inbuf,char *outbuf,int dum1,int dum2)
****************************************************************************/
int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int fnum = GETFNUM(inbuf,smb_vwv2);
uint32 smb_offs = IVAL(inbuf,smb_vwv3);
int smb_dsize = SVAL(inbuf,smb_vwv10);
@@ -1776,7 +1713,6 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
int cnum;
int nwritten = -1;
- int outsize = 0;
char *data;
cnum = SVAL(inbuf,smb_tid);
@@ -1804,10 +1740,8 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0))
return(UNIXERROR(ERRDOS,ERRnoaccess));
- outsize = set_message(outbuf,6,0,True);
+ set_message(outbuf,6,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
SSVAL(outbuf,smb_vwv2,nwritten);
if (nwritten < smb_dsize) {
@@ -1822,14 +1756,7 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (lp_syncalways(SNUM(cnum)) || write_through)
sync_file(fnum);
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -2828,8 +2755,6 @@ int reply_setdir(char *inbuf,char *outbuf)
****************************************************************************/
int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
{
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int fnum = GETFNUM(inbuf,smb_vwv2);
uint16 locktype = SVAL(inbuf,smb_vwv3);
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
@@ -2840,7 +2765,7 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
int i;
char *data;
uint32 ecode=0, dummy2;
- int outsize, eclass=0, dummy1;
+ int eclass=0, dummy1;
cnum = SVAL(inbuf,smb_tid);
@@ -2879,24 +2804,14 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
return ERROR(eclass,ecode);
}
- outsize = set_message(outbuf,2,0,True);
-
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
+ set_message(outbuf,2,0,True);
DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
timestring(),fnum,cnum,locktype,num_locks,num_ulocks));
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 403b41e86b..c377684536 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -59,8 +59,6 @@ extern int Protocol;
int maxxmit = BUFFER_SIZE;
-int chain_size = 0;
-
/* a fnum to use when chaining */
int chain_fnum = -1;
@@ -1645,7 +1643,7 @@ static BOOL open_sockets(BOOL is_daemon,int port)
#endif
/* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0);
+ s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
if (s == -1)
return(False);
@@ -3221,103 +3219,97 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
/****************************************************************************
-construct a chained reply and add it to the already made reply
-
-inbuf points to the original message start.
-inbuf2 points to the smb_wct part of the secondary message
-type is the type of the secondary message
-outbuf points to the original outbuffer
-outbuf2 points to the smb_wct field of the new outbuffer
-size is the total length of the incoming message (from inbuf1)
-bufsize is the total buffer size
-
-return how many bytes were added to the response
-****************************************************************************/
-int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize)
-{
- int outsize = 0;
- char *ibuf,*obuf;
- static BOOL in_chain = False;
- static char *last_outbuf=NULL;
- BOOL was_inchain = in_chain;
- int insize_remaining;
- static int insize_deleted;
-
-
- chain_size += PTR_DIFF(outbuf2,outbuf) - smb_wct;
- if (was_inchain)
- outbuf = last_outbuf;
- else
- insize_deleted = 0;
-
+ construct a chained reply and add it to the already made reply
+ **************************************************************************/
+int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
+{
+ static char *orig_inbuf;
+ static char *orig_outbuf;
+ int smb_com2 = CVAL(inbuf,smb_vwv0);
+ unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
+ char *inbuf2, *outbuf2;
+ int outsize2;
+ char inbuf_saved[smb_wct];
+ char outbuf_saved[smb_wct];
+ extern int chain_size;
+ int wct = CVAL(outbuf,smb_wct);
+ int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
+
+ /* maybe its not chained */
+ if (smb_com2 == 0xFF) {
+ CVAL(outbuf,smb_vwv0) = 0xFF;
+ return outsize;
+ }
- insize_deleted = 0;
- inbuf2 -= insize_deleted;
- insize_remaining = size - PTR_DIFF(inbuf2,inbuf);
- insize_deleted += size - (insize_remaining + smb_wct);
+ if (chain_size == 0) {
+ /* this is the first part of the chain */
+ orig_inbuf = inbuf;
+ orig_outbuf = outbuf;
+ }
- in_chain = True;
- last_outbuf = outbuf;
+ /* we need to tell the client where the next part of the reply will be */
+ SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
+ CVAL(outbuf,smb_vwv0) = smb_com2;
+ /* remember how much the caller added to the chain, only counting stuff
+ after the parameter words */
+ chain_size += outsize - smb_wct;
- /* allocate some space for the in and out buffers of the chained message */
- ibuf = (char *)malloc(size + SAFETY_MARGIN);
- obuf = (char *)malloc(bufsize + SAFETY_MARGIN);
+ /* work out pointers into the original packets. The
+ headers on these need to be filled in */
+ inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
+ outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
- if (!ibuf || !obuf)
- {
- DEBUG(0,("Out of memory in chain reply\n"));
- return(ERROR(ERRSRV,ERRnoresource));
- }
+ /* save the data which will be overwritten by the new headers */
+ memcpy(inbuf_saved,inbuf2,smb_wct);
+ memcpy(outbuf_saved,outbuf2,smb_wct);
- ibuf += SMB_ALIGNMENT;
- obuf += SMB_ALIGNMENT;
+ /* give the new packet the same header as the first part of the SMB */
+ memcpy(inbuf2,orig_inbuf,smb_wct);
/* create the in buffer */
- memcpy(ibuf,inbuf,smb_wct);
- memcpy(ibuf+smb_wct,inbuf2,insize_remaining);
- CVAL(ibuf,smb_com) = type;
+ CVAL(outbuf2,smb_com) = smb_com2;
/* create the out buffer */
- bzero(obuf,smb_size);
-
- set_message(obuf,0,0,True);
- CVAL(obuf,smb_com) = CVAL(ibuf,smb_com);
+ bzero(outbuf2,smb_size);
+ set_message(outbuf2,0,0,True);
+ CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
- memcpy(obuf+4,ibuf+4,4);
- CVAL(obuf,smb_rcls) = SUCCESS;
- CVAL(obuf,smb_reh) = 0;
- CVAL(obuf,smb_flg) = 0x80 | (CVAL(ibuf,smb_flg) & 0x8); /* bit 7 set
- means a reply */
- SSVAL(obuf,smb_flg2,1); /* say we support long filenames */
- SSVAL(obuf,smb_err,SUCCESS);
- SSVAL(obuf,smb_tid,SVAL(inbuf,smb_tid));
- SSVAL(obuf,smb_pid,SVAL(inbuf,smb_pid));
- SSVAL(obuf,smb_uid,SVAL(inbuf,smb_uid));
- SSVAL(obuf,smb_mid,SVAL(inbuf,smb_mid));
+ memcpy(outbuf2+4,inbuf2+4,4);
+ CVAL(outbuf2,smb_rcls) = SUCCESS;
+ CVAL(outbuf2,smb_reh) = 0;
+ CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
+ means a reply */
+ SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
+ SSVAL(outbuf2,smb_err,SUCCESS);
+ SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
+ SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
+ SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
+ SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
DEBUG(3,("Chained message\n"));
- show_msg(ibuf);
+ show_msg(inbuf2);
/* process the request */
- outsize = switch_message(type,ibuf,obuf,smb_wct+insize_remaining,
- bufsize-chain_size);
+ outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
+ bufsize-chain_size);
/* copy the new reply header over the old one, but preserve
the smb_com field */
- memcpy(outbuf+smb_com+1,obuf+smb_com+1,smb_wct-(smb_com+1));
-
- /* and copy the data from the reply to the right spot */
- memcpy(outbuf2,obuf+smb_wct,outsize - smb_wct);
-
- /* free the allocated buffers */
- if (ibuf) free(ibuf-SMB_ALIGNMENT);
- if (obuf) free(obuf-SMB_ALIGNMENT);
+ smb_com2 = CVAL(orig_outbuf,smb_com);
+ memmove(orig_outbuf,outbuf2,smb_wct);
+ CVAL(orig_outbuf,smb_com) = smb_com2;
- in_chain = was_inchain;
+ /* restore the saved data, being careful not to overwrite any
+ data from the reply header */
+ memcpy(inbuf2,inbuf_saved,smb_wct);
+ {
+ int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
+ if (ofs < 0) ofs = 0;
+ memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
+ }
- /* return how much extra has been added to the packet */
- return(outsize - smb_wct);
+ return(outsize2 + chain_size);
}
@@ -3330,10 +3322,12 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
int type = CVAL(inbuf,smb_com);
int outsize = 0;
int msg_type = CVAL(inbuf,0);
+ extern int chain_size;
smb_last_time = time(NULL);
chain_size = 0;
+ chain_fnum = -1;
bzero(outbuf,smb_size);
diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c
index 292b526df9..d418814a69 100644
--- a/source3/utils/nmblookup.c
+++ b/source3/utils/nmblookup.c
@@ -49,7 +49,7 @@ static BOOL open_sockets(void)
return False;
}
- ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
+ ServerFD = open_socket_in(SOCK_DGRAM, 0,3,interpret_addr(lp_socket_address()));
if (ServerFD == -1)
return(False);