summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/nttrans.c92
-rw-r--r--source3/smbd/open.c11
-rw-r--r--source3/smbd/server.c2
3 files changed, 71 insertions, 34 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index d30b59f0d3..62ca9fe1c8 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/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;
}
@@ -471,17 +500,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
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.
*/
@@ -566,6 +584,17 @@ int reply_ntcreate_and_X(connection_struct *conn,
}
/*
+ * 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.
*/
@@ -800,15 +829,6 @@ static int call_nt_transact_create(connection_struct *conn,
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.
*/
@@ -889,6 +909,14 @@ static int call_nt_transact_create(connection_struct *conn,
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/source3/smbd/open.c b/source3/smbd/open.c
index 311c494a97..a6e2953263 100644
--- a/source3/smbd/open.c
+++ b/source3/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/source3/smbd/server.c b/source3/smbd/server.c
index 744320887b..4151bbe12a 100644
--- a/source3/smbd/server.c
+++ b/source3/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"));