diff options
-rw-r--r-- | source3/include/smb.h | 18 | ||||
-rw-r--r-- | source3/lib/time.c | 8 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 104 |
3 files changed, 109 insertions, 21 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index 821bf12d94..734dddff14 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1049,8 +1049,18 @@ struct parm_struct /* these are the constants used in the above call. */ /* DesiredAccess */ -#if 0 -/* TODO.... JRA */ +/* File Specific access rights. */ +#define FILE_READ_DATA 0x001 +#define FILE_WRITE_DATA 0x002 +#define FILE_APPEND_DATA 0x004 +#define FILE_READ_EA 0x008 +#define FILE_WRITE_EA 0x010 +#define FILE_EXECUTE 0x020 +#define FILE_DELETE_CHILD 0x040 +#define FILE_READ_ATTRIBUTES 0x080 +#define FILE_WRITE_ATTRIBUTES 0x100 + +/* Generic access masks & rights. */ #define SPECIFIC_RIGHTS_MASK 0x00FFFFL #define STANDARD_RIGHTS_MASK 0xFF0000L #define DELETE_ACCESS (1L<<16) @@ -1060,10 +1070,6 @@ struct parm_struct #define SYNCHRONIZE_ACCESS (1L<<20) #define SYSTEM_SECURITY_ACCESS (1L<<24) -#define GENERIC_READ xxx? -#define GENERIC_WRITE xxx? -#endif - /* Flags field. */ #define REQUEST_OPLOCK 2 #define REQUEST_BATCH_OPLOCK 4 diff --git a/source3/lib/time.c b/source3/lib/time.c index 1b2347a45b..c73d219120 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -253,9 +253,13 @@ time_t interpret_long_date(char *p) double d; time_t ret; uint32 tlow,thigh; + /* The next two lines are a fix needed for the + broken SCO compiler. JRA. */ + time_t l_time_min = TIME_T_MIN; + time_t l_time_max = TIME_T_MAX; + tlow = IVAL(p,0); thigh = IVAL(p,4); - if (thigh == 0) return(0); d = ((double)thigh)*4.0*(double)(1<<30); @@ -265,7 +269,7 @@ time_t interpret_long_date(char *p) /* now adjust by 369 years to make the secs since 1970 */ d -= TIME_FIXUP_CONSTANT; - if (!(TIME_T_MIN <= d && d <= TIME_T_MAX)) + if (!(l_time_min <= d && d <= l_time_max)) return(0); ret = (time_t)(d+0.5); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 81aa578daf..9d6f0d4021 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -55,19 +55,20 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize) pstring fname; int cnum = SVAL(inbuf,smb_tid); int fnum = -1; - int smb_mode = SVAL(inbuf,smb_vwv3); + uint32 flags = SIVAL(inbuf,smb_ntcreate_Flags); + uint32 desired_access = SIVAL(inbuf,smb_ntcreate_DesiredAccess); + uint32 file_attributes = SIVAL(inbuf,smb_ntcreate_FileAttributes); + uint32 share_access = SIVAL(inbuf,smb_ntcreate_ShareAccess); + uint32 create_disposition = SIVAL(inbuf,smb_ntcreate_CreateDisposition); + + int smb_ofun; + int smb_open_mode; int smb_attr = SVAL(inbuf,smb_vwv5); /* Breakout the oplock request bits so we can set the reply bits separately. */ - BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf); + BOOL ex_oplock_request = flags & BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf); BOOL oplock_request = ex_oplock_request | core_oplock_request; -#if 0 - int open_flags = SVAL(inbuf,smb_vwv2); - int smb_sattr = SVAL(inbuf,smb_vwv4); - uint32 smb_time = make_unix_date3(inbuf+smb_vwv6); -#endif - int smb_ofun = SVAL(inbuf,smb_vwv8); int unixmode; int size=0,fmode=0,mtime=0,rmode=0; struct stat sbuf; @@ -77,10 +78,87 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(cnum)) - return reply_open_pipe_and_X(inbuf,outbuf,length,bufsize); - - /* XXXX we need to handle passed times, sattr and flags */ - + return nt_open_pipe_and_X(inbuf,outbuf,length,bufsize); + + /* If it's a request for a directory open, fail it. */ + if(flags & OPEN_DIRECTORY) + return(ERROR(ERRSRV,ERRfilespecs)); + + /* + * We need to construct the open_and_X ofun value from the + * NT values, as that's what our code is structured to accept. + */ + + switch( create_disposition ) { + case CREATE_NEW: + /* create if not exist, fail if exist */ + smb_ofun = 0x10; + break; + case CREATE_ALWAYS: + /* create if not exist, trunc if exist */ + smb_ofun = 0x12; + break; + case OPEN_EXISTING: + /* fail if not exist, open if exists */ + smb_ofun = 0x1; + break; + case OPEN_ALWAYS: + /* create if not exist, open if exists */ + smb_ofun = 0x11; + break; + case TRUNCATE_EXISTING: + /* fail if not exist, truncate if exists */ + smb_ofun = 0x2; + break; + default: + DEBUG(0,("reply_ntcreate_and_X: Incorrect value for create_disposition = %d\n", + create_disposition )); + return(ERROR(ERRDOS,ERRbadaccess)); + } + + /* + * Now contruct the smb_open_mode value from the desired access + * and the share access. + */ + + switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA) ) { + case FILE_READ_DATA: + smb_open_mode = 0; + break; + case FILE_WRITE_DATA: + smb_open_mode = 1; + break; + case FILE_READ_DATA|FILE_WRITE_DATA: + smb_open_mode = 2; + break; + default: + DEBUG(0,("reply_ntcreate_and_X: Incorrect value for desired_access = %x\n", + desired_access)); + return(ERROR(ERRDOS,ERRbadaccess)); + } + + /* Add in the requested share mode - ignore FILE_SHARE_DELETE for now. */ + switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) { + case FILE_SHARE_READ: + smb_open_mode |= (DENY_WRITE<<4); + break; + case FILE_SHARE_WRITE: + smb_open_mode |= (DENY_READ<<4); + break; + case (FILE_SHARE_READ|FILE_SHARE_WRITE): + smb_open_mode |= (DENY_NONE<<4); + break; + case FILE_SHARE_NONE: + smb_open_mode |= (DENY_ALL<<4); + break; + } + + /* + * Handle a O_SYNC request. + */ + if(file_attributes & FILE_FLAG_WRITE_THROUGH) + smb_open_mode |= (1<<14); + pstrcpy(fname,smb_buf(inbuf)); unix_convert(fname,cnum,0,&bad_path); @@ -100,7 +178,7 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize) unixmode = unix_mode(cnum,smb_attr | aARCH); - open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, + open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode, oplock_request, &rmode,&smb_action); fsp = &Files[fnum]; |