Skip to content

Commit 08e5efd

Browse files
committed
[bugfix] allow public downloads, tighten security
Do not allow members of group "repo" to modify package contents. Set UID for get-package.xq to allow guest to download packages while still be able to write logs.
1 parent 3f2d61f commit 08e5efd

File tree

5 files changed

+55
-97
lines changed

5 files changed

+55
-97
lines changed

modules/config.xqm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ declare function config:repo-descriptor() as element(repo:meta) {
7676
declare function config:repo-permissions() as map(*) {
7777
config:repo-descriptor()/repo:permissions !
7878
map {
79-
"user": ./@user/string(),
79+
"owner": ./@user/string(),
8080
"group": ./@group/string(),
8181
"mode": ./@mode/string()
8282
}

modules/db-utility.xqm

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function dbu:ensure-collection($path as xs:string) as xs:string {
3030
: will throw an error if the current user does not have the appropriate rights
3131
:
3232
: @param $path xs:string
33-
: @param $permissions map(xs:string, xs:string) user, group, mode
33+
: @param $permissions map(xs:string, xs:string) with "owner", "group", "mode"
3434
: @returns the path that was entered
3535
:)
3636
declare
@@ -60,18 +60,15 @@ function dbu:set-repo-permissions ($resource-or-collection as xs:string) as xs:s
6060
: will throw an error, if the current user does not have the appropriate rights
6161
:
6262
: @param $resource-or-collection xs:string
63-
: @param $permissions map(xs:string, xs:string) with "user", "group", "mode"
63+
: @param $permissions map(xs:string, xs:string) with "owner", "group", "mode"
6464
: @returns the path that was entered
6565
:)
6666
declare
6767
function dbu:set-permissions ($resource-or-collection as xs:string, $permissions as map(*)) as xs:string {
68-
let $set := (
69-
sm:chown($resource-or-collection, $permissions?owner),
70-
sm:chgrp($resource-or-collection, $permissions?group),
71-
sm:chmod(xs:anyURI($resource-or-collection), $permissions?mode)
72-
)
73-
74-
return $resource-or-collection
68+
sm:chown($resource-or-collection, $permissions?owner),
69+
sm:chgrp($resource-or-collection, $permissions?group),
70+
sm:chmod(xs:anyURI($resource-or-collection), $permissions?mode),
71+
$resource-or-collection
7572
};
7673

7774
declare

modules/log.xqm

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ xquery version "3.1";
2727
module namespace log="http://exist-db.org/xquery/app/log";
2828

2929
import module namespace config="http://exist-db.org/xquery/apps/config" at "config.xqm";
30-
import module namespace scanrepo="http://exist-db.org/xquery/admin/scanrepo" at "scan.xqm";
30+
import module namespace dbu="http://exist-db.org/xquery/utility/db" at "db-utility.xqm";
31+
32+
declare variable $log:base-collection := $config:logs-col;
33+
declare variable $log:file-permission := map:merge((
34+
$dbu:default-permissions,
35+
map { "mode": "rw-rw-r--" }
36+
));
3137

3238
(:~
3339
: Append entries to the structured application event log
@@ -37,53 +43,37 @@ import module namespace scanrepo="http://exist-db.org/xquery/admin/scanrepo" at
3743
:)
3844
declare function log:event($event as element(event)) as empty-sequence() {
3945
let $today := current-date()
40-
let $log-collection-name := log:collection($today)
41-
let $log-collection := $config:logs-col || "/" || $log-collection-name
46+
let $log-collection := log:collection($today)
4247
let $log-document-name := log:document-name($today)
43-
let $log-document := $log-collection || "/" || $log-document-name
44-
let $store-log :=
45-
if (doc-available($log-document)) then
46-
update insert $event into doc($log-document)/public-repo-log
47-
else
48-
(
49-
if (xmldb:collection-available($log-collection)) then
50-
()
51-
else
52-
log:mkcol($config:logs-col, $log-collection-name),
53-
scanrepo:store($log-collection, $log-document-name, element public-repo-log { $event })
54-
)
48+
5549
return
56-
()
50+
if (doc-available($log-collection || "/" || $log-document-name))
51+
then log:append-log($log-collection, $log-document-name, $event)
52+
else log:create-log($log-collection, $log-document-name, $event)
5753
};
5854

59-
declare %private function log:collection($date as xs:date) {
60-
format-date($date, "[Y]/[M01]")
55+
declare %private
56+
function log:append-log ($log-collection as xs:string, $log-document-name as xs:string, $event as element(event)) as empty-sequence() {
57+
let $node := doc($log-collection || "/" || $log-document-name)/public-repo-log
58+
let $update := update insert $event into $node
59+
return ()
6160
};
6261

63-
declare %private function log:document-name($date as xs:date) {
64-
"public-repo-log-" || format-date($date, "[Y]-[M01]-[D01]") || ".xml"
62+
declare %private
63+
function log:create-log ($log-collection as xs:string, $log-document-name as xs:string, $event as element(event)) as empty-sequence() {
64+
dbu:ensure-collection($log-collection)
65+
=> xmldb:store($log-document-name, element public-repo-log { $event })
66+
=> dbu:set-permissions($log:file-permission)
67+
=> log:return-empty()
6568
};
6669

67-
(:~
68-
: Recursively create a collection hierarchy
69-
:)
70-
declare %private function log:mkcol($collection as xs:string, $path as xs:string) {
71-
log:mkcol-recursive($collection, tokenize($path, "/"))
70+
declare %private
71+
function log:return-empty ($item as item()*) as empty-sequence() {};
72+
73+
declare %private function log:collection($date as xs:date) as xs:string {
74+
$log:base-collection || "/" || format-date($date, "[Y]/[M01]")
7275
};
7376

74-
declare
75-
%private
76-
function log:mkcol-recursive($collection as xs:string, $components as xs:string*) {
77-
if (exists($components)) then
78-
let $newColl := concat($collection, "/", $components[1])
79-
return (
80-
xmldb:create-collection($collection, $components[1]) !
81-
(
82-
sm:chgrp(xs:anyURI(.), config:repo-permissions()?mode),
83-
.
84-
),
85-
log:mkcol-recursive($newColl, subsequence($components, 2))
86-
)
87-
else
88-
()
77+
declare %private function log:document-name($date as xs:date) as xs:string {
78+
"public-repo-log-" || format-date($date, "[Y]-[M01]-[D01]") || ".xml"
8979
};

post-install.xq

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ xquery version "3.1";
88
:)
99

1010
import module namespace config="http://exist-db.org/xquery/apps/config" at "modules/config.xqm";
11+
import module namespace dbu="http://exist-db.org/xquery/utility/db" at "modules/db-utility.xqm";
1112
import module namespace scanrepo="http://exist-db.org/xquery/admin/scanrepo" at "modules/scan.xqm";
1213

1314
declare namespace sm="http://exist-db.org/xquery/securitymanager";
@@ -33,63 +34,33 @@ declare variable $logs-xconf :=
3334
</index>
3435
</collection>;
3536

36-
(: Helper function to recursively create a collection hierarchy :)
37-
declare function local:mkcol-recursive($collection as xs:string, $components as xs:string*) {
38-
if (exists($components)) then
39-
let $newColl := concat($collection, "/", $components[1])
40-
return (
41-
xmldb:create-collection($collection, $components[1]),
42-
local:mkcol-recursive($newColl, subsequence($components, 2))
43-
)
44-
else
45-
()
46-
};
37+
declare variable $permissions := config:repo-permissions();
4738

48-
(: Create a collection hierarchy :)
49-
declare function local:mkcol($collection as xs:string, $path as xs:string) {
50-
local:mkcol-recursive($collection, tokenize($path, "/"))
51-
};
39+
(: Create the data collection hierarchy and set the package permissions :)
5240

53-
(:~
54-
: Set user and group to be owner by values in repo.xml
55-
:)
56-
declare function local:set-data-collection-permissions($resource as xs:string) {
57-
if (sm:get-permissions(xs:anyURI($resource))/sm:permission/@group = config:repo-permissions()?group) then
58-
()
59-
else
60-
(
61-
sm:chown($resource, config:repo-permissions()?user),
62-
sm:chgrp($resource, config:repo-permissions()?group),
63-
sm:chmod(xs:anyURI($resource), config:repo-permissions()?mode)
64-
)
65-
};
66-
67-
(: Create the data collection hierarchy :)
68-
69-
xmldb:create-collection($config:app-data-parent-col, $config:app-data-col-name),
70-
for $col-name in ($config:icons-col-name, $config:metadata-col-name, $config:packages-col-name, $config:logs-col-name)
71-
return
72-
xmldb:create-collection($config:app-data-col, $col-name),
41+
for-each((
42+
$config:app-data-col,
43+
$config:packages-col,
44+
$config:icons-col,
45+
$config:metadata-col,
46+
$config:logs-col
47+
), dbu:ensure-collection(?)),
7348

7449
(: Create log indexes :)
7550

76-
local:mkcol("/db/system/config", $config:logs-col),
77-
xmldb:store("/db/system/config" || $config:logs-col, "collection.xconf", $logs-xconf),
51+
"/db/system/config" || $config:logs-col
52+
=> dbu:ensure-collection(map {"owner": "SYSTEM", "group": "dba", "mode": "rwxr-xr-x"})
53+
=> xmldb:store("collection.xconf", $logs-xconf)
54+
=> dbu:set-permissions(map {"owner": "SYSTEM", "group": "dba", "mode": "rw-r--r--"})
55+
,
7856
xmldb:reindex($config:logs-col),
7957

80-
(: Set user and group ownership on the package data collection hierarchy :)
81-
82-
for $col in ($config:app-data-col, xmldb:get-child-collections($config:app-data-col) ! ($config:app-data-col || "/" || .))
83-
return
84-
local:set-data-collection-permissions($col),
85-
8658
(: Build package metadata if missing :)
8759

8860
if (doc-available($config:raw-packages-doc) and doc-available($config:package-groups-doc)) then
8961
()
9062
else
9163
scanrepo:rebuild-all-package-metadata(),
9264

93-
(: Ensure get-package.xq is run as "repo" group, so that it can write to logs :)
94-
95-
sm:chmod(xs:anyURI($target || "/modules/get-package.xq"), "g+s")
65+
(: Ensure get-package.xq is run as "repo:repo", so that logs will always be writable :)
66+
sm:chmod(xs:anyURI($target || "/modules/get-package.xq"), "rwsr-sr-x")

repo.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<target>public-repo</target>
1111
<prepare/>
1212
<finish>post-install.xq</finish>
13-
<permissions password="repo" user="repo" group="repo" mode="rwxrwxr-x"/>
13+
<permissions password="repo" user="repo" group="repo" mode="rwxr-xr-x"/>
1414
<changelog>
1515
<change version="2.0.0">
1616
<ul xmlns="http://www.w3.org/1999/xhtml">

0 commit comments

Comments
 (0)