losing admin rights when not on internal network

catfeetstop
Contributor II

Does anyone know why our users lose admin right when they're not on our internal network? We're using cached AD accounts. The AD plugin specifies which AD groups have administrative rights. Shouldn't it cache the admin rights?

Jamie Bell
Apple Technology Administrator
The Westminster Schools
Ph: 404-609-6345

28 REPLIES 28

bentoms
Release Candidate Programs Tester

AFAIK, it's not cached & never has.

Regards,

Ben.

jarednichols
Honored Contributor

Credentials get cached, admin rights do not. You need to be within sight of your DC to gain those rights. We hard-code users into the admin group that should have it.

j
---
Jared F. Nichols
Desktop Engineer, Client Services
Information Services Department
MIT Lincoln Laboratory
244 Wood Street
Lexington, Massachusetts 02420
781.981.5436

catfeetstop
Contributor II

Excellent, now I have a policy that will add them to the admin group. Thanks!

Jamie Bell
Apple Technology Administrator
The Westminster Schools
Ph: 404-609-6345

catfeetstop
Contributor II

the variable "$3" should capture the user. The policy that runs the following script at login:

dscl / -append /Groups/admin GroupMembership $3

Jamie Bell
Apple Technology Administrator
The Westminster Schools
Ph: 404-609-6345

Matt
Valued Contributor

Is this policy smart enough to know if a user was removed from Ad rights?

--
Matt Lee, CCA/ACMT/ACPT/ACDT
Senior IT Analyst / Desktop Architecture Team / Apple S.M.E / JAMF Casper Administrator
Fox Networks Group

catfeetstop
Contributor II

I doubt it, should it be? The execution frequency is set to "Once per user" so that should help some. But you're probably right, I probably should make a script that will check to see if they're already in the group. Will having multiple entries of the same user in the group cause problems?

Jamie Bell
Apple Technology Administrator
The Westminster Schools
Ph: 404-609-6345

Matt
Valued Contributor

Not sure. I am interested in this as well. Ultimately it would be best if the script checked to see if the user was in an AD Group to Allow admins, then allows that admin priv to be cached, but also to verify that the user is still in the group the next time they login.

--
Matt Lee, CCA/ACMT/ACPT/ACDT
Senior IT Analyst / Desktop Architecture Team / Apple S.M.E / JAMF Casper Administrator
Fox Networks Group

rockpapergoat
Contributor III

the problem you'll have is that if you're off the network, you won't be able to lookup AD group membership in real time, so it's possible for a user to retain admin rights after he/she is removed from the AD group that dictates this.

you could cache the group membership locally using some other mechanism if you want.

what's the use case here, though? are these admin accounts for support staff or normal users?

an approach i took at a client involves configuring "deputy" admin accounts separate from normal AD accounts, then caching those locally with mobile homedirs and local admin group membership.

check my script here for ideas. if you extend it or have any comments, please let me know.

https://github.com/rockpapergoat/scripts/blob/master/accountmanagement/deputize.rb

Matt
Valued Contributor

