Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Objective-c/Mac OSX) How to distinguish managed AD users (AD user create mobile card) from local users on Mac OSX

<\RESOLVED>, Please see the first reply

My mac(10.9) has joined into a AD domain. In my program, I tried to recognize whether the current login user is local account or AD user. I can successfully distinguish them by using the following code.

+ (bool)isLocalUser:(NSString*)user
{
    NSError *dirSearchError = nil;
    ODRecord *foundUser = findUser(user, &dirSearchError);
    if(foundUser !=nil)
    {
        return YES;
    }else
    {
        return NO;
    }
}

ODRecord *findUser(NSString *user, NSError **error)

{
    NSLog(@"[MacLogonUI] findUser");
    ODNode *searchNode = [ODNode nodeWithSession: [ODSession defaultSession]
                                        type: kODNodeTypeLocalNodes
                                       error: error];

    if (searchNode == nil) {
        return nil;
    }

    NSDictionary *nodeInfo = [searchNode nodeDetailsForKeys:nil error:error];

    /* query this node for the user record we're interested in.
     * We only need one result, which is why maximumResults is set to 1.
     */
    ODQuery *userSearch = [ODQuery queryWithNode: searchNode
                              forRecordTypes: kODRecordTypeUsers
                                   attribute: kODAttributeTypeRecordName
                                   matchType: kODMatchEqualTo
                                 queryValues: user
                            returnAttributes: kODAttributeTypeStandardOnly
                              maximumResults: 1
                                       error: error];

    if (userSearch == nil) {
        return nil;
    }

    /* For this example we'll use a synchronous search. This could take a while
     * so asynchronous searching is preferable.
     */

    NSArray *foundRecords = [userSearch resultsAllowingPartial: NO error: error];

    if (foundRecords == nil || [foundRecords count] == 0) {
        return nil;
    }

    ODRecord *userRecord = [foundRecords objectAtIndex: 0];
   return [[userRecord retain] autorelease];
}

While when the AD user create a mobile card, it is viewed as a managed user(from the System preference -> Users & Groups). The code also recognize this kind of AD user as local. How to deal with this kind of situation?

Do you guys have any idea of this problem?

like image 799
xiao Avatar asked Oct 01 '22 06:10

xiao


1 Answers

I have solved this problem by myself. Hope the following code helps:

#import "DasUser.h"
#import <OpenDirectory/OpenDirectory.h>
#import <Collaboration/Collaboration.h>

@implementation DasUser


+ (bool)isLocalUser:(NSString*)user
{
    NSError *dirSearchError = nil;
    ODRecord *foundUser = findUser(user, &dirSearchError);
    if(foundUser !=nil)
    {
        return YES;
    }else
    {
        return NO;
    }
}

ODRecord *findUser(NSString *user, NSError **error)

{
    NSLog(@"[MacLogonUI] findUser");

    CSIdentityAuthorityRef defaultAuthority = CSGetManagedIdentityAuthority();
    CSIdentityClass identityClass = kCSIdentityClassUser;

    CSIdentityQueryRef query = CSIdentityQueryCreate(NULL, identityClass,                defaultAuthority);

    CFErrorRef err = NULL;
    CSIdentityQueryExecute(query, 0, &err);

    CFArrayRef results = CSIdentityQueryCopyResults(query);

    int numResults = CFArrayGetCount(results);

    NSMutableArray * managedUsers = [NSMutableArray array];
    for (int i = 0; i < numResults; ++i) {
        CSIdentityRef identity = (CSIdentityRef)CFArrayGetValueAtIndex(results, i);
        CBIdentity * identityObject = [CBIdentity identityWithCSIdentity:identity];
        NSString* posixName = [identityObject posixName];
        [managedUsers addObject:posixName];
    }

    CFRelease(results);
    CFRelease(query);

    ODNode *searchNode = [ODNode nodeWithSession: [ODSession defaultSession]
                                        type: kODNodeTypeLocalNodes
                                       error: error];

    if (searchNode == nil) {
        return nil;
    }

    /* query this node for the user record we're interested in.
     * We only need one result, which is why maximumResults is set to 1.
     */
    ODQuery *userSearch = [ODQuery queryWithNode: searchNode
                              forRecordTypes: kODRecordTypeUsers
                                   attribute: kODAttributeTypeRecordName
                                   matchType: kODMatchEqualTo
                                 queryValues: user
                            returnAttributes: kODAttributeTypeStandardOnly
                              maximumResults: 1
                                       error: error];

    if (userSearch == nil) {
        return nil;
    }

    /* For this example we'll use a synchronous search. This could take a while
     * so asynchronous searching is preferable.
     */

    NSArray *foundRecords = [userSearch resultsAllowingPartial: NO error: error];

    if([foundRecords count]>0)
    {
        NSString *nameStr = [foundRecords[0] recordName];

        NSLog(@"[MacLogonUI] findUser nameStr %@", nameStr);

        int j;
        for( j = 0; j<[managedUsers count]; j++)
        {
            if([nameStr isEqualToString:managedUsers[j]])
            {
                break;
            }
        }

        if(j<[managedUsers count])
        {
            foundRecords = nil;
        }
    }

    if (foundRecords == nil || [foundRecords count] == 0) {
        return nil;
    }

    ODRecord *userRecord = [foundRecords objectAtIndex: 0];
    return [[userRecord retain] autorelease];
}    

@end

While when network of the mac is disconnected. The managed user can not be listed. Is there anybody has any idea of this?

like image 112
xiao Avatar answered Oct 04 '22 10:10

xiao