CDS
view release on metacpan or search on metacpan
$ui->p('Note that the permissions only affect direct filesystem access. If your store is exposed by a server (e.g. a web server), it may be accessible to others.');
$ui->space;
$ui->command('⦠and remember it as TEXT');
$ui->p('Remembers the store under the label TEXT. See "cds help remember" for details.');
$ui->space;
$ui->command('cds check permissions [of STORE]');
$ui->p('Checks the permissions (owner, mode) of all accounts, boxes, box entries, and objects of the store, and reports any error. The permission scheme (user, group, or everybody) is derived from the "accounts" and "objects" folders.');
$ui->p('If the store is omitted, the selected store is used.');
$ui->space;
$ui->command('cds fix permissions [of STORE]');
$ui->p('Same as above, but tries to fix the permissions (chown, chmod) instead of just reporting them.');
$ui->space;
$ui->command('cds show permission scheme [of STORE]');
$ui->p('Reports the permission scheme of the store.');
$ui->space;
$ui->command('cds set permission scheme [of STORE] to (user USER|group GROUP|everybody)');
$ui->p('Sets the permission scheme of the stores, and changes all permissions accordingly.');
$ui->space;
$ui->command('cds add account ACCOUNT [to STORE]');
$ui->command('cds add account for FILE [to STORE]');
$ui->command('cds add account for KEYPAIR [to STORE]');
my $folder = shift;
# Create the folders to here if necessary
for my $intermediateFolder (CDS->intermediateFolders($folder)) {
mkdir $intermediateFolder, 0755;
}
# mkdir (if it does not exist yet) and chmod (if it does exist already)
mkdir $folder, $o->{permissions}->baseFolderMode;
chmod $o->{permissions}->baseFolderMode, $folder;
chown $o->{permissions}->uid // -1, $o->{permissions}->gid // -1, $folder;
# Check if the result is correct
my @s = stat $folder;
return $o->{ui}->error('Unable to create ', $o->{foldername}, '.') if ! scalar @s;
my $mode = $s[2];
return $o->{ui}->error($folder, ' exists, but is not a folder') if ! Fcntl::S_ISDIR($mode);
return $o->{ui}->error('Unable to set the owning user ', $o->{permissions}->user, ' for ', $folder, '.') if defined $o->{permissions}->uid && $s[4] != $o->{permissions}->uid;
return $o->{ui}->error('Unable to set the owning group ', $o->{permissions}->group, ' for ', $folder, '.') if defined $o->{permissions}->gid && $s[5] != $o->{permissions}->gid;
return $o->{ui}->error('Unable to set the mode on ', $folder, '.') if ($mode & 0777) != $o->{permissions}->baseFolderMode;
return 1;
sub traversalFailed {
my $o = shift;
my $folderStore = shift;
$o->{ui}->space;
$o->{ui}->p('Traversal failed because a file or folder could not be accessed. You may have to fix the permissions manually, or run this command with other privileges.');
$o->{ui}->p('If you have root privileges, you can take over this store using:');
my $userName = getpwuid($<);
my $groupName = getgrgid($();
$o->{ui}->line($o->{ui}->gold(' sudo chown -R ', $userName, ':', $groupName, ' ', $folderStore->folder));
$o->{ui}->p('and then set the desired permission scheme:');
$o->{ui}->line($o->{ui}->gold(' cds set permissions of ', $folderStore->folder, ' to â¦'));
$o->{ui}->space;
exit(1);
}
sub addAccount {
my $o = shift;
my $cmd = shift;
# Write the file
my $temporaryFile = $folder.'/.'.CDS->randomHex(16);
open(my $fh, '>:bytes', $temporaryFile) || return;
print $fh @_;
close $fh;
# Set the permissions
chmod $mode, $temporaryFile;
my $uid = $o->uid;
my $gid = $o->gid;
chown $uid // -1, $gid // -1, $temporaryFile if defined $uid && $uid != $< || defined $gid && $gid != $(;
return $temporaryFile;
}
sub mkdir {
my $o = shift;
my $folder = shift;
my $mode = shift;
return if -d $folder;
# Create the folder (note: mode is altered by umask)
my $success = mkdir $folder, $mode;
# Set the permissions
chmod $mode, $folder;
my $uid = $o->uid;
my $gid = $o->gid;
chown $uid // -1, $gid // -1, $folder if defined $uid && $uid != $< || defined $gid && $gid != $(;
return $success;
}
# Check the permissions of a file or folder, and fix them if desired.
# A logger object is called for the different cases (access error, correct permissions, wrong permissions, error fixing permissions).
sub checkPermissions {
my $o = shift;
my $item = shift;
my $expectedMode = shift;
my $logger = shift;
# Check
my $wrongUid = defined $expectedUid && $uid != $expectedUid;
my $wrongGid = defined $expectedGid && $gid != $expectedGid;
my $wrongMode = $mode != $expectedMode;
if ($wrongUid || $wrongGid || $wrongMode) {
# Something is wrong
$logger->wrong($item, $uid, $gid, $mode, $expectedUid, $expectedGid, $expectedMode) || return 1;
# Fix uid and gid
if ($wrongUid || $wrongGid) {
my $count = chown $expectedUid // -1, $expectedGid // -1, $item;
return $logger->setError($item) if $count < 1;
}
# Fix mode
if ($wrongMode) {
my $count = chmod $expectedMode, $item;
return $logger->setError($item) if $count < 1;
}
} else {
# Everything is OK
( run in 1.101 second using v1.01-cache-2.11-cpan-71847e10f99 )