diff --git a/net/radicale/Makefile b/net/radicale/Makefile new file mode 100644 index 000000000..329ab68f0 --- /dev/null +++ b/net/radicale/Makefile @@ -0,0 +1,138 @@ +# +# Copyright (C) 2008-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=radicale +PKG_VERSION:=0.10 +PKG_RELEASE:=1 +PKG_MAINTAINER:=Christian Schoenebeck + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=COPYING + +PKG_SOURCE:=Radicale-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://pypi.python.org/packages/source/R/Radicale/ +PKG_MD5SUM:=32655d8893962956ead0ad690cca6044 + +# needed for "r"adicale <-> "R"adicale +PKG_BUILD_DIR:=$(BUILD_DIR)/Radicale-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +# no default dependencies +PKG_DEFAULT_DEPENDS= + +define Package/$(PKG_NAME)/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + URL:=http://radicale.org/ + PKGARCH:=all + USERID:=radicale=5232:radicale=5232 +endef +define Package/$(PKG_NAME)-py2 + $(call Package/$(PKG_NAME)/Default) + PYTHON_VERSION:=2.7 + TITLE:=Radicale CalDAV/CardDAV server (Python 2) + VARIANT:=python2 + DEPENDS:=+python-logging +python-openssl +python-xml +python-codecs +endef +define Package/$(PKG_NAME)-py3 + $(call Package/$(PKG_NAME)/Default) + PYTHON_VERSION:=3.4 + TITLE:=Radicale CalDAV/CardDAV server (Python 3) + VARIANT:=python3 + DEPENDS:=+python3-logging +python3-openssl +python3-xml +python3-codecs +python3-email @BROKEN +endef + +# shown in LuCI package description +define Package/$(PKG_NAME)-py2/description +Radicale CalDAV/CardDAV server (Python 2) - Homepage: http://radicale.org/ +endef +define Package/$(PKG_NAME)-py3/description +Radicale CalDAV/CardDAV server (Python 3) - Homepage: http://radicale.org/ +endef + +# shown in make menuconfig +define Package/$(PKG_NAME)-py2/config + help + The Radicale Project is a CalDAV (calendar) and CardDAV (contact) server. + It aims to be a light solution, easy to use, easy to install, easy to configure. + As a consequence, it requires few software dependances and is pre-configured to work out-of-the-box. + !!! Will install and use Python $(PYTHON_VERSION) !!! + . + Version : $(PKG_VERSION) + Homepage: http://radicale.org/ + . + $(PKG_MAINTAINER) +endef +Package/$(PKG_NAME)-py3/config = $(Package/$(PKG_NAME)-py2/config) + +define Package/$(PKG_NAME)-py2/conffiles +/etc/config/radicale +/etc/radicale/users +/etc/radicale/rights +endef +Package/$(PKG_NAME)-py3/conffiles = $(Package/$(PKG_NAME)-py2/conffiles) + +define Build/Configure +endef +define Build/Compile +endef + +define Package/$(PKG_NAME)-py2/preinst + #!/bin/sh + [ -n "$${IPKG_INSTROOT}" ] && exit 0 # if run within buildroot exit + + # stop service if PKG_UPGRADE + [ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/$(PKG_NAME) stop >/dev/null 2>&1 + + exit 0 # supress errors from stop command +endef +define Package/$(PKG_NAME)-py3/preinst +$(call Package/$(PKG_NAME)-py2/preinst) +endef + +define Package/$(PKG_NAME)-py2/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/radicale.init $(1)/etc/init.d/radicale + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) ./files/radicale.hotplug $(1)/etc/hotplug.d/iface/80-radicale + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/radicale.config $(1)/etc/config/radicale + + $(INSTALL_DIR) $(1)/etc/radicale/ssl + $(INSTALL_DATA) ./files/config.template $(1)/etc/radicale/ + $(INSTALL_DATA) ./files/logging.template $(1)/etc/radicale/ + $(INSTALL_DATA) ./files/radicale.users $(1)/etc/radicale/users + $(INSTALL_DATA) ./files/radicale.rights $(1)/etc/radicale/rights + + $(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/site-packages/radicale + $(CP) \ + $(PKG_BUILD_DIR)/radicale/* \ + $(1)/usr/lib/python$(PYTHON_VERSION)/site-packages/radicale + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/radicale $(1)/usr/bin/ +endef +define Package/$(PKG_NAME)-py3/install + $(call Package/$(PKG_NAME)-py2/install, $(1)) +endef + +define Package/$(PKG_NAME)-py2/postinst + #!/bin/sh + # patch /usr/bin/radicale force run using python2 + /bin/sed -i 's/python/python2/' $${IPKG_INSTROOT}/usr/bin/radicale +endef +define Package/$(PKG_NAME)-py3/postinst + #!/bin/sh + # patch /usr/bin/radicale force run using python3 + /bin/sed -i 's/python/python3/' $${IPKG_INSTROOT}/usr/bin/radicale +endef + +$(eval $(call BuildPackage,$(PKG_NAME)-py2)) +$(eval $(call BuildPackage,$(PKG_NAME)-py3)) diff --git a/net/radicale/files/config.template b/net/radicale/files/config.template new file mode 100644 index 000000000..1b8fcf294 --- /dev/null +++ b/net/radicale/files/config.template @@ -0,0 +1,30 @@ +# -*- mode: conf -*- +# vim:ft=cfg + +### AUTO-GENERATED CONFIGURATION +### USED BY RADICALE +### DO NOT EDIT +### SEE /etc/config/radicale INSTEAD + +[server] +# daemon # handled by /etc/init.d/radicale +# pid # handled by /etc/init.d/radicale + +[encoding] + +[well-known] + +[auth] +# htpasswd_filename # hard-coded /etc/radicale/users + +[git] + +[rights] +# file # hard-coded /etc/radicale/rights + +[storage] + +[logging] +# config # hard-coded /var/etc/radicale/logging + +[headers] diff --git a/net/radicale/files/logging.template b/net/radicale/files/logging.template new file mode 100644 index 000000000..a730ca01a --- /dev/null +++ b/net/radicale/files/logging.template @@ -0,0 +1,47 @@ +# -*- mode: conf -*- +# vim:ft=cfg + +### AUTO-GENERATED CONFIGURATION +### USED BY RADICALE +### DO NOT EDIT +### SEE /etc/config/radicale INSTEAD + +[loggers] +keys = root + +[handlers] +keys = console,file,syslog + +[formatters] +keys = simple,full,syslog + +[logger_root] +level = DEBUG +handlers = console,file,syslog + +[handler_console] +class = StreamHandler +args = (sys.stdout,) +formatter = simple +# level = WARNING # set via /etc/config/radicale + +[handler_file] +class = handlers.RotatingFileHandler +formatter = full +# level = INFO # set via /etc/config/radicale +# args = ('[filename]','a',[maxbytes],[backupcount]) # set via /etc/config/radicale + +[handler_syslog] +class = handlers.SysLogHandler +args = ('/dev/log', handlers.SysLogHandler.LOG_DAEMON) +formatter = syslog +# level = WARNING # set via /etc/config/radicale + +[formatter_simple] +format = %(message)s + +[formatter_full] +format = %(asctime)s - %(levelname)s: %(message)s + +[formatter_syslog] +format = radicale [%(process)d]: %(message)s diff --git a/net/radicale/files/radicale.config b/net/radicale/files/radicale.config new file mode 100644 index 000000000..ea10bc9f4 --- /dev/null +++ b/net/radicale/files/radicale.config @@ -0,0 +1,192 @@ +# +# You find additional information on Radicale Homepage +# http://radicale.org +# +# OpenWrt's wiki needs to be setup/updated ;-) +# +# if setting additional options please remember that UCI does not support +# section names and option names with "-" (Dash) inside their name +# to use them anyway replace "-" with "_" (Underscore) +# Each Radicale's config [section] is setup as UCI config setting 'section' +# + +#################################################### +# Server options +# +config setting 'server' + + # hostname:port + # IPv4 syntax: address:port + # IPv6 syntax: [address]:port + # ATTENTION: + # only use ports > 1024 (non-privileged Ports) + # because this implementation is running as non-root user + # Default: 0.0.0.0:5232 +# list hosts '0.0.0.0:5232' +# list hosts 'localhost:5232' + + # SSL flag, enable HTTPS protocol + # Default: 0 (disabled) +# option ssl '1' + + # SSL Protocol used. See python's ssl module for available values + # Default: PROTOCOL_SSLv23 +# option protocol 'PROTOCOL_SSLv23' + + # Ciphers available. See python's ssl module for available ciphers +# option ciphers '' + + # SSL certificate path and file +# option certificate '/etc/radicale/ssl/server.crt' + + # SSL private key path and file +# option key '/etc/radicale/ssl/server.key' + + # Reverse DNS to resolve client address in logs + # Default: 0 (disabled) +# option dns_lookup '1' + + # Message displayed in the client when a password is needed +# option realm 'Radicale - Password Required' + + +#################################################### +# Encoding options +# +config setting 'encoding' + + # Encoding for responding requests +# option request 'utf-8' + + # Encoding for storing local collections +# option stock 'utf-8' + + +#################################################### +# Authentication options +# +config setting 'auth' + + # Authentication method + # Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | remote_user | custom + # Default: None + # if setting 'htpasswd' the file /etc/radicale/users is used (hardcoded) +# option type 'htpasswd' + + # Htpasswd encryption method + # Value: plain | sha1 | ssha | crypt +# option htpasswd_encryption 'crypt' + + # for other authenication methods consult Radicale documentation + # and set options here + + +#################################################### +# Git default options +# +config setting 'git' + + # Git default options +# option committer 'Radicale ' + + +#################################################### +# Rights backend +# +config setting 'rights' + + # Value: None | authenticated | owner_only | owner_write | from_file | custom + # Default: None + # if setting 'from_file' the file /etc/radicale/rights is used (hardcoded) +# option type 'from_file' + + # Custom rights handler +# option custom_handler '' + + +#################################################### +# Storage backend +# ------- +# WARNING: ONLY "filesystem" IS DOCUMENTED AND TESTED, +# OTHER BACKENDS ARE NOT READY FOR PRODUCTION. +# ------- +# +config setting 'storage' + # Value: filesystem | multifilesystem | database | custom + option type 'filesystem' + option filesystem_folder '/srv/radicale' + + +#################################################### +# Additional HTTP headers +# +config setting 'headers' + # enable all if using CardDavMATE-, CalDavZAP- or InfCloud- WEBclient +# list Access_Control_Allow_Origin '*' +# list Access_Control_Allow_Methods 'GET' +# list Access_Control_Allow_Methods 'POST' +# list Access_Control_Allow_Methods 'OPTIONS' +# list Access_Control_Allow_Methods 'PROPFIND' +# list Access_Control_Allow_Methods 'PROPPATCH' +# list Access_Control_Allow_Methods 'REPORT' +# list Access_Control_Allow_Methods 'PUT' +# list Access_Control_Allow_Methods 'MOVE' +# list Access_Control_Allow_Methods 'DELETE' +# list Access_Control_Allow_Methods 'LOCK' +# list Access_Control_Allow_Methods 'UNLOCK' +# list Access_Control_Allow_Headers 'User-Agent' +# list Access_Control_Allow_Headers 'Authorization' +# list Access_Control_Allow_Headers 'Content-type' +# list Access_Control_Allow_Headers 'Depth' +# list Access_Control_Allow_Headers 'If-match' +# list Access_Control_Allow_Headers 'If-None-Match' +# list Access_Control_Allow_Headers 'Lock-Token' +# list Access_Control_Allow_Headers 'Timeout' +# list Access_Control_Allow_Headers 'Destination' +# list Access_Control_Allow_Headers 'Overwrite' +# list Access_Control_Allow_Headers 'X-client' +# list Access_Control_Allow_Headers 'X-Requested-With' +# list Access_Control_Expose_Headers 'Etag' + + +#################################################### +# Global logging options +# +config setting 'logging' + + # Set the default logging level to debug for all outputs (ignore output level settings) + # Default: 0 (disabled) +# option debug '1' + # Log all environment variables (including those set in the shell) when starting + # Default: 0 (disabled) +# option full_environment '1' + + +#################################################### +# Spezial logging options +# !!! not documented in Radicale documentation +# !!! special settings for this implementation +# +config logging 'logger' + + # Level: DEBUG | INFO | WARNING | ERROR | CRITICAL + # To nearly disable logging set level to critical + + # log level on console +# option console_level 'ERROR' + + # Here we use Rotating Logfiles in this implementation + # !!! if maxbytes and/or backupcount is set to 0 !!! + # !!! file rotation is disabled and logfile grows endless !!! + # log level +# option file_level 'INFO' + # directory where log files are written +# option file_path '/var/log/radicale' + # max size of each logfile (see warning above) +# option file_maxbytes '8196' + # number of backup files to create (see warning above) +# option file_backupcount '1' + + # log level for syslog logging +# option syslog_level 'WARNING' + diff --git a/net/radicale/files/radicale.hotplug b/net/radicale/files/radicale.hotplug new file mode 100644 index 000000000..634ad2efa --- /dev/null +++ b/net/radicale/files/radicale.hotplug @@ -0,0 +1,16 @@ +#!/bin/sh + +# only (re-)start on ifup +[ "$ACTION" = "ifup" ] || exit 0 + +_PID=$(ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}') +kill -1 $_PID 2>/dev/null +if [ $? -eq 0 ]; then + # only restart if already running + logger -p user.info -t "radicale[$_PID]" \ + "Restart request due to '$ACTION' of interface '$INTERFACE'" + /etc/init.d/radicale restart +else + # only start if enabled + /etc/init.d/radicale enabled && /etc/init.d/radicale start +fi diff --git a/net/radicale/files/radicale.init b/net/radicale/files/radicale.init new file mode 100755 index 000000000..bb35a18a0 --- /dev/null +++ b/net/radicale/files/radicale.init @@ -0,0 +1,220 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2015 OpenWrt.org + +START=80 +STOP=10 + +CFGDIR=/var/etc/radicale +SYSCFG=$CFGDIR/config +LOGCFG=$CFGDIR/logging + +DATADIR="/srv/radicale" +LOGDIR="" + +PGREP="ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}' " + +# we could start with empty configuration file using defaults +[ -f /etc/config/radicale ] || touch /etc/config/radicale + +_uci2radicale() { + local _SYSTMP="$SYSCFG.tmp" + local _LOGTMP="$LOGCFG.tmp" + local _LOPT # list option name + local _LVAL # list option value + local _STYPE # section type + local _SNAME # section name + local _console_level="ERROR" # logging console level + local _file_level="INFO" # logging file level + local _file_path="/var/log/radicale" # logging file path + local _file_maxbytes="8196" # logging file maxBytes + local _file_backupcount="1" # logging file backupCount + local _syslog_level="WARNING" # logging syslog level + + # write list values to config + _write_list() { + _write_value "$_LOPT" "$_LVAL" # there might be spaces in _LVAL + _LOPT="" + _LVAL="" + } + + _write_value() { + # $1 option + # $2 value + local __OPT=$1 + local __VAL=$2 + # section "server" ignore option "daemon" and "pid" + [ "$_SNAME" = "server" -a "$__OPT" = "daemon" ] && return 0 + [ "$_SNAME" = "server" -a "$__OPT" = "pid" ] && return 0 + # section "logging" ignore option "config" (logging config file) + [ "$_SNAME" = "logging" -a "$__OPT" = "config" ] && return 0 + # section "auth" ignore option "htpasswd_filename" (htpasswd file) + [ "$_SNAME" = "auth" -a "$__OPT" = "htpasswd_filename" ] && return 0 + # section "rights" ignore option "file" (reg-based rights file) + [ "$_SNAME" = "rights" -a "$__OPT" = "file" ] && return 0 + # section "headers" replace "_" with "-" in option (UCI problem) + [ "$_SNAME" = "headers" ] && __OPT=$(echo "$__OPT" | sed -e "s#_#-#g") + # save data driectory + [ "$_SNAME" = "storage" -a "$__OPT" = "filesystem_folder" ] && DATADIR="$__VAL" + # special handling for well-known, value needs single quotes + [ "$_SNAME" = "well-known" -a "${__VAL#*\%\(}" != "$__VAL" ] && __VAL="'$__VAL'" + # handling of log settings + if [ "$_STYPE" = "logging" -a "$_SNAME" = "logger" ]; then + eval "_$__OPT='$__VAL'" # set to environment for later use + else + # handle bool + [ "$__VAL" = "0" ] && __VAL="False" + [ "$__VAL" = "1" ] && __VAL="True" + # append data to the corresponding section + sed -i "/\[$_SNAME\]/a $__OPT = $__VAL" $_SYSTMP + fi + } + + # redefined callback for sections when calling config_load + config_cb() { + # $1 "Type" + # $2 "Name" + # write out last list option + [ -n "$_LOPT" ] && _write_list + # mark invalid + _STYPE="" + _SNAME="" + # check section type + [ "$1" = "setting" -o "$1" = "logging" ] && { + _STYPE="$1" + _SNAME="$2" + } + # translate section name + [ "$2" = "well_known" ] && _SNAME="well-known" + return 0 + } + + # redefined callback for lists when calling config_load + list_cb() { + # $1 name of variable + # $2 value + # invalid section type then ignore + [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0 + # write out last list option if new list starts + [ -n "$_LOPT" -a "$_LOPT" != "$1" ] && _write_list + # new list option + if [ -z "$_LOPT" ]; then + _LOPT="$1" + _LVAL="$2" + else + _LVAL="$_LVAL, $2" + fi + return 0 + } + + # redefined callback for options when calling config_load + option_cb() { + # $1 name of variable + # $2 value + local __OPT="$1" + local __VAL="$2" + # invalid section type then ignore + [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0 + # ignore list entrys will be handled by list_cb() + [ "${__OPT#*_ITEM}" != "$__OPT" ] && return 0 # ignore lists *_ITEM* + [ "${__OPT#*_LENGTH}" != "$__OPT" ] && return 0 # ignore lists *_LENGTH + # write out last list option and clear + [ -n "$_LOPT" ] && _write_list + # write to file + _write_value "$__OPT" "$__VAL" # there might be spaces in __VAL + return 0 + } + + # temporary config file + # radicale need read access + mkdir -m0755 -p $CFGDIR + + cp /etc/radicale/config.template $_SYSTMP + config_load radicale # calling above config_cb()/option_cb()/list_cb() and write into $_SYSTMP + sed -i "/\[logging\]/a config = /var/etc/radicale/logging" $_SYSTMP # hard-code logging config + sed -i "/\[auth\]/a htpasswd_filename = /etc/radicale/users" $_SYSTMP # hard-code htpasswd + sed -i "/\[rights\]/a file = /etc/radicale/rights" $_SYSTMP # hard-code regexp-based rights + + # temporary logging config file + cp /etc/radicale/logging.template $_LOGTMP + LOGDIR="$_file_path" + sed -i "/\[handler_console\]/a level = $_console_level" $_LOGTMP + sed -i "/\[handler_file\]/a level = $_file_level" $_LOGTMP + sed -i "/\[handler_file\]/a args = ('$_file_path/radicale','a',$_file_maxbytes,$_file_backupcount)" $_LOGTMP + sed -i "/\[handler_syslog\]/a level = $_syslog_level" $_LOGTMP + + # move tmp to final + mv -f $_SYSTMP $SYSCFG + mv -f $_LOGTMP $LOGCFG +} + +_set_permission() { + # config file permissions (read access for group) + chmod 644 $SYSCFG $LOGCFG + chgrp -R radicale $CFGDIR + # log directory (full access and owner) + [ -d $LOGDIR ] || mkdir -m0755 -p $LOGDIR + chown -R radicale:radicale $LOGDIR + # data directory does not exist + [ -d $DATADIR ] || { + logger -p user.error -t "radicale[----]" "Data directory '$DATADIR' does not exists. Startup failed !!!" + exit 1 + } + chgrp -R radicale $DATADIR +} + +boot() { + return 0 # will be started by "iface" hotplug events +} + +start() { + _running() { + sleep 2 # give radicale time to completely come up + local _PID=$(eval "$PGREP") + kill -1 $_PID 2>/dev/null + [ $? -eq 0 ] \ + && logger -p user.notice -t "radicale[$_PID]" "Service started successfully"\ + || logger -p user.warn -t "radicale[----]" "Service failed to start" + } + + # if already running do nothing + local _PID=$(eval "$PGREP") + kill -1 $_PID 2>/dev/null && return 0 + + _uci2radicale + _set_permission + + radicale --daemon --config=$SYSCFG + + _running & # check if running and syslog + + return 0 +} + +reload() { + # reload is also used by luci + local _PID=$(eval "$PGREP") + kill -1 $_PID 2>/dev/null + if [ $? -eq 0 ]; then + # only restart if already running + restart + else + # only start if enabled + enabled && start + fi + return 0 +} + +stop() { + local _PID=$(eval "$PGREP") + [ -z "$_PID" ] && return 0 # not running + kill -15 $_PID 2>/dev/null + sleep 1 # give time to shutdown + local _tmp=$(eval "$PGREP") + if [ -z "$_tmp" ]; then + logger -p user.notice -t "radicale[$_PID]" "Service shutdown successfully" + else + kill -9 $_tmp # Normally never come here + logger -p user.warn -t "radicale[----]" "Service shutdown FORCED" + fi + return 0 +} diff --git a/net/radicale/files/radicale.rights b/net/radicale/files/radicale.rights new file mode 100644 index 000000000..3de3955d3 --- /dev/null +++ b/net/radicale/files/radicale.rights @@ -0,0 +1,49 @@ +# +# Authentication login is matched against the "user" key, and collection's path is matched against the "collection" key. +# You can use Python's ConfigParser interpolation values %(login)s and %(path)s. +# You can also get groups from the user regex in the collection with {0}, {1}, etc. +# +# For example, for the "user" key, ".+" means "authenticated user" and ".*" means "anybody" (including anonymous users). +# +# Section names are only used for naming the rule. +# Leading or ending slashes are trimmed from collection's path. +# + +# This means all users starting with "admin" may read any collection +[admin] +user: ^admin.*$ +collection: .* +permission: r + +# This means all users may read and write any collection starting with public. +# We do so by just not testing against the user string. +[public] +user: .* +collection: ^public(/.+)?$ +permission: rw + +# A little more complex: give read access to users from a domain for all +# collections of all the users (ie. user@domain.tld can read domain/\*). +[domain-wide-access] +user: ^.+@(.+)\..+$ +collection: ^{0}/.+$ +permission: r + +# Allow authenticated user to read all collections +[allow-everyone-read] +user: .+ +collection: .* +permission: r + +# Give write access to owners +[owner-write] +user: .+ +collection: ^%(login)s(/.+)?$ +permission: rw + +# Allow CardDavMATE-, CalDavZAP- or InfCloud- WEBclient to work +# anonymous users have read access to "/" but no files or subdir +[infcloud] +user: .* +collection: / +permission: r diff --git a/net/radicale/files/radicale.users b/net/radicale/files/radicale.users new file mode 100644 index 000000000..772217674 --- /dev/null +++ b/net/radicale/files/radicale.users @@ -0,0 +1,6 @@ +# +# Sample File +# + +user1:password1 +user2:password2 \ No newline at end of file diff --git a/net/radicale/patches/010-Run-as-user-group-radicale-radicale.patch b/net/radicale/patches/010-Run-as-user-group-radicale-radicale.patch new file mode 100644 index 000000000..e1f1c21eb --- /dev/null +++ b/net/radicale/patches/010-Run-as-user-group-radicale-radicale.patch @@ -0,0 +1,30 @@ +Subject: [PATCH] Run as user radicale and group radicale + +Patch to run Radicale service as radicale:radicale non root user + +Signed-off-by: Christian Schoenebeck +--- + bin/radicale | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/bin/radicale b/bin/radicale +index 619aca5..7466020 100755 +--- a/bin/radicale ++++ b/bin/radicale +@@ -26,6 +26,13 @@ Launch the server according to configuration and command-line options. + + """ + ++# inserted to run as user radicale ++import pwd, grp, os ++uid = pwd.getpwnam('radicale').pw_uid ++gid = grp.getgrnam('radicale').gr_gid ++os.setegid(gid) ++os.seteuid(uid) ++ + import radicale.__main__ + + +-- +2.1.0 +