diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e594810
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.rpm
+*.log
+*spec-20*
+*.tar.xz
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..64a80de
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+# Makefile for source rpm: smeserver-mod_dav
+# $Id: Makefile,v 1.1 2020/07/23 17:52:52 brianr Exp $
+NAME := smeserver-mod_dav
+SPECFILE = $(firstword $(wildcard *.spec))
+
+define find-makefile-common
+for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
+endef
+
+MAKEFILE_COMMON := $(shell $(find-makefile-common))
+
+ifeq ($(MAKEFILE_COMMON),)
+# attept a checkout
+define checkout-makefile-common
+test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
+endef
+
+MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
+endif
+
+include $(MAKEFILE_COMMON)
diff --git a/README.md b/README.md
index 8782a69..2e873fb 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,15 @@
-# smeserver-mod_dav
+# smeserver-mod_dav
-SMEServer Koozali developed git repo for smeserver-mod_dav smecontribs
\ No newline at end of file
+SMEServer Koozali developed git repo for smeserver-mod_dav smecontribs
+
+## Wiki
+
https://wiki.koozali.org/
+
+## Bugzilla
+Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=smeserver-mod_dav&product=SME%20Contribs&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED)
+
+## Description
+
+
*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.*
+*Once it has been checked, then this comment will be deleted*
+
diff --git a/contriborbase b/contriborbase
new file mode 100644
index 0000000..9b7fd51
--- /dev/null
+++ b/contriborbase
@@ -0,0 +1 @@
+contribs10
diff --git a/createlinks b/createlinks
new file mode 100644
index 0000000..e1e2f48
--- /dev/null
+++ b/createlinks
@@ -0,0 +1,8 @@
+#!/usr/bin/perl -w
+
+use esmith::Build::CreateLinks qw(:all);
+
+my $event = "smeserver-mod_dav-update";
+templates2events("/etc/httpd/conf/httpd.conf", $event);
+safe_symlink("sigusr1", "root/etc/e-smith/events/$event/services2adjust/httpd-e-smith");
+
diff --git a/root/etc/e-smith/db/configuration/defaults/modDAV/status b/root/etc/e-smith/db/configuration/defaults/modDAV/status
new file mode 100644
index 0000000..86981e6
--- /dev/null
+++ b/root/etc/e-smith/db/configuration/defaults/modDAV/status
@@ -0,0 +1 @@
+enabled
diff --git a/root/etc/e-smith/db/configuration/defaults/modDAV/type b/root/etc/e-smith/db/configuration/defaults/modDAV/type
new file mode 100644
index 0000000..24e1098
--- /dev/null
+++ b/root/etc/e-smith/db/configuration/defaults/modDAV/type
@@ -0,0 +1 @@
+service
diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/20LoadModule80mod_dav b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/20LoadModule80mod_dav
new file mode 100644
index 0000000..7923a1f
--- /dev/null
+++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/20LoadModule80mod_dav
@@ -0,0 +1,9 @@
+{
+ # vim: ft=perl:
+ my $status = $modDAV{status} || 'disabled';
+ if ( $status eq "enabled" )
+ {
+ $OUT .= "LoadModule dav_module\tmodules/mod_dav.so\n";
+ $OUT .= "LoadModule dav_fs_module modules/mod_dav_fs.so\n";
+ }
+}
diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/35DavLock b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/35DavLock
new file mode 100644
index 0000000..c9ac097
--- /dev/null
+++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/35DavLock
@@ -0,0 +1,7 @@
+{
+ my $status = $modDAV{status} || 'disabled';
+ if ( $status eq "enabled" )
+ {
+ $OUT .= "\nDAVLockDB /var/run/davLocks/DAVLock\n";
+ }
+}
diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/75BrowserMatchmod_dav b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/75BrowserMatchmod_dav
new file mode 100644
index 0000000..ab167fe
--- /dev/null
+++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/75BrowserMatchmod_dav
@@ -0,0 +1,11 @@
+#
+# The following directive disables redirects on non-GET requests for
+# a directory that does not include the trailing slash. This fixes a
+# problem with Microsoft WebFolders which does not appropriately handle
+# redirects for folders with DAV methods.
+# Same deal with Apple's DAV filesystem and Gnome VFS support for DAV.
+#
+BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
+BrowserMatch "^WebDrive" redirect-carefully
+BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
+BrowserMatch "^gnome-vfs" redirect-carefully
diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays
new file mode 100644
index 0000000..0806510
--- /dev/null
+++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/95Addmod_dav2ibays
@@ -0,0 +1,92 @@
+{
+ use esmith::AccountsDB;
+ use esmith::DAV;
+ my $adb = esmith::AccountsDB->open_ro();
+ $OUT = "";
+ foreach my $ibay ($adb->ibays)
+ {
+ my %properties = $ibay->props;
+ my $key = $ibay->key;
+ my $dynamicContent = $properties{'CgiBin'} || "disabled";
+ my $secureEXEC = $properties{'ModDavSecureEXEC'} || 'enabled';
+ my $access = $properties{'PublicAccess'} || 'none';
+ $OUT .= "\n # ibay $key disabled for httpd so no DAV access\n" if $access eq 'none';
+ next if $access eq 'none';
+ # true if have to be password accessible from somewhere.
+ my $satisfy = ($access eq 'global-pw-remote')? 'RequireAny': 'RequireAll';
+ if ($properties{'ModDav'})
+ {
+ if ($properties{'ModDav'} eq 'enabled')
+ {
+ my $ReadRequire = esmith::DAV::getRequireUser("read", $key );
+ my $WriteRequire = esmith::DAV::getRequireUser("write", $key);
+ my $ReadAllow = esmith::DAV::getAllow("read", $key, $localAccess );
+ my $WriteAllow = esmith::DAV::getAllow("write", $key, $localAccess );
+
+ $OUT .= "\n\n\n";
+ $OUT .= " # Enable DAV access for this directory tree\n";
+ $OUT .= " DAV On\n\n";
+ #we will not seriously let you type your password over the network without encryption
+ $OUT .= " SSLRequireSSL\n\n";
+
+ if ($dynamicContent eq 'enabled' && $secureEXEC eq 'enabled')
+ {
+ # we do not want PHP or CGI to be runt there for security reason
+ $OUT .= " \n";
+ $OUT .= " #disabling php\n";
+ $OUT .= " SetHandler !\n"; # could use also SetHandler none
+ $OUT .= " Require all denied\n" if ( $properties{'ModDavHidePHP'} || 'enabled' ) eq 'enabled';
+ $OUT .= " \n";
+ $OUT .= " Options -ExecCGI\n";
+ $OUT .= " RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo\n";
+ $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
+ }
+
+ $OUT .= " FileETag ".$properties{'ModDav-FileETag'}."\n\n" if ($properties{'ModDav-FileETag'});
+
+ $OUT .= " AllowOverride None\n";
+ $OUT .= " Options +Indexes \n\n";
+ $OUT .= " # Allow fancy indexing by columns and download by clicking icon\n";
+ $OUT .= " IndexOptions FancyIndexing IconsAreLinks\n\n";
+
+ # 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
+ $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";
+ $OUT .= " DirectoryIndex disabled\n\n" unless ( ($properties{'ModDavNoDirectoryIndex'}||"enabled" ) eq "disabled");
+ $OUT .= " #DirectoryIndex disabled : DavNoDirectoryIndex has been defined to force DirectoryIndex \n\n" if ( ($properties{'ModDavNoDirectoryIndex'}||"enabled" ) eq "disabled");
+
+ $OUT .= " AuthName \"$properties{'Name'}\"\n";
+ $OUT .= " AuthBasicProvider external\n";
+ $OUT .= " AuthType Basic\n";
+ $OUT .= " AuthExternal pwauth\n";
+ $OUT .= " <$satisfy>\n";
+ $OUT .= " " . $ReadRequire . "\n";
+ $OUT .= " " . $ReadAllow . "\n";
+ $OUT .= " $satisfy>\n\n";
+
+ # Ensure only valid users get to do stuff... update 2021/02:
+ # GET, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
+ # some suggest : AllowMethods HEAD GET POST CONNECT PUT DELETE OPTIONS PROPFIND PROPPATCH MKCOL MKCALENDAR COPY MOVE LOCK UNLOCK TRACE
+ # TRACE is not supposed to be limited by this directive, should use TraceEnable
+ # LimitExcept is suggested over Limit in order to catch all non standard methods
+ # however we put our limit to the whole folder with the Require user .... above, so the whole block under seems useless
+ # unless we reduce it to one user, or are fool to enlarge to Require valid-user
+# $OUT .= " \n\n";
+# $OUT .= " #Require all granted\n";
+# $OUT .= " Require user $userlist\n\n";
+# $OUT .= " \n\n";
+
+ $OUT .= " \n";
+ $OUT .= " \n";
+ $OUT .= " " . $WriteRequire . "\n";
+ $OUT .= " ". $WriteAllow ."\n";
+ $OUT .= " \n";
+ $OUT .= " \n\n";
+ $OUT .= "\n";
+ }
+ }
+ else
+ {
+ $OUT .= "\n # DAV disabled for ibay $key\n";
+ }
+ }
+}
diff --git a/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav
new file mode 100644
index 0000000..696dee8
--- /dev/null
+++ b/root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/21IbayWebDav
@@ -0,0 +1,32 @@
+{
+# this fragment is to force SSL redirection for webdav activated account in case it is not already enabled
+# could be removed if core fragment 20IbaysContent introduce forced ssl for DAV
+ use esmith::AccountsDB;
+ my $adb = esmith::AccountsDB->open_ro();
+ $OUT = "";
+ foreach my $ibay ($adb->ibays)
+ {
+ my %properties = $ibay->props;
+ my $key = $ibay->key;
+ my $dynamicContent = $properties{'CgiBin'} || "disabled";
+ my $secureEXEC = $properties{'ModDAVsecureEXEC'} || 'enabled';
+ my $access = $properties{'PublicAccess'} || 'none';
+ $OUT .= "\n # ibay $key disabled for httpd so no DAV access\n" if $access eq 'none';
+ next if $access eq 'none';
+ # true if have to be password accessible from somewhere.
+ if ($properties{'ModDav'})
+ {
+ if ($properties{'ModDav'} eq 'enabled')
+ {
+ # we force SSL redirection in case DAV is enabled
+ if (( $port ne $httpsPort ) && (($ibay->prop('SSL') || 'disabled') ne 'enabled'))
+ {
+ my $portspec = ($httpsPort eq 443) ? "" : ":$httpsPort";
+ $OUT .= " RewriteEngine on\n";
+ $OUT .= " RewriteRule ^/$key(/.*|\$) https://%{HTTP_HOST}${portspec}/$key\$1 \[L,R\]\n";
+ }
+ }
+ }
+ }
+}
+
diff --git a/root/usr/lib/tmpfiles.d/mod_dav.conf b/root/usr/lib/tmpfiles.d/mod_dav.conf
new file mode 100644
index 0000000..1f535f5
--- /dev/null
+++ b/root/usr/lib/tmpfiles.d/mod_dav.conf
@@ -0,0 +1 @@
+d /var/run/davLocks 0755 www www
diff --git a/root/usr/share/perl5/vendor_perl/esmith/DAV.pm b/root/usr/share/perl5/vendor_perl/esmith/DAV.pm
new file mode 100644
index 0000000..7c9079c
--- /dev/null
+++ b/root/usr/share/perl5/vendor_perl/esmith/DAV.pm
@@ -0,0 +1,118 @@
+
+package esmith::DAV;
+
+use strict;
+use warnings;
+use esmith::AccountsDB;
+my $adb = esmith::AccountsDB->open_ro();
+
+use vars qw( $AUTOLOAD @ISA );
+
+ sub getRequireUser {
+ my ($mode, $key) = @_;
+ my $ibay = $adb->get($key) or return "Require user admin";
+ my %properties = $ibay->props or return "Require user admin";
+ my $iBayGroup = $properties{'Group'} || 'admin';
+ my $accessMode = $properties{'UserAccess'} || 'wr-admin-rd-group';
+ my $access = $properties{'PublicAccess'} || 'none';
+ my $ispassibay = $access =~ /-pw/;
+ my $Anonymous = $properties{'ModDavAnonymousRead'} || "disabled";
+ my $MEMBERS = getMembers( $key, $iBayGroup);
+ my $REQUIRE = "";
+ if ($mode eq "read")
+ {
+ if ($accessMode eq "wr-group-rd-everyone")
+ {
+ if ( $Anonymous eq "enabled" )
+ {
+ $REQUIRE = "# Allowing unauthenticated read access";
+ }
+ else
+ {
+ my $EVERYONE = join(' ' , ( (map { $_->key } $adb->users) , qw (admin) )); #shared user members
+ #$REQUIRE = "#wr-group-rd-everyone : members of shared\n";
+ $REQUIRE .= "Require user " . $EVERYONE;
+ }
+ }
+ else
+ {
+ $REQUIRE = "Require user " . $MEMBERS;
+ if ($accessMode eq "wr-admin-rd-group")
+ {
+ # add "admin" to the read group to avoid read/write auth conflicts
+ $REQUIRE .= " admin";
+ }
+ }
+ if ($ispassibay)
+ {
+ #we have local-pw or global-pw or global-pw-remote
+ $REQUIRE = ( $REQUIRE =~ /Require user / ) ? "$REQUIRE $key" : "Require user $key";
+ $REQUIRE .= " $MEMBERS" if ( $access =~ /remote/ );
+ }
+ }
+ else
+ {
+ if ($accessMode eq "wr-admin-rd-group")
+ {
+ $REQUIRE = "Require user admin";
+ }
+ else
+ {
+ $REQUIRE = "Require user " . $MEMBERS;
+ }
+ }
+ return $REQUIRE;
+ }
+
+ sub getAllow {
+ my ($mode, $key, $localAccess ) = @_;
+ $localAccess = (defined $localAccess ) ? $localAccess : "127.0.0.1";
+ my $ibay = $adb->get($key) or return "Require ip 127.0.0.1";
+ my %properties = $ibay->props or return "Require ip 127.0.0.1";
+ my $Public = $properties{'PublicAccess'} || 'none';
+
+ my $allow = "Require ip 127.0.0.1";
+ if ($Public eq 'none')
+ {
+ $allow = "# allow from set to NONE";
+ }
+ elsif ($Public =~ /(local|remote)/ )
+ {
+ $allow = "Require ip " . $localAccess;
+ }
+ elsif ($Public =~ /global/)
+ {
+ $allow = "Require all granted";
+ }
+ return $allow;
+ }
+
+ sub getMembers {
+ my ($key, $iBayGroup) = @_;
+ my $MEMBERS = $key;
+ foreach my $group ( ($adb->groups, $adb->get('admin'), $adb->get('shared') ) )
+ {
+ my %groupprops = $group->props;
+ my $grpkey = $group->key;
+ if ($grpkey eq $iBayGroup)
+ {
+ # we have the group that owns the DAV iBay
+ # If there are members of the group validate on them,
+ # otherwise on the ibayname
+ my $GroupMembers = $groupprops{'Members'} || undef;
+ $GroupMembers = "admin" if ( $grpkey eq "admin" );
+ $GroupMembers = join(' ' , ( (map { $_->key } $adb->users) , qw (admin) )) if ( $grpkey eq "shared" ) ;
+
+ if ($GroupMembers)
+ {
+ # need to break user list on commas then output each one...
+ my @values = split(',',$GroupMembers);
+ $MEMBERS = "" unless (!@values) ;
+ foreach my $val (@values) {
+ $MEMBERS .= $val . " ";
+ }
+ }
+ }
+ }
+ return $MEMBERS;
+ }
diff --git a/root/var/run/davLocks/.gitignore b/root/var/run/davLocks/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/smeserver-mod_dav.spec b/smeserver-mod_dav.spec
new file mode 100644
index 0000000..e3fabd8
--- /dev/null
+++ b/smeserver-mod_dav.spec
@@ -0,0 +1,84 @@
+# $Id: smeserver-mod_dav.spec,v 1.7 2022/07/29 04:17:39 jpp Exp $
+# Authority: snetram
+# Name: Jonathan Martens
+
+%define name smeserver-mod_dav
+%define version 1.1
+%define release 9
+
+Summary: SME Server mod_dav implementation
+Name: %{name}
+Version: %{version}
+Release: %{release}%{?dist}
+License: GPL
+Group: Applications/Internet
+Source: %{name}-%{version}.tar.xz
+
+BuildArchitectures: noarch
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+Requires: e-smith-apache >= 2.6.0-19
+Requires: smeserver-release >= 10
+Requires: httpd >= 2.4.6
+BuildRequires: e-smith-devtools >= 1.13.1-03
+
+%description
+Implementation of mod_dav for SME Server 7.
+
+%changelog
+* Sat Sep 07 2024 cvs2git.sh aka Brian Read 1.1-9.sme
+- Roll up patches and move to git repo [SME: 12338]
+
+* Sat Sep 07 2024 BogusDateBot
+- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday,
+ by assuming the date is correct and changing the weekday.
+
+* Thu Jul 28 2022 Jean-Philippe Pialasse 1.1-8.sme
+- update to apache 2.4 access syntax [SME: 12051]
+
+* Mon Jun 21 2021 Terry Fage 1.1-7.sme
+- Ensure persistence of/var/run/davlocks on reboot/reconfig [SME: 11630]
+
+* Mon Mar 01 2021 Jean-Philipe Pialasse 1.1-6.sme
+- fix security issues [SME: 11077]
+ where user could access ibay he was not member of group
+- improve ibay dav template [SME 4564]
+ force ssl, secure php file, disable cgi and php
+ when DAV enabled on ibay, and respect rmeote access settings
+- descriptive login box [SME: 5337]
+- fix some typos and propertie names
+
+* Sun Feb 28 2021 Jean-Philipe Pialasse 1.1-4.sme
+- add createlinks and add -update event [SME: 11070]
+
+* Thu Oct 29 2020 Brian Read 1.1-3.sme
+- Initial import into SME10 tree [SME: 11070]
+
+* Tue Jun 10 2014 stephane de Labrusse - 1.1-2.sme
+- added new way to authenticate to apache [sme:8340]
+
+* Wed Nov 13 2013 Daniel Berteaud 1.1-1.sme
+- Rebuild for SME9
+
+* Mon May 28 2012 Jonathan Martens 1.0-1.sme
+- Initial version
+
+%prep
+%setup
+
+
+%build
+perl createlinks
+
+%install
+rm -rf %buildroot
+(cd root ; find . -depth -print | cpio -dump %buildroot)
+rm -f %{name}-%{version}-filelist
+/sbin/e-smith/genfilelist %buildroot \
+ --dir /var/run/davLocks 'attr(0755,www,www)' \
+ > %{name}-%{version}-filelist
+
+%clean
+rm -rf %buildroot
+
+%files -f %{name}-%{version}-filelist
+%defattr(-,root,root)