forked from webmin/webmin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchmod.cgi
executable file
·92 lines (85 loc) · 2.19 KB
/
chmod.cgi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/local/bin/perl
# chmod.cgi
# Change the ownership and permissions on a file
require './file-lib.pl';
$disallowed_buttons{'info'} && &error($text{'ebutton'});
&ReadParse();
&webmin_log($in{'linkto'} ? "relink" : "chmod", undef, $in{'path'}, \%in);
&switch_acl_uid_and_chroot();
print "Content-type: text/plain\n\n";
!$access{'ro'} && &can_access($in{'path'}) ||
&failure(&text('chmod_eaccess', $in{'path'}));
if (defined($in{'user'})) {
$uid = $in{'user'} =~ /^\d+$/ ? $in{'user'} :
defined(%user_to_uid) ? $user_to_uid{$in{'user'}} :
getpwnam($in{'user'});
&failure(&text('chmod_euser', $in{'user'})) if (!defined($uid));
$gid = $in{'group'} =~ /^\d+$/ ? $in{'group'} :
defined(%group_to_gid) ? $group_to_gid{$in{'group'}} :
getgrnam($in{'group'});
&failure(&text('chmod_egroup', $in{'group'})) if (!defined($gid));
}
if ($in{'linkto'}) {
# Just changing the link target
$follow && &failure($text{'chmod_efollow'});
&lock_file($in{'path'});
unlink($in{'path'});
symlink($in{'linkto'}, $in{'path'}) ||
&failure(&text('chmod_elink', $1));
&unlock_file($in{'path'});
}
elsif ($in{'rec'} == 0) {
# Just this file
&update($in{'path'}, 0);
}
elsif ($in{'rec'} == 1) {
# This directory and all its files
&update($in{'path'}, 0);
opendir(DIR, $in{'path'});
foreach $f (readdir(DIR)) {
next if ($f eq "." || $f eq "..");
next if (-l $full);
&update("$in{'path'}/$f", 1) if (!-d $full);
}
closedir(DIR);
}
elsif ($in{'rec'} == 2) {
# Directory and all subdirectories
&update($in{'path'}, 0);
&recurse($in{'path'});
}
print "\n";
sub recurse
{
local(@files, $f, $full);
opendir(DIR, $_[0]);
@files = readdir(DIR);
closedir(DIR);
foreach $f (@files) {
$full = "$_[0]/$f";
next if ($f eq "." || $f eq "..");
next if (-l $full);
&update($full, !-d $full);
&recurse($full) if (-d $full);
}
}
sub failure
{
print @_,"\n";
exit;
}
# update(file, perms_only)
sub update
{
local $perms = $in{'perms'};
if (defined($perms)) {
if ($_[1]) {
@st = stat($_[0]);
$perms = ($perms & 0777) | ($st[2] & 037777777000);
}
chmod($perms, $_[0]) || &failure(&text('chmod_echmod', $!));
}
if (defined($uid)) {
chown($uid, $gid, $_[0]) || &failure(&text('chmod_echown', $!));
}
}