1
0
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:
Jeremy Allison 2003-01-08 02:09:14 +00:00
parent 173856a77d
commit f420f75508
2 changed files with 45 additions and 8 deletions

View File

@ -1114,4 +1114,3 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
return True;
}

View File

@ -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++;