From 0c33046a0aa0461a5e932dd7b0b6e38ab9708867 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 1996 11:17:29 +0000 Subject: - added "netbios name" option in smb.conf to make controlling the name that samba uses possible - added "socket address" option to allow virtual SMB servers (on systems with IP aliasing line Linux) - disabled FAST_SHARE_MODES by default in Linux as older Linux boxes can't do shared writeable mappings. We really need autoconf ... - added new option types in loadparm so a string type can be specified ot be uppercase only, this is used for the workgroup and netbios name options - auto-create the lock directory if it doesn't exist in shared mem startup - get rid of announce_backup() - change a few comments in nmbd code - rewrote the chaining code completely. Hopefully it will handle any depth chains now. - added LPRng support (This used to be commit e9eac6cd49c352349580ddb13d720cb201aecc48) --- source3/client/client.c | 12 ++-- source3/client/clientutil.c | 8 +-- source3/include/includes.h | 1 - source3/include/proto.h | 10 +-- source3/include/smb.h | 2 +- source3/lib/system.c | 2 +- source3/lib/util.c | 23 ++++--- source3/locking/locking.c | 2 + source3/nameannounce.c | 115 ++------------------------------- source3/nameannounce.doc | 2 +- source3/nameelect.c | 2 +- source3/namepacket.c | 37 +++++------ source3/namework.c | 5 +- source3/nmbd/nmbd.c | 18 ++---- source3/param/loadparm.c | 40 ++++++++++-- source3/printing/printing.c | 154 ++++++++++++++++++++++++++++++++++++++++++++ source3/smbd/pipes.c | 17 +---- source3/smbd/reply.c | 125 ++++++----------------------------- source3/smbd/server.c | 154 +++++++++++++++++++++----------------------- source3/utils/nmblookup.c | 2 +- 20 files changed, 351 insertions(+), 380 deletions(-) (limited to 'source3') 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 @@ -136,102 +136,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 **************************************************************************/ @@ -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); } +/* + +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 + + 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; countjob = 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); -- cgit