diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/nttrans.c | 92 | ||||
-rw-r--r-- | source3/smbd/open.c | 11 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 |
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")); |