3 # This is a RackTables gateway for changing switch ports membership
4 # across VLANs. It works accordingly to the gateway protocol described
5 # in gateways.php and accepts the following commands on its stdin:
6 # * listvlans: list all VLANs found on the switch, propably filtering
7 # out those administratively prohibited. Only the VLANs from this
8 # list will be allowed as new destination for 'set' command.
9 # * listports: list all ports on the switch and their current status.
10 # Untagged (switchport mode access) ports will be shown with their
11 # VLAN ID and tagged ports will be shown as 'trunk' regardless of
12 # how many VLANs they are members of.
24 local endp
=$1 user
=$2 action
=$3 arg1
=$4 arg2
=$5 skip
=yes cval
25 [ -z "$endp" -o -z "$user" -o -z "$action" ] && return 1
27 # Now we strip PHP wrapping(s) and process auth rules only.
28 # Accept more than one ruleset on the floor.
30 if [ "$skip" = "yes" -a "$line" = "# S-T-A-R-T" ]; then
34 if [ "$skip" = "no" -a "$line" = "# S-T-O-P" ]; then
38 [ "$skip" = "yes" ] && continue
40 [ -z "${line###*}" ] && continue
42 # Parse the line and try to make a decision earliest possible.
43 # Username and endpoint must match values/regexps, action
44 # must exactly match. Action arguments are tested agains values
45 # or regexps, but only for 'change' action.
46 # If the current rule doesn't match, advance to the next one.
47 # We will fail authorization by default anyway.
50 cval
=`echo "$line" | cut -s -d' ' -f3`
51 [ "$action" = "$cval" ] ||
continue
54 cval
=`echo "$line" | cut -s -d' ' -f2 | cut -s -d'@' -f1`
55 [ -z "${user##$cval}" ] ||
continue
58 cval
=`echo "$line" | cut -s -d' ' -f2 | cut -s -d'@' -f2`
59 [ -z "${endp##$cval}" ] ||
continue
61 if [ "$action" = "change" ]; then
62 [ -z "$arg1" -o -z "$arg2" ] && return 1
63 cval
=`echo "$line" | cut -s -d' ' -f4`
64 [ -z "${arg1##$cval}" ] ||
continue
65 cval
=`echo "$line" | cut -s -d' ' -f5`
66 [ -z "${arg2##$cval}" ] ||
continue
69 # All criterias match. Pick the permission and bail out.
70 cval
=`echo "$line" | cut -s -d' ' -f1`
71 if [ "$cval" = "allow" ]; then
76 done < "$MYDIR/userauth.php"
80 # Not only connect, but gather all the data at once and remember the context.
83 endpoint
=`echo $args | cut -s -d' ' -f1`
84 hw
=`echo $args | cut -s -d' ' -f2`
85 sw
=`echo $args | cut -s -d' ' -f3`
86 user
=`echo $args | cut -s -d' ' -f4`
88 if [ -z "$endpoint" -o -z "$hw" -o -z "$sw" -o -z "$user" ]; then
89 echo 'ERR!too few arguments to connect'
93 Cisco
+IOS
+12.0|Cisco
+IOS
+12.2)
97 echo "ERR!Don't know how to handle $sw on $endpoint"
102 # authorize user, look for "connect" privilege
103 if ! authorized
$endpoint $user connect
; then
104 echo "ERR!User $user is not authorized to connect to $endpoint"
109 PORTINFO
=`mktemp /tmp/racktables.XXXX`
110 if ! [ -f "$PORTINFO" ]; then
111 echo 'ERR!could not create portinfo tmpfile'
114 VLANINFO
=`mktemp /tmp/racktables.XXXX`
115 if ! [ -f "$VLANINFO" ]; then
116 echo 'ERR!could not create vlaninfo tmpfile'
122 "$MYDIR/$handler.connector" $endpoint fetch
"$VLANINFO" "$PORTINFO"
124 if [ $ret = 0 ]; then
126 echo "OK!connected to $endpoint";
128 echo "ERR!Cannot connect to $endpoint, connector returned code $ret"
135 if ! [ -f "$F" ]; then
136 echo "ERR!Lost temp file '$F' on the way"
141 # tr might do the work, but use our chance to perform filtering once more
142 cat "$F" |
while read line
; do
143 [ "$line" = "" ] && continue
144 echo -n "$COMMA$line"
154 if [ -z "$setline" ]; then
155 echo 'ERR!missing set argument'
158 local REQUESTS
=`mktemp /tmp/racktables.XXXX`
159 local REPLIES
=`mktemp /tmp/racktables.XXXX`
160 echo $1 |
tr ';' '\n' |
while read setexpr
; do
161 portname
=`echo $setexpr | cut -s -d'=' -f1`
162 newvlan
=`echo $setexpr | cut -s -d'=' -f2`
163 curvlan
=`egrep "^$portname=" $PORTINFO | cut -s -d'=' -f2`
164 if [ -z "$curvlan" ]; then
165 echo "E!Could not find port $portname" >> "$REPLIES"
168 if [ "$curvlan" = "trunk" ]; then
169 echo "E!Port $portname is a trunk" >> "$REPLIES"
172 [ "$curvlan" = "$newvlan" ] && continue
173 # Authorize user for each change.
174 if ! authorized
$endpoint $user change
$curvlan $newvlan; then
175 echo "E!User $user is not authorized to assign port $portname@$endpoint from VLAN $curvlan to VLAN $newvlan" >> "$REPLIES"
178 echo "$portname $newvlan" >> "$REQUESTS"
180 nr
=`egrep -c '^.' "$REPLIES"`
181 if [ "$nr" -ge 1 ]; then
182 echo "W!$nr change request(s) have been ignored" >> "$REPLIES"
185 nq
=`egrep -c '^.' "$REQUESTS"`
186 if [ "$nq" -ge 1 ]; then
188 "$MYDIR/$handler.connector" $endpoint push
"$REQUESTS" "$REPLIES"
191 if [ $ret != 0 ]; then
192 echo "ERR!Failed to configure $endpoint, connector returned code $ret"
195 echo "I!$nq change request(s) have been processed" >> "$REPLIES"
200 echo -n $SEMICOLON$reply
202 [ -w "$MYDIR/changes.log" ] && echo "$reply" >> "$MYDIR/changes.log"
205 rm -f "$REQUESTS" "$REPLIES"
209 while read cmd args
; do
212 if [ $CONNECTED = 1 ]; then
213 echo 'ERR!Already connected'
219 if [ $CONNECTED = 1 ]; then
220 do_listfile
"$VLANINFO"
222 echo 'ERR!Not connected'
226 if [ $CONNECTED = 1 ]; then
227 do_listfile
"$PORTINFO"
229 echo 'ERR!Not connected'
233 if [ $CONNECTED = 1 ]; then
236 echo 'ERR!Not connected'
240 echo "ERR!unknown command $cmd"
244 rm -f "$PORTINFO" "$VLANINFO"