summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-08-17 07:15:54 +0000
committerAndrew Tridgell <tridge@samba.org>1998-08-17 07:15:54 +0000
commit4c5c26b1ef4be862fc2037dd5fcc120cb35bacca (patch)
tree7cd5959978923119145186e2a3838eb4ea3d3737 /source3
parent72ed7049d88e5296ebec362189e62a384385ad34 (diff)
downloadsamba-4c5c26b1ef4be862fc2037dd5fcc120cb35bacca.tar.gz
samba-4c5c26b1ef4be862fc2037dd5fcc120cb35bacca.tar.bz2
samba-4c5c26b1ef4be862fc2037dd5fcc120cb35bacca.zip
now that we have no global arrays we can start to split up the monster
server.c without breaking things. this splits off netprot.c and fileio.c for negprot and read/write/seek handling respectively. (This used to be commit b3d7014643ec9f2eef6e6f598f5b9db1fe2f930d)
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in4
-rw-r--r--source3/include/proto.h20
-rw-r--r--source3/include/smb.h7
-rw-r--r--source3/smbd/fileio.c117
-rw-r--r--source3/smbd/negprot.c415
-rw-r--r--source3/smbd/server.c485
6 files changed, 553 insertions, 495 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 634a37a357..e940afbd93 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -122,8 +122,8 @@ PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
passdb/pass_check.o passdb/ldap.o passdb/nispass.o
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
- smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o \
- smbd/groupname.o smbd/ipc.o smbd/mangle.o \
+ smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
+ smbd/groupname.o smbd/ipc.o smbd/mangle.o smbd/negprot.o \
smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
smbd/quotas.o smbd/reply.o smbd/ssl.o smbd/trans2.o smbd/uid.o
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 4c7c625397..667fc01a3b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1960,6 +1960,12 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum );
char *DirCacheCheck( char *path, char *name, int snum );
void DirCacheFlush(int snum);
+/*The following definitions come from smbd/fileio.c */
+
+int seek_file(files_struct *fsp,uint32 pos);
+int read_file(files_struct *fsp,char *data,uint32 pos,int n);
+int write_file(files_struct *fsp,char *data,int n);
+
/*The following definitions come from smbd/files.c */
files_struct *file_new(void );
@@ -2005,6 +2011,12 @@ int reply_sendtxt(connection_struct *conn,
int reply_sendend(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+/*The following definitions come from smbd/negprot.c */
+
+int reply_negprot(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size,
+ int dum_buffsize);
+
/*The following definitions come from smbd/nttrans.c */
int reply_ntcreate_and_X(connection_struct *conn,
@@ -2159,9 +2171,6 @@ int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
BOOL fcbopen, int *flags);
void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
int mode,int oplock_request, int *Access,int *action);
-int seek_file(files_struct *fsp,uint32 pos);
-int read_file(files_struct *fsp,char *data,uint32 pos,int n);
-int write_file(files_struct *fsp,char *data,int n);
BOOL become_service(connection_struct *conn,BOOL do_chdir);
int find_service(char *service);
int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line);
@@ -2174,11 +2183,6 @@ BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int tim
BOOL reload_services(BOOL test);
connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode);
BOOL attempt_close_oplocked_file(files_struct *fsp);
-int reply_corep(char *outbuf);
-int reply_coreplus(char *outbuf);
-int reply_lanman1(char *outbuf);
-int reply_lanman2(char *outbuf);
-int reply_nt1(char *outbuf);
void close_cnum(connection_struct *conn, uint16 vuid);
void exit_server(char *reason);
char *smb_fn_name(int type);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index c68f88cbdd..e88737f046 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -200,6 +200,13 @@ implemented */
#define aDIR (1L<<4)
#define aARCH (1L<<5)
+/* for readability... */
+#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
+#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
+#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
+#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
+#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
+
/* deny modes */
#define DENY_DOS 0
#define DENY_ALL 1
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
new file mode 100644
index 0000000000..edf87f3e7b
--- /dev/null
+++ b/source3/smbd/fileio.c
@@ -0,0 +1,117 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ read/write to a files_struct
+ Copyright (C) Andrew Tridgell 1992-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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+seek a file. Try to avoid the seek if possible
+****************************************************************************/
+int seek_file(files_struct *fsp,uint32 pos)
+{
+ uint32 offset = 0;
+
+ if (fsp->print_file && lp_postscript(fsp->conn->service))
+ offset = 3;
+
+ fsp->pos = (int)(lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset);
+ return(fsp->pos);
+}
+
+/****************************************************************************
+read from a file
+****************************************************************************/
+int read_file(files_struct *fsp,char *data,uint32 pos,int n)
+{
+ int ret=0,readret;
+
+#if USE_READ_PREDICTION
+ if (!fsp->can_write)
+ {
+ ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n);
+
+ data += ret;
+ n -= ret;
+ pos += ret;
+ }
+#endif
+
+#if WITH_MMAP
+ if (fsp->mmap_ptr)
+ {
+ int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1;
+ num = MIN(n,num);
+ if (num > 0)
+ {
+ memcpy(data,fsp->mmap_ptr+pos,num);
+ data += num;
+ pos += num;
+ n -= num;
+ ret += num;
+ }
+ }
+#endif
+
+ if (n <= 0)
+ return(ret);
+
+ if (seek_file(fsp,pos) != pos)
+ {
+ DEBUG(3,("Failed to seek to %d\n",pos));
+ return(ret);
+ }
+
+ if (n > 0) {
+ readret = read(fsp->fd_ptr->fd,data,n);
+ if (readret > 0) ret += readret;
+ }
+
+ return(ret);
+}
+
+
+/****************************************************************************
+write to a file
+****************************************************************************/
+int write_file(files_struct *fsp,char *data,int n)
+{
+
+ if (!fsp->can_write) {
+ errno = EPERM;
+ return(0);
+ }
+
+ if (!fsp->modified) {
+ struct stat st;
+ fsp->modified = True;
+ if (fstat(fsp->fd_ptr->fd,&st) == 0) {
+ int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
+ if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {
+ dos_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
+ }
+ }
+ }
+
+ return(write_data(fsp->fd_ptr->fd,data,n));
+}
+
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
new file mode 100644
index 0000000000..8e996cac21
--- /dev/null
+++ b/source3/smbd/negprot.c
@@ -0,0 +1,415 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ negprot reply code
+ Copyright (C) Andrew Tridgell 1992-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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+extern int Protocol;
+extern int max_recv;
+extern fstring global_myworkgroup;
+extern fstring remote_machine;
+extern pstring myhostname;
+
+/****************************************************************************
+reply for the core protocol
+****************************************************************************/
+static int reply_corep(char *outbuf)
+{
+ int outsize = set_message(outbuf,1,0,True);
+
+ Protocol = PROTOCOL_CORE;
+
+ return outsize;
+}
+
+
+/****************************************************************************
+reply for the coreplus protocol
+****************************************************************************/
+static int reply_coreplus(char *outbuf)
+{
+ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
+ int outsize = set_message(outbuf,13,0,True);
+ SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
+ readbraw and writebraw (possibly) */
+ CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
+ SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
+
+ Protocol = PROTOCOL_COREPLUS;
+
+ return outsize;
+}
+
+
+/****************************************************************************
+reply for the lanman 1.0 protocol
+****************************************************************************/
+static int reply_lanman1(char *outbuf)
+{
+ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
+ int secword=0;
+ BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
+
+ if (lp_security()>=SEC_USER) secword |= 1;
+ if (doencrypt) secword |= 2;
+
+ set_message(outbuf,13,doencrypt?8:0,True);
+ SSVAL(outbuf,smb_vwv1,secword);
+ /* Create a token value and add it to the outgoing packet. */
+ if (doencrypt)
+ generate_next_challenge(smb_buf(outbuf));
+
+ Protocol = PROTOCOL_LANMAN1;
+
+ CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
+ SSVAL(outbuf,smb_vwv2,max_recv);
+ SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
+ SSVAL(outbuf,smb_vwv4,1);
+ SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
+ readbraw writebraw (possibly) */
+ SIVAL(outbuf,smb_vwv6,getpid());
+ SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
+
+ put_dos_date(outbuf,smb_vwv8,t);
+
+ return (smb_len(outbuf)+4);
+}
+
+
+/****************************************************************************
+reply for the lanman 2.0 protocol
+****************************************************************************/
+static int reply_lanman2(char *outbuf)
+{
+ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
+ int secword=0;
+ BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
+ struct cli_state *cli = NULL;
+ char cryptkey[8];
+ char crypt_len = 0;
+
+ if (lp_security() == SEC_SERVER) {
+ cli = server_cryptkey();
+ }
+
+ if (cli) {
+ DEBUG(3,("using password server validation\n"));
+ doencrypt = ((cli->sec_mode & 2) != 0);
+ }
+
+ if (lp_security()>=SEC_USER) secword |= 1;
+ if (doencrypt) secword |= 2;
+
+ if (doencrypt) {
+ crypt_len = 8;
+ if (!cli) {
+ generate_next_challenge(cryptkey);
+ } else {
+ memcpy(cryptkey, cli->cryptkey, 8);
+ set_challenge(cli->cryptkey);
+ }
+ }
+
+ set_message(outbuf,13,crypt_len,True);
+ SSVAL(outbuf,smb_vwv1,secword);
+ SIVAL(outbuf,smb_vwv6,getpid());
+ if (doencrypt)
+ memcpy(smb_buf(outbuf), cryptkey, 8);
+
+ Protocol = PROTOCOL_LANMAN2;
+
+ CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
+ SSVAL(outbuf,smb_vwv2,max_recv);
+ SSVAL(outbuf,smb_vwv3,lp_maxmux());
+ SSVAL(outbuf,smb_vwv4,1);
+ SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
+ SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
+ put_dos_date(outbuf,smb_vwv8,t);
+
+ return (smb_len(outbuf)+4);
+}
+
+
+/****************************************************************************
+reply for the nt protocol
+****************************************************************************/
+static int reply_nt1(char *outbuf)
+{
+ /* dual names + lock_and_read + nt SMBs + remote API calls */
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS |CAP_NT_SMBS;
+
+/*
+ other valid capabilities which we may support at some time...
+ CAP_LARGE_FILES|
+ CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
+ */
+
+ int secword=0;
+ BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
+ int data_len;
+ struct cli_state *cli = NULL;
+ char cryptkey[8];
+ char crypt_len = 0;
+
+ if (lp_security() == SEC_SERVER) {
+ cli = server_cryptkey();
+ }
+
+ if (cli) {
+ DEBUG(3,("using password server validation\n"));
+ doencrypt = ((cli->sec_mode & 2) != 0);
+ }
+
+ if (doencrypt) {
+ crypt_len = 8;
+ if (!cli) {
+ generate_next_challenge(cryptkey);
+ } else {
+ memcpy(cryptkey, cli->cryptkey, 8);
+ set_challenge(cli->cryptkey);
+ }
+ }
+
+ if (lp_readraw() && lp_writeraw()) {
+ capabilities |= CAP_RAW_MODE;
+ }
+
+ if (lp_security() >= SEC_USER) secword |= 1;
+ if (doencrypt) secword |= 2;
+
+ /* decide where (if) to put the encryption challenge, and
+ follow it with the OEM'd domain name
+ */
+ data_len = crypt_len + strlen(global_myworkgroup) + 1;
+
+ set_message(outbuf,17,data_len,True);
+ pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
+
+ CVAL(outbuf,smb_vwv1) = secword;
+ SSVALS(outbuf,smb_vwv16+1,crypt_len);
+ if (doencrypt)
+ memcpy(smb_buf(outbuf), cryptkey, 8);
+
+ Protocol = PROTOCOL_NT1;
+
+ SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
+ SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
+ SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
+ SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
+ SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
+ SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
+ put_long_date(outbuf+smb_vwv11+1,t);
+ SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
+ SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
+
+ return (smb_len(outbuf)+4);
+}
+
+/* these are the protocol lists used for auto architecture detection:
+
+WinNT 3.51:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [XENIX CORE]
+protocol [MICROSOFT NETWORKS 1.03]
+protocol [LANMAN1.0]
+protocol [Windows for Workgroups 3.1a]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+protocol [NT LM 0.12]
+
+Win95:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [XENIX CORE]
+protocol [MICROSOFT NETWORKS 1.03]
+protocol [LANMAN1.0]
+protocol [Windows for Workgroups 3.1a]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+protocol [NT LM 0.12]
+
+OS/2:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [XENIX CORE]
+protocol [LANMAN1.0]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+*/
+
+/*
+ * Modified to recognize the architecture of the remote machine better.
+ *
+ * This appears to be the matrix of which protocol is used by which
+ * MS product.
+ Protocol WfWg Win95 WinNT OS/2
+ PC NETWORK PROGRAM 1.0 1 1 1 1
+ XENIX CORE 2 2
+ MICROSOFT NETWORKS 3.0 2 2
+ DOS LM1.2X002 3 3
+ MICROSOFT NETWORKS 1.03 3
+ DOS LANMAN2.1 4 4
+ LANMAN1.0 4 3
+ Windows for Workgroups 3.1a 5 5 5
+ LM1.2X002 6 4
+ LANMAN2.1 7 5
+ NT LM 0.12 6 8
+ *
+ * tim@fsg.com 09/29/95
+ */
+
+#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
+#define ARCH_WIN95 0x2
+#define ARCH_OS2 0xC /* Again OS/2 is like NT */
+#define ARCH_WINNT 0x8
+#define ARCH_SAMBA 0x10
+
+#define ARCH_ALL 0x1F
+
+/* List of supported protocols, most desired first */
+static struct {
+ char *proto_name;
+ char *short_name;
+ int (*proto_reply_fn)(char *);
+ int protocol_level;
+} supported_protocols[] = {
+ {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
+ {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
+ {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
+ {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
+ {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
+ {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
+ {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
+ {NULL,NULL},
+};
+
+
+/****************************************************************************
+ reply to a negprot
+****************************************************************************/
+int reply_negprot(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size,
+ int dum_buffsize)
+{
+ int outsize = set_message(outbuf,1,0,True);
+ int Index=0;
+ int choice= -1;
+ int protocol;
+ char *p;
+ int bcc = SVAL(smb_buf(inbuf),-2);
+ int arch = ARCH_ALL;
+
+ p = smb_buf(inbuf)+1;
+ while (p < (smb_buf(inbuf) + bcc))
+ {
+ Index++;
+ DEBUG(3,("Requested protocol [%s]\n",p));
+ if (strcsequal(p,"Windows for Workgroups 3.1a"))
+ arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
+ else if (strcsequal(p,"DOS LM1.2X002"))
+ arch &= ( ARCH_WFWG | ARCH_WIN95 );
+ else if (strcsequal(p,"DOS LANMAN2.1"))
+ arch &= ( ARCH_WFWG | ARCH_WIN95 );
+ else if (strcsequal(p,"NT LM 0.12"))
+ arch &= ( ARCH_WIN95 | ARCH_WINNT );
+ else if (strcsequal(p,"LANMAN2.1"))
+ arch &= ( ARCH_WINNT | ARCH_OS2 );
+ else if (strcsequal(p,"LM1.2X002"))
+ arch &= ( ARCH_WINNT | ARCH_OS2 );
+ else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
+ arch &= ARCH_WINNT;
+ else if (strcsequal(p,"XENIX CORE"))
+ arch &= ( ARCH_WINNT | ARCH_OS2 );
+ else if (strcsequal(p,"Samba")) {
+ arch = ARCH_SAMBA;
+ break;
+ }
+
+ p += strlen(p) + 2;
+ }
+
+ switch ( arch ) {
+ case ARCH_SAMBA:
+ set_remote_arch(RA_SAMBA);
+ break;
+ case ARCH_WFWG:
+ set_remote_arch(RA_WFWG);
+ break;
+ case ARCH_WIN95:
+ set_remote_arch(RA_WIN95);
+ break;
+ case ARCH_WINNT:
+ set_remote_arch(RA_WINNT);
+ break;
+ case ARCH_OS2:
+ set_remote_arch(RA_OS2);
+ break;
+ default:
+ set_remote_arch(RA_UNKNOWN);
+ break;
+ }
+
+ /* possibly reload - change of architecture */
+ reload_services(True);
+
+ /* a special case to stop password server loops */
+ if (Index == 1 && strequal(remote_machine,myhostname) &&
+ (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
+ exit_server("Password server loop!");
+
+ /* Check for protocols, most desirable first */
+ for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
+ {
+ p = smb_buf(inbuf)+1;
+ Index = 0;
+ if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
+ while (p < (smb_buf(inbuf) + bcc))
+ {
+ if (strequal(p,supported_protocols[protocol].proto_name))
+ choice = Index;
+ Index++;
+ p += strlen(p) + 2;
+ }
+ if(choice != -1)
+ break;
+ }
+
+ SSVAL(outbuf,smb_vwv0,choice);
+ if(choice != -1) {
+ extern fstring remote_proto;
+ fstrcpy(remote_proto,supported_protocols[protocol].short_name);
+ reload_services(True);
+ outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
+ DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
+ }
+ else {
+ DEBUG(0,("No protocol supported !\n"));
+ }
+ SSVAL(outbuf,smb_vwv0,choice);
+
+ DEBUG( 5, ( "negprot index=%d\n", choice ) );
+
+ return(outsize);
+}
+
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index a293075741..ccb830637d 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -65,8 +65,6 @@ extern int dcelogin_atmost_once;
*/
extern DOM_SID global_machine_sid;
-extern int Protocol;
-
/*
* Size of data we can send to client. Set
* by the client for all protocols above CORE.
@@ -100,13 +98,6 @@ extern int extra_time_offset;
extern pstring myhostname;
-/* for readability... */
-#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
-#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
-#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
-#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
-#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
-
/****************************************************************************
when exiting, take the whole family
****************************************************************************/
@@ -1988,97 +1979,6 @@ dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
unlock_share_entry( conn, dev, inode, token);
}
-/****************************************************************************
-seek a file. Try to avoid the seek if possible
-****************************************************************************/
-int seek_file(files_struct *fsp,uint32 pos)
-{
- uint32 offset = 0;
-
- if (fsp->print_file && lp_postscript(fsp->conn->service))
- offset = 3;
-
- fsp->pos = (int)(lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset);
- return(fsp->pos);
-}
-
-/****************************************************************************
-read from a file
-****************************************************************************/
-int read_file(files_struct *fsp,char *data,uint32 pos,int n)
-{
- int ret=0,readret;
-
-#if USE_READ_PREDICTION
- if (!fsp->can_write)
- {
- ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n);
-
- data += ret;
- n -= ret;
- pos += ret;
- }
-#endif
-
-#if WITH_MMAP
- if (fsp->mmap_ptr)
- {
- int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1;
- num = MIN(n,num);
- if (num > 0)
- {
- memcpy(data,fsp->mmap_ptr+pos,num);
- data += num;
- pos += num;
- n -= num;
- ret += num;
- }
- }
-#endif
-
- if (n <= 0)
- return(ret);
-
- if (seek_file(fsp,pos) != pos)
- {
- DEBUG(3,("Failed to seek to %d\n",pos));
- return(ret);
- }
-
- if (n > 0) {
- readret = read(fsp->fd_ptr->fd,data,n);
- if (readret > 0) ret += readret;
- }
-
- return(ret);
-}
-
-
-/****************************************************************************
-write to a file
-****************************************************************************/
-int write_file(files_struct *fsp,char *data,int n)
-{
-
- if (!fsp->can_write) {
- errno = EPERM;
- return(0);
- }
-
- if (!fsp->modified) {
- struct stat st;
- fsp->modified = True;
- if (fstat(fsp->fd_ptr->fd,&st) == 0) {
- int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
- if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {
- dos_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
- }
- }
- }
-
- return(write_data(fsp->fd_ptr->fd,data,n));
-}
-
/****************************************************************************
load parameters specific to a connection/service
@@ -3657,391 +3557,6 @@ BOOL attempt_close_oplocked_file(files_struct *fsp)
}
-/****************************************************************************
-reply for the core protocol
-****************************************************************************/
-int reply_corep(char *outbuf)
-{
- int outsize = set_message(outbuf,1,0,True);
-
- Protocol = PROTOCOL_CORE;
-
- return outsize;
-}
-
-
-/****************************************************************************
-reply for the coreplus protocol
-****************************************************************************/
-int reply_coreplus(char *outbuf)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int outsize = set_message(outbuf,13,0,True);
- SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw and writebraw (possibly) */
- CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
-
- Protocol = PROTOCOL_COREPLUS;
-
- return outsize;
-}
-
-
-/****************************************************************************
-reply for the lanman 1.0 protocol
-****************************************************************************/
-int reply_lanman1(char *outbuf)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int secword=0;
- BOOL doencrypt = SMBENCRYPT();
- time_t t = time(NULL);
-
- if (lp_security()>=SEC_USER) secword |= 1;
- if (doencrypt) secword |= 2;
-
- set_message(outbuf,13,doencrypt?8:0,True);
- SSVAL(outbuf,smb_vwv1,secword);
- /* Create a token value and add it to the outgoing packet. */
- if (doencrypt)
- generate_next_challenge(smb_buf(outbuf));
-
- Protocol = PROTOCOL_LANMAN1;
-
- CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_vwv2,max_recv);
- SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
- SSVAL(outbuf,smb_vwv4,1);
- SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw writebraw (possibly) */
- SIVAL(outbuf,smb_vwv6,getpid());
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
-
- put_dos_date(outbuf,smb_vwv8,t);
-
- return (smb_len(outbuf)+4);
-}
-
-
-/****************************************************************************
-reply for the lanman 2.0 protocol
-****************************************************************************/
-int reply_lanman2(char *outbuf)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int secword=0;
- BOOL doencrypt = SMBENCRYPT();
- time_t t = time(NULL);
- struct cli_state *cli = NULL;
- char cryptkey[8];
- char crypt_len = 0;
-
- if (lp_security() == SEC_SERVER) {
- cli = server_cryptkey();
- }
-
- if (cli) {
- DEBUG(3,("using password server validation\n"));
- doencrypt = ((cli->sec_mode & 2) != 0);
- }
-
- if (lp_security()>=SEC_USER) secword |= 1;
- if (doencrypt) secword |= 2;
-
- if (doencrypt) {
- crypt_len = 8;
- if (!cli) {
- generate_next_challenge(cryptkey);
- } else {
- memcpy(cryptkey, cli->cryptkey, 8);
- set_challenge(cli->cryptkey);
- }
- }
-
- set_message(outbuf,13,crypt_len,True);
- SSVAL(outbuf,smb_vwv1,secword);
- SIVAL(outbuf,smb_vwv6,getpid());
- if (doencrypt)
- memcpy(smb_buf(outbuf), cryptkey, 8);
-
- Protocol = PROTOCOL_LANMAN2;
-
- CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_vwv2,max_recv);
- SSVAL(outbuf,smb_vwv3,lp_maxmux());
- SSVAL(outbuf,smb_vwv4,1);
- SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
- put_dos_date(outbuf,smb_vwv8,t);
-
- return (smb_len(outbuf)+4);
-}
-
-
-/****************************************************************************
-reply for the nt protocol
-****************************************************************************/
-int reply_nt1(char *outbuf)
-{
- /* dual names + lock_and_read + nt SMBs + remote API calls */
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS |CAP_NT_SMBS;
-
-/*
- other valid capabilities which we may support at some time...
- CAP_LARGE_FILES|
- CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
- */
-
- int secword=0;
- BOOL doencrypt = SMBENCRYPT();
- time_t t = time(NULL);
- int data_len;
- struct cli_state *cli = NULL;
- char cryptkey[8];
- char crypt_len = 0;
-
- if (lp_security() == SEC_SERVER) {
- cli = server_cryptkey();
- }
-
- if (cli) {
- DEBUG(3,("using password server validation\n"));
- doencrypt = ((cli->sec_mode & 2) != 0);
- }
-
- if (doencrypt) {
- crypt_len = 8;
- if (!cli) {
- generate_next_challenge(cryptkey);
- } else {
- memcpy(cryptkey, cli->cryptkey, 8);
- set_challenge(cli->cryptkey);
- }
- }
-
- if (lp_readraw() && lp_writeraw()) {
- capabilities |= CAP_RAW_MODE;
- }
-
- if (lp_security() >= SEC_USER) secword |= 1;
- if (doencrypt) secword |= 2;
-
- /* decide where (if) to put the encryption challenge, and
- follow it with the OEM'd domain name
- */
- data_len = crypt_len + strlen(global_myworkgroup) + 1;
-
- set_message(outbuf,17,data_len,True);
- pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
-
- CVAL(outbuf,smb_vwv1) = secword;
- SSVALS(outbuf,smb_vwv16+1,crypt_len);
- if (doencrypt)
- memcpy(smb_buf(outbuf), cryptkey, 8);
-
- Protocol = PROTOCOL_NT1;
-
- SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
- SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
- SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
- SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
- SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
- SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
- put_long_date(outbuf+smb_vwv11+1,t);
- SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
- SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
-
- return (smb_len(outbuf)+4);
-}
-
-/* these are the protocol lists used for auto architecture detection:
-
-WinNT 3.51:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [XENIX CORE]
-protocol [MICROSOFT NETWORKS 1.03]
-protocol [LANMAN1.0]
-protocol [Windows for Workgroups 3.1a]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-protocol [NT LM 0.12]
-
-Win95:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [XENIX CORE]
-protocol [MICROSOFT NETWORKS 1.03]
-protocol [LANMAN1.0]
-protocol [Windows for Workgroups 3.1a]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-protocol [NT LM 0.12]
-
-OS/2:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [XENIX CORE]
-protocol [LANMAN1.0]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-*/
-
-/*
- * Modified to recognize the architecture of the remote machine better.
- *
- * This appears to be the matrix of which protocol is used by which
- * MS product.
- Protocol WfWg Win95 WinNT OS/2
- PC NETWORK PROGRAM 1.0 1 1 1 1
- XENIX CORE 2 2
- MICROSOFT NETWORKS 3.0 2 2
- DOS LM1.2X002 3 3
- MICROSOFT NETWORKS 1.03 3
- DOS LANMAN2.1 4 4
- LANMAN1.0 4 3
- Windows for Workgroups 3.1a 5 5 5
- LM1.2X002 6 4
- LANMAN2.1 7 5
- NT LM 0.12 6 8
- *
- * tim@fsg.com 09/29/95
- */
-
-#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
-#define ARCH_WIN95 0x2
-#define ARCH_OS2 0xC /* Again OS/2 is like NT */
-#define ARCH_WINNT 0x8
-#define ARCH_SAMBA 0x10
-
-#define ARCH_ALL 0x1F
-
-/* List of supported protocols, most desired first */
-struct {
- char *proto_name;
- char *short_name;
- int (*proto_reply_fn)(char *);
- int protocol_level;
-} supported_protocols[] = {
- {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
- {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
- {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
- {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
- {NULL,NULL},
-};
-
-
-/****************************************************************************
- reply to a negprot
-****************************************************************************/
-static int reply_negprot(connection_struct *conn,
- char *inbuf,char *outbuf, int dum_size,
- int dum_buffsize)
-{
- int outsize = set_message(outbuf,1,0,True);
- int Index=0;
- int choice= -1;
- int protocol;
- char *p;
- int bcc = SVAL(smb_buf(inbuf),-2);
- int arch = ARCH_ALL;
-
- p = smb_buf(inbuf)+1;
- while (p < (smb_buf(inbuf) + bcc))
- {
- Index++;
- DEBUG(3,("Requested protocol [%s]\n",p));
- if (strcsequal(p,"Windows for Workgroups 3.1a"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
- else if (strcsequal(p,"DOS LM1.2X002"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(p,"DOS LANMAN2.1"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(p,"NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT );
- else if (strcsequal(p,"LANMAN2.1"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"LM1.2X002"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
- arch &= ARCH_WINNT;
- else if (strcsequal(p,"XENIX CORE"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"Samba")) {
- arch = ARCH_SAMBA;
- break;
- }
-
- p += strlen(p) + 2;
- }
-
- switch ( arch ) {
- case ARCH_SAMBA:
- set_remote_arch(RA_SAMBA);
- break;
- case ARCH_WFWG:
- set_remote_arch(RA_WFWG);
- break;
- case ARCH_WIN95:
- set_remote_arch(RA_WIN95);
- break;
- case ARCH_WINNT:
- set_remote_arch(RA_WINNT);
- break;
- case ARCH_OS2:
- set_remote_arch(RA_OS2);
- break;
- default:
- set_remote_arch(RA_UNKNOWN);
- break;
- }
-
- /* possibly reload - change of architecture */
- reload_services(True);
-
- /* a special case to stop password server loops */
- if (Index == 1 && strequal(remote_machine,myhostname) &&
- (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
- exit_server("Password server loop!");
-
- /* Check for protocols, most desirable first */
- for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
- {
- p = smb_buf(inbuf)+1;
- Index = 0;
- if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
- while (p < (smb_buf(inbuf) + bcc))
- {
- if (strequal(p,supported_protocols[protocol].proto_name))
- choice = Index;
- Index++;
- p += strlen(p) + 2;
- }
- if(choice != -1)
- break;
- }
-
- SSVAL(outbuf,smb_vwv0,choice);
- if(choice != -1) {
- extern fstring remote_proto;
- fstrcpy(remote_proto,supported_protocols[protocol].short_name);
- reload_services(True);
- outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
- DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
- }
- else {
- DEBUG(0,("No protocol supported !\n"));
- }
- SSVAL(outbuf,smb_vwv0,choice);
-
- DEBUG( 5, ( "negprot index=%d\n", choice ) );
-
- return(outsize);
-}
-
/****************************************************************************
close a cnum