mirror of
https://github.com/samba-team/samba.git
synced 2025-01-17 02:05:21 +03:00
Fix open problem with changing attributes on an existing file - based
on work by <steve@griffin.sio2.nl>. Jeremy. (This used to be commit 465d86d95fbdeda423d1f4b06cee46c119a31447)
This commit is contained in:
parent
173856a77d
commit
f420f75508
@ -1114,4 +1114,3 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -698,7 +698,8 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
|
||||
}
|
||||
|
||||
|
||||
static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode, mode_t new_mode)
|
||||
static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
|
||||
mode_t new_mode, mode_t *returned_mode)
|
||||
{
|
||||
uint32 old_dos_mode, new_dos_mode;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
@ -711,22 +712,33 @@ static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t ex
|
||||
sbuf.st_mode = new_mode;
|
||||
new_dos_mode = dos_mode(conn, path, &sbuf);
|
||||
|
||||
/*
|
||||
* We only set returned mode to be the same as new_mode if
|
||||
* the file attributes need to be changed.
|
||||
*/
|
||||
|
||||
*returned_mode = (mode_t)0;
|
||||
|
||||
/* If we're mapping SYSTEM and HIDDEN ensure they match. */
|
||||
if (lp_map_system(SNUM(conn))) {
|
||||
if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
|
||||
return False;
|
||||
if (!(old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && (new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
|
||||
*returned_mode = new_mode;
|
||||
}
|
||||
if (lp_map_hidden(SNUM(conn))) {
|
||||
if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
|
||||
return False;
|
||||
if (!(old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && (new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
|
||||
*returned_mode = new_mode;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Open a file with a share mode. On output from this open we are guarenteeing
|
||||
that
|
||||
Open a file with a share mode.
|
||||
****************************************************************************/
|
||||
|
||||
files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
|
||||
int share_mode,int ofun, mode_t mode,int oplock_request,
|
||||
int *Access,int *action)
|
||||
@ -736,9 +748,9 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Open a file with a share mode. On output from this open we are guarenteeing
|
||||
that
|
||||
Open a file with a share mode.
|
||||
****************************************************************************/
|
||||
|
||||
files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
|
||||
uint32 desired_access,
|
||||
int share_mode,int ofun, mode_t mode,int oplock_request,
|
||||
@ -760,6 +772,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
|
||||
files_struct *fsp = NULL;
|
||||
int open_mode=0;
|
||||
uint16 port = 0;
|
||||
mode_t new_mode = (mode_t)0;
|
||||
|
||||
if (conn->printer) {
|
||||
/* printers are handled completely differently. Most of the passed parameters are
|
||||
@ -819,7 +832,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
|
||||
|
||||
/* We only care about matching attributes on file exists and truncate. */
|
||||
if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
|
||||
if (!open_match_attributes(conn, fname, psbuf->st_mode, mode)) {
|
||||
if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
|
||||
DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
|
||||
fname, psbuf->st_mode, mode ));
|
||||
file_free(fsp);
|
||||
@ -1089,11 +1102,36 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
|
||||
*/
|
||||
|
||||
if (!file_existed && !def_acl && (conn->vfs_ops.fchmod_acl != NULL)) {
|
||||
|
||||
int saved_errno = errno; /* We might get ENOSYS in the next call.. */
|
||||
|
||||
if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
|
||||
errno = saved_errno; /* Ignore ENOSYS */
|
||||
|
||||
} else if (new_mode) {
|
||||
|
||||
int ret = -1;
|
||||
|
||||
/* Attributes need changing. File already existed. */
|
||||
|
||||
if (conn->vfs_ops.fchmod_acl != NULL) {
|
||||
int saved_errno = errno; /* We might get ENOSYS in the next call.. */
|
||||
ret = conn->vfs_ops.fchmod_acl(fsp, fsp->fd, new_mode);
|
||||
|
||||
if (ret == -1 && errno == ENOSYS) {
|
||||
errno = saved_errno; /* Ignore ENOSYS */
|
||||
} else {
|
||||
DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
|
||||
fname, (int)new_mode));
|
||||
ret = 0; /* Don't do the fchmod below. */
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret == -1) && (conn->vfs_ops.fchmod(fsp, fsp->fd, new_mode) == -1))
|
||||
DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
|
||||
fname, (int)new_mode));
|
||||
}
|
||||
|
||||
|
||||
unlock_share_entry_fsp(fsp);
|
||||
|
||||
conn->num_files_open++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user