Determine if Active Directory user is admin or not

How to determine whether an Active Directory user is admin or not via code in swift ?

Currently i am doing it this way which doesnot look correct. Please suggest a better approach.


let session = ODSession()


let node = try ODNode(session: session, type: ODNodeType(kODNodeTypeAuthentication))

let query = try ODQuery(

node: node,

forRecordTypes: kODRecordTypeUsers,

attribute: nil,

matchType: ODMatchType(kODMatchAny),

queryValues: nil,

returnAttributes: [

kODAttributeTypeRecordName,

kODAttributeTypeEMailAddress

],

maximumResults: 0

)

let records = try query.resultsAllowingPartial(false) as! [ODRecord]

for record in records

{

let currRecordName = record.recordName

if(currRecordName == username)

{

// 'dsAttrTypeStandard:AppleMetaNodeLocation': '/Local/Default' for Local user

// 'dsAttrTypeStandard:AppleMetaNodeLocation': '/Active Directory/ABCD/abcd.in' for Domain user

let localOrDomainUser = try? record.values(forAttribute: "dsAttrTypeStandard:AppleMetaNodeLocation");

let localOrDomainUserString = localOrDomainUser?[0] as! String

if(localOrDomainUserString == "/Local/Default")

{

continue // Skip local user.. this is the case when we have both local and domain user with same name, but user has created a local user in the name "domainname\username"

}

let groupsAny = try? record.values(forAttribute: "memberOf");

let groups = groupsAny as? [String];

for currGroup in groups ?? []

{

/*

--- CN=Group Policy Creator Owners,CN=Users,DC=abcd,DC=ad,DC=def,DC=com

--- CN=Domain Admins,CN=Users,DC=abcd,DC=ad,DC=def,DC=com

--- CN=Enterprise Admins,CN=Users,DC=abcd,DC=ad,DC=def,DC=com

--- CN=Schema Admins,CN=Users,DC=abcd,DC=ad,DC=def,DC=com

--- CN=Administrators,CN=Builtin,DC=abcd,DC=ad,DC=def,DC=com

*/

var dnNames = currGroup.components(separatedBy: ",") // CN=Domain Admins

if(dnNames.count > 0)

{

var groupNames = dnNames[0].components(separatedBy: "=") // Domain Admins

let group = groupNames[1]

if(group == "Domain Admins" || group == "Enterprise Admins"

|| group == "Schema Admins" || group == "DnsAdmins" || group == "Administrators")

{

return true

}

}

}

break

}

}

Post not yet marked as solved Up vote post of bankumar Down vote post of bankumar
1.1k views
  • I fail to fully understand this code.

    Why attempt to retrieve records for ALL users? (kODMatchAny for kODRecordTypeUsers without limitations?) This WILL fail in large environments (most corporates) after few thousands of users.Why do this on the first place, if you want to "see whether a specific AD user is admin" ??This code only receives records from the LOCAL search-scope, not AD at all. Have you tested?Why the textual manipulation of group results? use OD objects..
Add a Comment

Replies

How to determine whether an Active Directory user is admin or not via code in swift ?

That question is more complex than it seems because OD allows groups to contain groups, and thus you can’t determine group membership by looking at a single user or group record. Rather, you have to search a group tree.

That’s not fun code to write, but fortunately you don’t need to write it because Apple has done so already. Check out the

mbr_check_membership
man page man page.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Does the ODRecord method isMemberRecord:error:, for determining group membership, handle nested groups? The documentation for the method is silent on that point. I'm wondering if I should change our code to use mbr_check_membership instead of isMemberRecord:error:.

Does the

ODRecord
method
-isMemberRecord:error:
, for determining group membership, handle nested groups?

That is a very good question. I hadn’t actually noticed that method before O-:

Anyway, I did some digging and it seems that

-isMemberRecord:error:
is a thin wrapper around
ODRecordContainsMember
(this is pretty common in OD land). The documentation for
ODRecordContainsMember
is rather limited, but the doc comments in
<CFOpenDirectory/CFODRecord.h>
make it clear that this does handle nested groups.

Yay! That’s a much nicher API than

mbr_check_membership
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"