Skip to content

Instantly share code, notes, and snippets.

@Neboer
Created July 25, 2024 04:09
Show Gist options
  • Save Neboer/7bbdc9e1e797842141bf4f6bd90ae288 to your computer and use it in GitHub Desktop.
Save Neboer/7bbdc9e1e797842141bf4f6bd90ae288 to your computer and use it in GitHub Desktop.
Offset the permission of a directory and all its content recursively.
#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;
}
@Neboer
Copy link
Author

Neboer commented Jul 25, 2024

compile: g++ -std=c++17 -o uid_offset uid_offset.cpp
run: sudo ./uid_offset /var/lib/machines/test -11451419

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment