Un/Re-binding to Active Directory

ryan_s
New Contributor II

This request is to help us out with a symptom where users' "login" keychain and AD become out-of-sync. In a good handful of these cases I'm seeing that a user attempts to actually change their password from the local machine as they should, but they are unable to because their Mac times out before reaching our DC. The fix? If we un-bind and re-bind the computer to our domain, accessing network resources and password resets seem to work just fine.

So, what I'd like to do is create something in Self Service where a user can kick off a policy/configuration and it will automatically unbind and rebind their machine to our domain.

I know there are Policy attributes in the GUI that will bind a machine to a domain, and we utilize this in our OS configurations -- it works find for binding a computer to the domain. However, there isn't a GUI-option to remove it from the current bound-domain, so I was thinking of scripting.

I am borrowing a script that Scott Blake has already created and slightly modified it for what I need:

#REFERENCE https://github.com/MScottBlake/mac_scripts/blob/master/bindMachineToActiveDirectory/bindMachineToActiveDirectory.sh


# Active Directory domain 
domain="mydomain.com" 


 # Username/Password used to perform binding 
 username="" 
 password="" 

 ## More variables - No need to edit 

 olddomain=$( dsconfigad -show | awk '/Active Directory Domain/{print $NF}' ) 
 computername=$( scutil --get ComputerName ) 
 adcomputerid=$( echo "${computername}" | tr [:lower:] [:upper:] ) 
 prefix="${adcomputerid:0:6}" 

 echo "Using computer name '${adcomputerid}'..." 
 echo "" 


 ## Unbind if already bound 


 # If the domain is correct 
 if [[ "${olddomain}" == "${domain}" ]]; then 
   # Check the id of a user 
   id -u "${username}" > /dev/null 2>&1 


   # If the check was successful... 
   if [[ $? == 0 ]]; then 
     echo -n "This machine is bound to AD. Unbinding..." 


     # Unbind from AD 
     dsconfigad -remove -force -u "${username}" -p "${password}" 


     # Re-check the id of a user 
     id -u "${username}" > /dev/null 2>&1 

     # If the check was successful... 
     if [[ $? == 0 ]]; then 
       echo "Failed (Error code: 1)" 
       exit 1 
     else 
       echo "Success" 
       echo "" 
     fi 
   fi 
 fi 


## Perform bind 
 dsconfigad -add "${domain}" -username "${username}" -password "${password}"  
 -computer "${adcomputerid}" -useuncpath enable -mobile enable  
     -mobileconfirm disable -shell /bin/bash -ou "${ou}" -force 

Great! It seems to do everything I am asking right? Well...the problem I am stuck on now is that I cannot have a password in clear text in a script, but it seems to be required for the above to function. I have an existing service account used to bind other machines....how can I reference this account (and with NO clear text passwords)

Thanks in advance for any advice!

1 ACCEPTED SOLUTION

bentoms
Release Candidate Programs Tester

@rseys, I'd look into how or why these macs are failing to communicate with the domain & requiring a rebind.

Often causes are:

ol] [li]Time: I have a few posts on that, including checking your DC's time is correct [https://...
/li] [li]Macs computer password: See [http://blogs.technet.com/b/askds/archive/2009/02/15/test2.... & https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/dsconfigad.8.ht...[/li]
[/lo

Lastly, could you not use the directory bindings in the JSS & have the self service policy use that? (If worried about people getting the password).

You could also use a service account that only has access to that OU/CN on your AD to add, remove or modify computer objects.

We have most of that setup & Macs stay bound from build to decomm. Even if a few years have passed.

Our users are then prompted via ADPassMon https://macmule.com/2014/04/01/announcing-adpassmon-v2-fork/ of password expiry.

View solution in original post

15 REPLIES 15

RobertHammen
Valued Contributor II

I just did this in a slightly more roundabout way.

First, I used Force Unbind (so the Computer object is left in AD). If that's a problem for you, don't follow this post:

https://derflounder.wordpress.com/2013/10/09/force-unbinding-with-dsconfigad-without-using-an-active-directory-admin-account/

As part of the unbind script, I also run the following commands:
/usr/bin/touch /Library/Application Support/JAMF/Receipts/NeedsADRebind.pkg
/usr/sbin/jamf recon

Next, I create Smart Group with criteria, Packages installed by Casper Suite, and add the "NeedsADRebind.pkg" to the criteria (this won't show up from the selectable list until a machine checks in with this setting, but you can just paste that in the field).

Lastly, I create a Policy, set to ongoing, with the Recurring check-in. There are 3 components of this policy:
a) Directory Bindings-> my AD binding
b) Maintenace->Inventory
c) Files and Folders - > run this command: /bin/rm -rf Library/Application Support/JAMF/Receipts/NeedsADRebind.pkg

