Example #1
0
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();
}
Example #2
0
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;
}
Example #3
0
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();
}
Example #4
0
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();
}
Example #5
0
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);
}
Example #6
0
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);
    }
}