From 87ea4b93ecde16a4156c9c307ad477537a837ef4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Oct 1997 02:59:22 +0000 Subject: damn. We need root privilages to do semaphore operations even if we have done the semget() as root. The problem is that become_root() and unbecome_root() are so slow! I've provided two options. The default is to set the semaphores (but _not_ the shared memory) world writeable so that a become_root() isn't needed. Otherwise you can define SECURE_SEMAPHORES and pay the performance penalty. (This used to be commit 2bbd8d2cbc5cf1901859a181bc9ec29822995e51) --- source3/locking/shmem_sysv.c | 71 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 28 deletions(-) (limited to 'source3/locking/shmem_sysv.c') diff --git a/source3/locking/shmem_sysv.c b/source3/locking/shmem_sysv.c index e3f40418d9..8832902820 100644 --- a/source3/locking/shmem_sysv.c +++ b/source3/locking/shmem_sysv.c @@ -39,6 +39,14 @@ extern int DEBUGLEVEL; #define IPC_PERMS 0644 #endif +#ifdef SECURE_SEMAPHORES +/* secure semaphores are slow because we have to do a become_root() + on every call! */ +#define SEMAPHORE_PERMS IPC_PERMS +#else +#define SEMAPHORE_PERMS 0666 +#endif + #ifdef SEMMSL #define SHMEM_HASH_SIZE (SEMMSL-1) #else @@ -92,45 +100,49 @@ static BOOL shm_initialize_called = False; static int read_only; -static BOOL sem_lock(int i) +static BOOL sem_change(int i, int op) { +#ifdef SECURE_SEMAPHORES + extern struct current_user current_user; + int became_root=0; +#endif struct sembuf sb; + int ret; + if (read_only) return True; - - sb.sem_num = i; - sb.sem_op = -1; - sb.sem_flg = SEM_UNDO; - if (semop(sem_id, &sb, 1) != 0) { - DEBUG(0,("ERROR: IPC lock failed on semaphore %d\n", i)); - return False; +#ifdef SECURE_SEMAPHORES + if (current_user.uid != 0) { + become_root(0); + became_root = 1; } - - return True; -} - -static BOOL sem_unlock(int i) -{ - struct sembuf sb; - if (read_only) return True; +#endif sb.sem_num = i; - sb.sem_op = 1; + sb.sem_op = op; sb.sem_flg = SEM_UNDO; - if (semop(sem_id, &sb, 1) != 0) { - DEBUG(0,("ERROR: IPC unlock failed on semaphore %d\n", i)); - return False; + ret = semop(sem_id, &sb, 1); + + if (ret != 0) { + DEBUG(0,("ERROR: sem_change(%d,%d) failed (%s)\n", + i, op, strerror(errno))); } - return True; +#ifdef SECURE_SEMAPHORES + if (became_root) { + unbecome_root(0); + } +#endif + + return ret == 0; } static BOOL global_lock(void) { global_lock_count++; if (global_lock_count == 1) - return sem_lock(0); + return sem_change(0, -1); return True; } @@ -138,7 +150,7 @@ static BOOL global_unlock(void) { global_lock_count--; if (global_lock_count == 0) - return sem_unlock(0); + return sem_change(0, 1); return True; } @@ -461,8 +473,7 @@ static int shm_get_userdef_off(void) ******************************************************************/ static BOOL shm_lock_hash_entry(unsigned int entry) { - DEBUG(0,("hash lock %d\n", entry)); - return sem_lock(entry+1); + return sem_change(entry+1, -1); } /******************************************************************* @@ -470,8 +481,7 @@ static BOOL shm_lock_hash_entry(unsigned int entry) ******************************************************************/ static BOOL shm_unlock_hash_entry(unsigned int entry) { - DEBUG(0,("hash unlock %d\n", entry)); - return sem_unlock(entry+1); + return sem_change(entry+1, 1); } @@ -545,7 +555,7 @@ struct shmem_ops *sysv_shm_open(int ronly) while (hash_size > 1) { sem_id = semget(SEMAPHORE_KEY, hash_size+1, - IPC_CREAT | IPC_EXCL | IPC_PERMS); + IPC_CREAT|IPC_EXCL| SEMAPHORE_PERMS); if (sem_id != -1 || errno != EINVAL) break; hash_size--; } @@ -584,6 +594,11 @@ struct shmem_ops *sysv_shm_open(int ronly) DEBUG(0,("ERROR: root did not create the semaphore\n")); return NULL; } + + sem_ds.sem_perm.mode = SEMAPHORE_PERMS; + if (semctl(sem_id, 0, IPC_SET, su) != 0) { + DEBUG(0,("ERROR shm_open : can't IPC_SET\n")); + } } -- cgit