1 |
jpp |
1.1 |
diff -Nur smeserver-mod_dav-1.1.old/createlinks smeserver-mod_dav-1.1/createlinks |
2 |
|
|
--- smeserver-mod_dav-1.1.old/createlinks 1969-12-31 19:00:00.000000000 -0500 |
3 |
|
|
+++ smeserver-mod_dav-1.1/createlinks 2021-02-28 23:12:35.438000000 -0500 |
4 |
|
|
@@ -0,0 +1,8 @@ |
5 |
|
|
+#!/usr/bin/perl -w |
6 |
|
|
+ |
7 |
|
|
+use esmith::Build::CreateLinks qw(:all); |
8 |
|
|
+ |
9 |
|
|
+my $event = "smeserver-mod_dav-update"; |
10 |
|
|
+templates2events("/etc/httpd/conf/httpd.conf", $event); |
11 |
|
|
+safe_symlink("sigusr1", "root/etc/e-smith/events/$event/services2adjust/httpd-e-smith"); |
12 |
|
|
+ |
13 |
|
|
diff -Nur smeserver-mod_dav-1.1.old/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays smeserver-mod_dav-1.1/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays |
14 |
|
|
--- smeserver-mod_dav-1.1.old/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays 2021-02-28 22:41:40.846000000 -0500 |
15 |
|
|
+++ smeserver-mod_dav-1.1/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays 2021-03-02 11:57:52.069000000 -0500 |
16 |
|
|
@@ -1,71 +1,92 @@ |
17 |
|
|
{ |
18 |
|
|
use esmith::AccountsDB; |
19 |
|
|
+ use esmith::DAV; |
20 |
|
|
my $adb = esmith::AccountsDB->open_ro(); |
21 |
|
|
$OUT = ""; |
22 |
|
|
foreach my $ibay ($adb->ibays) |
23 |
|
|
{ |
24 |
|
|
my %properties = $ibay->props; |
25 |
|
|
my $key = $ibay->key; |
26 |
|
|
+ my $dynamicContent = $properties{'CgiBin'} || "disabled"; |
27 |
|
|
+ my $secureEXEC = $properties{'ModDAVsecureEXEC'} || 'enabled'; |
28 |
|
|
+ my $access = $properties{'PublicAccess'} || 'none'; |
29 |
|
|
+ $OUT .= "\n # ibay $key disabled for httpd so no DAV access\n" if $access eq 'none'; |
30 |
|
|
+ next if $access eq 'none'; |
31 |
|
|
+ # true if have to be password accessible from somewhere. |
32 |
|
|
+ my $satisfy = ($access eq 'global-pw-remote')? 'any': 'all'; |
33 |
|
|
if ($properties{'ModDav'}) |
34 |
|
|
{ |
35 |
|
|
if ($properties{'ModDav'} eq 'enabled') |
36 |
|
|
{ |
37 |
|
|
+ my $ReadRequire = esmith::DAV::getRequireUser("read", $key ); |
38 |
|
|
+ my $WriteRequire = esmith::DAV::getRequireUser("write", $key); |
39 |
|
|
+ my $ReadAllow = esmith::DAV::getAllow("read", $key, $localAccess ); |
40 |
|
|
+ my $WriteAllow = esmith::DAV::getAllow("write", $key, $localAccess ); |
41 |
|
|
+ |
42 |
|
|
$OUT .= "\n<Directory /home/e-smith/files/ibays/$key/html>\n\n"; |
43 |
|
|
$OUT .= " # Enable DAV access for this directory tree\n"; |
44 |
|
|
$OUT .= " DAV On\n\n"; |
45 |
|
|
+ #we will not seriously let you type your password over the network without encryption |
46 |
|
|
+ $OUT .= " SSLRequireSSL\n\n"; |
47 |
|
|
+ |
48 |
|
|
+ if ($dynamicContent eq 'enabled' && $secureEXEC eq 'enabled') |
49 |
|
|
+ { |
50 |
|
|
+ # we do not want PHP or CGI to be runt there for security reason |
51 |
|
|
+ $OUT .= " <FilesMatch \\.php\$>\n"; |
52 |
|
|
+ $OUT .= " #disabling php\n"; |
53 |
|
|
+ $OUT .= " SetHandler !\n"; # could use also SetHandler none |
54 |
|
|
+ $OUT .= " deny from all\n" if ( $properties{'ModDAVhidephp'} || 'enabled' ) eq 'enabled'; |
55 |
|
|
+ $OUT .= " </FilesMatch>\n"; |
56 |
|
|
+ $OUT .= " Options -ExecCGI\n"; |
57 |
|
|
+ $OUT .= " RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo\n"; |
58 |
|
|
+ $OUT .= " php_flag engine off\n" if ((exists $php{status} and $php{status} eq "enabled") and $phpModule eq "enabled") ;# can not use this one when php module not in use |
59 |
|
|
+ } |
60 |
|
|
+ |
61 |
|
|
+ $OUT .= " FileETag ".$properties{'ModDav-FileETag'}."\n\n" if ($properties{'ModDav-FileETag'}); |
62 |
|
|
|
63 |
|
|
- if ($properties{'ModDav-FileETag'}) |
64 |
|
|
- { |
65 |
|
|
- $OUT .= " FileETag ".$properties{'ModDav-FileETag'}."\n\n"; |
66 |
|
|
- } |
67 |
|
|
$OUT .= " AllowOverride None\n"; |
68 |
|
|
$OUT .= " Options +Indexes \n\n"; |
69 |
|
|
$OUT .= " # Allow fancy indexing by columns and download by clicking icon\n"; |
70 |
|
|
$OUT .= " IndexOptions FancyIndexing IconsAreLinks\n\n"; |
71 |
|
|
- if ($properties{'Group'}) |
72 |
|
|
- { |
73 |
|
|
- $OUT .= " AuthName \"$key\"\n"; |
74 |
|
|
- $OUT .= " AuthBasicProvider external\n"; |
75 |
|
|
- $OUT .= " AuthType Basic\n"; |
76 |
|
|
- $OUT .= " AuthExternal pwauth\n\n"; |
77 |
|
|
- # Save groupname and find it in the group list |
78 |
|
|
- $iBayGroup = $properties{'Group'}; |
79 |
|
|
- foreach my $group ($adb->groups) |
80 |
|
|
- { |
81 |
|
|
- my %groupprops = $group->props; |
82 |
|
|
- my $grpkey = $group->key; |
83 |
|
|
- if ($grpkey eq $iBayGroup) |
84 |
|
|
- { |
85 |
|
|
- # we have the group that owns the DAV iBay |
86 |
|
|
- # If there are members of the group validate on them, |
87 |
|
|
- # otherwise on the ibayname |
88 |
|
|
- if ($groupprops{'Members'}) |
89 |
|
|
- { |
90 |
|
|
- # need to break user list on commas then output each one... |
91 |
|
|
- my @values = split(',',$groupprops{'Members'}); |
92 |
|
|
- $OUT .= " # Replace ibay name with any valid group member to validate\n"; |
93 |
|
|
- $OUT .= " Require user "; |
94 |
|
|
- foreach my $val (@values) { |
95 |
|
|
- $OUT .= $val . " "; |
96 |
|
|
- } |
97 |
|
|
- $OUT .= "\n\n"; |
98 |
|
|
- } |
99 |
|
|
- else |
100 |
|
|
- { |
101 |
|
|
- # No group members so use ibay name for validation |
102 |
|
|
- $OUT .= " # use ibay name to validate\n"; |
103 |
|
|
- $OUT .= " Require user " . $key . "\n\n"; |
104 |
|
|
- } |
105 |
|
|
- } |
106 |
|
|
- } |
107 |
|
|
- } |
108 |
|
|
- # Ensure only valid users get to do stuff... |
109 |
|
|
- $OUT .= " <Limit GET PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>\n\n"; |
110 |
|
|
- $OUT .= " Allow from all\n"; |
111 |
|
|
- $OUT .= " Require valid-user\n\n"; |
112 |
|
|
- $OUT .= " </Limit>\n\n"; |
113 |
|
|
+ |
114 |
|
|
+ # bug with httpd-2.4 fixed in httpd-2.5 only see https://bz.apache.org/bugzilla/show_bug.cgi?id=54914 PROPFIND will fail |
115 |
|
|
+ $OUT .= " #because of bug https://bz.apache.org/bugzilla/show_bug.cgi?id=54914 in httpd 2.4 DirectoryIndex disabled is needed for webdav to work\n"; |
116 |
|
|
+ $OUT .= " DirectoryIndex disabled\n\n" unless ( ($properties{'DavNoDirectoryIndex'}||"enabled" ) eq "disabled"); |
117 |
|
|
+ $OUT .= " #DirectoryIndex disabled : DavNoDirectoryIndex has been defined to force DirectoryIndex \n\n" if ( ($properties{'DavNoDirectoryIndex'}||"enabled" ) eq "disabled"); |
118 |
|
|
+ |
119 |
|
|
+ $OUT .= " order deny,allow\n"; |
120 |
|
|
+ $OUT .= " deny from all\n"; |
121 |
|
|
+ $OUT .= " " . $ReadAllow . "\n"; |
122 |
|
|
+ $OUT .= " AuthName \"$properties{'Name'}\"\n"; |
123 |
|
|
+ $OUT .= " AuthBasicProvider external\n"; |
124 |
|
|
+ $OUT .= " AuthType Basic\n"; |
125 |
|
|
+ $OUT .= " AuthExternal pwauth\n"; |
126 |
|
|
+ $OUT .= " " . $ReadRequire . "\n"; |
127 |
|
|
+ $OUT .= " Satisfy $satisfy\n\n"; |
128 |
|
|
+ |
129 |
|
|
+ # Ensure only valid users get to do stuff... update 2021/02: |
130 |
|
|
+ # GET, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK |
131 |
|
|
+ # some suggest : AllowMethods HEAD GET POST CONNECT PUT DELETE OPTIONS PROPFIND PROPPATCH MKCOL MKCALENDAR COPY MOVE LOCK UNLOCK TRACE |
132 |
|
|
+ # TRACE is not supposed to be limited by this directive, should use TraceEnable |
133 |
|
|
+ # LimitExcept is suggested over Limit in order to catch all non standard methods |
134 |
|
|
+ # however we put our limit to the whole folder with the Require user .... above, so the whole block under seems useless |
135 |
|
|
+ # unless we reduce it to one user, or are fool to enlarge to Require valid-user |
136 |
|
|
+# $OUT .= " <Limit GET PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>\n\n"; |
137 |
|
|
+# $OUT .= " Allow from all\n"; |
138 |
|
|
+# $OUT .= " Require user $userlist\n\n"; |
139 |
|
|
+# $OUT .= " </Limit>\n\n"; |
140 |
|
|
+ |
141 |
|
|
+ $OUT .= " <LimitExcept GET POST PROPFIND OPTIONS CONNECT>\n"; |
142 |
|
|
+ $OUT .= " " . $WriteRequire . "\n"; |
143 |
|
|
+ $OUT .= " Satisfy All\n"; |
144 |
|
|
+ $OUT .= " ". $WriteAllow ."\n"; |
145 |
|
|
+ $OUT .= " </LimitExcept>\n\n"; |
146 |
|
|
$OUT .= "</Directory>\n"; |
147 |
|
|
} |
148 |
|
|
} |
149 |
|
|
+ else |
150 |
|
|
+ { |
151 |
|
|
+ $OUT .= "\n # DAV disabled for ibay $key\n"; |
152 |
|
|
+ } |
153 |
|
|
} |
154 |
|
|
} |
155 |
|
|
diff -Nur smeserver-mod_dav-1.1.old/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav smeserver-mod_dav-1.1/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav |
156 |
|
|
--- smeserver-mod_dav-1.1.old/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav 1969-12-31 19:00:00.000000000 -0500 |
157 |
|
|
+++ smeserver-mod_dav-1.1/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav 2021-03-02 11:57:55.866000000 -0500 |
158 |
|
|
@@ -0,0 +1,34 @@ |
159 |
|
|
+{ |
160 |
|
|
+# this fragment is to force SSL redirection for webdav activated account in case it is not already enabled |
161 |
|
|
+# could be removed if core fragment 20IbaysContent introduce forced ssl for DAV |
162 |
|
|
+ use esmith::AccountsDB; |
163 |
|
|
+ my $adb = esmith::AccountsDB->open_ro(); |
164 |
|
|
+ $OUT = ""; |
165 |
|
|
+ foreach my $ibay ($adb->ibays) |
166 |
|
|
+ { |
167 |
|
|
+ my %properties = $ibay->props; |
168 |
|
|
+ my $key = $ibay->key; |
169 |
|
|
+ my $dynamicContent = $properties{'CgiBin'} || "disabled"; |
170 |
|
|
+ my $secureEXEC = $properties{'ModDAVsecureEXEC'} || 'enabled'; |
171 |
|
|
+ my $access = $properties{'PublicAccess'} || 'none'; |
172 |
|
|
+ $OUT .= "\n # ibay $key disabled for httpd so no DAV access\n" if $access eq 'none'; |
173 |
|
|
+ next if $access eq 'none'; |
174 |
|
|
+ # true if have to be password accessible from somewhere. |
175 |
|
|
+ my $ispassibay = $access =~ /-pw/; |
176 |
|
|
+ my $satisfy = ($access eq 'global-pw-remote')? 'any': 'all'; |
177 |
|
|
+ if ($properties{'ModDav'}) |
178 |
|
|
+ { |
179 |
|
|
+ if ($properties{'ModDav'} eq 'enabled') |
180 |
|
|
+ { |
181 |
|
|
+ # we force SSL redirection in case DAV is enabled |
182 |
|
|
+ if (( $port ne $httpsPort ) && (($ibay->prop('SSL') || 'disabled') ne 'enabled')) |
183 |
|
|
+ { |
184 |
|
|
+ my $portspec = ($httpsPort eq 443) ? "" : ":$httpsPort"; |
185 |
|
|
+ $OUT .= " RewriteEngine on\n"; |
186 |
|
|
+ $OUT .= " RewriteRule ^/$key(/.*|\$) https://%{HTTP_HOST}${portspec}/$key\$1 \[L,R\]\n"; |
187 |
|
|
+ } |
188 |
|
|
+ } |
189 |
|
|
+ } |
190 |
|
|
+ } |
191 |
|
|
+} |
192 |
|
|
+ |
193 |
|
|
diff -Nur smeserver-mod_dav-1.1.old/root/usr/share/perl5/vendor_perl/esmith/DAV.pm smeserver-mod_dav-1.1/root/usr/share/perl5/vendor_perl/esmith/DAV.pm |
194 |
|
|
--- smeserver-mod_dav-1.1.old/root/usr/share/perl5/vendor_perl/esmith/DAV.pm 1969-12-31 19:00:00.000000000 -0500 |
195 |
|
|
+++ smeserver-mod_dav-1.1/root/usr/share/perl5/vendor_perl/esmith/DAV.pm 2021-03-02 12:07:13.442000000 -0500 |
196 |
|
|
@@ -0,0 +1,118 @@ |
197 |
|
|
+ |
198 |
|
|
+package esmith::DAV; |
199 |
|
|
+ |
200 |
|
|
+use strict; |
201 |
|
|
+use warnings; |
202 |
|
|
+use esmith::AccountsDB; |
203 |
|
|
+my $adb = esmith::AccountsDB->open_ro(); |
204 |
|
|
+ |
205 |
|
|
+use vars qw( $AUTOLOAD @ISA ); |
206 |
|
|
+ |
207 |
|
|
+ sub getRequireUser { |
208 |
|
|
+ my ($mode, $key) = @_; |
209 |
|
|
+ my $ibay = $adb->get($key) or return "Require user admin"; |
210 |
|
|
+ my %properties = $ibay->props or return "Require user admin"; |
211 |
|
|
+ my $iBayGroup = $properties{'Group'} || 'admin'; |
212 |
|
|
+ my $accessMode = $properties{'UserAccess'} || 'wr-admin-rd-group'; |
213 |
|
|
+ my $access = $properties{'PublicAccess'} || 'none'; |
214 |
|
|
+ my $ispassibay = $access =~ /-pw/; |
215 |
|
|
+ my $Anonymous = $properties{'ModDavAnonymousRead'} || "enabled"; |
216 |
|
|
+ my $MEMBERS = getMembers( $key, $iBayGroup); |
217 |
|
|
+ my $REQUIRE = ""; |
218 |
|
|
+ if ($mode eq "read") |
219 |
|
|
+ { |
220 |
|
|
+ if ($accessMode eq "wr-group-rd-everyone") |
221 |
|
|
+ { |
222 |
|
|
+ if ( $Anonymous eq "enabled" ) |
223 |
|
|
+ { |
224 |
|
|
+ $REQUIRE = "# Allowing unauthenticated read access"; |
225 |
|
|
+ } |
226 |
|
|
+ else |
227 |
|
|
+ { |
228 |
|
|
+ my $EVERYONE = join(' ' , ( (map { $_->key } $adb->users) , qw (admin) )); #shared user members |
229 |
|
|
+ #$REQUIRE = "#wr-group-rd-everyone : members of shared\n"; |
230 |
|
|
+ $REQUIRE .= "Require user " . $EVERYONE; |
231 |
|
|
+ } |
232 |
|
|
+ } |
233 |
|
|
+ else |
234 |
|
|
+ { |
235 |
|
|
+ $REQUIRE = "Require user " . $MEMBERS; |
236 |
|
|
+ if ($accessMode eq "wr-admin-rd-group") |
237 |
|
|
+ { |
238 |
|
|
+ # add "admin" to the read group to avoid read/write auth conflicts |
239 |
|
|
+ $REQUIRE .= " admin"; |
240 |
|
|
+ } |
241 |
|
|
+ } |
242 |
|
|
+ if ($ispassibay) |
243 |
|
|
+ { |
244 |
|
|
+ #we have local-pw or global-pw or global-pw-remote |
245 |
|
|
+ $REQUIRE = ( $REQUIRE =~ /Require user / ) ? "$REQUIRE $key" : "Require user $key"; |
246 |
|
|
+ $REQUIRE .= " $MEMBERS" if ( $access =~ /remote/ ); |
247 |
|
|
+ } |
248 |
|
|
+ } |
249 |
|
|
+ else |
250 |
|
|
+ { |
251 |
|
|
+ if ($accessMode eq "wr-admin-rd-group") |
252 |
|
|
+ { |
253 |
|
|
+ $REQUIRE = "Require user admin"; |
254 |
|
|
+ } |
255 |
|
|
+ else |
256 |
|
|
+ { |
257 |
|
|
+ $REQUIRE = "Require user " . $MEMBERS; |
258 |
|
|
+ } |
259 |
|
|
+ } |
260 |
|
|
+ return $REQUIRE; |
261 |
|
|
+ } |
262 |
|
|
+ |
263 |
|
|
+ sub getAllow { |
264 |
|
|
+ my ($mode, $key, $localAccess ) = @_; |
265 |
|
|
+ $localAccess = (defined $localAccess ) ? $localAccess : "127.0.0.1"; |
266 |
|
|
+ my $ibay = $adb->get($key) or return "allow from 127.0.0.1"; |
267 |
|
|
+ my %properties = $ibay->props or return "allow from 127.0.0.1"; |
268 |
|
|
+ my $Public = $properties{'PublicAccess'} || 'none'; |
269 |
|
|
+ |
270 |
|
|
+ my $allow = "allow from 127.0.0.1"; |
271 |
|
|
+ if ($Public eq 'none') |
272 |
|
|
+ { |
273 |
|
|
+ $allow = "# allow from set to NONE"; |
274 |
|
|
+ } |
275 |
|
|
+ elsif ($Public =~ /(local|remote)/ ) |
276 |
|
|
+ { |
277 |
|
|
+ $allow = "allow from " . $localAccess; |
278 |
|
|
+ } |
279 |
|
|
+ elsif ($Public =~ /global/) |
280 |
|
|
+ { |
281 |
|
|
+ $allow = "allow from all"; |
282 |
|
|
+ } |
283 |
|
|
+ return $allow; |
284 |
|
|
+ } |
285 |
|
|
+ |
286 |
|
|
+ sub getMembers { |
287 |
|
|
+ my ($key, $iBayGroup) = @_; |
288 |
|
|
+ my $MEMBERS = $key; |
289 |
|
|
+ foreach my $group ( ($adb->groups, $adb->get('admin'), $adb->get('shared') ) ) |
290 |
|
|
+ { |
291 |
|
|
+ my %groupprops = $group->props; |
292 |
|
|
+ my $grpkey = $group->key; |
293 |
|
|
+ if ($grpkey eq $iBayGroup) |
294 |
|
|
+ { |
295 |
|
|
+ # we have the group that owns the DAV iBay |
296 |
|
|
+ # If there are members of the group validate on them, |
297 |
|
|
+ # otherwise on the ibayname |
298 |
|
|
+ my $GroupMembers = $groupprops{'Members'} || undef; |
299 |
|
|
+ $GroupMembers = "admin" if ( $grpkey eq "admin" ); |
300 |
|
|
+ $GroupMembers = join(' ' , ( (map { $_->key } $adb->users) , qw (admin) )) if ( $grpkey eq "shared" ) ; |
301 |
|
|
+ |
302 |
|
|
+ if ($GroupMembers) |
303 |
|
|
+ { |
304 |
|
|
+ # need to break user list on commas then output each one... |
305 |
|
|
+ my @values = split(',',$GroupMembers); |
306 |
|
|
+ $MEMBERS = "" unless (!@values) ; |
307 |
|
|
+ foreach my $val (@values) { |
308 |
|
|
+ $MEMBERS .= $val . " "; |
309 |
|
|
+ } |
310 |
|
|
+ } |
311 |
|
|
+ } |
312 |
|
|
+ } |
313 |
|
|
+ return $MEMBERS; |
314 |
|
|
+ } |