From 44bc9f239aa0b3cdf6cf9ad8d3911e397eba7335 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Oct 1997 03:14:32 +0000 Subject: change the semantics of hosts allow/hosts deny so that a global setting applies to all shares regardless of any settings on other shares. This allows us to immediately drop a connection if it does not come from a allowed host, without even parsing the first SMB packet. The next time we get a nasty security hole we can offer people the option of just setting their hosts allow line. If we drop a connection in this way we generate a "Not listening for calling name" response and then exit. add a per share "oplocks" option in smb.conf. I think its important to be able to disable oplocks on a per-share basis as there are occasions then they are definately not wanted, for example when sharing data between a windows box and a unix application. This also allows us to tell people "try disabling oplocks" when diagnosing problems. fix a bug in process_smb(). It was taking the length of the packet from outbuf, not inbuf (this bug was introduced with the oplocks code). Jeremy, I assume this wasn't deliberate? --- source/include/proto.h | 1 + source/param/loadparm.c | 6 ++++++ source/smbd/server.c | 23 +++++++++++++++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/include/proto.h b/source/include/proto.h index ac81f8cb370..51433333c50 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -248,6 +248,7 @@ BOOL lp_map_archive(int ); BOOL lp_locking(int ); BOOL lp_strict_locking(int ); BOOL lp_share_modes(int ); +BOOL lp_oplocks(int ); BOOL lp_onlyuser(int ); BOOL lp_manglednames(int ); BOOL lp_widelinks(int ); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 1a9771df229..fb656aa627f 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -257,6 +257,7 @@ typedef struct BOOL bLocking; BOOL bStrictLocking; BOOL bShareModes; + BOOL bOpLocks; BOOL bOnlyUser; BOOL bMangledNames; BOOL bWidelinks; @@ -338,6 +339,7 @@ static service sDefault = True, /* bLocking */ False, /* bStrictLocking */ True, /* bShareModes */ + True, /* bOpLocks */ False, /* bOnlyUser */ True, /* bMangledNames */ True, /* bWidelinks */ @@ -541,6 +543,7 @@ struct parm_struct {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL}, {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL}, {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL}, + {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL}, {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL}, {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL}, {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL}, @@ -935,6 +938,7 @@ FN_LOCAL_BOOL(lp_map_archive,bMap_archive) FN_LOCAL_BOOL(lp_locking,bLocking) FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking) FN_LOCAL_BOOL(lp_share_modes,bShareModes) +FN_LOCAL_BOOL(lp_oplocks,bOpLocks) FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser) FN_LOCAL_BOOL(lp_manglednames,bMangledNames) FN_LOCAL_BOOL(lp_widelinks,bWidelinks) @@ -1138,6 +1142,8 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService) iSERVICE(i).bRead_only = False; /* No share modes on printer services. */ iSERVICE(i).bShareModes = False; + /* No oplocks on printer services. */ + iSERVICE(i).bOpLocks = False; /* Printer services must be printable. */ iSERVICE(i).bPrint_ok = True; diff --git a/source/smbd/server.c b/source/smbd/server.c index b9bdbaa6553..7b04d228c32 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -1841,7 +1841,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); be extended to level II oplocks (multiple reader oplocks). */ - if(oplock_request && (num_share_modes == 0)) + if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum))) { fs_p->granted_oplock = True; global_oplocks_open++; @@ -2412,12 +2412,27 @@ static BOOL open_sockets(BOOL is_daemon,int port) static void process_smb(char *inbuf, char *outbuf) { extern int Client; - static int trans_num = 0; - + static int trans_num; int msg_type = CVAL(inbuf,0); - int32 len = smb_len(outbuf); + int32 len = smb_len(inbuf); int nread = len + 4; + if (trans_num == 0) { + /* on the first packet, check the global hosts allow/ hosts + 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(-1)) { + /* send a negative session response "not listining on calling + name" */ + static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; + DEBUG(1,("%s Connection denied from %s\n", + timestring(),client_addr())); + send_smb(Client,buf); + exit_server("connection denied"); + } + } + DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len)); DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread)); -- cgit