// open (or create if missing) and set appropriate access rights int openCreateSharedFile(const char* pathname, int flags) { int fd = os_utils::open(pathname, flags | O_RDWR | O_CREAT, S_IREAD | S_IWRITE); if (fd < 0) raiseError(fd, pathname); // Security check - avoid symbolic links in /tmp. // Malicious user can create a symlink with this name pointing to say // security2.fdb and when the lock file is created the file will be damaged. struct stat st; int rc; do { rc = fstat(fd, &st); } while (fd != 0 && SYSCALL_INTERRUPTED(errno)); if (rc != 0) { int e = errno; close(fd); raiseError(e, pathname); } if (S_ISLNK(st.st_mode)) { close(fd); raiseError(ELOOP, pathname); } changeFileRights(pathname, 0660); return fd; }
// create directory for lock files and set appropriate access rights void createLockDirectory(const char* pathname) { do { if (access(pathname, R_OK | W_OK | X_OK) == 0) { struct STAT st; if (os_utils::stat(pathname, &st) != 0) system_call_failed::raise("stat"); if (S_ISDIR(st.st_mode)) return; // not exactly original meaning, but very close to it system_call_failed::raise("access", ENOTDIR); } } while (SYSCALL_INTERRUPTED(errno)); while (mkdir(pathname, 0700) != 0) // anyway need chmod to avoid umask effects { if (SYSCALL_INTERRUPTED(errno)) { continue; } (Arg::Gds(isc_lock_dir_access) << pathname).raise(); } changeFileRights(pathname, 0770); }