From 4c5c26b1ef4be862fc2037dd5fcc120cb35bacca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 07:15:54 +0000 Subject: 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) --- source3/smbd/server.c | 485 -------------------------------------------------- 1 file changed, 485 deletions(-) (limited to 'source3/smbd/server.c') 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 -- cgit