Skip to main content

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

AFAIK, it's not cached & never has.

Regards,

Ben.


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


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


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


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


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


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


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


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


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.


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


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).


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>


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).


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


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

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!


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


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. :(


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.


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?


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.


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.


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.


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!