Erik Sapir
Erik Sapir

Reputation: 24707

how can i check file write permissions in C++ code?

In my C++ program, I want to make sure i can write info to a file. How can I perform this check?

Upvotes: 1

Views: 2211

Answers (3)

svv
svv

Reputation: 29

There could be different file rights POSIX, ACL, RBAC etc. Only POSIX rights are standard

There simplest way to check is to open file for writing in append mode:

std::ofstream file(filePath, std::ios::app);
if (!file.is_open()) {
    std::cerr << "File cannot be opened for writing." << std::endl;
    return false;
}

Manually check file permissions even for POSIX rights is a bad idea, because it leads to tremendous code. Under UNIX you have to process three triads: -rw-rw-r-x

Current process has user (uid) and group (groupId) rights. User could be in a set of groups - see UNIX "id" command. So the most tricky part is to check group rights of the file agains all possible groups. Let file is a regular file and not a symlink

First part: user itself has rights to write the file

struct stat fileStat;
stat(filePath.c_str(), &fileStat);

// User is the same as the owner of the file
if (fileStat.st_uid == getuid()) {
    if ((std::filesystem::status(filePath).permissions() & std::filesystem::perms::owner_write) != 
        std::filesystem::perms::none) {
        return true;
    }
}

Second part: one of groups user belongs to has ability to write

// Get groups list
std::vector<gid_t> groups;
int ngroups = 0;
uint result = getgrouplist(username.c_str(), groupId, nullptr, &ngroups);
groups.resize(ngroups);
result = getgrouplist(username.c_str(), groupId, groups.data(), &ngroups);

// Check all groups
for (uint i = 0; i < ngroups; ++i) {
    if (groups[i] == fileStat.st_gid) {
        // User belongs to a group that is equal to file group
        if ((std::filesystem::status(filePath).permissions() & std::filesystem::perms::group_write) != 
            std::filesystem::perms::none) {
            return true;
        }
    }
}

Third part: check others permissions

if ((std::filesystem::status().permissions() & std::filesystem::perms::others_write) != 
    std::filesystem::perms::none) {
    return true;
}

Upvotes: 1

anon
anon

Reputation:

The only sure way to find if you can write to a file is to try to write to a file. It is possible, and even likely in some circumstances, that a file will have its permissions changed between calls to function such as stat and the actual write. Your code must deal with write failures anyway, so it makes sense to centralise the testing code there.

Upvotes: 4

Richard Pennington
Richard Pennington

Reputation: 19965

You use the stat() system call, which the purists will tell you doesn't exist unless you change the tags on your question.

Upvotes: 2

Related Questions