static void test_safe_chmod_unsafe_link(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //test_switch_symlink(); assert_int_equal(chown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(chmod(TEST_SUBDIR "/" TEST_FILE, 0777), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod(TEST_FILE, 0644), -1); assert_int_equal(errno, EACCES); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); return_to_test_dir(); }
bool CopyFilePermissionsDisk(const char *source, const char *destination) { struct stat statbuf; if (stat(source, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "Can't copy permissions '%s'. (stat: %s)", source, GetErrorStr()); return false; } if (safe_chmod(destination, statbuf.st_mode) != 0) { Log(LOG_LEVEL_INFO, "Can't copy permissions '%s'. (chmod: %s)", source, GetErrorStr()); return false; } if (safe_chown(destination, statbuf.st_uid, statbuf.st_gid) != 0) { Log(LOG_LEVEL_INFO, "Can't copy permissions '%s'. (chown: %s)", source, GetErrorStr()); return false; } if (!CopyFileExtendedAttributesDisk(source, destination)) { return false; } return true; }
static void test_safe_chmod_extra_slashes(void) { setup_tempfiles(); struct stat statbuf; assert_int_equal(chmod("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, 0777), 0); assert_int_equal(stat("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, 0644), 0); assert_int_equal(stat("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0644); return_to_test_dir(); }
static void test_safe_chmod_relative_file(void) { setup_tempfiles(); struct stat statbuf; assert_int_equal(chmod(TEST_SUBDIR "/" TEST_FILE, 0777), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod(TEST_SUBDIR "/" TEST_FILE, 0644), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0644); return_to_test_dir(); }
void LogHashChange(const char *file, FileState status, char *msg, const Promise *pp) { FILE *fp; char fname[CF_BUFSIZE]; time_t now = time(NULL); mode_t perm = 0600; static char prevFile[CF_MAXVARSIZE] = ""; /* GLOBAL_X */ // we might get called twice.. if (strcmp(file, prevFile) == 0) { return; } strlcpy(prevFile, file, CF_MAXVARSIZE); /* This is inefficient but we don't want to lose any data */ snprintf(fname, CF_BUFSIZE, "%s/state/%s", CFWORKDIR, CF_FILECHANGE_NEW); MapName(fname); #ifndef __MINGW32__ struct stat sb; if (stat(fname, &sb) != -1) { if (sb.st_mode & (S_IWGRP | S_IWOTH)) { Log(LOG_LEVEL_ERR, "File '%s' (owner %ju) is writable by others (security exception)", fname, (uintmax_t)sb.st_uid); } } #endif /* !__MINGW32__ */ if ((fp = safe_fopen(fname, "a")) == NULL) { Log(LOG_LEVEL_ERR, "Could not write to the hash change log. (fopen: %s)", GetErrorStr()); return; } const char *handle = PromiseID(pp); fprintf(fp, "%ld,%s,%s,%c,%s\n", (long) now, handle, file, FileStateToChar(status), msg); fclose(fp); safe_chmod(fname, perm); }
void RotateFiles(char *name, int number) { int i, fd; struct stat statbuf; char from[CF_BUFSIZE], to[CF_BUFSIZE]; if (IsItemIn(ROTATED, name)) { return; } PrependItem(&ROTATED, name, NULL); if (stat(name, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "No access to file %s", name); return; } for (i = number - 1; i > 0; i--) { snprintf(from, CF_BUFSIZE, "%s.%d", name, i); snprintf(to, CF_BUFSIZE, "%s.%d", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.gz", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.gz", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.Z", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.Z", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.bz", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.bz", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.bz2", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.bz2", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } } snprintf(to, CF_BUFSIZE, "%s.1", name); if (CopyRegularFileDisk(name, to) == false) { Log(LOG_LEVEL_DEBUG, "Copy failed in RotateFiles '%s' -> '%s'", name, to); return; } safe_chmod(to, statbuf.st_mode); if (safe_chown(to, statbuf.st_uid, statbuf.st_gid)) { UnexpectedError("Failed to chown %s", to); } safe_chmod(name, 0600); /* File must be writable to empty .. */ if ((fd = safe_creat(name, statbuf.st_mode)) == -1) { Log(LOG_LEVEL_ERR, "Failed to create new '%s' in disable(rotate). (creat: %s)", name, GetErrorStr()); } else { if (safe_chown(name, statbuf.st_uid, statbuf.st_gid)) /* NT doesn't have fchown */ { UnexpectedError("Failed to chown '%s'", name); } fchmod(fd, statbuf.st_mode); close(fd); } }