Restricting login to account based on IP address
At work we needed to have a standard local account that would work off campus, but not on campus. Here was my solution.
First I check for the user and create it if it doesn't exist
#!bash
user_exists=`dscl . -read /Users/remote GeneratedUID | grep -c GeneratedUID`
if [ $user_exists -ne 1 ]; then
echo "creating remote user"
sudo dscl . -create /Users/remote
dscl . -create /Users/remote UserShell /bin/bash
sudo dscl . -create /Users/remote RealName "remote"
dscl . -create /Users/remote UniqueID 509
dscl . -create /Users/remote PrimaryGroupID 1000
dscl . -create /Users/remote NFSHomeDirectory /Local/Users/remote
dscl . -passwd /Users/remote remote
fi
because these are fully managed machines, I know what UIDs are available. (For a method that checks for available UID I've posted a script from Andrew Mortensen below)
The next part of the script will check if the user is logged in as "remote" and on campus using a regular expression (our two subnets are 10.5.5.X and 10.6.6.X). You could also check a router, DHCP server, or internal DNS as other approaches. If they are on campus I use a display utility called BigHonkingText to throw up a message and then kill the loginwindow.
#!bash
user="$1"
if [ "$user" == "remote" ]; then
IP=`ifconfig | grep "inet " | grep -v 127.0.0.1 | awk 'NR>1{exit};{ print $2 }'`
echo $IP
if [[ "$IP" =~ 10.[5,6].[5,6].[0-9]* ]]; then
echo "on campus"
/usr/local/bin/BigHonkingText "account not allowed on campus"
killall loginwindow
# reboot
fi
fi
Here is the script from Andrew Mortensen:
#!bash
#! /bin/sh
# create a template user
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
# arbitrary uid
N_UID=501
# arbitrary gid
N_GID=501
# user name
N_USERNAME="$1"
# home
N_HOME="/var/${N_USERNAME}"
# system default user home template
SYSHOMETEMPLATE="/System/Library/User Template/English.lproj"
# make sure the uid and gid are available
while [ true ]; do
user="`dscl . -search /users UniqueID ${N_UID} 2>/dev/null`"
if [ -z "${user}" ]; then
break
fi
N_UID=$((${N_UID} + 1));
done
while [ true ]; do
group=`dscl . -search /groups PrimaryGroupID ${N_GID} 2>/dev/null`
if [ -z "${group}" ]; then
break
fi
N_GID=$((${N_GID} + 1));
done
# create user
dscl . <
create "/users/${N_USERNAME}"
create "/users/${N_USERNAME}" AppleMetaNodeLocation /Local/Default
create "/users/${N_USERNAME}" GeneratedUID `uuidgen`
create "/users/${N_USERNAME}" UniqueID ${N_UID}
create "/users/${N_USERNAME}" PrimaryGroupID ${N_GID}
create "/users/${N_USERNAME}" Password "*"
create "/users/${N_USERNAME}" RecordName ${N_USERNAME}
create "/users/${N_USERNAME}" RecordType dsRecTypeNative:users
create "/users/${N_USERNAME}" NFSHomeDirectory ${N_HOME}
create "/users/${N_USERNAME}" RealName "Template User"
create "/users/${N_USERNAME}" UserShell /bin/bash
EOF
if [ $? -ne 0 ]; then
logger -is Creation of ${N_USERNAME} failed.
# destroy account
dscl . -delete "/users/${N_USERNAME}" 2>/dev/null
exit 2
fi
# create group
dscl . <
create "/groups/${N_USERNAME}"
create "/groups/${N_USERNAME}" AppleMetaNodeLocation /Local/Default
create "/groups/${N_USERNAME}" GeneratedUID `uuidgen`
create "/groups/${N_USERNAME}" PrimaryGroupID ${N_GID}
create "/groups/${N_USERNAME}" RecordName ${N_USERNAME}
create "/groups/${N_USERNAME}" RecordType dsRecTypeNative:groups
create "/groups/${N_USERNAME}" Password "*"
create "/groups/${N_USERNAME}" GroupMembership ${N_USERNAME}
EOF
if [ $? -ne 0 ]; then
logger -is Creation of ${N_USERNAME} failed.
# destroy account
dscl . -delete "/users/${N_USERNAME}" 2>/dev/null
dscl . -delete "/groups/${N_USERNAME}" 2>/dev/null
exit 2
fi
# make home directory
mkdir -m 0700 -p ${N_HOME}
ditto --rsrc "${SYSHOMETEMPLATE}" "${N_HOME}"
if [ $? -ne 0 ]; then
logger -is Creation of ${N_USERNAME} failed.
# destroy account
dscl . -delete "/users/${N_USERNAME}" 2>/dev/null
dscl . -delete "/groups/${N_USERNAME}" 2>/dev/null
exit 2
fi
chown -R ${N_USERNAME}:${N_USERNAME} ${N_HOME}
logger -i Creation of template user ${N_USERNAME} succeeded.
exit 0