diff options
-rw-r--r-- | source3/include/proto.h | 8 | ||||
-rw-r--r-- | source3/locking/locking.c | 6 | ||||
-rw-r--r-- | source3/locking/locking_shm.c | 11 | ||||
-rw-r--r-- | source3/locking/locking_slow.c | 39 | ||||
-rw-r--r-- | source3/locking/shmem.c | 55 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 | ||||
-rw-r--r-- | source3/utils/status.c | 2 |
7 files changed, 76 insertions, 47 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index f0c855c689..cdecd1ec88 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -351,7 +351,7 @@ int lp_minor_announce_version(void); BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset); BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode); BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode); -BOOL locking_init(void); +BOOL locking_init(int read_only); BOOL locking_end(void); BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok); BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token); @@ -365,11 +365,11 @@ void share_status(FILE *f); /*The following definitions come from locking_shm.c */ -struct share_ops *locking_shm_init(void); +struct share_ops *locking_shm_init(int ronly); /*The following definitions come from locking_slow.c */ -struct share_ops *locking_slow_init(void); +struct share_ops *locking_slow_init(int ronly); /*The following definitions come from lsaparse.c */ @@ -869,7 +869,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize); /*The following definitions come from shmem.c */ -BOOL smb_shm_open(char *file_name, int size); +BOOL smb_shm_open(char *file_name, int size, int ronly); BOOL smb_shm_close( void ); int smb_shm_alloc(int size); BOOL smb_shm_free(int offset); diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c75497c6b9..ae977b0f69 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -111,17 +111,17 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * /**************************************************************************** initialise the locking functions ****************************************************************************/ -BOOL locking_init(void) +BOOL locking_init(int read_only) { #ifdef FAST_SHARE_MODES - share_ops = locking_shm_init(); + share_ops = locking_shm_init(read_only); if (!share_ops) { DEBUG(0,("ERROR: Failed to initialise fast share modes - trying slow code\n")); } if (share_ops) return True; #endif - share_ops = locking_slow_init(); + share_ops = locking_slow_init(read_only); if (!share_ops) { DEBUG(0,("ERROR: Failed to initialise share modes!\n")); return False; diff --git a/source3/locking/locking_shm.c b/source3/locking/locking_shm.c index 8383b687e4..410fcb9760 100644 --- a/source3/locking/locking_shm.c +++ b/source3/locking/locking_shm.c @@ -58,6 +58,7 @@ typedef struct share_mode_entry e; } shm_share_mode_entry; +static int read_only; /******************************************************************* deinitialize the shared memory for share_mode management @@ -715,17 +716,21 @@ static struct share_ops share_ops = { /******************************************************************* initialize the shared memory for share_mode management ******************************************************************/ -struct share_ops *locking_shm_init(void) +struct share_ops *locking_shm_init(int ronly) { pstring shmem_file_name; + + read_only = ronly; pstrcpy(shmem_file_name,lp_lockdir()); - if (!directory_exist(shmem_file_name,NULL)) + if (!directory_exist(shmem_file_name,NULL)) { + if (read_only) return NULL; mkdir(shmem_file_name,0755); + } trim_string(shmem_file_name,"","/"); if (!*shmem_file_name) return(False); strcat(shmem_file_name, "/SHARE_MEM_FILE"); - if (smb_shm_open(shmem_file_name, lp_shmem_size())) + if (smb_shm_open(shmem_file_name, lp_shmem_size(), read_only)) return &share_ops; return NULL; } diff --git a/source3/locking/locking_slow.c b/source3/locking/locking_slow.c index cc646c6ca6..9bd6d65aa7 100644 --- a/source3/locking/locking_slow.c +++ b/source3/locking/locking_slow.c @@ -58,6 +58,14 @@ extern files_struct Files[]; #define SME_PORT_OFFSET 16 #define SME_OPLOCK_TYPE_OFFSET 18 +/* we need world read for smbstatus to function correctly */ +#ifdef SECURE_SHARE_MODES +#define SHARE_FILE_MODE 0600 +#else +#define SHARE_FILE_MODE 0644 +#endif + +static int read_only; /******************************************************************* deinitialize share_mode management @@ -87,6 +95,8 @@ Force a share file to be deleted. ********************************************************************/ static int delete_share_file( int cnum, char *fname ) { + if (read_only) return -1; + /* the share file could be owned by anyone, so do this as root */ become_root(False); @@ -120,14 +130,13 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) if(!share_name(cnum, dev, inode, fname)) return False; + if (read_only) return True; + /* we need to do this as root */ become_root(False); { - int old_umask; BOOL gotlock = False; - old_umask = umask(0); - /* * There was a race condition in the original slow share mode code. * A smbd could open a share mode file, and before getting @@ -147,11 +156,8 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) { struct stat dummy_stat; -#ifdef SECURE_SHARE_MODES - fd = (int)open(fname,O_RDWR|O_CREAT,0600); -#else /* SECURE_SHARE_MODES */ - fd = (int)open(fname,O_RDWR|O_CREAT,0666); -#endif /* SECURE_SHARE_MODES */ + fd = (int)open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT), + SHARE_FILE_MODE); if(fd < 0) { @@ -192,8 +198,6 @@ static BOOL slow_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) * as we don't want to return and leave ourselves running * as root ! */ - - umask(old_umask); } *ptok = (int)fd; @@ -214,6 +218,8 @@ static BOOL slow_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int toke struct stat sb; pstring fname; + if (read_only) return True; + /* Fix for zero length share files from Gerald Werner <wernerg@mfldclin.edu> */ @@ -959,13 +965,14 @@ static int slow_share_forall(void (*fn)(share_mode_entry *, char *)) strcat(lname,"/"); strcat(lname,s); - fd = open(lname,O_RDWR,0); + fd = open(lname,read_only?O_RDONLY:O_RDWR,0); if (fd < 0) { continue; } /* Lock the share mode file while we read it. */ - if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) { + if(!read_only && + fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) { close(fd); continue; } @@ -1027,10 +1034,14 @@ static struct share_ops share_ops = { /******************************************************************* initialize the slow share_mode management ******************************************************************/ -struct share_ops *locking_slow_init(void) +struct share_ops *locking_slow_init(int ronly) { + + read_only = ronly; + if (!directory_exist(lp_lockdir(),NULL)) { - mkdir(lp_lockdir(),0755); + if (!read_only) + mkdir(lp_lockdir(),0755); if (!directory_exist(lp_lockdir(),NULL)) return NULL; } diff --git a/source3/locking/shmem.c b/source3/locking/shmem.c index 9daca3e482..1f9cb8b732 100644 --- a/source3/locking/shmem.c +++ b/source3/locking/shmem.c @@ -34,6 +34,13 @@ extern int DEBUGLEVEL; #define SMB_SHM_VERSION 2 +/* we need world read for smbstatus to function correctly */ +#ifdef SECURE_SHARE_MODES +#define SHM_FILE_MODE 0600 +#else +#define SHM_FILE_MODE 0644 +#endif + /* WARNING : offsets are used because mmap() does not guarantee that all processes have the shared memory mapped to the same address */ @@ -75,6 +82,8 @@ static int smb_shm_times_locked = 0; static BOOL smb_shm_initialize_called = False; +static int read_only; + static BOOL smb_shm_global_lock(void) { if (smb_shm_fd < 0) @@ -90,6 +99,9 @@ static BOOL smb_shm_global_lock(void) DEBUG(5,("smb_shm_global_lock : locked %d times\n",smb_shm_times_locked)); return True; } + + if (read_only) + return True; /* Do an exclusive wait lock on the first byte of the file */ if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_WRLCK) == False) @@ -124,6 +136,9 @@ static BOOL smb_shm_global_unlock(void) DEBUG(5,("smb_shm_global_unlock : still locked %d times\n",smb_shm_times_locked)); return True; } + + if (read_only) + return True; /* Do a wait unlock on the first byte of the file */ if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_UNLCK) == False) @@ -170,11 +185,10 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth int free_slot = -1; int erased_slot; -#ifndef SECURE_SHARE_MODES - smb_shm_processes_fd = open(processreg_file, O_RDWR | O_CREAT, 0666); -#else /* SECURE_SHARE_MODES */ - smb_shm_processes_fd = open(processreg_file, O_RDWR | O_CREAT, 0600); -#endif /* SECURE_SHARE_MODES */ + smb_shm_processes_fd = open(processreg_file, + read_only?O_RDONLY:(O_RDWR|O_CREAT), + SHM_FILE_MODE); + if ( smb_shm_processes_fd < 0 ) { DEBUG(0,("ERROR smb_shm_register_process : processreg_file open failed with code %s\n",strerror(errno))); @@ -231,7 +245,6 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid) { - int old_umask; int smb_shm_processes_fd = -1; int nb_read; pid_t other_pid; @@ -240,9 +253,7 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid) BOOL found = False; - old_umask = umask(0); smb_shm_processes_fd = open(processreg_file, O_RDWR); - umask(old_umask); if ( smb_shm_processes_fd < 0 ) { DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file open failed with code %s\n",strerror(errno))); @@ -380,22 +391,19 @@ static void smb_shm_solve_neighbors(struct SmbShmBlockDesc *head_p ) -BOOL smb_shm_open(char *file_name, int size) +BOOL smb_shm_open(char *file_name, int size, int ronly) { int filesize; BOOL created_new = False; BOOL other_processes = True; - int old_umask; + + read_only = ronly; DEBUG(5,("smb_shm_open : using shmem file %s to be of size %d\n",file_name,size)); - old_umask = umask(0); -#ifndef SECURE_SHARE_MODES - smb_shm_fd = open(file_name, O_RDWR | O_CREAT, 0666); -#else /* SECURE_SHARE_MODES */ - smb_shm_fd = open(file_name, O_RDWR | O_CREAT, 0600); -#endif /* SECURE_SHARE_MODE */ - umask(old_umask); + smb_shm_fd = open(file_name, read_only?O_RDONLY:(O_RDWR|O_CREAT), + SHM_FILE_MODE); + if ( smb_shm_fd < 0 ) { DEBUG(0,("ERROR smb_shm_open : open failed with code %s\n",strerror(errno))); @@ -433,14 +441,15 @@ BOOL smb_shm_open(char *file_name, int size) strcpy(smb_shm_processreg_name, file_name); strcat(smb_shm_processreg_name, ".processes"); - if (! smb_shm_register_process(smb_shm_processreg_name, getpid(), &other_processes)) + if (!read_only && + !smb_shm_register_process(smb_shm_processreg_name, getpid(), &other_processes)) { smb_shm_global_unlock(); close(smb_shm_fd); return False; } - if (created_new || !other_processes) + if (!read_only && (created_new || !other_processes)) { /* we just created a new one, or are the first opener, lets set it size */ if( ftruncate(smb_shm_fd, size) <0) @@ -466,7 +475,11 @@ BOOL smb_shm_open(char *file_name, int size) size = filesize; } - smb_shm_header_p = (struct SmbShmHeader *)mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, smb_shm_fd, 0); + smb_shm_header_p = (struct SmbShmHeader *)mmap(NULL, size, + read_only?PROT_READ: + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + smb_shm_fd, 0); /* WARNING, smb_shm_header_p can be different for different processes mapping the same file ! */ if (smb_shm_header_p == (struct SmbShmHeader *)(-1)) { @@ -478,7 +491,7 @@ BOOL smb_shm_open(char *file_name, int size) } - if (created_new || !other_processes) + if (!read_only && (created_new || !other_processes)) { smb_shm_initialize(size); /* Create the hash buckets for the share file entries. */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 88f7497ee5..93042e119b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -5145,7 +5145,7 @@ static void usage(char *pname) if (!open_sockets(is_daemon,port)) exit(1); - if (!locking_init()) + if (!locking_init(0)) exit(1); /* possibly reload the services file. */ diff --git a/source3/utils/status.c b/source3/utils/status.c index 3e349f920a..f124d79939 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -262,7 +262,7 @@ static void print_share_mode(share_mode_entry *e, char *fname) printf("\n"); - locking_init(); + locking_init(1); if (share_mode_forall(print_share_mode) <= 0) printf("No locked files\n"); |