fix
[mirror/dsa-puppet.git] / modules / roles / files / static-mirroring / static-mirror-ssh-wrap
1 #!/bin/bash
2
3 # This is a wrapper script for ssh access on Debian's static mirroring infrastructure.
4 #
5 # It limits the commands the master can run on static-mirroring mirrors (i.e.
6 # the things running apache) on one hand, and also on static-mirroring sources,
7 # that is the things that create the data.
8
9 # Copyright (c) 2009, 2010, 2012 Peter Palfrader
10 #
11 # Permission is hereby granted, free of charge, to any person obtaining
12 # a copy of this software and associated documentation files (the
13 # "Software"), to deal in the Software without restriction, including
14 # without limitation the rights to use, copy, modify, merge, publish,
15 # distribute, sublicense, and/or sell copies of the Software, and to
16 # permit persons to whom the Software is furnished to do so, subject to
17 # the following conditions:
18 #
19 # The above copyright notice and this permission notice shall be
20 # included in all copies or substantial portions of the Software.
21 #
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 set -e
31 set -u
32
33 MYLOGNAME="`basename "$0"`[$$]"
34 COMPONENTLIST=/etc/static-components.conf
35
36 usage() {
37         echo "local Usage: $0 <basedir> <host>"
38         echo "via ssh orig command:"
39         echo "                      mirror <component> <serial>"
40         echo "                      rsync ..."
41                 do_rsync "$remote_host" "$@"
42 }
43
44 one_more_arg() {
45         if [ "$#" -lt 1 ]; then
46                 usage >&2
47                 exit 1
48         fi
49 }
50
51 info() {
52         logger -p daemon.info -t "$MYLOGNAME" "$1"
53 }
54
55 croak() {
56         logger -s -p daemon.warn -t "$MYLOGNAME" "$1"
57         exit 1
58 }
59
60 do_mirror() {
61         local basedir="$1"; shift
62         local remote_host="$1"; shift
63         one_more_arg "$@"
64         local component="$1"; shift
65         one_more_arg "$@"
66         local serial="$1"; shift
67
68         masterhost="$(awk -v component="$component" '$2 == component {print $1; exit}' "$COMPONENTLIST")"
69         if [ -z "$masterhost" ]; then
70                 croak "Did not find master for component $component."
71         elif [ "$msterhost" != "$remote_host" ]; then
72                 croak "$remote_host is not master for $component."
73         else
74                 info "Host $remote_host triggered a mirror run for $component, serial $serial"
75                 exec /usr/local/bin/static-mirror-run "$basedir/mirrors/$component" "$remote_host:$component/-new-" "$serial"
76                 echo >&2 "Exec failed"
77                 croak "exec failed"
78         fi
79 }
80
81 do_rsync() {
82         local remote_host="$1"
83         shift
84
85         local allowed_rsyncs
86         allowed_rsyncs=()
87
88         if [ -e "$COMPONENTLIST" ]; then
89                 for path in $(awk -v host="$(hostname -f)" '$3 == host {print $4}' $COMPONENTLIST); do
90                         allowed_rsyncs+=("--server --sender -lHtrze.iLsf --safe-links . $path/.")
91                 done
92         fi
93         for cmd_idx in ${!allowed_rsyncs[*]}; do
94                 allowed="${allowed_rsyncs[$cmd_idx]}"
95                 if [ "$*" = "$allowed" ]; then
96                         info "Running for host $remote_host: rsync $*"
97                         exec rsync "$@"
98                         echo >&2 "Exec failed"
99                         exit 1
100                 fi
101         done
102
103         info "NOT allowed for $remote_host: rsync $*"
104         echo >&2 "This rsync command ($*) not allowed."
105         exit 1
106 }
107
108
109 if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
110         usage
111         exit 0
112 fi
113
114 one_more_arg "$@"
115 basedir="$1"
116 shift
117
118 one_more_arg "$@"
119 remote_host="$1"
120 shift
121
122
123 # check/parse remote command line
124 if [ -z "${SSH_ORIGINAL_COMMAND:-}" ] ; then
125         croak "Did not find SSH_ORIGINAL_COMMAND"
126 fi
127 set "dummy" ${SSH_ORIGINAL_COMMAND}
128 shift
129
130 one_more_arg "$@"
131 action="$1"
132 shift
133
134 case "$action" in
135         mirror)
136                 do_mirror "$basedir" "$remote_host" "$@"
137                 ;;
138         rsync)
139                 do_rsync "$remote_host" "$@"
140                 ;;
141         *)
142                 croak "Invalid operation '$action'"
143                 ;;
144 esac