To summarize:
a) script force unbinds, creates this dummy receipt, and runs a recon to ensure the JSS knows about that receipt existing on the machine
b) machine falls into scope of re-bind script, which will happen at the next recurring check-in (15/5/whatever you have it set to, or sudo jamf policy to force it)
c) re-bind script runs, rebinds to AD, removes the dummy receipt, and runs a recon to ensure the JSS knows the receipt is no longer on the machine (and it falls out of scope of the re-bind script).

Not sure if this is adaptable to you, but YMMV.

stevewood
Honored Contributor II
Honored Contributor II

@rseys are you concerned with the password being saved in a log file, or with it being passed via the script? You could pass the password as a variable in the JSS policy, either $4, $5, or.... So in your policy on JSS, where you have the script added you would enter the password in Parameter 4, Parameter 5, etc. This is how I am able to pass AD credentials for my Move Domain script.

If you are concerned with the password getting caught up in a script, you could purge the jamf.log file and the system.log file if you wanted to. To be real tricky, I'd imagine you could backup the logs before running the dsconfigad portion, unbind/re-bind, purge the logs, and then move the backups back into place. Not sure if that will work, but it sounds logical enough.

mscottblake
Valued Contributor

Hi @rseys,

First of all, I'm glad you are able to make use of that script.

If you change the unbind portion to remove the username and password (dsconfigad -remove -force) it will perform the removal locally, but since it does not have any credentials for the domain, it cannot make any changes there. This actually seems okay in your case since you are going to be adding it right back.

However, re-binding the machine will either need credentials, or you will need to use one of the built-in directory bindings.

mm2270
Legendary Contributor III

The jamf.log shouldn't actually capture any passwords in it when the script runs, since its all within a script. The only thing it will note is that the policy is running and the script (by its name) is running, but the credentials used within it should not get added to the log file. The only time that actually happens is when you use the Advanced/Run Command filed. The policy log will show something like "Running command "dsconfigad -add ...." etc, including the username & password passed to the command.

But I would agree with @stevewood that if you're concerned about having the script actually have the username & password hardcoded, just convert them into parameters passed to the script instead. That way if anyone actually get ahold of the script they would only see something like $4 or $5 in place of the actual credentials.
Mind you, I think the parameter strings get passed to the script in the clear, so there is still that possible concern.

bentoms
Release Candidate Programs Tester

@rseys, I'd look into how or why these macs are failing to communicate with the domain & requiring a rebind.

Often causes are:

