Tag Archives: Active Directory

A quick Powershell script I hacked together that will enumerate all Active Directory users, and build an XML file for an application I wrote that generates user reports for a specific application.

The output file format is similar to:

<quickreports>
  <report name="Organizational Unit">
  <database name="v001"/>
  <usrlogin name="jdoe01"/>
</report>
<quickreports>
$ErrorActionPreference= 'silentlycontinue'
$arr=@{}

foreach ($usr in Get-ADUser -Filter *  | select samaccountname) {

$user = get-aduser -identity $usr.samaccountname -ErrorAction SilentlyContinue
$userou = (($user.DistinguishedName -split "=",2)[-1].split(",")[1] -split "=",2)[-1]

$key = $userou
$value = $usr.samaccountname

if ($arr.ContainsKey("$userou")) {
$arr["$userou"] += $usr.samaccountname 
} else {
$arr["$userou"] = @()
$arr.add($key,$value)
}

}
$foo = "<?xml version=""1.0"" encoding=""utf-8""?>`r`n"
$foo += "<quickreports>`r`n"

$foo += foreach ($ou in $arr.keys) {

    write-output "  <report name=""$ou"">`r`n"

    foreach ($u in $arr["$ou"]) {
                if ($u.contains("01")) {
                    write-output "<database name=""v001""/>`r`n"
                } elseif ($u.contains("04")) {
                    write-output "<database name=""v004""/>`r`n"
                } else { 
                    write-output "<database name=""""/>`r`n"
                }
        write-output "<usrlogin name=""$u""/>`r`n"
}
    write-output "</report>`r`n"
}

$foo += "</quickreports>"

$foo | out-file quickreport.xml

# for some reason the outputted file was dumping 0x00 into the file.  Eventually
# I'll clean all this up and just write all the attributes and elements from up above
# but now is not the time as this is just a quick and dirty POC

$fn = "quickreport.xml"
$xmlDoc = [system.xml.xmldocument](get-content $fn)

$xmlDoc.save($fn)

I’ve added a few servers to a test Windows domain and some of those servers include Debian Linux operating systems. Here are the basic steps on joining a Debian server to Windows Active Directory Domain and setting up domain user login on the Linux server.

I assume you have an installation of Debian up and running.  I used Debian 8 “Jessie” in my post.

Install Necessary Packages

$ apt-get install realmd ntp adcli sssd

Post Installation Tasks

$ mkdir -p /var/lib/samba/private
$ systemctl enable sssd

Join Domain

Make sure we can get information about the domain we want to join.

$ realm discover techish.local
techish.local
  type: kerberos
  realm-name: TECHISH.LOCAL
  domain-name: techish.local
  configured: no
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin

All looks good, now join.

$ realm join --user=administrator techish.local
Password for administrator:
 * Installing necessary packages: samba-common-bin, sssd-tools

Start SSSD

$ systemctl start sssd

At this point, should be joined and we can now test authentication for users…

$ getent passwd rkreider@techish.local
rkreider@techish.local:*:485401343:485400513:Richard J. Kreider:/home/techish.local/rkreider:/bin/bash

Home Directory Setup

$ echo "session required pam_mkhomedir.so skel=/etc/skel/ umask=0022" | tee -a /etc/pam.d/common-session

Local Admin Privileges

Think Domain Admin on a Windows PC, but for Linux – sudo.

On Debian 8.6, this was installed when sssd was installed – but, just to make sure:

$ apt-get install libsss-sudo
$ echo "%domain\ admins@techish.local ALL= ALL" | tee -a /etc/sudoers.d/domain_admins

Logging in as Domain User

login as: techish\rkreider
techish\rkreider@debian's password:
rkreider@techish.local@debian:~$

Cooked this up in a few minutes.  Should return all proxyAddress that are SMTP and all SMTP default addresses for all users not disabled in a specified Organizational Unit.

ldapsearch -x -h "ldapserver.example.com" -b "ou=Users,ou=example,dc=example,dc=com" -D "example\ldapadmin" -w "s3cr3t" '(& (objectClass=User)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' | grep -i "^mail\|^proxyAddresses: SMTP:" | grep -v "mailNickname" | sed 's/mail: //' | sed -e 's/proxyAddresses: SMTP://gI' | sed 's!$!\ OK!' | uniq >> $VALID

An existing user in a Windows domain was moving companies (to a parent company) that is not part of the infrastructure.  After the employee left his account was to be terminated but still be able to access email only, so no login/remote access to systems, computers on the network.

By disabling the account, this would prevent authentication for Exchange needs so I couldn’t do that.

Create a Security Group

I created a new Security Group, Email Only.

2014-08-06_092620

I added this specific user to the newly created Security Group.

2014-08-06_092640

Create a Group Policy

Next, I created a new Group Policy for the domain and applied it to the Computers OU.

Group Policy:  Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment > Deny Log on Locally

2014-08-06_092519

I modified Deny Log on Locally policy and added my newly created Security Group, Email Only.

2014-08-06_092818

Testing

To test functionality, I logged on as an administrator to a PC in the domain and ran gpupdate /force.  This updates the group policy on that computer.  Then I logged off and tried logging back on as the user that I added to the Security Distribution Group.  Login failed, so this worked.

Next, I tested OWA, Outlook Anywhere, and Outlook.  I was able to successfully authenticate and send/receive email without an issue.

Now this user has access to OWA and Outlook Anywhere or Outlook without the ability to log on locally to a computer in the domain.

 

I have been working on a Perl script using NET::LDAP to query against and Active Directory system and update an email application and I needed to have it exclude Disabled accounts.

Here is the filter I am currently using.

filter => "(&(objectClass=User)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))",

To only return Disabled accounts, I would use the following code.

filter => "(&(objectClass=User)((userAccountControl:1.2.840.113556.1.4.803:=2)))",

Here is a list of the userAccountControl flags.

Property flagValue in hexadecimalValue in decimal
SCRIPT0x00011
ACCOUNTDISABLE0x00022
HOMEDIR_REQUIRED0x00088
LOCKOUT0x001016
PASSWD_NOTREQD0x002032
PASSWD_CANT_CHANGE Note  You cannot assign this permission by directly modifying the UserAccountControl attribute.  For information about how to set the permission programmatically, see the “Property flag descriptions” section.0x004064
ENCRYPTED_TEXT_PWD_ALLOWED0x0080128
TEMP_DUPLICATE_ACCOUNT0x0100256
NORMAL_ACCOUNT0x0200512
INTERDOMAIN_TRUST_ACCOUNT0x08002048
WORKSTATION_TRUST_ACCOUNT0x10004096
SERVER_TRUST_ACCOUNT0x20008192
DONT_EXPIRE_PASSWORD0x1000065536
MNS_LOGON_ACCOUNT0x20000131072
SMARTCARD_REQUIRED0x40000262144
TRUSTED_FOR_DELEGATION0x80000524288
NOT_DELEGATED0x1000001048576
USE_DES_KEY_ONLY0x2000002097152
DONT_REQ_PREAUTH0x4000004194304
PASSWORD_EXPIRED0x8000008388608
TRUSTED_TO_AUTH_FOR_DELEGATION0x100000016777216
PARTIAL_SECRETS_ACCOUNT0x0400000067108864

References