Reputation: 1489
This command: dsconfigad -show
does what I need but I need admin rights to run it.
The above command outputs some information I'm interested in:
You are bound to Active Directory:
Active Directory Forest = xx.xxxxxx.local
Active Directory Domain = xx.xxxxxx.local
Computer Account = (computer name)
I'd like to be able to get the Active Directory Domain
seen above programatically, and preferably without having to have sudo permissions.
Any suggestions? I've browsed the Open Directory docs and it is not entirely obvious to me how to do this. I also tried some code examples just to query the AD for something without success... I'll continue to work on it but I was hoping someone here had some knowledge to share.
Upvotes: 5
Views: 3186
Reputation: 61
If you are searching for this, here is some Swift code returning extra info with actual bound computer name. If nil is returned the Mac isn't bound.
import Foundation
import OpenDirectory
struct ComputerAccount {
let name: String
let domain: String
let distinguishedName: String?
let dnsName: String?
let networkAddresses: [String]
let smbsid: String?
static func with(record: ODRecord, domain: String) -> ComputerAccount {
// note: record.recordName has a dollar sign appended to it
// instead of assuming that, we just use the real name if we can get it
let computerName: String
if let name = try? record.values(forAttribute: "dsAttrTypeStandard:RealName").first as? String {
computerName = name
} else {
computerName = record.recordName
}
let distinguishedName = try? record.values(forAttribute: "dsAttrTypeNative:distinguishedName").first as? String
let dnsName = try? record.values(forAttribute: kODAttributeTypeDNSName).first as? String
let networkAddresses = try? record.values(forAttribute: "dsAttrTypeNative:networkAddress") as? [String]
let smbsid = try? record.values(forAttribute: kODAttributeTypeSMBSID).first as? String
return ComputerAccount(name: computerName, domain: domain, distinguishedName: distinguishedName, dnsName: dnsName, networkAddresses: networkAddresses ?? [], smbsid: smbsid)
}
}
func activeDirectoryComputerAccount() -> ComputerAccount? {
var trustAccounts = [String]()
let session = ODSession.default()!
guard let activeDirectory = try? ODNode(session: session, name: "/Active Directory") else { return nil }
guard let domainNames = try? activeDirectory.subnodeNames() as? [String] else { return nil }
for domainName in domainNames {
if let configuration = session.configuration(forNodename: domainName) {
if let trustAccount = configuration.trustAccount {
trustAccounts.append(trustAccount)
if let globalCatalog = try? ODNode(session: session, name: domainName + "/Global Catalog") {
let attrs = ["dsAttrTypeStandard:RealName",
"dsAttrTypeNative:distinguishedName",
"dsAttrTypeNative:networkAddress",
kODAttributeTypeSMBSID]
if let record = try? globalCatalog.record(withRecordType: kODRecordTypeComputers,
name: trustAccount,
attributes: attrs) {
let dom = domainName.components(separatedBy: "/").last ?? ""
return ComputerAccount.with(record: record, domain: dom)
}
}
}
}
}
return nil
}
Upvotes: 0
Reputation: 13932
Without node authentication you should at least see if AD is bound by looking at the active OD plugins - it should include AD if it is bound. It may or may not show the domain (typically it does for LDAP but I don't have AD to test here so your mileage may vary):
import Foundation
import OpenDirectory
let mySession = ODSession.default()
do {
print(try mySession?.nodeNames())
}
catch {
print("error: \(error)")
}
#include <Foundation/Foundation.h>
#include <OpenDirectory/OpenDirectory.h>
int main(int ac, char **av) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ODSession *mySession = [ODSession defaultSession];
NSError *err = 0;
NSArray *nodeNames = [mySession nodeNamesAndReturnError:&err];
if (err) NSLog(@"error: %@", err);
if (nodeNames) NSLog(@"nodes: %@", nodeNames);
[pool release];
return 0;
}
Upvotes: 2