summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/smb.h18
-rw-r--r--source3/lib/time.c8
-rw-r--r--source3/smbd/nttrans.c104
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];