3 # Create or update a .htaccess file
5 require './htaccess-lib.pl';
7 $can_create || &error($text{'dir_ecannotcreate'});
8 @dirs = &list_directories();
9 &error_setup($text{'dir_err'});
10 &foreign_require($apachemod, "apache-lib.pl");
12 # Work out what .htaccess file to use
13 $in{'dir'} =~ s/\\/\//g; # use forward slashes
14 if ($in{'new'} && $in{'dir'} !~ /^([a-z]:)?\//i && $default_dir ne "/") {
16 $in{'dir'} = "$default_dir/$in{'dir'}";
18 ($dir) = grep { $_->[0] eq $in{'dir'} } @dirs;
20 $dir && &error($text{'dir_eclash'});
21 $htaccess = "$in{'dir'}/$config{'htaccess'}";
24 $htaccess = "$dir->[0]/$config{'htaccess'}";
27 # Check for button that redirects to the Apache module for editing all
28 # options in .htaccess file
30 &redirect("../apache/htaccess_index.cgi?file=".
35 &lock_file($htaccess);
36 &lock_file($directories_file);
38 # Get the apache directives for the .htaccess file, if any
39 $authz = $apache::httpd_modules{'mod_auth_digest'} >= 2.2;
40 $auf = $in{'crypt'} == 3 && !$authz ? "AuthDigestFile" : "AuthUserFile";
41 $agf = $in{'crypt'} == 3 && !$authz ? "AuthDigestGroupFile" : "AuthGroupFile";
42 $conf = &foreign_call($apachemod, "get_htaccess_config", $htaccess);
43 $currfile = &foreign_call($apachemod, "find_directive",
45 $currgfile = &foreign_call($apachemod, "find_directive",
47 &lock_file($currfile) if ($currfile);
49 # Make sure it is allowed, and create new file if needed
51 &can_access_dir($htaccess) || &error($text{'dir_ecannot'});
52 $missing = !-r $htaccess;
53 &open_tempfile(TEST, ">>$htaccess", 1) || &error(&text('dir_ehtaccess', $htaccess, $!));
54 &close_tempfile(TEST);
56 &set_ownership_permissions(
57 undef, undef, oct($config{'perms'}) || 0644, $htaccess);
60 if ($in{'delete'} || $in{'remove'}) {
62 # Blow away .htaccess, htpasswd and htgroups
63 &unlink_logged($htaccess);
64 &unlink_logged($currfile) if ($currfile && !-d $currfile);
65 &unlink_logged($currgfile) if ($currgfile && !-d $currgfile);
68 # Take the authentication directives out of .htaccess
69 &foreign_call($apachemod, "save_directive",
70 "require", [ ], $conf, $conf);
72 @dirs = grep { $_ ne $dir } @dirs;
77 $in{'dir'} =~ /^([a-z]:)?\// && -d $in{'dir'} ||
78 &error($text{'dir_edir'});
81 # Parse users file option
83 # Users file is always automatic
84 $file = $in{'new'} ? "$in{'dir'}/$config{'htpasswd'}"
88 # User choose for it to be automatic
89 $file = "$in{'dir'}/$config{'htpasswd'}";
93 $in{'file'} || &error($text{'dir_efile'});
94 if ($in{'file'} !~ /^([a-z]:)?\//) {
95 $file = "$in{'dir'}/$in{'file'}";
101 -d $file && &error(&text('dir_efiledir', $file));
103 # Parse groups file option
104 if (!$can_htgroups) {
105 # Groups file is always fixed, or none
106 $gfile = $in{'new'} ? undef : $dir->[3];
108 elsif ($in{'gauto'} == 2) {
112 elsif ($in{'gauto'} == 1) {
113 # User choose for groups file to be automatic
114 $gfile = "$in{'dir'}/$config{'htgroups'}";
117 # Groups file was entered by user
118 $in{'file'} || &error($text{'dir_egfile'});
119 if ($in{'gfile'} !~ /^([a-z]:)?\//) {
120 $gfile = "$in{'dir'}/$in{'gfile'}";
123 $gfile = $in{'gfile'};
126 -d $gfile && &error(&text('dir_egfiledir', $gfile));
128 # Parse require option
129 @require = ( $in{'require_mode'} );
130 if ($in{'require_mode'} eq "user") {
131 @users = split(/\s+/, $in{'require_user'});
132 @users || &error($text{'dir_erequire_user'});
133 push(@require, @users);
135 elsif ($in{'require_mode'} eq "group") {
136 @groups = split(/\s+/, $in{'require_group'});
137 @groups || &error($text{'dir_erequire_group'});
138 push(@require, @groups);
142 $sync = join(",", grep { $in{'sync_'.$_} }
143 ('create', 'update', 'delete'));
147 # Either update an existing .htaccess to ensure that all
148 # needed directives exist, or create from scratch
150 # Use the existing users path if there is one, otherwise add
151 $currfile = &foreign_call($apachemod, "find_directive",
157 &foreign_call($apachemod, "save_directive",
158 $auf, [ "\"$file\"" ], $conf, $conf);
161 # Use the existing groups path if there is one, otherwise add
162 $currgfile = &foreign_call($apachemod, "find_directive",
168 &foreign_call($apachemod, "save_directive",
169 $agf, [ "\"$gfile\"" ], $conf,$conf);
172 # Add an auth type if needed
173 $currtype = &foreign_call($apachemod, "find_directive",
174 "AuthType", $conf, 1);
176 &foreign_call($apachemod, "save_directive",
178 [ $in{'crypt'} == 3 ? "Digest" : "Basic" ],
182 # Add a realm if needed
183 $currrealm = &foreign_call($apachemod, "find_directive",
184 "AuthName", $conf, 1);
186 $in{'realm'} || &error($text{'dir_erealm'});
187 &foreign_call($apachemod, "save_directive", "AuthName",
188 [ "\"$in{'realm'}\"" ], $conf, $conf);
191 # Add a require if needed
192 $currrequire = &foreign_call($apachemod, "find_directive",
193 "require", $conf, 1);
195 &foreign_call($apachemod, "save_directive",
196 "require", [ join(" ", @require) ],
200 # Add AuthDigestProvider if needed
201 if ($authz && $in{'crypt'} == 3) {
202 &foreign_call($apachemod, "save_directive",
203 "AuthDigestProvider",
204 [ "file" ], $conf, $conf);
207 # Add 'extra directives' if needed
209 foreach $edline (split(/\t+/, $config{'extra_directives'})) {
211 $edline =~ m/(.*?)\s+(.*)/;
212 ($ed, $edval) = ($1, $2);
213 $curred = &foreign_call($apachemod, "find_directive",
216 &foreign_call($apachemod, "save_directive",
217 $ed, [$edval], $conf, $conf);
221 # Add to the known directories list
222 $sync = "-" if (!$can_sync);
223 $dir = [ $in{'dir'}, $file, $in{'crypt'}, $sync, $gfile ];
227 # Just update the users and groups file paths, realm and
229 &foreign_call($apachemod, "save_directive",
232 &foreign_call($apachemod, "save_directive",
233 $agf, $gfile ? [ $gfile ] : [ ],
235 &foreign_call($apachemod, "save_directive",
236 "AuthName", [ "\"$in{'realm'}\"" ],
238 &foreign_call($apachemod, "save_directive",
239 "require", [ join(" ", @require) ],
242 # Update the known directories list
244 $dir->[2] = $in{'crypt'};
245 $dir->[3] = $sync if ($can_sync);
249 # Create an empty users file if needed
252 &open_tempfile(FILE, ">$file", 1, 1) ||
253 &error(&text('dir_ehtpasswd', $file, $!));
254 &close_tempfile(FILE) ||
255 &error(&text('dir_ehtpasswd', $file, $!));
257 &set_ownership_permissions(
258 undef, undef, oct($config{'perms'}) || 0644, $file);
261 # Create an empty groups file if needed
262 if ($gfile && !-r $gfile) {
264 &open_tempfile(FILE, ">$gfile", 1, 1) ||
265 &error(&text('dir_ehtgroup', $gfile, $!));
266 &close_tempfile(FILE) ||
267 &error(&text('dir_ehtgroup', $gfile, $!));
268 &unlock_file($gfile);
269 &set_ownership_permissions(
270 undef, undef, oct($config{'perms'}) || 0644, $gfile);
277 &save_directories(\@dirs);
279 &webmin_log($in{'delete'} || $in{'remove'} ? "delete" :
280 $in{'new'} ? "create" : "modify",