We have regular users who are admins (politics I don't want to get into!!!!) Sometimes though users only have admin rights for certain projects and then the rights go away. Currently, I use the built in AD group (through the AD Bind Option in Casper). It would be great if when those users login and it checks AD it caches the rights and the next time its on the Network it just verifies that the user is still all good. If not it removes it from the local group (since AD will automatically remove them anyways.) We also use Mobile Accounts on all machines.

--
Matt Lee, CCA/ACMT/ACPT/ACDT
Senior IT Analyst / Desktop Architecture Team / Apple S.M.E / JAMF Casper Administrator
Fox Networks Group

bentoms
Release Candidate Programs Tester

I've an AppleScript app that queries AD group membership & maps printers accordingly.

Would be easy to modify the script.

http://macmule.com/2011/08/07/how-to-map-drives-printers-based-on-ad-group-membership-on-osx/

Regards,

Ben.

tlarkin
Honored Contributor

I think there is a group called AD admins or something which does add them to the admin group if not there are scripts to do such things

david_yenzer
Contributor II

Politics aside, we also have this issue - our teacher users are intended to be local admins. They login with their AD credentials and while on the network they are local admins, but off network they are not local admins. JAMF Support basically responded by saying that things are that way intentionally (no way around it or to resolve this issue without third-party scripting knowledge we don't have).

nessts
Valued Contributor II

Here is a perl script that adds all local users to admin group.
#!/usr/bin/perl -w

use strict;
use Sys::Syslog;

$ENV{PATH} = '/bin:/usr/bin:/usr/sbin';
umask 0022;

(my $progname = $0) =~ s#.*/##;

my $rc = 0;
my $fbuser = "someuser";
my $user;
my %wtmp;
my @tmp;

main:

openlog $progname, undef, 'user';

open L, "last |" or die "$progname: $! ";
while(<L>) { s/^s//; s/s$//; next if /^$/; next if /$fbuser/; chomp; @tmp = split; next unless $tmp[1] eq "console"; next if $tmp[0] eq "root"; next if $tmp[0] eq "localadmin"; next if $tmp[0] eq "shutdown"; $wtmp{lc($tmp[0])} ++; } close L;

foreach $user (keys %wtmp) { open DSCLREAD, "dscl . -read Groups/admin GroupMembership |" or die "$progname: dscl: $! "; my @dsclread = <DSCLREAD>; next if (grep /$user/, @dsclread); syslog('notice', "adding %s to admin group ", $user); $rc = system("dscl . -append Groups/admin GroupMembership $user");
}
closelog;
exit $rc;

then you can create a launch daemon
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict> <key>Disabled</key> <false/> <key>KeepAlive</key> <false/> <key>Label</key> <string>com.hp.addtoadmin</string> <key>ProgramArguments</key> <array> <string>/pathto/AddUsersToAdmin.pl</string> </array> <key>LowPriorityIO</key> <false/> <key>Nice</key> <integer>1</integer> <key>StartCalendarInterval</key> <dict> <key>Minute</key> <integer>10</integer> </dict> <key>UserName</key> <string>root</string>
</dict>
</plist>

jarednichols
Honored Contributor

And here's mine in shell script:

#!/bin/sh

# Filename: makeUserAdmin.sh
# Purpose: hard-code users into the Admin group.
# Author: Jared F. Nichols

#Check if run as root
ROOT_UID="0"
if [ "$UID" -ne "$ROOT_UID" ] ; then
    echo "Please run this script as root or with sudo rights!"
    exit 1
fi

#Put into an array all users from input and normalize to all lower-case.
Users[0]="$(echo ${4} | tr 'A-Z' 'a-z')"
Users[1]="$(echo ${5} | tr 'A-Z' 'a-z')"
Users[2]="$(echo ${6} | tr 'A-Z' 'a-z')"
Users[3]="$(echo ${7} | tr 'A-Z' 'a-z')"
Users[4]="$(echo ${8} | tr 'A-Z' 'a-z')"
Users[5]="$(echo ${9} | tr 'A-Z' 'a-z')"
Users[6]="$(echo ${10} | tr 'A-Z' 'a-z')"
Users[7]="$(echo ${11} | tr 'A-Z' 'a-z')"

#Assign to an array the current Admins on the box. We'll need this for comparisson.
Admins=(`dscl . -read /Groups/admin GroupMembership | cut -d ":" -f 2`)

#Let's get to work
AdminsTmp=(${Admins[@]})
AdminsToAdd=(${Users[@]})

for (( j=0 ; j<${#AdminsTmp[@]} ; j++ ))
do
    for (( i=0 ; i<${#AdminsToAdd[@]} ; i++ ))
    do
        if [[ "${AdminsToAdd[$i]}" == "${AdminsTmp[$j]}" ]]
        then
            unset AdminsToAdd[$i]
            let "i--"
        fi
    done
done

if [[ ${AdminsToAdd[@]} != "" ]] 
then
    dscl . -append /Groups/admin GroupMembership ${AdminsToAdd[@]}

else
    echo "Nothing to add to Admin group. The user(s) you're trying to add may already be there."
fi

Yes, I realize I could clean it up a bit with some loops. This is intended to be used with Casper Remote or Casper Install. Let me know if you need some help decoding it (especially that nested loop).

tlarkin
Honored Contributor

I would do it by UID of the user. Any user with UID over 1000 will be a network/portable. You should be binding your Macs to AD with the option to create mobile accounts, and then adding those mobile accounts to the admin group. That way they are admins off campus.

here is a script I wrote a long time ago to do this exact thing.

https://jamfnation.jamfsoftware.com/discussion.html?id=4701

If you scroll down to my post with the script it should be what you are looking for. This promotes all AD users to admin though. So, just be aware of that.

Thanks,
Tom

Matt
Valued Contributor

Script I wrote, requires AD.

#!/bin/bash

# Add Network Admin to Local Admin Group
# author: matt.lee@fox.com 

# Declaring Variables

realname=`dscl . read /Users/$3 RealName | sed -e '$!d' -e 's/^[ 	]*//'`
adgroupname="GROUPNAME"
localgroup=`dscl localhost read /Local/Default/Groups/admin GroupMembership | tr " " "
" | grep "$3"`
adgroup=`dscl "/ADPATH/" -read /Groups/$adgroupname member | grep -o "$realname"`

# Checking AD Group Membership 

# If User is in AD Admin Group but Not Local Admin

if [[ "$realname" == "$adgroup" && "$3" != "$localgroup" ]]; then
        dscl . append /Groups/admin GroupMembership $3
            echo $3 "successfully added"
   exit

# If User is in AD Admin Group and is a Local Admin

elif [[ "$realname" == "$adgroup" && "$3" == "$localgroup" ]]; then
        echo $3 "is already a Local Admin"
    exit

# If User is not in the AD  Group

elif [[ "$realname" != "$adgroup" && "$3" == "$localgroup" ]]; then
        echo $3 "is a Local Admin Only"
    exit

elif [[ "$realname" != "$adgroup" ]]; then
        echo $3 "is not a Network Admin"
    exit



fi

cstout
Contributor III
Contributor III

Jared,

Your script appears to be what I need to use in my environment, but I'm confused at how you use it in your implementation. I have managed mobile accounts on Macs bound to AD. Department OU's from AD are added during imaging specifying which AD accounts should have admin rights. A lot of these Macs are mobile, however, and like it's already been said, they have no admin rights when off the network.

My question for you is: In what scenario do you use this script? I can't see it being run remotely, since that would assume a network connection is present. With a network connection present, there is no issue with admin access and the script won't do anything. Without a network connection, the user account has no admin rights to run the script under "sudo."

Do you have a policy set for this script? Any help and insight is greatly appreciated. Thank you!

Aaron
Contributor II

I have a similar setup (yeah, politics aside) but my solution is much simpler? Am I missing something?

I just have a policy that runs once per user, on login - it runs a script that simply has:

#!/bin/bash

if [ ! "$3" = "admin" ] && [ ! "$3" = "root" ]; then dseditgroup -o edit -a "$3" -t user admin dseditgroup -o edit -a "$3" -t user wheel
fi

franton
Valued Contributor III

We have a cross platform solution here ... or rather there was a Windows solution that i've had to do some hackery to fit to OS X.

So on our SYSVOL folder we have a text file in the format of:

computername windows:stuff FullUserNames separated by comma if necessary M-A9999:Administrators:ADD:DOMAINusername M-A9998:Administrators:ADD:DOMAINusername2,DOMAINusername3 M-A9997:Administrators:ADD:DOMAINusername2,DOMAINusername3,DOMAINusername1

There's lots of legacy Windows ... stuff in here that I then process with this:

#!/bin/bash

# Script to grab the localadmins file and apply changes to a target computer at logon.

# Author      : r.purves@arts.ac.uk

# Set up needed variables here

macname=$( scutil --get ComputerName | awk '{print substr($0,length($0)-3,4)}' )
adminfile="/var/tmp/localadmins.txt"
OIFS=$IFS
IFS=$'
'

# Mount fileshare where local admin file is kept.

mkdir /Volumes/SYSVOL
mount_smbfs -o nobrowse //'DOMAIN;*deletedaccountname*:*deletedpw*'@DOMAIN/SYSVOL /Volumes/SYSVOL

# Copy localadmin file to temp folder

cp /Volumes/SYSVOL/DOMAIN/localadmin/localadmins.txt /var/tmp/localadmins.txt

# Unmount and clean up fileshare.

diskutil umount force /Volumes/SYSVOL

# Read admin rights file line by line and process. -r used to make sure  char is processed.

cat $adminfile | while read -r adminline
do

# Because the file contains bash reserved characters, we must remove them before processing.
# This will cause the script to ignore the line totally.

line=$( echo ${adminline//[*]/} )

# Grab the name of the computer from the current line of the file

   compname=$( echo "${line}" | cut -d : -f 1 | awk '{print substr($0,length($0)-3,4)}' )

# Find out how many users are listed by counting the commas

   usercount=$( echo $((`echo ${line} | sed 's/[^,]//g' | wc -m`-1)) )

# Does the current computer name match the one in the file?

   if [ "$macname" = "$compname" ];
   then

# Loop to check name(s) are present on the mac and process them into the admin group.   

      for (( loop=0; loop<=usercount; loop++ ))
      do

         field=$(($loop + 1))

# Cut out the 4th field, select the user depending on the loop by cutting using , as a delimiter
# Then strip off the DOMAIN and finally remove Windows horrible 
 that it appends to end of every line

         username=$( echo "${line}" | cut -d : -f 4 | cut -d "," -f ${field} | cut -c11- | sed "s/$(printf '
')$//" )

# Does specified user exist on the system in /Users? Loop round and if so place in admin group.

         for Account in `ls /Users`
         do

            if [[ $Account == $username ]];
            then
               echo "adding "$username" to admin group"
               dscl . -merge /Groups/admin GroupMembership "$username"
            fi
         done
      done
   fi
done

# Clean up and finish

IFS=$OIFS
rm /var/tmp/localadmins.txt
exit 0

This allows us to specify users to get admin rights, rather than blanket cover an entire computer.
I am not proud of any of this hackery. :(

cstout
Contributor III
Contributor III

Hi Aaron,

Your script appears to be what I need to implement via policy. I added it and let it run, but I get the following error:

Record was not found.
Record was not found.

My apologies, but I have a limited knowledge in scripting. Do I need to modify that script? Does that script simply look at the current user's privileges, and if it finds that the user has admin privs, it will add that user to the local admin group?

Thank you for your help.

Aaron
Contributor II

I'm not sure, sorry. There's nothing special about my setup from what has been explained above. A quick Google doesn't bring up much, but I saw that maybe adding "-n /Local/Default" in there might help?

cstout
Contributor III
Contributor III

I've tried all the scripts listed here on a 10.8.3 client bound to AD and I get similar results across the board. Each script effectively tells me there is no change to be made since the user account is listing as already in the Admin group. Though that's true for an active network connection to the domain, as soon as I unplug the cable and restart, that same account is no longer an admin. I've tried running the script locally, via Casper Remote, and Policy. Not sure where to go from here.

gachowski
Valued Contributor II

Jamie and Christopher,

I think remember with I was test beta versions of X.8.0 that if I had the "allow administration by" box checked I saw your behavior. Not 100% sure but worth a quick try.

cstout
Contributor III
Contributor III

That is interesting, but if I disable that feature, I'll have a bigger problem on my hand. Each bound computer has different sets of administrators based on where that computer is located. Some computers are used by multiple departments, which means I need multiple OU's listed there in order for those users to have admin access.

cstout
Contributor III
Contributor III

Aaron, your script appears to be working! I made the mistake of trying to test it via Casper Remote, but it doesn't appear that Casper Remote supports the $3 variable. I logged out and logged in, let the login policy run and there was my account listed in the local admin group. Thanks so much!

cstout
Contributor III
Contributor III

I may have spoken too soon. The script may be working too well. For testing purposes I've deleted my AD account from the computer and removed the OU that account is in from Directory Utility under "Allow administration by." Even though the OU my account is in is not in that list, the script appears to be granting my account administrator privileges regardless.

Am I reading the script wrong? Originally I thought the line:
if [ ! "$3" = "admin" ] && [ ! "$3" = "root" ]
is stating if $3 (cstout) has administrator privileges, then add to the local admin group.
If that is incorrect, is it querying to see if $3 is the actual user "admin" or "root"?

Aaron
Contributor II

That bit is just to check if it's the actual username that is being logged in. I have a default admin account on each Mac, and I enable root as well. There's no point running this script for these two logins, so I skip it if one of these accounts logs in.

Due to the (admittedly crappy political stuff) setup I have, everyone gets admin rights regardless of whether "Allow administration by" is set or not. It's just a quick and hacky script to get the job done. You might want to look at Matt's script above, as it seems to take your scenario into consideration.

cstout
Contributor III
Contributor III

Matt's script appears to be exactly what I need. I am unsure if a declared variable needs to be customized for my environment, but the script is reporting properly back to the JSS. The script is running without error, but is showing that my AD account "is not a Network Admin" when System Preferences is accurately showing that my AD admin rights have been applied to my user. The script appears to not be properly verifying AD group membership and is defaulting to "User is not a Network Admin."

Any ideas?

Edit: I ended up modifying Matt's script with a different membership lookup. I couldn't figure out why Matt's script in my environment would not turn out any results, but if I had to guess it would be the way our AD was set up is far from simple. My modified script is at: https://jamfnation.jamfsoftware.com/discussion.html?id=7427