Draft sanity checker for smbpasswd
David Collier-Brown
davecb at canada.sun.com
Tue Jul 24 16:27:33 GMT 2001
Kevin, can you check this out and sugegst additions? You may have
to manually unfold lines folded in mail...
--dave
#!/bin/sh
#
# checksmbpasswd -- check the smb password file against /etc/passwd
# and /etc/shadow. Reading smbpasswd requires running as root.
# Developed on Solaris, may require fettling --dave c-b
#
#set -x
SMBPASSWD=/usr/local/samba/private/smbpasswd
#Shadow=0
Yp=0
main() {
trap 'rm /tmp/$$.passwd' 0 1 2 3 4 5 6 7 8 9
if [ $# -lt 1 ]; then
say "checksmbpasswd: you must provide a file."
say "Usage: checksmbpasswd [-y] file"
exit 1
fi
while [ "$1" != "" ]; do
case "$1" in
# -s) # Include /etc/shadow
# Shadow=1
# ;;
-y|-n) # Use YP/NIS
Yp=1
;;
-*) # oops
say "Unrecognized option \"$1\" ignored."
;;
*) # End of options
break
;;
esac
shift
done
file="$1"
compare $file
check $file
}
#
# compare -- see if the file contains mismatches with /etc/passwd
#
compare() {
file=$1
# Get a safe copy of /etc/passwd and/or /etc/shadow
getpass |\
nawk -F: '{
printf("%s:x:%s:%s:%s:%s:%s\n",$1,$3,$4,$5,$6,$7);
}' |\
sort |\
sed -e '/^#/d' >/tmp/$$.passwd
#cat /tmp/$$.passwd
# Check lines
linesInSmbpasswd=`cat $SMBPASSWD |sed -e '/^#/d' | wc -l`
linesInPasswd=`cat /tmp/$$.passwd |sed -e '/^#/d' | wc -l`
if [ "$linesInSmbpasswd" -gt "$linesInPasswd" ]; then
say "Danger: more lines in smbpassword file than
passwd file."
elif [ "$linesInSmbpasswd" -lt "$linesInPasswd" ]; then
say "Note: more lines in passwd file than smbpassword
file (comm
on)."
else
say "Note: exactly $linesInSmbpasswd lines in smb and
passwwd fi
le."
return
fi
# Show the mismatch(es).
say "Lines in smbpasswd file missing from passwd file are:"
comm -23 $SMBPASSWD /tmp/$$.passwd 1>&2
say ""
say "Lines in passwd file missing from smbpasswd file are:"
comm -13 $SMBPASSWD /tmp/$$.passwd 1>&2
say ""
}
#
# check -- see if the smbpasswd file is well-formed
#
check() {
file=$1
cat $file |\
tr ' :' '_ ' |\
while read name uid lanman nt flags lastchanged junk; do
# say "$name $uid $lanman $nt $flags $lastchanged"
# Name and uid must match unix.
unixUid=`nawk -F: '$1 ~ /'$name'/ { print $3; exit}'
/tmp/$$.pas
swd`
if [ "$uid" -ne "$unixUid" ]; then
say "Error: could not match ${name}'s uid in
the passwd
file."
fi
echo $lanman |\
nawk '
/.*/ {
len = length($1);
if (len != 32) {
print "Error: length of LanMAN hash
for " name \
" was " len ", not 32."
}
if ($1 == "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
{
print "Warning: LanMAN hash for " name
\
" was 32 Xs, a disabled
account."
}
if ($1 ~ /NO PASSWORD/) {
print "Warning: LanMAN hash for " name
\
" was NO PASSWORD."
}
}' name=$name
# NT hash must be 32 hex digits
echo $nt |\
nawk '
/.*/ {
len = length($1);
if (len != 32) {
print "Error: length of NT hash for "
name \
" was " len ", not 32."
}
}' name=$name
# flags are "[" 11 characters "]", limited to UNDW
echo $flags |\
nawk '
/.*/ {
len = length($1);
if (len != 13) {
print "Error: length of flags for "
name \
" was " len ", not 13."
}
user=index($1, "U");
no=index($1, "N");
disabled=index($1, "D");
wstrust=index($1, "W");
if (user != 0 && wstrust != 0) {
print "Error: flags for " name \
"inlude both User and
Workstation-trust.
"
}
if (no != 0) {
print "Warning: flags for " name \
" include No-password"
}
if (disabled != 0) {
print "Warning: flags for " name \
" include Disabled"
}
}' name=$name
# Last-changed time; no checks yet.
done
say "$0: checking done"
say
}
getpass() {
if [ "$Yp" -eq 1 ]; then
ypcat passwd
else
cat /etc/passwd
fi
}
say() {
echo "$*" 1>&2
}
main "$@"
More information about the samba-technical
mailing list