diff --git a/server/fd.c b/server/fd.c index 524cc7a5072..e7f57966b26 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2430,6 +2430,16 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, goto failed; } + if (is_file_executable( fd->unix_name ) != is_file_executable( name ) && !fstat( fd->unix_fd, &st )) + { + if (is_file_executable( fd->unix_name )) + /* set executable bit where read bit is set */ + st.st_mode |= (st.st_mode & 0444) >> 2; + else + st.st_mode &= ~0111; + fchmod( fd->unix_fd, st.st_mode ); + } + free( fd->unix_name ); fd->unix_name = name; fd->closed->unix_name = name; diff --git a/server/file.c b/server/file.c index 71b84486b0f..bce202138e0 100644 --- a/server/file.c +++ b/server/file.c @@ -191,6 +191,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ return &file->obj; } +int is_file_executable( const char *name ) +{ + int len = strlen( name ); + return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" )); +} + static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len, unsigned int access, unsigned int sharing, int create, unsigned int options, unsigned int attrs, @@ -236,8 +242,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si else mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666; - if (len >= 4 && - (!strcasecmp( name + len - 4, ".exe" ) || !strcasecmp( name + len - 4, ".com" ))) + if (is_file_executable( name )) { if (mode & S_IRUSR) mode |= S_IXUSR; diff --git a/server/file.h b/server/file.h index 4341ad3b040..0df4c177162 100644 --- a/server/file.h +++ b/server/file.h @@ -149,6 +149,7 @@ extern void file_set_error(void); extern struct object_type *file_get_type( struct object *obj ); extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ); +extern int is_file_executable( const char *name ); /* file mapping functions */