From 8d3808c63c540597dc8dbacdfe0ee1323a694ab8 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 12 Apr 2000 08:18:12 +0000 Subject: uhh, guys: i spent my entire day updating from yesterday's cvs main commits. i mean, nothing else. i wasn't able to do any debugging of the issues from yesterday. so now, there are two possible sets of bugs, compounded. this commit compiles but hasn't been tested, i haven't had a chance to. i'd really appreciate it if this stopped happening. once is enough. now i am going to get something to eat and if i am lucky, i will be able to hold a fork. this is serious. now i've updated TNG to cvs main, don't make me maintain it, please do it yourselves. thanks. p.s i'm never, ever, working in a branch again. if that's not ok, i won't do the work. it's not worth it. --- source/client/client.c | 7 - source/include/byteorder.h | 4 + source/include/includes.h | 2 + source/include/profile.h | 6 + source/include/proto.h | 42 ++-- source/include/smb.h | 20 -- source/include/smb_macros.h | 5 +- source/lib/access.c | 6 +- source/lib/cmd_interp.c | 8 - source/lib/debug.c | 2 +- source/lib/util.c | 141 +++-------- source/lib/util_file.c | 186 ++++---------- source/lib/util_sec.c | 2 +- source/lib/util_sock.c | 535 +++++++++++++++++++++++++++++----------- source/lib/util_status.c | 2 +- source/libsmb/clientgen.c | 2 +- source/libsmb/namequery.c | 2 +- source/libsmb/passchange.c | 1 - source/locking/locking.c | 6 +- source/msrpc/msrpcd.c | 6 - source/nmbd/nmbd.c | 1 - source/nmbd/nmbd_processlogon.c | 53 ++-- source/smbd/blocking.c | 19 +- source/smbd/close.c | 2 +- source/smbd/connection.c | 12 +- source/smbd/ipc.c | 7 +- source/smbd/nttrans.c | 10 +- source/smbd/open.c | 186 +++++++------- source/smbd/oplock.c | 10 +- source/smbd/password.c | 4 +- source/smbd/process.c | 27 +- source/smbd/quotas.c | 24 ++ source/smbd/reply.c | 133 ++++++---- source/smbd/server.c | 55 +++-- source/smbd/service.c | 9 +- source/smbd/ssl.c | 6 +- source/smbd/trans2.c | 7 +- source/web/cgi.c | 9 +- source/web/swat.c | 4 +- 39 files changed, 841 insertions(+), 722 deletions(-) diff --git a/source/client/client.c b/source/client/client.c index 5f8c428df87..e869c829aab 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -41,7 +41,6 @@ static pstring workgroup; static char *cmdstr; static BOOL got_pass; extern struct in_addr ipzero; -extern pstring scope; static int name_type = 0x20; @@ -1927,7 +1926,6 @@ static void usage(char *pname) DEBUG(0,("\t-O socket_options socket options to use\n")); DEBUG(0,("\t-R name resolve order use these name resolution services only\n")); DEBUG(0,("\t-M host send a winpopup message to the host\n")); - DEBUG(0,("\t-i scope use this NetBIOS scope\n")); DEBUG(0,("\t-N don't ask for a password\n")); DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n")); DEBUG(0,("\t-d debuglevel set the debuglevel\n")); @@ -2220,9 +2218,6 @@ static int do_message_op(void) pstrcpy(desthost,optarg); message = True; break; - case 'i': - pstrcpy(scope,optarg); - break; case 'N': got_pass = True; break; @@ -2350,10 +2345,8 @@ static int do_message_op(void) } if (!process(base_directory)) { - close_sockets(); return(1); } - close_sockets(); return(0); } diff --git a/source/include/byteorder.h b/source/include/byteorder.h index d5dadb44acf..b270627b7f5 100644 --- a/source/include/byteorder.h +++ b/source/include/byteorder.h @@ -274,4 +274,8 @@ it also defines lots of intermediate macros, just ignore those :-) DEBUG(5,("%s%04x %s: %08x\n", \ tab_depth(depth), base, string, outbuf)); } +/* Alignment macros. */ +#define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) +#define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1)) + #endif /* _BYTEORDER_H */ diff --git a/source/include/includes.h b/source/include/includes.h index d50c9aa4133..96e52be5736 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -630,6 +630,8 @@ union semun_hack { #define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0)) #endif +#define SMB_BIG_UINT_BITS (sizeof(SMB_BIG_UINT)*8) + #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif diff --git a/source/include/profile.h b/source/include/profile.h index 353f6a6b429..0924dc29372 100644 --- a/source/include/profile.h +++ b/source/include/profile.h @@ -23,7 +23,13 @@ /* this file defines the profile structure in the profile shared memory area */ +#define PROF_SHMEM_KEY ((key_t)0x07021999) +#define PROF_SHM_MAGIC 0x6349985 +#define PROF_SHM_VERSION 1 + struct profile_struct { + int prof_shm_magic; + int prof_shm_version; unsigned smb_count; /* how many SMB packets we have processed */ unsigned uid_changes; /* how many times we change our effective uid */ }; diff --git a/source/include/proto.h b/source/include/proto.h index 0319900f82f..92aaa9bfe6f 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -548,7 +548,6 @@ BOOL file_exist(char *fname, SMB_STRUCT_STAT * sbuf); int file_rename(char *from, char *to); time_t file_modtime(char *fname); BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st); -SMB_OFF_T file_size(char *file_name); char *attrib_string(uint16 mode); void show_msg(char *buf); void smb_setlen(char *buf, int len); @@ -577,13 +576,12 @@ int interpret_protocol(char *str, int def); uint32 interpret_addr(char *str); struct in_addr *interpret_addr2(char *str); BOOL zero_ip(struct in_addr ip); -BOOL matchname(char *remotehost, struct in_addr addr); void standard_sub_basic(char *str); void standard_sub_vuser(const user_struct * vuser, char *str); void standard_sub(connection_struct * conn, user_struct * vuser, char *str); BOOL same_net(struct in_addr ip1, struct in_addr ip2, struct in_addr mask); struct hostent *Get_Hostbyname(const char *name); -BOOL process_exists(int pid); +BOOL process_exists(pid_t pid); int get_unixgroups(const char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t ** p_groups); BOOL get_unix_grps(int *p_ngroups, struct group **p_groups); @@ -599,8 +597,6 @@ void free_namearray(name_compare_entry * name_array); BOOL is_myname(char *s); void set_remote_arch(enum remote_arch_types type); enum remote_arch_types get_remote_arch(void); -char *align4(char *q, char *base); -char *align2(char *q, char *base); void out_ascii(FILE * f, const uchar * buf, int len); void out_struct(FILE * f, const char *buf1, int len, int per_line); void out_data(FILE * f, const char *buf1, int len, int per_line); @@ -661,10 +657,10 @@ BOOL do_file_lock(int fd, int waitsecs, int type); BOOL file_lock(int fd, int type, int secs, int *plock_depth); BOOL file_unlock(int fd, int *plock_depth); uint32 map_lock_offset(uint32 high, uint32 low); -SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format, - BOOL *err); -SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format, - BOOL *err); +SMB_BIG_UINT get_lock_count(char *data, int data_offset, + BOOL large_file_format); +SMB_BIG_UINT get_lock_offset(char *data, int data_offset, + BOOL large_file_format, BOOL *err); BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); void *startfileent(char *pfile, char *s_readbuf, int bufsize, int *file_lock_depth, BOOL update); @@ -766,32 +762,34 @@ BOOL create_new_sid(DOM_SID *sid); BOOL is_a_socket(int fd); void set_socket_options(int fd, char *options); -void close_sockets(void); -ssize_t write_socket(int fd, char *buf, size_t len); int write_data_outstanding(int fd, unsigned int time_out, BOOL *more); int read_data_outstanding(int fd, unsigned int time_out); ssize_t read_udp_socket(int fd, char *buf, size_t len); +ssize_t read_socket_with_timeout(int fd, char *buf, size_t mincnt, + size_t maxcnt, unsigned int time_out); ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, unsigned int time_out); BOOL send_keepalive(int client); ssize_t read_data(int fd, char *buffer, size_t N); ssize_t write_data(int fd, char *buffer, size_t N); +ssize_t write_socket_data(int fd, char *buffer, size_t N); +ssize_t write_socket(int fd, char *buf, size_t len); ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout); BOOL receive_smb(int fd, char *buffer, unsigned int timeout); BOOL client_receive_smb(int fd, char *buffer, unsigned int timeout); +BOOL send_null_session_msg(int fd); BOOL send_smb(int fd, char *buffer); BOOL send_one_packet(char *buf, int len, struct in_addr ip, int port, int type); int open_socket_in(int type, int port, int dlevel, uint32 socket_addr, BOOL rebind); int open_socket_out(int type, struct in_addr *addr, int port, int timeout); -void set_client_connection_name(const char *name, int fd); -void set_client_connection_addr(const char *addr, int fd); -char *client_connection_name(void); -char *client_connection_addr(void); void reset_globals_after_fork(void); -char *client_name(int fd); -char *client_addr(int fd); +void client_setfd(int fd); +char *client_name(void); +char *client_addr(void); +char *get_socket_name(int fd); +char *get_socket_addr(int fd); int open_pipe_sock(char *path); int create_pipe_socket(char *dir, int dir_perms, char *path, int path_perms); @@ -1263,13 +1261,13 @@ int brl_forall(BRLOCK_FN(fn)); void locking_close_file(files_struct *fsp); BOOL is_locked(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, + SMB_BIG_UINT count,SMB_BIG_UINT offset, enum brl_type lock_type); BOOL do_lock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, int *eclass,uint32 *ecode); BOOL do_unlock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, + SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode); BOOL locking_init(int read_only); BOOL locking_end(void); @@ -5848,7 +5846,7 @@ int reply_nttrans(connection_struct *conn, /*The following definitions come from smbd/open.c */ -void fd_close(files_struct *fsp, int *err_ret); +int fd_close(struct connection_struct *conn, files_struct *fsp); void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action); int open_file_stat(files_struct *fsp,connection_struct *conn, @@ -6018,6 +6016,8 @@ int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf, /*The following definitions come from smbd/server.c */ +int smbd_server_fd(void); +void smbd_set_server_fd(int fd); BOOL reload_services(BOOL test); void exit_server(char *reason); diff --git a/source/include/smb.h b/source/include/smb.h index af7a2e49a40..7d6e2e85c42 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -980,26 +980,6 @@ struct connect_record time_t start; }; -/* This is used by smbclient to send it to a smbfs mount point */ -struct connection_options -{ - int protocol; - /* Connection-Options */ - uint32 max_xmit; - uint16 server_vuid; - uint16 tid; - /* The following are LANMAN 1.0 options */ - uint16 sec_mode; - uint16 max_mux; - uint16 max_vcs; - uint16 rawmode; - uint32 sesskey; - /* The following are NT LM 0.12 options */ - uint32 maxraw; - uint32 capabilities; - uint16 serverzone; -}; - /* key and data in the connections database - used in smbstatus and smbd */ struct connections_key { diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index c65812ebdf6..88838b4b913 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -80,7 +80,10 @@ #define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn) #define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \ - return(ERROR(ERRDOS,ERRbadfid)) + return(ERROR(ERRDOS,ERRbadfid)); \ + else if((fsp)->fd == -1) \ + return(ERROR(ERRDOS,ERRbadaccess)) + #define CHECK_READ(fsp) if (!(fsp)->can_read) \ return(ERROR(ERRDOS,ERRbadaccess)) #define CHECK_WRITE(fsp) if (!(fsp)->can_write) \ diff --git a/source/lib/access.c b/source/lib/access.c index 01f559750fa..d646c0823be 100644 --- a/source/lib/access.c +++ b/source/lib/access.c @@ -253,13 +253,13 @@ BOOL check_access(int sock, char *allow_list, char *deny_list) if (!ret) { if (allow_access(deny_list,allow_list, - client_name(sock),client_addr(sock))) { + get_socket_name(sock),get_socket_addr(sock))) { DEBUG(2,("Allowed connection from %s (%s)\n", - client_name(sock),client_addr(sock))); + get_socket_name(sock),get_socket_addr(sock))); ret = True; } else { DEBUG(0,("Denied connection from %s (%s)\n", - client_name(sock),client_addr(sock))); + get_socket_name(sock),get_socket_addr(sock))); } } diff --git a/source/lib/cmd_interp.c b/source/lib/cmd_interp.c index 5c431d63b96..56d1cab8312 100644 --- a/source/lib/cmd_interp.c +++ b/source/lib/cmd_interp.c @@ -32,7 +32,6 @@ #endif extern pstring debugf; -extern pstring scope; extern pstring global_myname; extern pstring user_socket_options; @@ -1168,13 +1167,6 @@ static void cmd_set(struct client_info *info, int argc, char *argv[]) break; } - case 'i': - { - cmd_set_options |= CMD_SCOPE; - pstrcpy(scope, optarg); - break; - } - case 'U': { char *lp; diff --git a/source/lib/debug.c b/source/lib/debug.c index c90b28fcd79..e47d947d961 100644 --- a/source/lib/debug.c +++ b/source/lib/debug.c @@ -276,7 +276,7 @@ static void check_log_size( void ) (void)fclose( dbf ); dbf = NULL; reopen_logs(); - if( dbf && file_size( debugf ) > maxlog ) + if( dbf && get_file_size( debugf ) > maxlog ) { pstring name; diff --git a/source/lib/util.c b/source/lib/util.c index 613eee18a59..5c2152b9b4a 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -24,12 +24,34 @@ #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) #ifdef WITH_NISPLUS_HOME -#include -#else -#include "rpcsvc/ypclnt.h" +#ifdef BROKEN_NISPLUS_INCLUDE_FILES +/* + * The following lines are needed due to buggy include files + * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and + * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA. + * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as + * an enum in /usr/include/rpcsvc/nis.h. + */ + +#if defined(GROUP) +#undef GROUP #endif + +#if defined(GROUP_OBJ) +#undef GROUP_OBJ #endif +#endif /* BROKEN_NISPLUS_INCLUDE_FILES */ + +#include + +#else /* !WITH_NISPLUS_HOME */ + +#include "rpcsvc/ypclnt.h" + +#endif /* WITH_NISPLUS_HOME */ +#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */ + #ifdef WITH_SSL #include #undef Realloc /* SSLeay defines this and samba has a function of this name */ @@ -37,8 +59,6 @@ extern SSL *ssl; extern int sslFd; #endif /* WITH_SSL */ -pstring scope = ""; - extern int DEBUGLEVEL; int Protocol = PROTOCOL_COREPLUS; @@ -46,9 +66,6 @@ int Protocol = PROTOCOL_COREPLUS; /* a default finfo structure to ensure all fields are sensible */ file_info def_finfo = { -1, 0, 0, 0, 0, 0, 0, "" }; -/* the client file descriptor */ -extern int Client; - /* this is used by the chaining code */ int chain_size = 0; @@ -72,7 +89,7 @@ fstring local_machine = ""; fstring remote_arch = "UNKNOWN"; static enum remote_arch_types ra_type = RA_UNKNOWN; fstring remote_proto = "UNKNOWN"; -pstring user_socket_options = ""; +pstring user_socket_options = DEFAULT_SOCKET_OPTIONS; pstring sesssetup_user = ""; @@ -287,18 +304,6 @@ BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st) return ret; } -/******************************************************************* -returns the size in bytes of the named file -********************************************************************/ -SMB_OFF_T file_size(char *file_name) -{ - SMB_STRUCT_STAT buf; - buf.st_size = 0; - if (sys_stat(file_name, &buf) != 0) - return (SMB_OFF_T) - 1; - return (buf.st_size); -} - /******************************************************************* return a string representing an attribute for a file ********************************************************************/ @@ -388,7 +393,7 @@ void smb_setlen(char *buf, int len) int set_message(char *buf, int num_words, int num_bytes, BOOL zero) { if (zero) - memset(buf + smb_size, 0, num_words * 2 + num_bytes); + memset(buf + smb_size, '\0', num_words * 2 + num_bytes); CVAL(buf, smb_wct) = num_words; SSVAL(buf, smb_vwv + num_words * SIZEOFWORD, num_bytes); smb_setlen(buf, smb_size + num_words * 2 + num_bytes - 4); @@ -1595,6 +1600,9 @@ BOOL yesno(char *p) set the length of a file from a filedescriptor. Returns 0 on success, -1 on failure. ****************************************************************************/ + +/* tpot vfs need to recode this function */ + int set_filelen(int fd, SMB_OFF_T len) { /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot @@ -1653,8 +1661,7 @@ this is a version of setbuffer() for those machines that only have setvbuf /**************************************************************************** - copies or initialises to zeros. checks NULL pointers, basically. - returns True on an actual memcpy. +parse out a filename from a path name. Assumes dos style filenames. ****************************************************************************/ BOOL Memcpy(void *to, const void *from, size_t size) { @@ -1848,56 +1855,6 @@ BOOL zero_ip(struct in_addr ip) } -/******************************************************************* - matchname - determine if host name matches IP address - ******************************************************************/ -BOOL matchname(char *remotehost, struct in_addr addr) -{ - struct hostent *hp; - int i; - - if ((hp = Get_Hostbyname(remotehost)) == 0) - { - DEBUG(0, ("Get_Hostbyname(%s): lookup failure", remotehost)); - return False; - } - - /* - * Make sure that gethostbyname() returns the "correct" host name. - * Unfortunately, gethostbyname("localhost") sometimes yields - * "localhost.domain". Since the latter host name comes from the - * local DNS, we just have to trust it (all bets are off if the local - * DNS is perverted). We always check the address list, though. - */ - - if (strcasecmp(remotehost, hp->h_name) - && strcasecmp(remotehost, "localhost")) - { - DEBUG(0, ("host name/name mismatch: %s != %s", - remotehost, hp->h_name)); - return False; - } - - /* Look up the host address in the address list we just got. */ - for (i = 0; hp->h_addr_list[i]; i++) - { - if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) - == 0) - return True; - } - - /* - * The host name does not map to the original host address. Perhaps - * someone has compromised a name server. More likely someone botched - * it, but that could be dangerous, too. - */ - - DEBUG(0, ("host name/address mismatch: %s != %s", - inet_ntoa(addr), hp->h_name)); - return False; -} - - #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) /****************************************************************** Remove any mount options such as -rsize=2048,wsize=2048 etc. @@ -2140,15 +2097,13 @@ void standard_sub_basic(char *str) switch (*(p + 1)) { case 'I': - pstring_sub(p, "%I", - client_connection_addr()); + pstring_sub(p, "%I", client_addr()); break; case 'L': pstring_sub(p, "%L", local_machine); break; case 'M': - pstring_sub(p, "%M", - client_connection_name()); + pstring_sub(p, "%M", client_name()); break; case 'R': pstring_sub(p, "%R", remote_proto); @@ -2421,7 +2376,7 @@ struct hostent *Get_Hostbyname(const char *name) check if a process exists. Does this work on all unixes? ****************************************************************************/ -BOOL process_exists(int pid) +BOOL process_exists(pid_t pid) { return (kill(pid, 0) == 0 || errno != ESRCH); } @@ -2882,6 +2837,9 @@ void set_remote_arch(enum remote_arch_types type) case RA_WINNT: fstrcpy(remote_arch, "WinNT"); return; + case RA_WIN2K: + fstrcpy(remote_arch, "Win2K"); + return; case RA_SAMBA: fstrcpy(remote_arch, "Samba"); return; @@ -2901,31 +2859,6 @@ enum remote_arch_types get_remote_arch(void) } -/******************************************************************* - align a pointer to a multiple of 4 bytes. - ********************************************************************/ -char *align4(char *q, char *base) -{ - int mod = PTR_DIFF(q, base) & 3; - if (mod != 0) - { - q += 4 - mod; - } - return q; -} - -/******************************************************************* -align a pointer to a multiple of 2 bytes -********************************************************************/ -char *align2(char *q, char *base) -{ - if (PTR_DIFF(q, base) & 1) - { - q++; - } - return q; -} - void out_ascii(FILE * f, const uchar * buf, int len) { int i; diff --git a/source/lib/util_file.c b/source/lib/util_file.c index ae0f7bde5d9..e27f5801db0 100644 --- a/source/lib/util_file.c +++ b/source/lib/util_file.c @@ -142,37 +142,35 @@ uint32 map_lock_offset(uint32 high, uint32 low) /**************************************************************************** Get a lock count, dealing with large count requests. ****************************************************************************/ - -SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format, - BOOL *err) +SMB_BIG_UINT get_lock_count(char *data, int data_offset, + BOOL large_file_format) { - SMB_OFF_T count = 0; - - *err = False; + SMB_BIG_UINT count = 0; if (!large_file_format) { - count = (SMB_OFF_T) IVAL(data, SMB_LKLEN_OFFSET(data_offset)); + count = + (SMB_BIG_UINT) IVAL(data, + SMB_LKLEN_OFFSET(data_offset)); } else { -#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS) - +#if defined(HAVE_LONGLONG) count = - (((SMB_OFF_T) + (((SMB_BIG_UINT) IVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << - 32) | ((SMB_OFF_T) IVAL(data, - SMB_LARGE_LKLEN_OFFSET_LOW - (data_offset))); - -#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */ + 32) | ((SMB_BIG_UINT) + IVAL(data, + SMB_LARGE_LKLEN_OFFSET_LOW + (data_offset))); +#else /* HAVE_LONGLONG */ /* - * NT4.x seems to be broken in that it sends large file + * NT4.x seems to be broken in that it sends large file (64 bit) * lockingX calls even if the CAP_LARGE_FILES was *not* - * negotiated. For boxes without large file locks truncate the + * negotiated. For boxes without large unsigned ints truncate the * lock count by dropping the top 32 bits. */ @@ -190,57 +188,13 @@ SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format, 0); } - if (IVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) - { - /* - * Before we error out, see if we can sensibly map the top bits - * down to the lower bits - or lose the top bits if they are all 1's. - * It seems that NT has this horrible bug where it will send 64 bit - * lock requests even if told not to. JRA. - */ - - if (IVAL - (data, - SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) == - (uint32)0xFFFFFFFF) - count = - (SMB_OFF_T) IVAL(data, - SMB_LARGE_LKLEN_OFFSET_HIGH - (data_offset)); - else - if (IVAL - (data, - SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) - == (uint32)0xFFFFFFFF) - count = - (SMB_OFF_T) IVAL(data, - SMB_LARGE_LKLEN_OFFSET_LOW - (data_offset)); - else - { - - DEBUG(0, - ("get_lock_count: Error : a large file count (%x << 32 | %x) was sent and we don't \ -support large counts.\n", - (unsigned int)IVAL(data, - SMB_LARGE_LKLEN_OFFSET_HIGH - (data_offset)), - (unsigned int)IVAL(data, - SMB_LARGE_LKLEN_OFFSET_LOW - (data_offset)))); - - *err = True; - return (SMB_OFF_T) - 1; - } - } - else - count = - (SMB_OFF_T) IVAL(data, - SMB_LARGE_LKLEN_OFFSET_LOW - (data_offset)); - -#endif /* LARGE_SMB_OFF_T */ + count = + (SMB_BIG_UINT) IVAL(data, + SMB_LARGE_LKLEN_OFFSET_LOW + (data_offset)); +#endif /* HAVE_LONGLONG */ } + return count; } @@ -248,54 +202,55 @@ support large counts.\n", Get a lock offset, dealing with large offset requests. ****************************************************************************/ -SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format, - BOOL *err) +SMB_BIG_UINT get_lock_offset(char *data, int data_offset, + BOOL large_file_format, BOOL *err) { - SMB_OFF_T offset = 0; + SMB_BIG_UINT offset = 0; *err = False; if (!large_file_format) { offset = - (SMB_OFF_T) IVAL(data, SMB_LKOFF_OFFSET(data_offset)); + (SMB_BIG_UINT) IVAL(data, + SMB_LKOFF_OFFSET(data_offset)); } else { -#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS) - +#if defined(HAVE_LONGLONG) offset = - (((SMB_OFF_T) + (((SMB_BIG_UINT) IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << - 32) | ((SMB_OFF_T) IVAL(data, - SMB_LARGE_LKOFF_OFFSET_LOW - (data_offset))); - -#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */ + 32) | ((SMB_BIG_UINT) + IVAL(data, + SMB_LARGE_LKOFF_OFFSET_LOW + (data_offset))); +#else /* HAVE_LONGLONG */ /* - * NT4.x seems to be broken in that it sends large file + * NT4.x seems to be broken in that it sends large file (64 bit) * lockingX calls even if the CAP_LARGE_FILES was *not* - * negotiated. For boxes without large file locks mangle the + * negotiated. For boxes without large unsigned ints mangle the * lock offset by mapping the top 32 bits onto the lower 32. */ if (IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) { - uint32 low = IVAL(data, - SMB_LARGE_LKOFF_OFFSET_LOW - (data_offset)); - uint32 high = IVAL(data, - SMB_LARGE_LKOFF_OFFSET_HIGH - (data_offset)); + uint32 low = + IVAL(data, + SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); + uint32 high = + IVAL(data, + SMB_LARGE_LKOFF_OFFSET_HIGH + (data_offset)); uint32 new_low = 0; if ((new_low = map_lock_offset(high, low)) == 0) { *err = True; - return (SMB_OFF_T) - 1; + return (SMB_BIG_UINT) - 1; } DEBUG(3, @@ -308,57 +263,13 @@ SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format, new_low); } - if (IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) - { - /* - * Before we error out, see if we can sensibly map the top bits - * down to the lower bits - or lose the top bits if they are all 1's. - * It seems that NT has this horrible bug where it will send 64 bit - * lock requests even if told not to. JRA. - */ - - if (IVAL - (data, - SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) == - (uint32)0xFFFFFFFF) - offset = - (SMB_OFF_T) IVAL(data, - SMB_LARGE_LKOFF_OFFSET_HIGH - (data_offset)); - else - if (IVAL - (data, - SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) - == (uint32)0xFFFFFFFF) - offset = - (SMB_OFF_T) IVAL(data, - SMB_LARGE_LKOFF_OFFSET_LOW - (data_offset)); - else - { - - DEBUG(0, - ("get_lock_count: Error : a large file offset (%x << 32 | %x) was sent and we don't \ -support large offsets.\n", - (unsigned int)IVAL(data, - SMB_LARGE_LKOFF_OFFSET_HIGH - (data_offset)), - (unsigned int)IVAL(data, - SMB_LARGE_LKOFF_OFFSET_LOW - (data_offset)))); - - *err = True; - return (SMB_OFF_T) - 1; - } - } - else - offset = - (SMB_OFF_T) IVAL(data, - SMB_LARGE_LKOFF_OFFSET_LOW - (data_offset)); - + offset = + (SMB_BIG_UINT) IVAL(data, + SMB_LARGE_LKOFF_OFFSET_LOW + (data_offset)); #endif /* LARGE_SMB_OFF_T */ } + return offset; } @@ -805,7 +716,6 @@ SMB_OFF_T get_file_size(char *file_name) return (buf.st_size); } - /*************************************************************** Internal fn to enumerate the smbpasswd list. Returns a void pointer to ensure no modification outside this module. Checks for atomic diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c index f88d3259853..4306a94191d 100644 --- a/source/lib/util_sec.c +++ b/source/lib/util_sec.c @@ -306,7 +306,6 @@ void become_user_permanently(uid_t uid, gid_t gid) } -#ifdef AUTOCONF_TEST /**************************************************************************** this function just checks that we don't get ENOSYS back ****************************************************************************/ @@ -335,6 +334,7 @@ static int have_syscall(void) return 0; } +#ifdef AUTOCONF_TEST main() { if (getuid() != 0) { diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index f751cea7ec8..b9f6dbc6648 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -32,9 +32,6 @@ extern int DEBUGLEVEL; BOOL passive = False; -/* the client file descriptor */ -int Client = -1; - /* the port, where client connected */ int ClientPort = 0; @@ -49,7 +46,7 @@ int smb_read_error = 0; /**************************************************************************** -determine if a file descriptor is in fact a socket + Determine if a file descriptor is in fact a socket. ****************************************************************************/ BOOL is_a_socket(int fd) { @@ -69,7 +66,8 @@ struct int option; int value; int opttype; -} socket_options[] = +} +socket_options[] = { { "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL} @@ -96,6 +94,11 @@ struct OPT_ON} , #endif +#ifdef SO_REUSEPORT + { + "SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL} + , +#endif #ifdef SO_SNDBUF { "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT} @@ -133,7 +136,7 @@ struct /**************************************************************************** -set user socket options + Set user socket options. ****************************************************************************/ void set_socket_options(int fd, char *options) { @@ -193,47 +196,18 @@ void set_socket_options(int fd, char *options) } if (ret != 0) - DEBUG(0, ("Failed to set socket option %s\n", tok)); + DEBUG(0, + ("Failed to set socket option %s (Error %s)\n", + tok, strerror(errno))); } } /**************************************************************************** - close the socket communication + Read from a socket. ****************************************************************************/ -void close_sockets(void) -{ -#ifdef WITH_SSL - sslutil_disconnect(Client); -#endif /* WITH_SSL */ - close(Client); - Client = -1; -} - - - -/**************************************************************************** -write to a socket -****************************************************************************/ -ssize_t write_socket(int fd, char *buf, size_t len) -{ - ssize_t ret = 0; - - if (passive) - return (len); - DEBUG(6, ("write_socket(%d,%d)\n", fd, len)); - ret = write_data(fd, buf, len); - - DEBUG(6, ("write_socket(%d,%d) wrote %d\n", fd, len, ret)); - if (ret <= 0) - DEBUG(0, - ("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", - len, fd, strerror(errno))); - - return (ret); -} /******************************************************************* checks if write data is outstanding. @@ -315,7 +289,98 @@ ssize_t read_udp_socket(int fd, char *buf, size_t len) } /**************************************************************************** -read data from a device with a timout in msec. + Read data from a socket with a timout in msec. +mincount = if timeout, minimum to read before returning +maxcount = number to be read. +time_out = timeout in milliseconds +****************************************************************************/ + +ssize_t read_socket_with_timeout(int fd, char *buf, size_t mincnt, + size_t maxcnt, unsigned int time_out) +{ + ssize_t readret; + size_t nread = 0; + + /* just checking .... */ + if (maxcnt <= 0) + return (0); + + /* Blocking read */ + if (time_out <= 0) + { + if (mincnt == 0) + mincnt = maxcnt; + + while (nread < mincnt) + { +#ifdef WITH_SSL + if (fd == sslFd) + { + readret = + SSL_read(ssl, buf + nread, + maxcnt - nread); + } + else + { + readret = + read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + + if (readret <= 0) + { + return readret; + } + + nread += readret; + } + return ((ssize_t) nread); + } + + /* Most difficult - timeout read */ + /* If this is ever called on a disk file and + mincnt is greater then the filesize then + system performance will suffer severely as + select always returns true on disk files */ + + for (nread = 0; nread < mincnt;) + { + int selrtn = read_data_outstanding(fd, time_out); + + /* Check if error */ + if (selrtn <= 0) + { + return selrtn; + } + +#ifdef WITH_SSL + if (fd == sslFd) + { + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + } + else + { + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + + if (readret <= 0) + { + return readret; + } + nread += readret; + } + + /* Return the number we got */ + return ((ssize_t) nread); +} + +/**************************************************************************** + Read data from a socket with a timout in msec. mincount = if timeout, minimum to read before returning maxcount = number to be read. time_out = timeout in milliseconds @@ -387,6 +452,9 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, if (selrtn == -1) { /* something is wrong. Maybe the socket is dead? */ + DEBUG(0, + ("read_socket_with_timeout: timeout read. select error = %s.\n", + strerror(errno))); smb_read_error = READ_ERROR; return -1; } @@ -394,6 +462,8 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, /* Did we timeout ? */ if (selrtn == 0) { + DEBUG(10, + ("read_socket_with_timeout: timeout read. select timed out.\n")); smb_read_error = READ_TIMEOUT; return -1; } @@ -414,6 +484,8 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, if (readret == 0) { /* we got EOF on the file descriptor */ + DEBUG(5, + ("read_socket_with_timeout: timeout read. EOF from client.\n")); smb_read_error = READ_EOF; return -1; } @@ -421,6 +493,9 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, if (readret == -1) { /* the descriptor is probably dead */ + DEBUG(0, + ("read_socket_with_timeout: timeout read. read error = %s.\n", + strerror(errno))); smb_read_error = READ_ERROR; return -1; } @@ -432,7 +507,6 @@ ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt, return ((ssize_t) nread); } - /**************************************************************************** send a keepalive packet (rfc1002) ****************************************************************************/ @@ -443,7 +517,7 @@ BOOL send_keepalive(int client) buf[0] = 0x85; buf[1] = buf[2] = buf[3] = 0; - return (write_data(client, (char *)buf, 4) == 4); + return (write_socket_data(client, (char *)buf, 4) == 4); } @@ -475,11 +549,17 @@ ssize_t read_data(int fd, char *buffer, size_t N) if (ret == 0) { + DEBUG(10, + ("read_data: read of %d returned 0. Error = %s\n", + (int)(N - total), strerror(errno))); smb_read_error = READ_EOF; return 0; } if (ret == -1) { + DEBUG(0, + ("read_data: read failure for %d. Error = %s\n", + (int)(N - total), strerror(errno))); smb_read_error = READ_ERROR; return -1; } @@ -488,9 +568,55 @@ ssize_t read_data(int fd, char *buffer, size_t N) return (ssize_t) total; } +/**************************************************************************** + Read data from a socket, reading exactly N bytes. +****************************************************************************/ + +static ssize_t read_socket_data(int fd, char *buffer, size_t N) +{ + ssize_t ret; + size_t total = 0; + + smb_read_error = 0; + + while (total < N) + { +#ifdef WITH_SSL + if (fd == sslFd) + { + ret = SSL_read(ssl, buffer + total, N - total); + } + else + { + ret = read(fd, buffer + total, N - total); + } +#else /* WITH_SSL */ + ret = read(fd, buffer + total, N - total); +#endif /* WITH_SSL */ + + if (ret == 0) + { + DEBUG(10, + ("read_socket_data: recv of %d returned 0. Error = %s\n", + (int)(N - total), strerror(errno))); + smb_read_error = READ_EOF; + return 0; + } + if (ret == -1) + { + DEBUG(0, + ("read_socket_data: recv failure for %d. Error = %s\n", + (int)(N - total), strerror(errno))); + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t) total; +} /**************************************************************************** - write data to a fd + Write data to a fd. ****************************************************************************/ ssize_t write_data(int fd, char *buffer, size_t N) { @@ -513,7 +639,51 @@ ssize_t write_data(int fd, char *buffer, size_t N) #endif /* WITH_SSL */ if (ret == -1) + { + DEBUG(0, + ("write_data: write failure. Error = %s\n", + strerror(errno))); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t) total; +} + +/**************************************************************************** + Write data to a socket - use send rather than write. +****************************************************************************/ + +ssize_t write_socket_data(int fd, char *buffer, size_t N) +{ + size_t total = 0; + ssize_t ret; + + while (total < N) + { +#ifdef WITH_SSL + if (fd == sslFd) + { + ret = SSL_write(ssl, buffer + total, N - total); + } + else + { + ret = send(fd, buffer + total, N - total, 0); + } +#else /* WITH_SSL */ + ret = send(fd, buffer + total, N - total, 0); +#endif /* WITH_SSL */ + + if (ret == -1) + { + DEBUG(0, + ("write_socket_data: write failure. Error = %s\n", + strerror(errno))); return -1; + } if (ret == 0) return total; @@ -522,6 +692,26 @@ ssize_t write_data(int fd, char *buffer, size_t N) return (ssize_t) total; } +/**************************************************************************** +write to a socket +****************************************************************************/ +ssize_t write_socket(int fd, char *buf, size_t len) +{ + ssize_t ret = 0; + + if (passive) + return (len); + DEBUG(6, ("write_socket(%d,%d)\n", fd, (int)len)); + ret = write_socket_data(fd, buf, len); + + DEBUG(6, ("write_socket(%d,%d) wrote %d\n", fd, (int)len, (int)ret)); + if (ret <= 0) + DEBUG(0, + ("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + (int)len, fd, strerror(errno))); + + return (ret); +} /**************************************************************************** @@ -542,10 +732,10 @@ static ssize_t read_smb_length_return_keepalive(int fd, char *inbuf, { if (timeout > 0) ok = - (read_with_timeout(fd, inbuf, 4, 4, timeout) - == 4); + (read_socket_with_timeout + (fd, inbuf, 4, 4, timeout) == 4); else - ok = (read_data(fd, inbuf, 4) == 4); + ok = (read_socket_data(fd, inbuf, 4) == 4); if (!ok) return (-1); @@ -584,6 +774,8 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) break; } + DEBUG(10, ("read_smb_length: got smb length of %d\n", len)); + return len; } @@ -626,7 +818,7 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) if (len > 0) { - ret = read_data(fd, buffer + 4, len); + ret = read_socket_data(fd, buffer + 4, len); if (ret != len) { smb_read_error = READ_ERROR; @@ -650,7 +842,6 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) BOOL client_receive_smb(int fd, char *buffer, unsigned int timeout) { BOOL ret; - uint8 msg_type; for (;;) { @@ -664,22 +855,42 @@ BOOL client_receive_smb(int fd, char *buffer, unsigned int timeout) } /* Ignore session keepalive packets. */ - msg_type = CVAL(buffer, 0); - if (msg_type != 0x85) + if (CVAL(buffer, 0) != 0x85) break; } - if (msg_type == 0) - { - show_msg(buffer); - } - else - { - dump_data(10, buffer, smb_len(buffer) + 4); - } show_msg(buffer); return ret; } +/**************************************************************************** + send an null session message to a fd +****************************************************************************/ + +BOOL send_null_session_msg(int fd) +{ + ssize_t ret; + uint32 blank = 0; + size_t len = 4; + size_t nwritten = 0; + char *buffer = (char *)␣ + + while (nwritten < len) + { + ret = write_socket(fd, buffer + nwritten, len - nwritten); + if (ret <= 0) + { + DEBUG(0, + ("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n", + (int)len, (int)ret)); + exit(1); + } + nwritten += ret; + } + + DEBUG(10, ("send_null_session_msg: sent 4 null bytes to client.\n")); + return True; +} + /**************************************************************************** send an smb to a fd ****************************************************************************/ @@ -697,8 +908,7 @@ BOOL send_smb(int fd, char *buffer) { DEBUG(0, ("Error writing %d bytes to client. %d. Exiting\n", - len, ret)); - close_sockets(); + (int)len, (int)ret)); exit(1); } nwritten += ret; @@ -804,8 +1014,20 @@ int open_socket_in(int type, int port, int dlevel, uint32 socket_addr, val = 1; else val = 0; - setsockopt(res, SOL_SOCKET, SO_REUSEADDR, (char *)&val, - sizeof(val)); + if (setsockopt + (res, SOL_SOCKET, SO_REUSEADDR, (char *)&val, + sizeof(val)) == -1) + DEBUG(dlevel, + ("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n", + val, port, strerror(errno))); +#ifdef SO_REUSEPORT + if (setsockopt + (res, SOL_SOCKET, SO_REUSEPORT, (char *)&val, + sizeof(val)) == -1) + DEBUG(dlevel, + ("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n", + val, port, strerror(errno))); +#endif /* SO_REUSEPORT */ } /* now we've got a socket - we need to bind it */ @@ -838,14 +1060,14 @@ int open_socket_in(int type, int port, int dlevel, uint32 socket_addr, /**************************************************************************** - create an outgoing socket + create an outgoing socket. timeout is in milliseconds. **************************************************************************/ int open_socket_out(int type, struct in_addr *addr, int port, int timeout) { struct sockaddr_in sock_out; int res, ret; int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout * 1000) / connect_loop; + int loops = (timeout) / connect_loop; /* create a socket to write to */ res = socket(PF_INET, type, 0); @@ -920,148 +1142,167 @@ int open_socket_out(int type, struct in_addr *addr, int port, int timeout) expanded if more variables need reseting. ******************************************************************/ -static BOOL global_client_name_done = False; -static BOOL global_client_addr_done = False; -static pstring client_name_buf; -static fstring client_addr_buf; -static int last_fd = -1; -void set_client_connection_name(const char *name, int fd) +void reset_globals_after_fork(void) { - global_client_name_done = True; - pstrcpy(client_name_buf, name); - last_fd = fd; + /* + * Re-seed the random crypto generator, so all smbd's + * started from the same parent won't generate the same + * sequence. + */ + { + unsigned char dummy; + generate_random_buffer(&dummy, 1, True); + } } -void set_client_connection_addr(const char *addr, int fd) +/* the following 3 client_*() functions are nasty ways of allowing + some generic functions to get info that really should be hidden in + particular modules */ +static int client_fd = -1; + +void client_setfd(int fd) { - global_client_addr_done = True; - pstrcpy(client_addr_buf, addr); - last_fd = fd; + client_fd = fd; } -char *client_connection_name(void) +char *client_name(void) { - if (global_client_name_done) - { - return client_name_buf; - } - return client_name(Client); + return get_socket_name(client_fd); } -char *client_connection_addr(void) +char *client_addr(void) { - if (global_client_addr_done) - { - return client_addr_buf; - } - return client_addr(Client); + return get_socket_addr(client_fd); } -void reset_globals_after_fork(void) +/******************************************************************* + matchname - determine if host name matches IP address. Used to + confirm a hostname lookup to prevent spoof attacks + ******************************************************************/ +static BOOL matchname(char *remotehost, struct in_addr addr) { - global_client_name_done = False; - global_client_addr_done = False; + struct hostent *hp; + int i; + + if ((hp = Get_Hostbyname(remotehost)) == 0) + { + DEBUG(0, + ("Get_Hostbyname(%s): lookup failure.\n", remotehost)); + return False; + } /* - * Re-seed the random crypto generator, so all smbd's - * started from the same parent won't generate the same - * sequence. + * Make sure that gethostbyname() returns the "correct" host name. + * Unfortunately, gethostbyname("localhost") sometimes yields + * "localhost.domain". Since the latter host name comes from the + * local DNS, we just have to trust it (all bets are off if the local + * DNS is perverted). We always check the address list, though. */ + + if (strcasecmp(remotehost, hp->h_name) + && strcasecmp(remotehost, "localhost")) { - unsigned char dummy; - generate_random_buffer(&dummy, 1, True); + DEBUG(0, ("host name/name mismatch: %s != %s\n", + remotehost, hp->h_name)); + return False; + } + + /* Look up the host address in the address list we just got. */ + for (i = 0; hp->h_addr_list[i]; i++) + { + if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) + == 0) + return True; } + + /* + * The host name does not map to the original host address. Perhaps + * someone has compromised a name server. More likely someone botched + * it, but that could be dangerous, too. + */ + + DEBUG(0, ("host name/address mismatch: %s != %s\n", + inet_ntoa(addr), hp->h_name)); + return False; } /******************************************************************* - return the DNS name of the client + return the DNS name of the remote end of a socket ******************************************************************/ -char *client_name(int fd) +char *get_socket_name(int fd) { - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *)(&sa); - int length = sizeof(sa); + static pstring name_buf; + static fstring addr_buf; struct hostent *hp; + struct in_addr addr; + char *p; - if (global_client_name_done && last_fd == fd) - return client_name_buf; + p = get_socket_addr(fd); - last_fd = fd; - global_client_name_done = False; - - pstrcpy(client_name_buf, "UNKNOWN"); + /* it might be the same as the last one - save some DNS work */ + if (strcmp(p, addr_buf) == 0) + return name_buf; + pstrcpy(name_buf, "UNKNOWN"); if (fd == -1) - { - return client_name_buf; - } + return name_buf; - if (getpeername(fd, &sa, &length) < 0) - { - DEBUG(0, - ("getpeername failed. Error was %s\n", - strerror(errno))); - return client_name_buf; - } + fstrcpy(addr_buf, p); + + if (inet_aton(p, &addr) == 0) + return name_buf; /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *)&sockin->sin_addr, - sizeof(sockin->sin_addr), AF_INET)) == 0) + if ( + (hp = + gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), + AF_INET)) == 0) { - DEBUG(1, ("Gethostbyaddr failed for %s\n", client_addr(fd))); - StrnCpy(client_name_buf, client_addr(fd), - sizeof(client_name_buf) - 1); + DEBUG(1, ("Gethostbyaddr failed for %s\n", p)); + pstrcpy(name_buf, p); } else { - StrnCpy(client_name_buf, (char *)hp->h_name, - sizeof(client_name_buf) - 1); - if (!matchname(client_name_buf, sockin->sin_addr)) + pstrcpy(name_buf, (char *)hp->h_name); + if (!matchname(name_buf, addr)) { DEBUG(0, - ("Matchname failed on %s %s\n", client_name_buf, - client_addr(fd))); - pstrcpy(client_name_buf, "UNKNOWN"); + ("Matchname failed on %s %s\n", name_buf, p)); + pstrcpy(name_buf, "UNKNOWN"); } } - global_client_name_done = True; - return client_name_buf; + return name_buf; } /******************************************************************* - return the IP addr of the client as a string + return the IP addr of the remote end of a socket as a string ******************************************************************/ -char *client_addr(int fd) +char *get_socket_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *)(&sa); int length = sizeof(sa); + static fstring addr_buf; - if (global_client_addr_done && fd == last_fd) - return client_addr_buf; - - last_fd = fd; - global_client_addr_done = False; - - fstrcpy(client_addr_buf, "0.0.0.0"); + fstrcpy(addr_buf, "0.0.0.0"); if (fd == -1) { - return client_addr_buf; + return addr_buf; } if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0, ("getpeername failed. Error was %s\n", - strerror(errno))); - return client_addr_buf; + DEBUG(0, + ("getpeername failed. Error was %s\n", + strerror(errno))); + return addr_buf; } - fstrcpy(client_addr_buf, (char *)inet_ntoa(sockin->sin_addr)); + fstrcpy(addr_buf, (char *)inet_ntoa(sockin->sin_addr)); - global_client_addr_done = True; - return client_addr_buf; + return addr_buf; } /******************************************************************* diff --git a/source/lib/util_status.c b/source/lib/util_status.c index 836388a1bd5..c9f427348ce 100644 --- a/source/lib/util_status.c +++ b/source/lib/util_status.c @@ -57,7 +57,7 @@ BOOL get_connection_status(struct connect_record **crec, (*crec) = NULL; - num_recs = file_size(fname) / sizeof(*c); + num_recs = get_file_size(fname) / sizeof(*c); DEBUG(5,("Opened status file %s, record count %d\n",fname, num_recs)); diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 164e8fbc4dd..cc5fac099d1 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -52,7 +52,7 @@ static char *cli_put_string(struct cli_state *cli, char *p, const char *str, uint16 flgs2 = SVAL(cli->outbuf, smb_flg2); if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) { - p = align2(p, cli->outbuf); + p = ALIGN2(p, cli->outbuf); p = ascii_to_unibuf(p, str, 1024); if (skip_end) { diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c index 39e02e3259a..56ca5707af7 100644 --- a/source/libsmb/namequery.c +++ b/source/libsmb/namequery.c @@ -810,7 +810,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd slprintf(bufp, sizeof(fstring), "\\MAILSLOT\\NET\\GETDC%d", dgm_id); mailslot_name = bufp; bufp += (strlen(bufp) + 1); - bufp = align2(bufp, buffer); + bufp = ALIGN2(bufp, buffer); bufp = ascii_to_unibuf(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1); SIVAL(bufp,0,1); SSVAL(bufp,4,0xFFFF); diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c index 0fc480e73f8..6ec4901c65a 100644 --- a/source/libsmb/passchange.c +++ b/source/libsmb/passchange.c @@ -23,7 +23,6 @@ extern pstring global_myname; -extern pstring scope; /************************************************************* change a password on a remote machine using IPC calls diff --git a/source/locking/locking.c b/source/locking/locking.c index 45d414daf1e..1bb0a3b59c9 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -57,7 +57,7 @@ void locking_close_file(files_struct *fsp) Utility function called to see if a file region is locked. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, + SMB_BIG_UINT count,SMB_BIG_UINT offset, enum brl_type lock_type) { int snum = SNUM(conn); @@ -78,7 +78,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ BOOL do_lock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; @@ -115,7 +115,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, Utility function called by unlocking requests. ****************************************************************************/ BOOL do_unlock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, + SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode) { BOOL ok = False; diff --git a/source/msrpc/msrpcd.c b/source/msrpc/msrpcd.c index 50f2d3a388c..b17d1d3f0c7 100644 --- a/source/msrpc/msrpcd.c +++ b/source/msrpc/msrpcd.c @@ -34,7 +34,6 @@ int last_message = -1; /* a useful macro to debug the last message processed */ #define LAST_MESSAGE() smb_fn_name(last_message) -extern pstring scope; extern int DEBUGLEVEL; extern fstring remote_machine; @@ -339,7 +338,6 @@ static void usage(char *pname) printf("\t-P passive only\n"); printf("\t-a append to log file (default)\n"); printf("\t-o overwrite log file, don't append\n"); - printf("\t-i scope NetBIOS scope to use (default none)\n"); printf("\n"); } @@ -403,10 +401,6 @@ static void usage(char *pname) while ( EOF != (opt = getopt(argc, argv, "i:l:s:d:Dh?Paof:")) ) switch (opt) { - case 'i': - pstrcpy(scope,optarg); - break; - case 'P': { extern BOOL passive; diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index 57d025c6604..c7ebe48822a 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -859,7 +859,6 @@ static void usage(char *pname) #endif /* SIGUSR2 */ process(); - close_sockets(); if (dbf) fclose(dbf); diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c index 66bcf39e245..d29673cedf1 100644 --- a/source/nmbd/nmbd_processlogon.c +++ b/source/nmbd/nmbd_processlogon.c @@ -70,8 +70,6 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); code = SVAL(buf,0); DEBUG(1,("process_logon_packet: Logon from %s: code = %x\n", inet_ntoa(p->ip), code)); - dump_data(4, buf, len); - switch (code) { case 0: @@ -118,24 +116,21 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); char *machine = q; getdc = skip_string(machine,1); - unicomp = skip_string(getdc,1); - - q = align2(unicomp, buf); - - /* skip unicode string -- cannot go beyond end of input buffer */ - q = skip_unibuf(q, buf + len - q); + q = skip_string(getdc,1); + q = ALIGN2(q, buf); /* at this point we can work out if this is a W9X or NT style request. Experiments show that the difference is wether the packet ends here. For a W9X request we now end with a pair of bytes (usually 0xFE 0xFF) whereas with NT we have two further strings - the following is a simple way of detecting this */ - if (PTR_DIFF(q, buf) >= len) - { + if (len - PTR_DIFF(q, buf) <= 3) { short_request = True; } else { + unicomp = q; /* A full length (NT style) request */ + q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp)); if (len - PTR_DIFF(q, buf) > 8) { /* with NT5 clients we can sometimes @@ -166,18 +161,14 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); /* PDC and domain name */ if (!short_request) /* Make a full reply */ { - q = align2(q, buf); + q = ALIGN2(q, buf); q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */ q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True); /* Domain name*/ - ntversion = 0x1; - lmnttoken = 0xffff; - lm20token = 0xffff; - - SIVAL(q, 0, ntversion); - SSVAL(q, 4, lmnttoken); - SSVAL(q, 6, lm20token); + SIVAL(q, 0, 1); /* our nt version */ + SSVAL(q, 4, 0xffff); /* our lmnttoken */ + SSVAL(q, 6, 0xffff); /* our lm20token */ q += 8; } @@ -207,8 +198,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", q += 2; unicomp = q; - uniuser = skip_unicode_string(unicomp,1); - getdc = skip_unicode_string(uniuser,1); + uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp)); + getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser)); q = skip_string(getdc,1); q += 4; /* Account Control Bits - indicating username type */ domainsidsize = IVAL(q, 0); @@ -217,7 +208,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", if (domainsidsize != 0) { q += domainsidsize; - q = align4(q, buf); + q = ALIGN4(q, buf); } if (len - PTR_DIFF(q, buf) > 8) { @@ -235,8 +226,9 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", ntversion = IVAL(q, 0); lmnttoken = SVAL(q, 4); lm20token = SVAL(q, 6); + q += 8; - DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %x\n", domainsidsize, ntversion)); + DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion)); /* * we respond regadless of whether the machine is in our password @@ -244,10 +236,6 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", * Let's ignore the SID. */ - ntversion = 0x1; - lmnttoken = 0xffff; - lm20token = 0xffff; - unibuf_to_ascii(ascuser, uniuser, sizeof(ascuser)-1); DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser)); @@ -271,15 +259,14 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", q += dos_PutUniCode(q, reply_name,sizeof(pstring), True); unistrcpy(q, uniuser); - q = skip_unicode_string(q, 1); /* User name (workstation trust account) */ + q = skip_unibuf(q, PTR_DIFF(buf+len, q)); /* User name (workstation trust account) */ q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True); - SIVAL(q, 0, ntversion); - q += 4; - SSVAL(q, 0, lmnttoken); - q += 2; - SSVAL(q, 0, lm20token); - q += 2; + /* tell the client what version we are */ + SIVAL(q, 0, 1); /* our ntversion */ + SSVAL(q, 4, 0xffff); /* our lmnttoken */ + SSVAL(q, 6, 0xffff); /* our lm20token */ + q += 8; dump_data(4, outbuf, PTR_DIFF(q, outbuf)); diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c index deb9bae9d1c..255e6453485 100644 --- a/source/smbd/blocking.c +++ b/source/smbd/blocking.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Blocking Locking functions - Copyright (C) Jeremy Allison 1998-2000 + Copyright (C) Jeremy Allison 1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,7 +23,6 @@ #include "nterr.h" extern int DEBUGLEVEL; -extern int Client; extern char *OutBuffer; /**************************************************************************** @@ -136,7 +135,7 @@ static void send_blocking_reply(char *outbuf, int outsize) if(outsize > 4) smb_setlen(outbuf,outsize - 4); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); } /**************************************************************************** @@ -182,7 +181,7 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); ERROR(eclass,ecode); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); } /**************************************************************************** @@ -196,7 +195,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - SMB_OFF_T count = (SMB_OFF_T) 0, offset = (SMB_OFF_T) 0; + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -220,7 +219,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec uint32 dummy2; BOOL err; - count = get_lock_count( data, i, large_file_format, &err); + count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); /* @@ -281,7 +280,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, numtoread, startpos, READ_LOCK, &eclass, &ecode)) { + if(!do_lock( fsp, conn, (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -344,7 +343,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) { + if (!do_lock(fsp, conn, (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* @@ -392,7 +391,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_OFF_T count = 0, offset = 0; + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int eclass=0; @@ -408,7 +407,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { BOOL err; - count = get_lock_count( data, blr->lock_num, large_file_format, &err); + count = get_lock_count( data, blr->lock_num, large_file_format); offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); /* diff --git a/source/smbd/close.c b/source/smbd/close.c index c14641e9c92..74396352b0d 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -113,7 +113,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) if (lp_share_modes(SNUM(conn))) unlock_share_entry_fsp(fsp); - fd_close(fsp, &err); + err = fd_close(conn, fsp); /* NT uses smbclose to start a print - weird */ if (normal_close && fsp->print_file) diff --git a/source/smbd/connection.c b/source/smbd/connection.c index 8b613d8f8ae..9c859e4d896 100644 --- a/source/smbd/connection.c +++ b/source/smbd/connection.c @@ -105,7 +105,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO crec.start = time(NULL); StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1); - StrnCpy(crec.addr,conn?conn->client_address:client_connection_addr(),sizeof(crec.addr)-1); + StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1); dbuf.dptr = (char *)&crec; dbuf.dsize = sizeof(crec); @@ -329,7 +329,7 @@ static void utmp_yield(pid_t pid, const connection_struct *conn) } DEBUG(2,("utmp_yield: conn: user:%s cnum:%d\n", - conn->user, conn->cnum)); + conn->user, conn->cnum)); memset((char *)&u, '\0', sizeof(struct utmp)); u.ut_type = DEAD_PROCESS; @@ -340,7 +340,7 @@ static void utmp_yield(pid_t pid, const connection_struct *conn) } } -static void utmp_claim(const struct connections_data *crec, const connection_struct *conn) +static void utmp_claim(const struct connect_record *crec, const connection_struct *conn) { struct utmp u; @@ -354,10 +354,10 @@ static void utmp_claim(const struct connections_data *crec, const connection_str return; } - DEBUG(2,("utmp_claim: conn: user:%s cnum:%d\n", - conn->user, conn->cnum)); + DEBUG(2,("utmp_claim: conn: user:%s cnum:%d i:%d\n", + conn->user, conn->cnum, i)); DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s\n", - crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_connection_name())); + crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_name())); memset((char *)&u, '\0', sizeof(struct utmp)); diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 578775e73a0..9a9fe4cb2c5 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -37,7 +37,6 @@ extern fstring local_machine; #define NERR_notsupported 50 -extern int Client; extern int smb_read_error; extern uint32 global_client_caps; @@ -146,7 +145,7 @@ void send_trans_reply(char *outbuf, } show_msg(outbuf); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); tot_data = this_ldata; tot_param = this_lparam; @@ -179,7 +178,7 @@ void send_trans_reply(char *outbuf, SSVAL(outbuf, smb_vwv9, 0); show_msg(outbuf); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); tot_data += this_ldata; tot_param += this_lparam; @@ -473,7 +472,7 @@ int reply_trans(connection_struct * conn, char *inbuf, char *outbuf, int size, of the parameter/data bytes */ outsize = set_message(outbuf, 0, 0, True); show_msg(outbuf); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); } /* receive the rest of the trans packet */ diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 5f4c194b79f..1122ae33b6b 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -25,7 +25,6 @@ extern int DEBUGLEVEL; extern int Protocol; -extern int Client; extern int smb_read_error; extern int global_oplock_break; extern BOOL case_sensitive; @@ -89,7 +88,7 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err */ if(params_to_send == 0 && data_to_send == 0) { - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); return 0; } @@ -218,7 +217,7 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err params_to_send, data_to_send, paramsize, datasize)); /* Send the packet */ - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); pp += params_sent_thistime; pd += data_sent_thistime; @@ -1425,7 +1424,6 @@ static ubi_slList change_notify_queue = { NULL, (ubi_slNodePtr)&change_notify_qu static void change_notify_reply_packet(char *inbuf, int error_class, uint32 error_code) { - extern int Client; char outbuf[smb_size+38]; memset(outbuf, '\0', sizeof(outbuf)); @@ -1450,7 +1448,7 @@ static void change_notify_reply_packet(char *inbuf, int error_class, uint32 erro */ set_message(outbuf,18,0,False); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); } /**************************************************************************** @@ -2680,7 +2678,7 @@ due to being in oplock break state.\n" )); /* We need to send an interim response then receive the rest of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) { BOOL ret; diff --git a/source/smbd/open.c b/source/smbd/open.c index f4c0733b20d..cc02abe4f6a 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -28,35 +28,41 @@ extern uint16 global_oplock_port; extern BOOL global_client_failed_oplock_break; /**************************************************************************** -fd support routines - attempt to do a dos_open + fd support routines - attempt to do a dos_open. ****************************************************************************/ + static int fd_open(struct connection_struct *conn, char *fname, - int flags, mode_t mode) + int flags, mode_t mode) { - int fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode); + int fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode); - /* Fix for files ending in '.' */ - if((fd == -1) && (errno == ENOENT) && + /* Fix for files ending in '.' */ + if((fd == -1) && (errno == ENOENT) && (strchr(fname,'.')==NULL)) { - pstrcat(fname,"."); - fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode); - } + pstrcat(fname,"."); + fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode); + } + + DEBUG(10,("fd_open: name %s, mode = %d, fd = %d. %s\n", fname, (int)mode, fd, + (fd == -1) ? strerror(errno) : "" )); - return fd; + return fd; } /**************************************************************************** -close the file associated with a fsp + Close the file associated with a fsp. ****************************************************************************/ -void fd_close(files_struct *fsp, int *err_ret) + +int fd_close(struct connection_struct *conn, files_struct *fsp) { - fsp->conn->vfs_ops.close(fsp->fd); + int ret = conn->vfs_ops.close(fsp->fd); fsp->fd = -1; - } + return ret; +} /**************************************************************************** -check a filename for the pipe string + Check a filename for the pipe string. ****************************************************************************/ static void check_for_pipe(char *fname) @@ -73,99 +79,111 @@ static void check_for_pipe(char *fname) } /**************************************************************************** -open a file + Open a file. ****************************************************************************/ static void open_file(files_struct *fsp,connection_struct *conn, char *fname1,int flags,mode_t mode) { - extern struct current_user current_user; - pstring fname; - int accmode = (flags & O_ACCMODE); + extern struct current_user current_user; + pstring fname; + int accmode = (flags & O_ACCMODE); SMB_STRUCT_STAT sbuf; - fsp->open = False; + fsp->open = False; fsp->fd = 0; - fsp->oplock_type = NO_OPLOCK; - errno = EPERM; + fsp->oplock_type = NO_OPLOCK; + errno = EPERM; - pstrcpy(fname,fname1); + pstrcpy(fname,fname1); - /* check permissions */ + /* Check permissions */ - /* - * This code was changed after seeing a client open request - * containing the open mode of (DENY_WRITE/read-only) with - * the 'create if not exist' bit set. The previous code - * would fail to open the file read only on a read-only share - * as it was checking the flags parameter directly against O_RDONLY, - * this was failing as the flags parameter was set to O_RDONLY|O_CREAT. - * JRA. - */ + /* + * This code was changed after seeing a client open request + * containing the open mode of (DENY_WRITE/read-only) with + * the 'create if not exist' bit set. The previous code + * would fail to open the file read only on a read-only share + * as it was checking the flags parameter directly against O_RDONLY, + * this was failing as the flags parameter was set to O_RDONLY|O_CREAT. + * JRA. + */ if (!CAN_WRITE(conn)) { - /* It's a read-only share - fail if we wanted to write. */ - if(accmode != O_RDONLY) { - DEBUG(3,("Permission denied opening %s\n",fname)); - check_for_pipe(fname); - return; - } else if(flags & O_CREAT) { - /* We don't want to write - but we must make sure that O_CREAT - doesn't create the file if we have write access into the - directory. - */ - flags &= ~O_CREAT; - } - } + /* It's a read-only share - fail if we wanted to write. */ + if(accmode != O_RDONLY) { + DEBUG(3,("Permission denied opening %s\n",fname)); + check_for_pipe(fname); + return; + } else if(flags & O_CREAT) { + /* We don't want to write - but we must make sure that O_CREAT + doesn't create the file if we have write access into the + directory. + */ + flags &= ~O_CREAT; + } + } /* actually do the open */ fsp->fd = fd_open(conn, fname, flags, mode); - - if (fsp->fd == -1) { - DEBUG(3,("Error opening file %s (%s) (flags=%d)\n", - fname,strerror(errno),flags)); - check_for_pipe(fname); - return; - } + + if (fsp->fd == -1) { + DEBUG(3,("Error opening file %s (%s) (flags=%d)\n", + fname,strerror(errno),flags)); + check_for_pipe(fname); + return; + } conn->vfs_ops.fstat(fsp->fd, &sbuf); - conn->num_files_open++; + /* + * POSIX allows read-only opens of directories. We don't + * want to do this (we use a different code path for this) + * so catch a directory open and return an EISDIR. JRA. + */ + + if(S_ISDIR(sbuf.st_mode)) { + fd_close(conn, fsp); + errno = EISDIR; + return; + } + + conn->num_files_open++; fsp->mode = sbuf.st_mode; fsp->inode = sbuf.st_ino; fsp->dev = sbuf.st_dev; - GetTimeOfDay(&fsp->open_time); - fsp->vuid = current_user.key.vuid; - fsp->size = 0; - fsp->pos = -1; - fsp->open = True; - fsp->can_lock = True; - fsp->can_read = ((flags & O_WRONLY)==0); - fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); - fsp->share_mode = 0; + GetTimeOfDay(&fsp->open_time); + fsp->vuid = current_user.key.vuid; + fsp->size = 0; + fsp->pos = -1; + fsp->open = True; + fsp->can_lock = True; + fsp->can_read = ((flags & O_WRONLY)==0); + fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); + fsp->share_mode = 0; fsp->print_file = False; - fsp->modified = False; - fsp->oplock_type = NO_OPLOCK; - fsp->sent_oplock_break = NO_BREAK_SENT; - fsp->is_directory = False; - fsp->stat_open = False; - fsp->directory_delete_on_close = False; - fsp->conn = conn; - /* - * Note that the file name here is the *untranslated* name - * ie. it is still in the DOS codepage sent from the client. - * All use of this filename will pass though the sys_xxxx - * functions which will do the dos_to_unix translation before - * mapping into a UNIX filename. JRA. - */ - string_set(&fsp->fsp_name,fname); - fsp->wbmpx_ptr = NULL; - fsp->wcp = NULL; /* Write cache pointer. */ + fsp->modified = False; + fsp->oplock_type = NO_OPLOCK; + fsp->sent_oplock_break = NO_BREAK_SENT; + fsp->is_directory = False; + fsp->stat_open = False; + fsp->directory_delete_on_close = False; + fsp->conn = conn; + /* + * Note that the file name here is the *untranslated* name + * ie. it is still in the DOS codepage sent from the client. + * All use of this filename will pass though the sys_xxxx + * functions which will do the dos_to_unix translation before + * mapping into a UNIX filename. JRA. + */ + string_set(&fsp->fsp_name,fname); + fsp->wbmpx_ptr = NULL; + fsp->wcp = NULL; /* Write cache pointer. */ - DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", - *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name, - BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), - conn->num_files_open)); + DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", + *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name, + BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), + conn->num_files_open)); } /**************************************************************************** @@ -598,7 +616,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode); if (!fsp->open && flags==O_RDWR && errno != ENOENT && fcbopen) { - flags = O_RDONLY; + flags = O_RDONLY; open_file(fsp,conn,fname,flags,mode); } diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c index c310cf9874d..532b856e067 100644 --- a/source/smbd/oplock.c +++ b/source/smbd/oplock.c @@ -753,7 +753,6 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, st BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token) { - extern int Client; extern uint32 global_client_caps; char outbuf[128]; BOOL got_lock = False; @@ -781,7 +780,7 @@ BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token) /* Prepare the SMBlockingX message. */ prepare_break_message( outbuf, fsp, False); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); } /* @@ -832,7 +831,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B { extern uint32 global_client_caps; extern struct current_user current_user; - extern int Client; char *inbuf = NULL; char *outbuf = NULL; files_struct *fsp = NULL; @@ -923,7 +921,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT; - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); /* We need this in case a readraw crosses on the wire. */ global_oplock_break = True; @@ -958,7 +956,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B while((fsp = initial_break_processing(dev, inode, tval)) && OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { - if(receive_smb(Client,inbuf, timeout) == False) + if(receive_smb(smbd_server_fd(),inbuf, timeout) == False) { /* * Die if we got an error. @@ -1019,7 +1017,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B { DEBUG( 0, ( "oplock_break: unable to re-become user!" ) ); DEBUGADD( 0, ( "Shutting down server\n" ) ); - close_sockets(); close(oplock_sock); exit_server("unable to re-become user"); } @@ -1059,7 +1056,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B { DEBUG( 0, ( "oplock_break: client failure in break - " ) ); DEBUGADD( 0, ( "shutting down this smbd.\n" ) ); - close_sockets(); close(oplock_sock); exit_server("oplock break failure"); } diff --git a/source/smbd/password.c b/source/smbd/password.c index 06d2fcf8ee0..539e2fae76e 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -551,7 +551,7 @@ BOOL check_hosts_equiv(char *user) /* note: don't allow hosts.equiv on root */ if (fname && *fname && (pass->pw_uid != 0)) { - if (check_user_equiv(user, client_connection_name(), fname)) + if (check_user_equiv(user, client_name(), fname)) return (True); } @@ -563,7 +563,7 @@ BOOL check_hosts_equiv(char *user) slprintf(rhostsfile, sizeof(rhostsfile) - 1, "%s/.rhosts", home); if (check_user_equiv - (user, client_connection_name(), rhostsfile)) + (user, client_name(), rhostsfile)) return (True); } } diff --git a/source/smbd/process.c b/source/smbd/process.c index 476ddf9a7bd..ae872975f09 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -133,7 +133,6 @@ The timeout is in milli seconds static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout, BOOL *got_smb) { - extern int Client; fd_set fds; int selrtn; struct timeval to; @@ -167,13 +166,13 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, */ FD_ZERO(&fds); - FD_SET(Client,&fds); + FD_SET(smbd_server_fd(),&fds); maxfd = setup_oplock_select_set(&fds); to.tv_sec = timeout / 1000; to.tv_usec = (timeout % 1000) * 1000; - selrtn = sys_select(MAX(maxfd,Client)+1,&fds,NULL, timeout>0?&to:NULL); + selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL, timeout>0?&to:NULL); /* Check if error */ if(selrtn == -1) { @@ -188,10 +187,10 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, return False; } - if (FD_ISSET(Client,&fds)) + if (FD_ISSET(smbd_server_fd(),&fds)) { *got_smb = True; - return receive_smb(Client, buffer, 0); + return receive_smb(smbd_server_fd(), buffer, 0); } else { @@ -419,7 +418,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize static int num_smb_messages = sizeof(smb_messages) / sizeof(struct smb_message_struct); int match; - extern int Client; extern int global_smbpid; if (pid == (pid_t)-1) @@ -541,7 +539,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize /* does this protocol need to be run as guest? */ if ((flags & AS_GUEST) && (!become_guest() || - !check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1)))) { + !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) { return(ERROR(ERRSRV,ERRaccess)); } @@ -595,7 +593,6 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) ****************************************************************************/ void process_smb(char *inbuf, char *outbuf) { - extern int Client; #ifdef WITH_SSL extern BOOL sslEnabled; /* don't use function for performance reasons */ static int sslConnected = 0; @@ -614,13 +611,13 @@ void process_smb(char *inbuf, char *outbuf) deny parameters before doing any parsing of the packet passed to us by the client. This prevents attacks on our parsing code from hosts not in the hosts allow list */ - if (!check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1))) { + if (!check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) { /* send a negative session response "not listining on calling name" */ static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; DEBUG( 1, ( "Connection denied from %s\n", - client_addr(Client) ) ); - send_smb(Client,(char *)buf); + client_addr() ) ); + send_smb(smbd_server_fd(),(char *)buf); exit_server("connection denied"); } } @@ -630,7 +627,7 @@ void process_smb(char *inbuf, char *outbuf) #ifdef WITH_SSL if(sslEnabled && !sslConnected){ - sslConnected = sslutil_negotiate_ssl(Client, msg_type); + sslConnected = sslutil_negotiate_ssl(smbd_server_fd(), msg_type); if(sslConnected < 0){ /* an error occured */ exit_server("SSL negotiation failed"); }else if(sslConnected){ @@ -666,7 +663,7 @@ void process_smb(char *inbuf, char *outbuf) nread, smb_len(outbuf))); } else - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); } trans_num++; } @@ -857,7 +854,6 @@ void check_reload(int t) static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time) { - extern int Client; static time_t last_keepalive_sent_time = 0; static time_t last_idle_closed_check = 0; time_t t; @@ -902,11 +898,10 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t if (keepalive && (t - last_keepalive_sent_time)>keepalive) { - if (!send_keepalive(Client)) { + if (!send_keepalive(smbd_server_fd())) { DEBUG( 2, ( "Keepalive failed - exiting.\n" ) ); return False; } - DEBUG(0,("TODO: send keepalive to all smbd client-side SMB connections\n")); last_keepalive_sent_time = t; } diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index 329f261f273..1e81443c5ef 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -363,6 +363,11 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U #endif } + /* If softlimit is zero, set it equal to hardlimit. + */ + + if (D.dqb_bsoftlimit==0) + D.dqb_bsoftlimit = D.dqb_bhardlimit; /* Use softlimit to determine disk space. A user exceeding the quota is told * that there's no space left. Writes might actually work for a bit if the @@ -432,6 +437,12 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U return (False); } + /* If softlimit is zero, set it equal to hardlimit. + */ + + if (D.dqb_bsoftlimit==0) + D.dqb_bsoftlimit = D.dqb_bhardlimit; + /* Use softlimit to determine disk space, except when it has been exceeded */ if (D.dqb_bsoftlimit==0) @@ -662,6 +673,13 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U } else return(False); } + + /* If softlimit is zero, set it equal to hardlimit. + */ + + if (D.dqb_bsoftlimit==0) + D.dqb_bsoftlimit = D.dqb_bhardlimit; + if (D.dqb_bsoftlimit==0) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ @@ -773,6 +791,12 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B return(False); } + /* If softlimit is zero, set it equal to hardlimit. + */ + + if (D.dqb_bsoftlimit==0) + D.dqb_bsoftlimit = D.dqb_bhardlimit; + /* Use softlimit to determine disk space. A user exceeding the quota is told * that there's no space left. Writes might actually work for a bit if the * hardlimit is set higher than softlimit. Effectively the disk becomes diff --git a/source/smbd/reply.c b/source/smbd/reply.c index de6842f682e..12411d981ce 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -41,7 +41,6 @@ extern BOOL short_case_preserve; extern pstring sesssetup_user; extern pstring global_myname; extern fstring global_myworkgroup; -extern int Client; extern int global_oplock_break; uint32 global_client_caps = 0; unsigned int smb_echo_count = 0; @@ -49,6 +48,7 @@ unsigned int smb_echo_count = 0; /**************************************************************************** report a possible attack via the password buffer overflow bug ****************************************************************************/ + static void overflow_attack(int len) { if (DEBUGLVL(0)) @@ -56,8 +56,7 @@ static void overflow_attack(int len) dbgtext("ERROR: Invalid password length %d.\n", len); dbgtext("Your machine may be under attack by someone "); dbgtext("attempting to exploit an old bug.\n"); - dbgtext("Attack was from IP = %s.\n", - client_connection_addr()); + dbgtext("Attack was from IP = %s.\n", client_addr()); } exit_server("possible attack"); } @@ -66,6 +65,7 @@ static void overflow_attack(int len) /**************************************************************************** reply to an special message ****************************************************************************/ + int reply_special(char *inbuf, char *outbuf) { int outsize = 4; @@ -209,12 +209,10 @@ static void parse_connect(char *p, char *service, char *user, } } - - - /**************************************************************************** Reply to a tcon. ****************************************************************************/ + int reply_tcon(connection_struct * conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) { @@ -1923,7 +1921,7 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf, continue; if (!conn->vfs_ops. unlink(dos_to_unix(fname, False))) - count++; + count++; DEBUG(3, ("reply_unlink : doing unlink on %s\n", fname)); @@ -1956,6 +1954,7 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf, /**************************************************************************** reply to a readbraw (core+ protocol) ****************************************************************************/ + int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) { @@ -1975,7 +1974,8 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, if (global_oplock_break) { _smb_setlen(header, 0); - transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0); + transfer_file(0, smbd_server_fd(), (SMB_OFF_T) 0, header, 4, + 0); DEBUG(5, ("readbraw - oplock break finished\n")); return -1; } @@ -1991,7 +1991,8 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, ("fnum %d not open in readbraw - cache prime?\n", (int)SVAL(inbuf, smb_vwv0))); _smb_setlen(header, 0); - transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0); + transfer_file(0, smbd_server_fd(), (SMB_OFF_T) 0, header, 4, + 0); return (-1); } @@ -2022,7 +2023,8 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, 64 bit offsets.\n", (unsigned int)IVAL(inbuf, smb_vwv8))); _smb_setlen(header, 0); - transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0); + transfer_file(0, smbd_server_fd(), (SMB_OFF_T) 0, + header, 4, 0); return (-1); } @@ -2034,7 +2036,8 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, ("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos)); _smb_setlen(header, 0); - transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0); + transfer_file(0, smbd_server_fd(), (SMB_OFF_T) 0, + header, 4, 0); return (-1); } } @@ -2045,7 +2048,9 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, maxcount = MIN(65535, maxcount); maxcount = MAX(mincount, maxcount); - if (!is_locked(fsp, conn, maxcount, startpos, READ_LOCK)) + if (!is_locked + (fsp, conn, (SMB_BIG_UINT) maxcount, (SMB_BIG_UINT) startpos, + READ_LOCK)) { SMB_OFF_T size = fsp->size; SMB_OFF_T sizeneeded = startpos + maxcount; @@ -2117,7 +2122,7 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf, ret = 0; _smb_setlen(header, ret); - transfer_file(0, Client, 0, header, 4 + ret, 0); + transfer_file(0, smbd_server_fd(), 0, header, 4 + ret, 0); #endif /* UNSAFE_READRAW */ DEBUG(5, ("readbraw finished\n")); @@ -2159,7 +2164,8 @@ int reply_lockread(connection_struct * conn, char *inbuf, char *outbuf, */ if (!do_lock - (fsp, conn, numtoread, startpos, WRITE_LOCK, &eclass, &ecode)) + (fsp, conn, (SMB_BIG_UINT) numtoread, (SMB_BIG_UINT) startpos, + WRITE_LOCK, &eclass, &ecode)) { if ((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) { @@ -2216,7 +2222,9 @@ int reply_read(connection_struct * conn, char *inbuf, char *outbuf, int size, numtoread = MIN(BUFFER_SIZE - outsize, numtoread); data = smb_buf(outbuf) + 3; - if (is_locked(fsp, conn, numtoread, startpos, READ_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) numtoread, (SMB_BIG_UINT) startpos, + READ_LOCK)) return (ERROR(ERRDOS, ERRlock)); if (numtoread > 0) @@ -2284,11 +2292,14 @@ int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf, (unsigned int)IVAL(inbuf, smb_vwv10))); return (ERROR(ERRDOS, ERRbadaccess)); } + #endif /* LARGE_SMB_OFF_T */ } - if (is_locked(fsp, conn, smb_maxcnt, startpos, READ_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) smb_maxcnt, (SMB_BIG_UINT) startpos, + READ_LOCK)) return (ERROR(ERRDOS, ERRlock)); nread = read_file(fsp, data, startpos, smb_maxcnt); @@ -2308,6 +2319,7 @@ int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf, /**************************************************************************** reply to a writebraw (core+ or LANMAN1.0 protocol) ****************************************************************************/ + int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { @@ -2346,7 +2358,9 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf, CVAL(inbuf, smb_com) = SMBwritec; CVAL(outbuf, smb_com) = SMBwritec; - if (is_locked(fsp, conn, tcount, startpos, WRITE_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) tcount, (SMB_BIG_UINT) startpos, + WRITE_LOCK)) return (ERROR(ERRDOS, ERRlock)); if (numtowrite > 0) @@ -2368,10 +2382,11 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf, outsize = set_message(outbuf, Protocol > PROTOCOL_COREPLUS ? 1 : 0, 0, True); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); /* Now read the raw data into the buffer and write it */ - if (read_smb_length(Client, inbuf, SMB_SECONDARY_WAIT) == -1) + if (read_smb_length(smbd_server_fd(), inbuf, SMB_SECONDARY_WAIT) == + -1) { exit_server("secondary writebraw failed"); } @@ -2386,7 +2401,7 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf, (int)tcount, (int)nwritten, (int)numtowrite)); } - nwritten = vfs_transfer_file(Client, NULL, -1, fsp, + nwritten = vfs_transfer_file(smbd_server_fd(), NULL, -1, fsp, (SMB_OFF_T) numtowrite, NULL, 0, startpos + nwritten); total_written += nwritten; @@ -2421,6 +2436,7 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf, /**************************************************************************** reply to a writeunlock (core+) ****************************************************************************/ + int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { @@ -2441,7 +2457,9 @@ int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf, startpos = IVAL(inbuf, smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) numtowrite, (SMB_BIG_UINT) startpos, + WRITE_LOCK)) return (ERROR(ERRDOS, ERRlock)); /* The special X/Open SMB protocol handling of @@ -2458,7 +2476,9 @@ int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf, if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0)) return (UNIXERROR(ERRDOS, ERRnoaccess)); - if (!do_unlock(fsp, conn, numtowrite, startpos, &eclass, &ecode)) + if (!do_unlock + (fsp, conn, (SMB_BIG_UINT) numtowrite, (SMB_BIG_UINT) startpos, + &eclass, &ecode)) return (ERROR(eclass, ecode)); outsize = set_message(outbuf, 1, 0, True); @@ -2496,7 +2516,9 @@ int reply_write(connection_struct * conn, char *inbuf, char *outbuf, int size, startpos = IVAL(inbuf, smb_vwv2); data = smb_buf(inbuf) + 3; - if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) numtowrite, (SMB_BIG_UINT) startpos, + WRITE_LOCK)) return (ERROR(ERRDOS, ERRlock)); /* X/Open SMB protocol says that if smb_vwv1 is @@ -2579,10 +2601,13 @@ int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf, (unsigned int)IVAL(inbuf, smb_vwv12))); return (ERROR(ERRDOS, ERRbadaccess)); } + #endif /* LARGE_SMB_OFF_T */ } - if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) numtowrite, (SMB_BIG_UINT) startpos, + WRITE_LOCK)) return (ERROR(ERRDOS, ERRlock)); /* X/Open SMB protocol says that, unlike SMBwrite @@ -2849,6 +2874,7 @@ int reply_close(connection_struct * conn, char *inbuf, char *outbuf, int size, /**************************************************************************** reply to a writeclose (Core+ protocol) ****************************************************************************/ + int reply_writeclose(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { @@ -2870,7 +2896,9 @@ int reply_writeclose(connection_struct * conn, mtime = make_unix_date3(inbuf + smb_vwv4); data = smb_buf(inbuf) + 1; - if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) numtowrite, (SMB_BIG_UINT) startpos, + WRITE_LOCK)) return (ERROR(ERRDOS, ERRlock)); nwritten = write_file(fsp, data, startpos, numtowrite); @@ -2906,7 +2934,7 @@ int reply_lock(connection_struct * conn, char *inbuf, char *outbuf, int length, int dum_buffsize) { int outsize = set_message(outbuf, 0, 0, True); - SMB_OFF_T count, offset; + SMB_BIG_UINT count, offset; int eclass; uint32 ecode; files_struct *fsp = file_fsp(inbuf, smb_vwv0); @@ -2914,8 +2942,8 @@ int reply_lock(connection_struct * conn, CHECK_FSP(fsp, conn); CHECK_ERROR(fsp); - count = IVAL(inbuf, smb_vwv1); - offset = IVAL(inbuf, smb_vwv3); + count = (SMB_BIG_UINT) IVAL(inbuf, smb_vwv1); + offset = (SMB_BIG_UINT) IVAL(inbuf, smb_vwv3); DEBUG(3, ("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fd, fsp->fnum, (double)offset, (double)count)); @@ -2946,7 +2974,7 @@ int reply_unlock(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { int outsize = set_message(outbuf, 0, 0, True); - SMB_OFF_T count, offset; + SMB_BIG_UINT count, offset; int eclass; uint32 ecode; files_struct *fsp = file_fsp(inbuf, smb_vwv0); @@ -2954,8 +2982,8 @@ int reply_unlock(connection_struct * conn, char *inbuf, char *outbuf, CHECK_FSP(fsp, conn); CHECK_ERROR(fsp); - count = IVAL(inbuf, smb_vwv1); - offset = IVAL(inbuf, smb_vwv3); + count = (SMB_BIG_UINT) IVAL(inbuf, smb_vwv1); + offset = (SMB_BIG_UINT) IVAL(inbuf, smb_vwv3); if (!do_unlock(fsp, conn, count, offset, &eclass, &ecode)) return (ERROR(eclass, ecode)); @@ -3021,7 +3049,7 @@ int reply_echo(connection_struct * conn, smb_setlen(outbuf, outsize - 4); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); } DEBUG(3, ("echo %d times\n", smb_reverb)); @@ -4165,14 +4193,14 @@ int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf, #endif uint16 num_ulocks = SVAL(inbuf, smb_vwv6); uint16 num_locks = SVAL(inbuf, smb_vwv7); - SMB_OFF_T count = 0, offset = 0; + SMB_BIG_UINT count = 0, offset = 0; int32 lock_timeout = IVAL(inbuf, smb_vwv4); int i; char *data; uint32 ecode = 0, dummy2; int eclass = 0, dummy1; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - BOOL err1, err2; + BOOL err; CHECK_FSP(fsp, conn); CHECK_ERROR(fsp); @@ -4187,6 +4215,7 @@ int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf, DEBUG(5, ("reply_lockingX: oplock break reply from client for fnum = %d\n", fsp->fnum)); + /* * Make sure we have granted an exclusive or batch oplock on this file. */ @@ -4207,7 +4236,6 @@ no oplock granted on this file (%s).\n", if (remove_oplock(fsp) == False) { - DEBUG(0, ("reply_lockingX: error in removing oplock on file %s\n", fsp->fsp_name)); @@ -4230,13 +4258,13 @@ no oplock granted on this file (%s).\n", of smb_unlkrng structs */ for (i = 0; i < (int)num_ulocks; i++) { - count = get_lock_count(data, i, large_file_format, &err1); - offset = get_lock_offset(data, i, large_file_format, &err2); + count = get_lock_count(data, i, large_file_format); + offset = get_lock_offset(data, i, large_file_format, &err); /* * There is no error code marked "stupid client bug".... :-). */ - if (err1 || err2) + if (err) return ERROR(ERRDOS, ERRnoaccess); DEBUG(10, @@ -4258,13 +4286,13 @@ no oplock granted on this file (%s).\n", for (i = 0; i < (int)num_locks; i++) { - count = get_lock_count(data, i, large_file_format, &err1); - offset = get_lock_offset(data, i, large_file_format, &err2); + count = get_lock_count(data, i, large_file_format); + offset = get_lock_offset(data, i, large_file_format, &err); /* * There is no error code marked "stupid client bug".... :-). */ - if (err1 || err2) + if (err) return ERROR(ERRDOS, ERRnoaccess); DEBUG(10, @@ -4303,17 +4331,15 @@ no oplock granted on this file (%s).\n", */ for (i--; i >= 0; i--) { - count = - get_lock_count(data, i, large_file_format, - &err1); + count = get_lock_count(data, i, large_file_format); offset = get_lock_offset(data, i, large_file_format, - &err2); + &err); /* * There is no error code marked "stupid client bug".... :-). */ - if (err1 || err2) + if (err) return ERROR(ERRDOS, ERRnoaccess); do_unlock(fsp, conn, count, offset, &dummy1, &dummy2); @@ -4370,7 +4396,9 @@ int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf, tcount = maxcount; total_read = 0; - if (is_locked(fsp, conn, maxcount, startpos, READ_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) maxcount, (SMB_BIG_UINT) startpos, + READ_LOCK)) return (ERROR(ERRDOS, ERRlock)); do @@ -4391,7 +4419,7 @@ int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf, SSVAL(outbuf, smb_vwv6, nread); SSVAL(outbuf, smb_vwv7, smb_offset(data, outbuf)); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); total_read += nread; startpos += nread; @@ -4404,6 +4432,7 @@ int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf, /**************************************************************************** reply to a SMBwritebmpx (write block multiplex primary) request ****************************************************************************/ + int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { @@ -4433,7 +4462,9 @@ int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf, not an SMBwritebmpx - set this up now so we don't forget */ CVAL(outbuf, smb_com) = SMBwritec; - if (is_locked(fsp, conn, tcount, startpos, WRITE_LOCK)) + if (is_locked + (fsp, conn, (SMB_BIG_UINT) tcount, (SMB_BIG_UINT) startpos, + WRITE_LOCK)) return (ERROR(ERRDOS, ERRlock)); nwritten = write_file(fsp, data, startpos, numtowrite); @@ -4485,7 +4516,7 @@ int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf, { /* we need to send both a primary and a secondary response */ smb_setlen(outbuf, outsize - 4); - send_smb(Client, outbuf); + send_smb(smbd_server_fd(), outbuf); /* now the secondary */ outsize = set_message(outbuf, 1, 0, True); @@ -4586,6 +4617,7 @@ int reply_writebs(connection_struct * conn, char *inbuf, char *outbuf, /**************************************************************************** reply to a SMBsetattrE ****************************************************************************/ + int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { @@ -4641,6 +4673,7 @@ int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf, /**************************************************************************** reply to a SMBgetattrE ****************************************************************************/ + int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf, int size, int dum_buffsize) { diff --git a/source/smbd/server.c b/source/smbd/server.c index f36df3d020c..58d5e27759f 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -39,16 +39,35 @@ int last_message = -1; extern int DEBUGLEVEL; extern pstring user_socket_options; +extern int ClientPort; #ifdef WITH_DFS extern int dcelogin_atmost_once; #endif /* WITH_DFS */ - extern fstring remote_machine; extern pstring OriginalDir; +/* really we should have a top level context structure that has the + client file descriptor as an element. That would require a major rewrite :( + + the following 2 functions are an alternative - they make the file + descriptor private to smbd + */ +static int server_fd; + +int smbd_server_fd(void) +{ + return server_fd; +} + +void smbd_set_server_fd(int fd) +{ + server_fd = fd; + client_setfd(fd); +} + /**************************************************************************** when exiting, take the whole family ****************************************************************************/ @@ -72,20 +91,18 @@ static void killkids(void) ****************************************************************************/ static BOOL open_sockets_inetd(void) { - extern int Client; - extern int ClientPort; /* Started from inetd. fd 0 is the socket. */ /* We will abort gracefully when the client or remote system goes away */ - Client = dup(0); + smbd_set_server_fd(dup(0)); ClientPort = SMB_PORT; /* close our standard file descriptors */ close_low_fds(); - set_socket_options(Client,"SO_KEEPALIVE"); - set_socket_options(Client,user_socket_options); + set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); + set_socket_options(smbd_server_fd(),user_socket_options); return True; } @@ -114,8 +131,6 @@ static int open_server_socket(int port, uint32 ipaddr) ****************************************************************************/ static BOOL open_sockets(BOOL is_daemon,int port, int port445) { - extern int Client; - extern int ClientPort; int num_interfaces = iface_count(); int fd_listenset[FD_SETSIZE]; fd_set listen_set; @@ -244,18 +259,18 @@ max can be %d\n", #endif } - Client = accept(s,&addr,&in_addrlen); + smbd_set_server_fd(accept(s,&addr,&in_addrlen)); - if (Client == -1 && errno == EINTR) + if (smbd_server_fd() == -1 && errno == EINTR) continue; - if (Client == -1) { + if (smbd_server_fd() == -1) { DEBUG(0,("open_sockets: accept: %s\n", strerror(errno))); continue; } - if (Client != -1 && fork()==0) { + if (smbd_server_fd() != -1 && fork()==0) { /* Child code ... */ /* close the listening socket(s) */ @@ -267,8 +282,8 @@ max can be %d\n", close_low_fds(); am_parent = 0; - set_socket_options(Client,"SO_KEEPALIVE"); - set_socket_options(Client,user_socket_options); + set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); + set_socket_options(smbd_server_fd(),user_socket_options); /* Reset global variables in util.c so that client substitutions will be @@ -285,7 +300,7 @@ max can be %d\n", return True; } /* The parent doesn't need this socket */ - close(Client); + close(smbd_server_fd()); /* Force parent to check log size after * spawning child. Fix from @@ -353,10 +368,9 @@ BOOL reload_services(BOOL test) load_interfaces(); { - extern int Client; - if (Client != -1) { - set_socket_options(Client,"SO_KEEPALIVE"); - set_socket_options(Client,user_socket_options); + if (smbd_server_fd() != -1) { + set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); + set_socket_options(smbd_server_fd(),user_socket_options); } } @@ -754,7 +768,7 @@ static void usage(char *pname) pidfile_create("smbd"); } - if (!open_sockets(is_daemon,port,port445)) + if (!open_sockets(is_daemon,port, port445)) exit(1); /* @@ -782,7 +796,6 @@ static void usage(char *pname) exit(1); smbd_process(); - close_sockets(); exit_server("normal exit"); return(0); diff --git a/source/smbd/service.c b/source/smbd/service.c index 3cb36e05941..2d75292ee4a 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -205,7 +205,6 @@ connection_struct *make_connection(char *service,char *user, const struct passwd *pass = NULL; BOOL guest = False; BOOL force = False; - extern int Client; connection_struct *conn; vuser_key key; @@ -223,7 +222,7 @@ connection_struct *make_connection(char *service,char *user, } DEBUG(0,("%s (%s) couldn't find service %s\n", - remote_machine, client_connection_addr(), service)); + remote_machine, client_addr(), service)); *ecode = ERRinvnetname; return NULL; } @@ -252,7 +251,7 @@ connection_struct *make_connection(char *service,char *user, } if (!lp_snum_ok(snum) || - !check_access(Client, + !check_access(smbd_server_fd(), lp_hostsallow(snum), lp_hostsdeny(snum))) { *ecode = ERRaccess; return NULL; @@ -348,7 +347,7 @@ connection_struct *make_connection(char *service,char *user, conn->vuid = vuid; conn->uid = pass->pw_uid; conn->gid = pass->pw_gid; - safe_strcpy(conn->client_address, client_connection_addr(), sizeof(conn->client_address)-1); + safe_strcpy(conn->client_address, client_addr(), sizeof(conn->client_address)-1); conn->num_files_open = 0; conn->lastused = time(NULL); conn->service = snum; @@ -678,7 +677,7 @@ void close_cnum(connection_struct *conn, uint16 vuid) unbecome_user(); DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n", - remote_machine,client_connection_addr(), + remote_machine,conn->client_address, lp_servicename(SNUM(conn)))); if (conn->vfs_ops.disconnect != NULL) { diff --git a/source/smbd/ssl.c b/source/smbd/ssl.c index be9aae7c5c3..65d6532d486 100644 --- a/source/smbd/ssl.c +++ b/source/smbd/ssl.c @@ -248,20 +248,20 @@ char *reqHosts, *resignHosts; reqHosts = lp_ssl_hosts(); resignHosts = lp_ssl_hosts_resign(); - if(!allow_access(resignHosts, reqHosts, client_name(fd), client_addr(fd))){ + if(!allow_access(resignHosts, reqHosts, get_socket_name(fd), get_socket_addr(fd))){ sslEnabled = False; return 0; } if(msg_type != 0x81){ /* first packet must be a session request */ DEBUG( 0, ( "Client %s did not use session setup; access denied\n", - client_addr(fd) ) ); + client_addr() ) ); send_smb(fd, (char *)buf); return -1; } buf[4] = 0x8e; /* negative session response: use SSL */ send_smb(fd, (char *)buf); if(sslutil_accept(fd) != 0){ - DEBUG( 0, ( "Client %s failed SSL negotiation!\n", client_addr(fd) ) ); + DEBUG( 0, ( "Client %s failed SSL negotiation!\n", client_addr() ) ); return -1; } return 1; diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index f1fa30b0c62..2ca06ab7464 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -27,7 +27,6 @@ extern int DEBUGLEVEL; extern int Protocol; extern BOOL case_sensitive; -extern int Client; extern int smb_read_error; extern fstring local_machine; extern int global_oplock_break; @@ -66,7 +65,7 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params, the empty packet */ if(params_to_send == 0 && data_to_send == 0) { - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); return 0; } @@ -161,7 +160,7 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params, params_to_send, data_to_send, paramsize, datasize)); /* Send the packet */ - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); pp += params_sent_thistime; pd += data_sent_thistime; @@ -2288,7 +2287,7 @@ int reply_trans2(connection_struct *conn, /* We need to send an interim response then receive the rest of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); while (num_data_sofar < total_data || num_params_sofar < total_params) { diff --git a/source/web/cgi.c b/source/web/cgi.c index f253156b5be..ea73a0f1a70 100644 --- a/source/web/cgi.c +++ b/source/web/cgi.c @@ -198,6 +198,7 @@ void cgi_load_variables(FILE *f1) } fclose(stdin); + open("/dev/null", O_RDWR); if ((s=query_string) || (s=getenv("QUERY_STRING"))) { for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) { @@ -333,7 +334,7 @@ handle a http authentication line static BOOL cgi_handle_authorization(char *line) { char *p, *user, *user_pass; - const struct passwd *pass = NULL; + struct passwd *pass = NULL; BOOL ret = False; if (strncasecmp(line,"Basic ", 6)) { @@ -503,7 +504,7 @@ void cgi_setup(char *rootdir, int auth_required) f = sys_fopen("/tmp/cgi.log", "a"); if (f) fprintf(f,"\n[Date: %s %s (%s)]\n", http_timestring(time(NULL)), - client_name(1), client_addr(1)); + get_socket_name(1), get_socket_addr(1)); #endif /* we are a mini-web server. We need to read the request from stdin @@ -603,7 +604,7 @@ return the hostname of the client char *cgi_remote_host(void) { if (inetd_server) { - return client_name(1); + return get_socket_name(1); } return getenv("REMOTE_HOST"); } @@ -614,7 +615,7 @@ return the hostname of the client char *cgi_remote_addr(void) { if (inetd_server) { - return client_addr(1); + return get_socket_addr(1); } return getenv("REMOTE_ADDR"); } diff --git a/source/web/swat.c b/source/web/swat.c index cf9c6935096..c4ea1c92b80 100644 --- a/source/web/swat.c +++ b/source/web/swat.c @@ -975,8 +975,10 @@ static void printers_page(void) /* just in case it goes wild ... */ alarm(300); - dbf = sys_fopen("/dev/null", "w"); + /* we don't want any SIGPIPE messages */ + BlockSignals(True,SIGPIPE); + dbf = sys_fopen("/dev/null", "w"); if (!dbf) dbf = stderr; /* we don't want stderr screwing us up */ -- cgit