ol] [li]Time: I have a few posts on that, including checking your DC's time is correct [https://...
/li] [li]Macs computer password: See [http://blogs.technet.com/b/askds/archive/2009/02/15/test2.... & https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/dsconfigad.8.ht...[/li]
[/lo

Lastly, could you not use the directory bindings in the JSS & have the self service policy use that? (If worried about people getting the password).

You could also use a service account that only has access to that OU/CN on your AD to add, remove or modify computer objects.

We have most of that setup & Macs stay bound from build to decomm. Even if a few years have passed.

Our users are then prompted via ADPassMon https://macmule.com/2014/04/01/announcing-adpassmon-v2-fork/ of password expiry.

ryan_s
New Contributor II

Following up on an old post -- after much research and trial/error, we found that when we are imaging Macs with Casper, there is no explicit (local) NTP server file created on the machine. Apparently when you do not go through the setup wizard that OEM images present (where you set your time zone) this does not create the appropriate NTP file and eventually the Mac will lose trust with the domain after the time falls slightly out-of-sync with our DCs

We verified that System Prefs > Date & Time doesn't show anything obviously misconfigured, but we saw in /etc there is not a "ntp.conf" file listed. However if one were to manually adjust the time zone in SysPrefs, this immediately creates the aforementioned file. So we have now deployed a policy to run once against each machine that is a simple command:

systemsetup -setnetworktimeserver time.apple.com

We have had a significant drop in tickets and incidents relating to Macs losing trust to the domain and as a result, are not needing to rebind as often. I am not sure if this is something that others are seeing when imaging their Macs with Casper Imaging, but I figured I would share!

KyleEricson
Valued Contributor II

I tried this but I get this error:
bash: /Users/administrator/Desktop/ad.sh: Permission denied
bash-3.2# chmod +x /Users/administrator/Desktop/ad.sh bash-3.2# /Users/administrator/Desktop/ad.sh
/Users/administrator/Desktop/ad.sh: line 1: {rtf1ansiansicpg1252cocoartf1561cocoasubrtf400: command not found
/Users/administrator/Desktop/ad.sh: line 2: syntax error near unexpected token `}'
/Users/administrator/Desktop/ad.sh: line 2: `{fonttblf0fnilfcharset0 Menlo-Regular;f1fswissfcharset0 Helvetica;}'

Read My Blog: https://www.ericsontech.com

stevewood
Honored Contributor II
Honored Contributor II

@kericson if you're referring to the script in the opening post, it is missing the shebang at the top of the script. So change this:

#REFERENCE https://github.com/MScottBlake/mac_scripts/blob/master/bindMachineToActiveDirectory/bindMachineToActiveDirectory.sh


# Active Directory domain 
domain="mydomain.com"

To add the shebang:

#!/bin/bash
#REFERENCE https://github.com/MScottBlake/mac_scripts/blob/master/bindMachineToActiveDirectory/bindMachineToActiveDirectory.sh


# Active Directory domain 
domain="mydomain.com"

KyleEricson
Valued Contributor II

I got a new error now, the issue was a "" before,
/Users/kyleri/Desktop/AD-Bind.sh: line 57: -computer: command not found
/Users/kyleri/Desktop/AD-Bind.sh: line 58: -mobileconfirm: command not found
Intune-Mac-2:~ kyleri$

Read My Blog: https://www.ericsontech.com

mscottblake
Valued Contributor

@kerickson Lines 56, 57, and 58 are all a single command. You either need to put it all on one line or add the back to the line endings.

alexmcclements
Contributor

I do this in a slight less dignified manner, I use a policy with a script to force unbind the machine set to before and then use the Directory Bindings feature to rebind the machine.

The techs can then call it by a custom trigger on any effected machines.

KyleEricson
Valued Contributor II

@mscottblake I did verify that it is on one line

Script result: Using computer name 'INTUNE MAC #2'...<br/><br/>-n This machine is bound to AD. Unbinding...<br/>Success<br/><br/>dsconfigad: Container does not exist<br/>

What do Container does not exist mean?

Read My Blog: https://www.ericsontech.com

mscottblake
Valued Contributor

@kerickson It means the Active Directory Organizational Unit (or OU) does not exist. You either have a typo in the path to the OU or it truly doesn't exist within AD yet.

KyleEricson
Valued Contributor II

I got this to work finally. Not sure what I did but all good now.

Read My Blog: https://www.ericsontech.com

PCSysops
New Contributor II

I am running into an issue with this script. When it binds to AD, it binds but it is missing 1 character at the end. I have a script that I run before to change the computer name to a Prefix of "LTM" and then the serial number. I verified that the computername/localhostname/hostname are all the same, but when I look at the Computer ID when trying to Bind to AD, it cutts off or missing the last digit or letter of the computer name. So when it binds, it is missing a character. Any ideas?

Edit: Looks like when you auto bind, the character limit is 15, which mine was 16 cutting off the last character. You can manually edit the length beyond that, but wanted to automate this process. I just eliminated 1 character out of my prefix to fix.