-
Notifications
You must be signed in to change notification settings - Fork 0
/
frogg_smb_check.sh
249 lines (217 loc) · 5.69 KB
/
frogg_smb_check.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#!/bin/bash
# _ __ _
# ((-)).--.((-))
# / '' \
# ( \______/ )
# \ ( ) /
# / /~~~~~~~~\ \
# /~~\/ / \ \/~~\
# ( ( ( ) ) )
# \ \ \ \ / / / /
# _\ \/ \.______./ \/ /_
# ___/ /\__________/\ \___
# *****************************
# Frogg - admin@frogg.fr
# http://github.com/FroggDev/zabbix-smb
# *****************************
##########
# PARAMS #
##########
# Action for the script
SMBACTION=$1
# SMB Server IP
SMBSERVER=$2
# SMB formated share list
# ex: action=share share1,share2,share3
# ex: action=right share1|user1:pass1+r,share1|user2:pass2+w
SMBSHARES=$3
##########
# CONSTS #
##########
#Element separator
declare -r SEP=","
#Share separator
declare -r SSEP="|"
#User separator
declare -r USEP=":"
#Right separator
declare -r RSEP="+"
#########
# FUNCS #
#########
# ---
# Check if can check SMB rights
# @param serverIP
# @return 0/1
function canCheckSmbShares()
{
[[ $(smbclient -L $1 -g -N -U zabbix) == "session setup failed: NT_STATUS_ACCESS_DENIED" ]] && return 1 || return 0
}
# ---
# Get the SMB shares of a server
# @param serverIP
# @param shareList
# @return smb shares not found
function checkSmbShares()
{
# Init result (empty by default = ok)
RESULT=""
# get all SMB share for the server
SMBSHARESFOUND=$(getSmbShares "$1")
# get all SMB share sent by user separated by $SEP
SMBSHARES=$(echo $2 | tr "$SEP" "\n")
# For each SMB share test if exist in server SMB share list
while IFS= read -r SHARE; do
#set share as lower case
SHARE="[${SHARE,,}]"
# Check if SMB share does not exist in SMB server shares
if [[ ! " ${SMBSHARESFOUND} " =~ " ${SHARE} " ]]; then
RESULT="${RESULT}${SHARE}"
fi
done <<< ${SMBSHARES}
# Return nothing if all is ok, else the lis of share with trouble
echo $RESULT
}
# ---
# Get the SMB shares of a server
# @param serverIP
# @param shareList
# @return smb shares not found
function checkSmbRights()
{
RESULT=""
# get all SMB share sent by user separated by $SEP
SMBSHARES=$(echo $2 | tr "$SEP" "\n")
# For each SMB share test if exist in server SMB share list
while IFS= read -r SHAREINFO; do
#DATAS = share|user:pass
DATAS=$(getElementAt "$SHAREINFO" "$RSEP" 1)
RIGHT=$(getElementAt "$SHAREINFO" "$RSEP" 2)
#set right as lower case
RIGHT=${RIGHT,,}
SHARE=$(getElementAt "$DATAS" "$SSEP" 1)
#set share as lower case
SHARE=${SHARE,,}
#USERS = user:pass
USERS=$(getElementAt "$DATAS" "$SSEP" 2)
USER=$(getElementAt "$USERS" "$USEP" 1)
PASS=$(getElementAt "$USERS" "$USEP" 2)
#Set USER=anonymous if no user set
[ "$USER" = "" ] && USER="anonymous"
# User as string for the result
USERSTR=$(getUserStr "$USER" "$PASS")
# Debug
#echo "Trying rights ${RIGHT} on ${1}/${SHARE} for $USER $PASS"
case ${RIGHT} in
# should be able to write
("w") [ $(canWriteSmb "${1}" "${SHARE}" "$USER" "$PASS") -eq 0 ] && RESULT="${RESULT}[${SHARE}${USERSTR}${RSEP}${RIGHT}]";;
# should not be able to read
("n") [ $(canReadSmb "${1}" "${SHARE}" "$USER" "$PASS") -eq 1 ] && RESULT="${RESULT}[${SHARE}${USERSTR}${RSEP}${RIGHT}]";;
# by default check read but should not be able to write
(*)
[ $(canReadSmb "${1}" "${SHARE}" "$USER" "$PASS") -eq 0 ] && RESULT="${RESULT}[${SHARE}${USERSTR}${RSEP}r]";
[ $(canWriteSmb "${1}" "${SHARE}" "$USER" "$PASS") -eq 1 ] && RESULT="${RESULT}[${SHARE}${USERSTR}${RSEP}w]";
;;
esac
done <<< $SMBSHARES
# Return nothing if all is ok, else the lis of share with trouble
echo $RESULT
}
##############
# FUNCS UTIL #
##############
# ---
# Get the SMB shares of a server
# @param serverIP
# @return smb shares found
function getSmbShares()
{
echo $(
smbclient -L $1 -g -N -U zabbix 2> /dev/null |
awk -F'|' '$1 == "Disk" {print $2}' |
while IFS= read -r SHARE
do
#set share as lower case
echo "[${SHARE,,}]"
done
)
}
# ---
# Check if user can read in the SMB share
# @param serverIP
# @param share
# @param user
# @param password
# @return true if can read
function canReadSmb()
{
# All before 1st /
SHARE="${2%%/*}"
# All after 1st /
FOLDER="${2#*/}/"
smbclient "//$1/$SHARE" "$4" -U "$3" -c "cd $FOLDER;dir" >/dev/null 2>&1 && echo 1 || echo 0
}
# ---
# Check if user can write in the SMB share
# @param serverIP
# @param share
# @param user
# @param password
# @return true if can write
function canWriteSmb()
{
# All before 1st /
SHARE="${2%%/*}"
# All after 1st /
FOLDER="${2#*/}/"
smbclient "//$1/$SHARE" "$4" -U "$3" -c "cd $FOLDER;md -tmpfolderfroggtest-;rd -tmpfolderfroggtest-" >/dev/null 2>&1 && echo 1 || echo 0
}
# ---
# Get element at position after spliting a string
# @param string
# @param spliting char
# @param array position
# @return string at position splited
function getElementAt()
{
RESULT=""
# spliting the string
ELEMENTS=$(echo $1 | tr "$2" "\n")
i=1
while IFS= read -r ELEMENT; do
# if position match return the string as result
[ $i -eq $3 ] && RESULT=$ELEMENT
((i++))
done <<< $ELEMENTS
echo $RESULT
}
# ---
# Return formated user as string for display the result without useless empty separator
# @param user
# @param pass
# @return formated |user:pass or |user if no pass or nothing if no user
function getUserStr()
{
RESULT=""
[ ! $1 = "" ] && RESULT="${SSEP}${1}" && [ ! $2 = "" ] && RESULT="${RESULT}${USEP}${2}"
echo $RESULT
}
########
# MAIN #
########
# Clean screen
#clear
case ${SMBACTION} in
# command check share
("share")
if canCheckSmbShares "$SMBSERVER";then
echo $(checkSmbShares "$SMBSERVER" "$SMBSHARES")
else
echo "[ SMB rights error : NT_STATUS_ACCESS_DENIED ]"
fi
;;
# command check right
("right")echo $(checkSmbRights "$SMBSERVER" "$SMBSHARES");;
# command not set or invalid
(*)echo "Error : command [${SMBACTION}] not found"
esac