Apple provide the Open Directory framework for their Active Directory implementation.
How can I use their Open Directory framework to get the "bound" ODNode object and "this" computer's ODRecord object?
What I mean by this is that, from the command line, I can use dsconfigad -show to get some info like:
Active Directory Forest = ad-root.local
Active Directory Domain = example.com
Computer Account = serno123$
But I'm not sure how to get access to those "Domain" and "Computer Account" from my Swift/Objective-C code without hardcoding. I am able to see some relevant nodes with a code snippet like
do {
let nn = ODSession.default().nodeNames()
print("Node names: \(nn)")
} catch {
print("ERROR: \(error)")
}
which logs something like:
Node names: [/Active Directory/EG, /Active Directory/EG/ad-root.local, /Active Directory/EG/example.com, /Contacts, /Local/Default, /Search]
but its unclear how to get the "this computer is bound to X via computer account Y" information it seems I would need to jump from one of these nodes (which one?) to having the ODRecord representing the computer my code is running on.
If I had the "Active Directory Domain = example.com" info available to my code I think I could get the right node via:
let adDomain = "example.com"
let adExtraPart = "EG" // where does this come from?
let nameToSearch = "/Active Directory/\(adExtraPart)/\(adDomain)"
do {
let n = try ODNode(session: ODSession.default(), name: nameToSearch)
print("Node: \(n)")
mainAdNode = n; // [used below]
} catch {
print("ERROR: \(error)")
}
But I don't know how to get the adDomain or adExtraPart configuration dynamically.
Similarly if I could get that far then for the computer's record I could do something like:
let n = mainAdNode // e.g. from snippet above
let computerAccount = "serno123$"
do {
let r = try n.record(withRecordType: kODRecordTypeComputesr, name: computerAccount, attributes: nil)
print("Record: \(r)")
computerRecord = r // the object I want to use in my code…
} catch {
print("ERROR: \(error)")
}
but again it is unclear where I could obtain the computerAccount value without hardcoding it or making assumptions re. its relationship to the hostname or whatnot.
To be clear, I'm not necessarily looking to use the exact APIs above. If instead I could simply:
let mainAdNode = try ODSession.default().domainNode()
let computerRecord = try mainAdNode.computerAccount()
// …
that would be even better!
This is not a complete answer, but I did find that there is an ODNodeType that corresponds to something usable as the "main" or "default" node:
let adNode = try ODNode(
session: ODSession.default(),
type: ODNodeType(kODNodeTypeAuthentication)
)
As the documentation says, this isn't just for authentication but is [emphasis added] a "node used for authentication or record lookups." On my machine and probably elsewhere, it returns the /Search node in practice.
As to the second part of my question, if the computer's Active Directory identifier is already known then one can use the /Search node obtained above to retrieve it:
let computerRecord = try adNode.record(
withRecordType: kODRecordTypeComputers,
name: "\(computer.id)$",
attributes: nil
)
…but of course this still "hardcodes" the machine name or at least presumes knowledge of how to get it via some other mechanism, rather than the Active Directory "domain binding" itself :-/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With