Created
July 25, 2024 04:09
-
-
Save Neboer/7bbdc9e1e797842141bf4f6bd90ae288 to your computer and use it in GitHub Desktop.
Offset the permission of a directory and all its content recursively.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <filesystem> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
namespace fs = std::filesystem; | |
void chown_with_offset(const fs::path &target_path, long offset, bool symbolic = false) | |
{ | |
struct stat fileStat; | |
if (lstat(target_path.c_str(), &fileStat) != 0) | |
{ | |
std::cerr << "Error: Unable to get status of " << target_path << std::endl; | |
return; | |
} | |
long new_uid = fileStat.st_uid + offset; | |
long new_gid = fileStat.st_gid + offset; | |
// clip new id to zero if it is negative | |
if (new_uid < 0) | |
new_uid = 0; | |
if (new_gid < 0) | |
new_gid = 0; | |
// change owner and group of the file or symbolic link | |
if (symbolic) | |
{ | |
if (lchown(target_path.c_str(), new_uid, new_gid) != 0) | |
{ | |
std::cerr << "Error: Unable to change owner and group of " << target_path << std::endl; | |
return; | |
} | |
} | |
else | |
{ | |
if (chown(target_path.c_str(), new_uid, new_gid) != 0) | |
{ | |
std::cerr << "Error: Unable to change owner and group of " << target_path << std::endl; | |
return; | |
} | |
} | |
} | |
void applyUidGidOffset(const fs::path &dirname, long offset) | |
{ | |
chown_with_offset(dirname, offset); | |
// loop through all files and directories in the directory | |
for (auto &entry : fs::recursive_directory_iterator(dirname, fs::directory_options::none)) | |
{ | |
chown_with_offset(entry.path(), offset, fs::is_symlink(entry.symlink_status())); | |
} | |
std::cout << "UID and GID offset applied successfully." << std::endl; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc != 3) | |
{ | |
std::cerr << "Usage: " << argv[0] << " <directory> <offset>" << std::endl; | |
return 1; | |
} | |
fs::path dirname = argv[1]; | |
long offset = std::stol(argv[2]); | |
applyUidGidOffset(dirname, offset); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
compile:
g++ -std=c++17 -o uid_offset uid_offset.cpp
run:
sudo ./uid_offset /var/lib/machines/test -11451419