From d891421d16ff80998dee429227bd391455f9d1a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Oct 1998 16:55:03 +0000 Subject: libsmb/smbdes.c: #ifdef'ed out code prior to removal. rpc_client/cli_pipe.c: Inlined code removed from smbdes.c rpc_server/srv_samr.c: Fixed unused variable warning. rpc_server/srv_util.c: Inlined code removed from smbdes.c Luke - the above changes are the first part of the changes you and I discussed as being neccessary at the CIFS conference. *PLEASE REVIEW THESE CHANGES* - make sure I haven't broken any of the authenticated DCE/RPC code. smbd/nttrans.c: Fixed to allow NT5.0beta2 to use Samba shares with NT SMB support. smbd/open.c: Fixed mkdir when called from nttrans calls. smbd/server.c: Set correct size for strcpy of global_myworkgroup. Jeremy. --- source/libsmb/smbdes.c | 5 +++ source/rpc_client/cli_pipe.c | 31 ++++++++++++++- source/rpc_server/srv_samr.c | 3 +- source/rpc_server/srv_util.c | 32 ++++++++++++++- source/smbd/nttrans.c | 92 +++++++++++++++++++++++++++++--------------- source/smbd/open.c | 11 +++++- source/smbd/server.c | 2 +- 7 files changed, 138 insertions(+), 38 deletions(-) diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c index 9d531ef26dd..8a13935cf90 100644 --- a/source/libsmb/smbdes.c +++ b/source/libsmb/smbdes.c @@ -358,6 +358,10 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } +#if 0 +/* + * Prepare to remove... JRA. + */ void NTLMSSPhash( unsigned char hash[258], unsigned char key[5]) { unsigned char j = 0; @@ -389,6 +393,7 @@ void NTLMSSPhash( unsigned char hash[258], unsigned char key[5]) hash[256] = 0; hash[257] = 0; } +#endif void NTLMSSPcalc( unsigned char hash[258], unsigned char *data, int len) { diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index 15025ceef31..e02bb889cc5 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -922,7 +922,36 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL); pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL); NTLMSSPOWFencrypt(lm_hash, lm_owf, p24); - NTLMSSPhash(cli->ntlmssp_hash, p24); + { + unsigned char j = 0; + int ind; + unsigned char k2[8]; + + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + for (ind = 0; ind < 256; ind++) + { + cli->ntlmssp_hash[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (cli->ntlmssp_hash[ind] + k2[ind%8]); + + tc = cli->ntlmssp_hash[ind]; + cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j]; + cli->ntlmssp_hash[j] = tc; + } + + cli->ntlmssp_hash[256] = 0; + cli->ntlmssp_hash[257] = 0; + } +/* NTLMSSPhash(cli->ntlmssp_hash, p24); */ bzero(lm_hash, sizeof(lm_hash)); /* this is a hack due to limitations in rpc_api_pipe */ diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c index 9a37f76121f..e9204e065ff 100644 --- a/source/rpc_server/srv_samr.c +++ b/source/rpc_server/srv_samr.c @@ -226,7 +226,6 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, { SAMR_R_UNKNOWN_2C r_u; uint32 status = 0x0; - uint32 rid; /* find the policy handle. open a policy on it. */ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1)) @@ -235,7 +234,7 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, } /* find the user's rid */ - if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff) + if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff)) { status = NT_STATUS_OBJECT_TYPE_MISMATCH; } diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c index b3557c77688..51df42cdff0 100644 --- a/source/rpc_server/srv_util.c +++ b/source/rpc_server/srv_util.c @@ -346,7 +346,37 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) { uchar p24[24]; NTLMSSPOWFencrypt(smb_pass->smb_passwd, lm_owf, p24); - NTLMSSPhash(p->ntlmssp_hash, p24); + { + unsigned char j = 0; + int ind; + + unsigned char k2[8]; + + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + for (ind = 0; ind < 256; ind++) + { + p->ntlmssp_hash[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (p->ntlmssp_hash[ind] + k2[ind%8]); + + tc = p->ntlmssp_hash[ind]; + p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; + p->ntlmssp_hash[j] = tc; + } + + p->ntlmssp_hash[256] = 0; + p->ntlmssp_hash[257] = 0; + } +/* NTLMSSPhash(p->ntlmssp_hash, p24); */ p->ntlmssp_seq_num = 0; } else diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index d30b59f0d37..62ca9fe1c8b 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -312,35 +312,47 @@ static void restore_case_semantics(uint32 file_attributes) static int map_create_disposition( uint32 create_disposition) { + int ret; + switch( create_disposition ) { case FILE_CREATE: /* create if not exist, fail if exist */ - return 0x10; + ret = 0x10; + break; case FILE_SUPERSEDE: case FILE_OVERWRITE_IF: /* create if not exist, trunc if exist */ - return 0x12; + ret = 0x12; + break; case FILE_OPEN: /* fail if not exist, open if exists */ - return 0x1; + ret = 0x1; + break; case FILE_OPEN_IF: /* create if not exist, open if exists */ - return 0x11; + ret = 0x11; + break; case FILE_OVERWRITE: /* fail if not exist, truncate if exists */ - return 0x2; + ret = 0x2; + break; default: DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n", create_disposition )); return -1; } + + DEBUG(10,("map_create_disposition: Mapped create_disposition %lx to %x\n", + (unsigned long)create_disposition, ret )); + + return ret; } /**************************************************************************** Utility function to map share modes. ****************************************************************************/ -static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 file_attributes) +static int map_share_mode( char *fname, uint32 desired_access, uint32 share_access, uint32 file_attributes) { int smb_open_mode = -1; @@ -356,15 +368,28 @@ static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 fi break; } + /* + * NB. For DELETE_ACCESS we should really check the + * directory permissions, as that is what controls + * delete, and for WRITE_DAC_ACCESS we should really + * check the ownership, as that is what controls the + * chmod. Note that this is *NOT* a security hole (this + * note is for you, Andrew) as we are not *allowing* + * the access at this point, the actual unlink or + * chown or chmod call would do this. We are just helping + * clients out by telling them if they have a hope + * of any of this succeeding. POSIX acls may still + * deny the real call. JRA. + */ + if (smb_open_mode == -1) { - if(desired_access & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES| - WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS)) - smb_open_mode = 2; - else if(desired_access & (FILE_EXECUTE|FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS)) + if(desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS| + FILE_EXECUTE|FILE_READ_ATTRIBUTES| + FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) smb_open_mode = 0; else { - DEBUG(0,("map_share_mode: Incorrect value for desired_access = %x\n", - desired_access)); + DEBUG(0,("map_share_mode: Incorrect value %lx for desired_access to file %s\n", + (unsigned long)desired_access, fname)); return -1; } } @@ -391,6 +416,10 @@ static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 fi if(file_attributes & FILE_FLAG_WRITE_THROUGH) smb_open_mode |= (1<<14); + DEBUG(10,("map_share_mode: Mapped desired access %lx, share access %lx, file attributes %lx \ +to open_mode %x\n", (unsigned long)desired_access, (unsigned long)share_access, + (unsigned long)file_attributes, smb_open_mode )); + return smb_open_mode; } @@ -470,17 +499,6 @@ int reply_ntcreate_and_X(connection_struct *conn, if((smb_ofun = map_create_disposition( create_disposition )) == -1) return(ERROR(ERRDOS,ERRbadaccess)); - /* - * Now contruct the smb_open_mode value from the desired access - * and the share access. - */ - - if((smb_open_mode = map_share_mode(desired_access, - share_access, - file_attributes)) == -1) { - return(ERROR(ERRDOS,ERRbadaccess)); - } - /* * Get the file name. */ @@ -565,6 +583,17 @@ int reply_ntcreate_and_X(connection_struct *conn, return chain_reply(inbuf,outbuf,length,bufsize); } + /* + * Now contruct the smb_open_mode value from the filename, + * desired access and the share access. + */ + + if((smb_open_mode = map_share_mode(fname, desired_access, + share_access, + file_attributes)) == -1) { + return(ERROR(ERRDOS,ERRbadaccess)); + } + /* * Ordinary file or directory. */ @@ -799,15 +828,6 @@ static int call_nt_transact_create(connection_struct *conn, if((smb_ofun = map_create_disposition( create_disposition )) == -1) return(ERROR(ERRDOS,ERRbadaccess)); - /* - * Now contruct the smb_open_mode value from the desired access - * and the share access. - */ - - if((smb_open_mode = map_share_mode( desired_access, share_access, file_attributes)) == -1) - return(ERROR(ERRDOS,ERRbadaccess)); - - /* * Get the file name. */ @@ -888,6 +908,14 @@ static int call_nt_transact_create(connection_struct *conn, oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; + /* + * Now contruct the smb_open_mode value from the desired access + * and the share access. + */ + + if((smb_open_mode = map_share_mode( fname, desired_access, share_access, file_attributes)) == -1) + return(ERROR(ERRDOS,ERRbadaccess)); + /* * If it's a request for a directory open, deal with it separately. */ diff --git a/source/smbd/open.c b/source/smbd/open.c index 311c494a97c..a6e29532636 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -696,6 +696,7 @@ static int check_share_mode( share_mode_entry *share, int deny_mode, /**************************************************************************** open a file with a share mode ****************************************************************************/ + 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) { @@ -714,6 +715,9 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int fsp->open = False; fsp->fd_ptr = 0; + DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n", + fname, share_mode, ofun, mode, oplock_request )); + /* this is for OS/2 EAs - try and say we don't support them */ if (strstr(fname,".+,;=[].")) { @@ -725,11 +729,14 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int unix_ERR_code = ERROR_EAS_NOT_SUPPORTED; #endif /* OS2_WPS_FIX */ + DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n")); return; } if ((ofun & 0x3) == 0 && file_existed) { + DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n", + fname )); errno = EEXIST; return; } @@ -770,6 +777,8 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int { if (!fcbopen) { + DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n", + fname, !CAN_WRITE(conn) ? "share" : "file" )); errno = EACCES; return; } @@ -978,7 +987,7 @@ int open_directory(files_struct *fsp,connection_struct *conn, * Create the directory. */ - if(dos_mkdir(fname, unixmode) < 0) { + if(dos_mkdir(fname, unix_mode(conn,aDIR)) < 0) { DEBUG(0,("open_directory: unable to create %s. Error was %s\n", fname, strerror(errno) )); return -1; diff --git a/source/smbd/server.c b/source/smbd/server.c index 744320887bf..4151bbe12a7 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -642,7 +642,7 @@ static void usage(char *pname) codepage_initialise(lp_client_code_page()); - pstrcpy(global_myworkgroup, lp_workgroup()); + fstrcpy(global_myworkgroup, lp_workgroup()); if(!pdb_generate_sam_sid()) { DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n")); -- cgit v1.2.1