-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfs-cve-2016-6662.sh
160 lines (141 loc) · 4.1 KB
/
fs-cve-2016-6662.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/bin/bash -e
set -o pipefail
FIX=0
EXIT_STATUS=0
SEND_JSON=0
MYCONF=$(which my_print_defaults 2>&1)
usage() {
echo "Usage: $0 [-f]"
echo "Options:"
echo " -f: Fix any problems found"
echo " -j: JSON output"
echo " -v: Verbose output"
echo " -p: specify the my_print_defaults location"
echo " -h: Show this help"
echo
echo "This script finds, checks, and optionally fixes any configuration"
echo "files that my_print_defaults reads. It enforces ownership similar to this:"
echo "-rw-r--r--. 1 root root"
exit 1
}
die() {
printf "[ERROR]: %s\n" "${@}"
exit 1
}
info() {
if [[ $VERBOSE == 1 ]]; then
printf "[INFO]: %s\n" "${@}"
fi
}
warn() {
printf "[WARNING]: %s\n" "${@}"
if [[ $FIX != 1 ]]; then
EXIT_STATUS=1
fi
}
check_file() {
local f=$1
info "Checking ${f}"
if [[ -e $f ]]; then
# Files should be owned by root:root
owner=$(stat -L -c "%U" $f)
group=$(stat -L -c "%G" $f)
if [[ $owner != "root" || $group != "root" ]]; then
warn "Owner of $f is $owner:$group, not root:root."
if [[ $FIX == 1 ]]; then
chown root:root ${f}
fi
fi
# Files should be 644 or more restrictive
mode=$(stat -L -c "%a" $f)
if [[ ( $(( 8#${mode} & 8#020 )) != 0 ) || ( $(( 8#${mode} & 8#002 )) != 0 ) ]]; then
warn "$f is mode ${mode}";
if [[ $FIX == 1 ]]; then
if [[ -f $f ]]; then
chmod 644 ${f}
elif [[ -d $f ]]; then
chmod 755 ${f}
fi
fi
fi
if [[ -f $f ]]; then
# Check for !includedir directives
include_dirs=( $(awk '$1 ~ /^!includedir$/ {print $2}' $f) )
if [[ $include_dirs ]]; then
for d in "${include_dirs[@]}"; do
info "$f has an includedir: $d"
check_file $d
for cfa in ${d%%/}/*.cnf; do
check_file $cfa
done
done
fi
# Check for !include directives
includes=( $(awk '$1 ~ /^!include$/ {print $2}' $f) )
if [[ $includes ]]; then
for cf in "${includes[@]}"; do
info "$f has an include: $cf"
check_file $cf
done
fi
fi
else
warn "$f does not exist and should be created"
if [[ $FIX == 1 ]]; then
info "Creating ${f}..."
mkdir -p $(dirname ${f})
touch ${f}
chmod 644 ${f}
fi
fi
}
while getopts ":fhvjp:" opt; do
case $opt in
f)
FIX=1
;;
v)
VERBOSE=1
;;
j)
SEND_JSON=1
;;
p)
MYCONF=${OPTARG}
;;
h)
usage
;;
\?)
usage
;;
esac
done
test -x "${MYCONF}" || {
echo "my_print_defaults not found in PATH - update path or run with -p /path/to/my_print_defaults"
exit 2
}
# Check everything that my_print_defaults tells us it's using
# Without --help we get the same output but a return value of 1...
files=$(${MYCONF} --help 2>/dev/null | grep -A1 'Default options are read from the following files' | grep my.cnf | tr ' ' "\\n") || die "Failed to run: ${MYCONF}"
files_array=( $files )
# Check my.cnf and .my.cnf in the datadir, and /usr/my.cnf
datadir=$(${MYCONF} mysqld 2>/dev/null | awk -F '=' '$1 ~ /datadir/ {print $2}')
files_array+=("${datadir%%/}/my.cnf" "${datadir%%/}/.my.cnf" '/usr/my.cnf')
result=()
for f in $(echo "${files_array[@]}" | tr ' ' '\n' | sort -u); do
# Don't check files with a tilde in the path
if [[ $f =~ "~" ]]; then continue; fi
test ${SEND_JSON} -eq 1 && {
_out="$(check_file $f)"
test -z "${_out}" && continue
result+=("$(printf '"%s",' "${_out}" )")
} || {
check_file $f
}
done
test ${SEND_JSON} -eq 1 && \
test ${#result[@]} -gt 0 && {
printf '{"messages": [%s]}' "$(echo ${result[@]} | sed 's;,$;;')"
}
exit $EXIT_STATUS