site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com On vendredi, juillet 15, 2005, at 10:55 PM, Chris Vitale wrote: Hello, In case you can stand Objective-C: #import <Cocoa/Cocoa.h> #include <DNSServiceDiscovery/DNSServiceDiscovery.h> #include <DirectoryService/DirServices.h> #include <DirectoryService/DirServicesUtils.h> #include <DirectoryService/DirServicesConst.h> @interface PBDirectoryServicesManager : NSObject { tDirReference directoryServicesReference_; tDataBufferPtr dataBuffer_; tDirNodeReference localNodeReference_; NSMutableDictionary * usersCache_; NSMutableDictionary * groupsCache_; } + (PBDirectoryServicesManager *) defaultManager; - (void) _buildCaches; - (void) increaseDataBuffer; - (NSMutableArray *) usersArray; - (NSMutableArray *) groupsArray; - (NSString *) userAccountForUID:(int) inUID; - (NSString *) groupForGID:(int) inGID; @end ------8<------------8<-------------8<------------- #import "PBDirectoryServicesManager.h" const long PBDS_BUFFER_SIZE = 8192; @implementation PBDirectoryServicesManager + (PBDirectoryServicesManager *) defaultManager { static PBDirectoryServicesManager * sDSManager=nil; if (sDSManager==nil) { sDSManager=[PBDirectoryServicesManager new]; [sDSManager _buildCaches]; } return sDSManager; } - (id) init { self=[super init]; if (self!=nil) { tDirStatus tStatus; tStatus = dsOpenDirService(&directoryServicesReference_); if (dataBuffer_!=NULL) { unsigned long tDirectoryNodeCount; unsigned long tDirectoryNodeIndex; long error; char * tDirectoryNodePath; tDirectoryNodeCount=0; tDirectoryNodePath=NULL; if (error == eDSBufferTooSmall) { [self increaseDataBuffer]; } } while (error == eDSBufferTooSmall); if ( error == eDSNoErr ) { if (tDirectoryNodeCount!= 0) { tDataList * tDirectoryName; error = 1; } } } if (tDirectoryNodePath!=NULL) { long error = eDSNoErr; tDataList * tNodeList; if (error==eDSNoErr) { return self; } } } } dsCloseDirService(directoryServicesReference_); } return nil; } return self; } - (void) dealloc { if (localNodeReference_!=NULL) { dsCloseDirNode(localNodeReference_); } if (dataBuffer_!=NULL) { dsDataBufferDeAllocate(directoryServicesReference_,dataBuffer_); } if (directoryServicesReference_!=NULL) { dsCloseDirService(directoryServicesReference_); } } #pragma mark - - (void) increaseDataBuffer { unsigned long tBufferSize = dataBuffer_->fBufferSize; dsDataBufferDeAllocate(directoryServicesReference_, dataBuffer_); #pragma mark - - (void) _buildCaches { long error = eDSNoErr; unsigned long tRecordCount; tContextData context = NULL; tDataList * tRecordName; // Users tRecordCount=0; if (tRecordName != NULL) { tDataList * tRecordType; if (tRecordType!=NULL) { tDataList * tAttributesType; // We're interesting by the uid and account name dsDataListDeallocate(directoryServicesReference_, tRecordName ); } // Groups error = eDSNoErr; context = NULL; tRecordCount=0; if (tRecordName != NULL) { tDataList * tRecordType; if (tRecordType!=NULL) { tDataList * tAttributesType; // We're interesting by the gid and group name dsDataListDeallocate(directoryServicesReference_, tRecordName ); } } error = eDSNoErr; for (i = 1; (i <= inCount) && (error == eDSNoErr);i++) { tAttributeListRef attributeListRef = 0; tRecordEntry * recordEntryPtr = NULL; if ( error == eDSNoErr && recordEntryPtr!=NULL) { char * tRecordName=NULL; unsigned long j; if (error == eDSNoErr && attributeEntryPtr) { unsigned long k; valueEntryPtr = NULL; break; } else { // A COMPLETER } } attributeEntryPtr = NULL; dsCloseAttributeValueList(valueRef); valueRef = 0; } else { // A COMPLETER } } free(tRecordName); } recordEntryPtr = NULL; dsCloseAttributeList(attributeListRef); } else { // A COMPLETER } } return nMutableDictionary; } - (NSMutableArray *) usersArray { NSMutableArray * tMutableArray=nil; int tCount; tCount=[usersCache_ count]; tMutableArray=[NSMutableArray arrayWithCapacity:tCount]; if (tMutableArray!=nil && tCount>0) { NSEnumerator * tKeyEnumerator; NSNumber * tKey; tKeyEnumerator=[usersCache_ keyEnumerator]; while (tKey=[tKeyEnumerator nextObject]) { NSDictionary * tDictionary; [tMutableArray addObject:tDictionary]; } } return tMutableArray; } - (NSMutableArray *) groupsArray { NSMutableArray * tMutableArray=nil; int tCount; tCount=[groupsCache_ count]; tMutableArray=[NSMutableArray arrayWithCapacity:tCount]; if (tMutableArray!=nil && tCount>0) { NSEnumerator * tKeyEnumerator; NSNumber * tKey; tKeyEnumerator=[groupsCache_ keyEnumerator]; while (tKey=[tKeyEnumerator nextObject]) { NSDictionary * tDictionary; [tMutableArray addObject:tDictionary]; } } return tMutableArray; } - (NSString *) userAccountForUID:(int) inUID { return [usersCache_ objectForKey:[NSNumber numberWithInt:inUID]]; } - (NSString *) groupForGID:(int) inGID { return [groupsCache_ objectForKey:[NSNumber numberWithInt:inGID]]; } @end _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... Since new users are not added to /etc/passwd I doubted that the standard C password functions would work. I thought I'd have to use Apple's fancy pants APIs. getpwent worked just fine. - (NSMutableDictionary *) _dictionaryWithLocalRef:(tDirNodeReference) inReference data:(tDataBufferPtr) inData count:(unsigned long) inCount; if (tStatus == eDSNoErr) { dataBuffer_ = dsDataBufferAllocate(directoryServicesReference_, PBDS_BUFFER_SIZE ); do { error = dsFindDirNodes(directoryServicesReference_,dataBuffer_,NULL,eDSLocalNode Names,&tDirectoryNodeCount,NULL); tDirectoryName = dsDataListAllocate(directoryServicesReference_); if (tDirectoryName!=NULL) { for (tDirectoryNodeIndex = 1;(tDirectoryNodeIndex <= tDirectoryNodeCount) && (error == eDSNoErr); tDirectoryNodeIndex++ ) { error = dsGetDirNodeName(directoryServicesReference_,dataBuffer_,tDirectoryNodeI ndex, &tDirectoryName ); if ( error == eDSNoErr ) { tDirectoryNodePath = dsGetPathFromList(directoryServicesReference_,tDirectoryName, "/" ); if (tDirectoryNodePath!= NULL) { dsDataListDeallocate(directoryServicesReference_, tDirectoryName ); break; } else { NSLog(@"[PBDirectoryServicesUtilities.m:70 dsGetPathFromList failed"); } } } } else { NSLog(@"[PBDirectoryServicesUtilities.m:77 dsDataListAllocate failed"); tNodeList = dsBuildFromPath(directoryServicesReference_,tDirectoryNodePath, "/" ); if ( tNodeList != NULL ) { error = dsOpenDirNode( directoryServicesReference_, tNodeList, &localNodeReference_); dsDataListDeallocate(directoryServicesReference_,tNodeList); dataBuffer_=dsDataBufferAllocate( directoryServicesReference_, tBufferSize*2 ); } tRecordName = dsBuildListFromStrings(directoryServicesReference_,kDSRecordsAll,NULL); tRecordType = dsBuildListFromStrings(directoryServicesReference_,kDSStdRecordTypeUsers ,NULL); tAttributesType = dsBuildListFromStrings(directoryServicesReference_, kDS1AttrUniqueID, NULL); if (tAttributesType!=NULL) { do { error = dsGetRecordList(localNodeReference_,dataBuffer_,tRecordName,eDSExact,tRe cordType,tAttributesType,0,&tRecordCount,&context); if ( error == eDSNoErr ) { usersCache_=[[self _dictionaryWithLocalRef:localNodeReference_ data:dataBuffer_ count:tRecordCount] retain]; if (usersCache_==nil) { error=eUndefinedError; } } else if ( error == eDSBufferTooSmall ) { [self increaseDataBuffer]; } } while (((error == eDSNoErr) && (context != NULL)) || (error == eDSBufferTooSmall) ); dsDataListDeallocate(directoryServicesReference_,tAttributesType); } dsDataListDeallocate(directoryServicesReference_,tRecordType); } tRecordName = dsBuildListFromStrings(directoryServicesReference_,kDSRecordsAll,NULL); tRecordType = dsBuildListFromStrings(directoryServicesReference_,kDSStdRecordTypeGroup s,NULL); tAttributesType = dsBuildListFromStrings(directoryServicesReference_, kDS1AttrPrimaryGroupID, NULL); if (tAttributesType!=NULL) { do { error = dsGetRecordList(localNodeReference_,dataBuffer_,tRecordName,eDSExact,tRe cordType,tAttributesType,0,&tRecordCount,&context); if ( error == eDSNoErr ) { groupsCache_=[[self _dictionaryWithLocalRef:localNodeReference_ data:dataBuffer_ count:tRecordCount] retain]; if (groupsCache_==nil) { error=eUndefinedError; } } else if ( error == eDSBufferTooSmall ) { [self increaseDataBuffer]; } } while (((error == eDSNoErr) && (context != NULL)) || (error == eDSBufferTooSmall) ); dsDataListDeallocate(directoryServicesReference_,tAttributesType); } dsDataListDeallocate(directoryServicesReference_,tRecordType); } - (NSMutableDictionary *) _dictionaryWithLocalRef:(tDirNodeReference) inReference data:(tDataBufferPtr) inData count:(unsigned long) inCount { NSMutableDictionary * nMutableDictionary=nil; unsigned long i; long error; tAttributeEntry * attributeEntryPtr = NULL; tAttributeValueEntry * valueEntryPtr = NULL; nMutableDictionary=[NSMutableDictionary dictionaryWithCapacity:inCount]; error = dsGetRecordEntry(inReference, inData, i, &attributeListRef, &recordEntryPtr); error = dsGetRecordNameFromEntry( recordEntryPtr, &tRecordName ); if (error==eDSNoErr && tRecordName!=NULL) { for (j = 1; (j <= recordEntryPtr->fRecordAttributeCount) && (error == eDSNoErr);j++) { tAttributeValueListRef valueRef = 0; error = dsGetAttributeEntry(inReference,inData, attributeListRef, j, &valueRef, &attributeEntryPtr); for (k = 1; (k <= attributeEntryPtr->fAttributeValueCount) && (error == eDSNoErr);k++) { error = dsGetAttributeValue(inReference,inData,k,valueRef,&valueEntryPtr); if ( error == eDSNoErr && valueEntryPtr!=NULL) { [nMutableDictionary setObject:[NSString stringWithUTF8String:tRecordName] forKey:[NSNumber numberWithInt:atoi(valueEntryPtr->fAttributeValueData.fBufferData)]]; dsDeallocAttributeValueEntry(directoryServicesReference_,valueEntryPtr ); dsDeallocAttributeEntry(directoryServicesReference_,attributeEntryPtr); dsDeallocRecordEntry(directoryServicesReference_,recordEntryPtr); tDictionary=[NSDictionary dictionaryWithObjectsAndKeys:[usersCache_ objectForKey:tKey],@"Name", tKey,@"ID", nil]; tDictionary=[NSDictionary dictionaryWithObjectsAndKeys:[groupsCache_ objectForKey:tKey],@"Name", tKey,@"ID", nil]; This email sent to site_archiver@lists.apple.com