"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib/file-create-locked.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

file-create-locked.c  (dovecot-2.3.16):file-create-locked.c  (dovecot-2.3.17)
skipping to change at line 25 skipping to change at line 25
creation to work even while the directory is simultaneously being creation to work even while the directory is simultaneously being
rmdir()ed. */ rmdir()ed. */
#define MAX_MKDIR_COUNT 10 #define MAX_MKDIR_COUNT 10
#define MAX_RETRY_COUNT 1000 #define MAX_RETRY_COUNT 1000
static int static int
try_lock_existing(int fd, const char *path, try_lock_existing(int fd, const char *path,
const struct file_create_settings *set, const struct file_create_settings *set,
struct file_lock **lock_r, const char **error_r) struct file_lock **lock_r, const char **error_r)
{ {
struct file_lock_settings lock_set = set->lock_settings;
struct stat st1, st2; struct stat st1, st2;
int ret; int ret;
lock_set.unlink_on_free = FALSE;
lock_set.close_on_free = FALSE;
if (fstat(fd, &st1) < 0) { if (fstat(fd, &st1) < 0) {
*error_r = t_strdup_printf("fstat(%s) failed: %m", path); *error_r = t_strdup_printf("fstat(%s) failed: %m", path);
return -1; return -1;
} }
if (file_wait_lock_error(fd, path, F_WRLCK, set->lock_method, if (file_wait_lock(fd, path, F_WRLCK, &lock_set, set->lock_timeout_secs,
set->lock_timeout_secs, lock_r, error_r) <= 0) lock_r, error_r) <= 0)
return -1; return -1;
if (stat(path, &st2) == 0) { if (stat(path, &st2) == 0) {
ret = st1.st_ino == st2.st_ino && ret = st1.st_ino == st2.st_ino &&
CMP_DEV_T(st1.st_dev, st2.st_dev) ? 1 : 0; CMP_DEV_T(st1.st_dev, st2.st_dev) ? 1 : 0;
} else if (errno == ENOENT) { } else if (errno == ENOENT) {
ret = 0; ret = 0;
} else { } else {
*error_r = t_strdup_printf("stat(%s) failed: %m", path); *error_r = t_strdup_printf("stat(%s) failed: %m", path);
ret = -1; ret = -1;
} }
if (ret <= 0) { if (ret <= 0) {
/* the fd is closed next - no need to unlock */ /* the fd is closed next - no need to unlock */
file_lock_free(lock_r); file_lock_free(lock_r);
} else {
file_lock_set_unlink_on_free(
*lock_r, set->lock_settings.unlink_on_free);
file_lock_set_close_on_free(
*lock_r, set->lock_settings.close_on_free);
} }
return ret; return ret;
} }
static int static int
try_mkdir(const char *path, const struct file_create_settings *set, try_mkdir(const char *path, const struct file_create_settings *set,
const char **error_r) const char **error_r)
{ {
uid_t uid = set->mkdir_uid != 0 ? set->mkdir_uid : (uid_t)-1; uid_t uid = set->mkdir_uid != 0 ? set->mkdir_uid : (uid_t)-1;
gid_t gid = set->mkdir_gid != 0 ? set->mkdir_gid : (gid_t)-1; gid_t gid = set->mkdir_gid != 0 ? set->mkdir_gid : (gid_t)-1;
skipping to change at line 106 skipping to change at line 115
int orig_errno = errno; int orig_errno = errno;
if ((ret = try_mkdir(path, set, error_r)) < 0) if ((ret = try_mkdir(path, set, error_r)) < 0)
return -1; return -1;
errno = orig_errno; errno = orig_errno;
} }
if (fd == -1) { if (fd == -1) {
*error_r = t_strdup_printf("safe_mkstemp(%s) failed: %m", path); *error_r = t_strdup_printf("safe_mkstemp(%s) failed: %m", path);
return -1; return -1;
} }
struct file_lock_settings lock_set = set->lock_settings;
lock_set.unlink_on_free = FALSE;
lock_set.close_on_free = FALSE;
ret = -1; ret = -1;
if (file_try_lock_error(fd, str_c(temp_path), F_WRLCK, if (file_try_lock(fd, str_c(temp_path), F_WRLCK, &lock_set,
set->lock_method, lock_r, error_r) <= 0) { lock_r, error_r) <= 0) {
} else if (link(str_c(temp_path), path) < 0) { } else if (link(str_c(temp_path), path) < 0) {
if (errno == EEXIST) { if (errno == EEXIST) {
/* just created by somebody else */ /* just created by somebody else */
ret = 0; ret = 0;
} else if (errno == ENOENT) { } else if (errno == ENOENT) {
/* nobody should be deleting the temp file unless the /* nobody should be deleting the temp file unless the
entire directory is deleted. */ entire directory is deleted. */
*error_r = t_strdup_printf( *error_r = t_strdup_printf(
"Temporary file %s was unexpectedly deleted", "Temporary file %s was unexpectedly deleted",
str_c(temp_path)); str_c(temp_path));
} else { } else {
*error_r = t_strdup_printf("link(%s, %s) failed: %m", *error_r = t_strdup_printf("link(%s, %s) failed: %m",
str_c(temp_path), path); str_c(temp_path), path);
} }
file_lock_free(lock_r); file_lock_free(lock_r);
} else { } else {
file_lock_set_path(*lock_r, path); file_lock_set_path(*lock_r, path);
file_lock_set_unlink_on_free(
*lock_r, set->lock_settings.unlink_on_free);
file_lock_set_close_on_free(
*lock_r, set->lock_settings.close_on_free);
i_unlink_if_exists(str_c(temp_path)); i_unlink_if_exists(str_c(temp_path));
*fd_r = fd; *fd_r = fd;
return 1; return 1;
} }
orig_errno = errno; orig_errno = errno;
i_close_fd(&fd); i_close_fd(&fd);
i_unlink_if_exists(str_c(temp_path)); i_unlink_if_exists(str_c(temp_path));
errno = orig_errno; errno = orig_errno;
return ret; return ret;
} }
 End of changes. 7 change blocks. 
4 lines changed or deleted 21 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)