mirror of
https://github.com/darlinghq/darling-DSTools.git
synced 2024-11-23 12:09:42 +00:00
b1d05a7ba1
It's for Homebrew
295 lines
8.1 KiB
Objective-C
295 lines
8.1 KiB
Objective-C
/*
|
|
* Copyright (c) 2003-2009 Apple Inc. All rights reserved.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_START@
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
|
* file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_END@
|
|
*/
|
|
|
|
/*!
|
|
* @header PathRecordConfig
|
|
*/
|
|
|
|
#import "PathRecordConfig.h"
|
|
#import "DSoDirectory.h"
|
|
#import "DSoNode.h"
|
|
#import "DSoNodeConfig.h"
|
|
#import "DSoRecord.h"
|
|
#import "DSoUser.h"
|
|
#import "DSoException.h"
|
|
|
|
#import <DirectoryService/DirServicesConst.h>
|
|
#import <opendirectory/odutils.h>
|
|
|
|
@interface PathRecordConfig (Private)
|
|
|
|
- (void) _destroyRights;
|
|
|
|
@end
|
|
|
|
|
|
@implementation PathRecordConfig (Private)
|
|
|
|
- (void)_destroyRights
|
|
{
|
|
// free _authExternalForm
|
|
if (_haveRights) {
|
|
[[_record node] customCall:eODCustomCallConfigureDestroyAuthRef
|
|
withAuthorization:&_authExternalForm];
|
|
_haveRights = NO;
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation PathRecordConfig
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Initialization / teardown
|
|
#pragma mark ******** Initialization / teardown ********
|
|
|
|
- init
|
|
{
|
|
[super init];
|
|
bzero(&_authExternalForm,sizeof(_authExternalForm));
|
|
return self;
|
|
}
|
|
|
|
- initWithRecord:(DSoRecord*)inRec
|
|
{
|
|
[super initWithRecord:inRec];
|
|
bzero(&_authExternalForm,sizeof(_authExternalForm));
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[self _destroyRights];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)setAuthExternalForm:(AuthorizationExternalForm*)externalForm {
|
|
// don't set _haveRights here since a node above us owns the auth right
|
|
memcpy(&_authExternalForm, externalForm, sizeof(AuthorizationExternalForm));
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// PathItemProtocol implementations
|
|
#pragma mark ******** PathItemProtocol implementations ********
|
|
|
|
- (tDirStatus) authenticateName:(NSString*)inUsername withPassword:(NSString*)inPassword authOnly:(BOOL)inAuthOnly
|
|
{
|
|
NSAutoreleasePool* pool = [NSAutoreleasePool new];
|
|
DSoSearchNode* searchNode = [[[_record node] directory] searchNode];
|
|
DSoUser* user = nil;
|
|
tDirStatus status = eDSAuthFailed;
|
|
NSMutableData* outputData = nil;
|
|
|
|
NS_DURING
|
|
user = [searchNode findUser:inUsername];
|
|
if (user != nil) {
|
|
status = [[user node] authenticateName:inUsername withPassword:inPassword authOnly:YES];
|
|
if (status == eDSNoErr && inAuthOnly == NO) {
|
|
outputData = [NSMutableData dataWithLength:sizeof(AuthorizationExternalForm)];
|
|
status = [[_record node] customCall:eODCustomCallConfigureGetAuthRef
|
|
sendItems:[NSArray arrayWithObjects:inUsername,inPassword,nil]
|
|
outputData:outputData];
|
|
if (status == eDSNoErr && [outputData length] >= sizeof( AuthorizationExternalForm ) )
|
|
{
|
|
[outputData getBytes:&_authExternalForm length:sizeof( AuthorizationExternalForm )];
|
|
_haveRights = YES;
|
|
}
|
|
}
|
|
}
|
|
NS_HANDLER
|
|
NS_ENDHANDLER
|
|
|
|
[pool release];
|
|
|
|
return status;
|
|
}
|
|
|
|
- (tDirStatus) createKey:(NSString*)inKey withValues:(NSArray*)inValues
|
|
{
|
|
return [self modify:ATTR_CREATE withKey:inKey withValues:inValues];
|
|
}
|
|
|
|
- (tDirStatus) deleteItem
|
|
{
|
|
tDirStatus nError = eDSNoErr;
|
|
|
|
NS_DURING
|
|
[_record removeRecord];
|
|
NS_HANDLER
|
|
if ([localException isKindOfClass:[DSoException class]])
|
|
nError = [(DSoException*)localException status];
|
|
else
|
|
[localException raise];
|
|
NS_ENDHANDLER
|
|
|
|
return nError;
|
|
}
|
|
|
|
- (NSDictionary*)getDictionary:(NSArray*)inKeys
|
|
{
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
NSArray *records = nil;
|
|
NSDictionary *attribs = nil;
|
|
|
|
NS_DURING
|
|
|
|
if ([[NSString stringWithUTF8String:[_record getType]] hasPrefix:@kDSStdRecordTypePrefix])
|
|
records = [[_record node] findRecordNames:@kDSRecordsAll
|
|
andAttributes:[NSArray arrayWithObject:@kDSAttributesAll]
|
|
ofType:[_record getType]
|
|
matchType:eDSExact];
|
|
else
|
|
records = [[_record node] findRecordNames:@kDSRecordsAll
|
|
andAttributes:[NSArray arrayWithObject:@kDSAttributesAll]
|
|
ofType:[_record getType]
|
|
matchType:eDSExact];
|
|
for (NSDictionary *recordDict in records) {
|
|
NSArray *values = [recordDict objectForKey:@kDSNAttrRecordName];
|
|
if ([values count] > 0 && [[values objectAtIndex:0] isEqual: [_record getName]]) {
|
|
attribs = recordDict;
|
|
break;
|
|
}
|
|
}
|
|
if ([inKeys count] > 0)
|
|
{
|
|
//NSArray* niceKeys = prefixedAttributeKeysWithNode([_record node], inKeys);
|
|
NSMutableDictionary* attribsFiltered = [NSMutableDictionary dictionary];
|
|
for (NSString *key in inKeys) {
|
|
NSString *niceKey = nil;
|
|
if ([key hasPrefix:@kDSStdAttrTypePrefix] || [key hasPrefix:@kDSNativeAttrTypePrefix])
|
|
{
|
|
niceKey = key;
|
|
}
|
|
else
|
|
{
|
|
niceKey = [@kDSStdAttrTypePrefix stringByAppendingString:key];
|
|
if ([attribs objectForKey: niceKey] == nil && ![[[[_record node] directory] standardAttributeTypes] containsObject:niceKey])
|
|
niceKey = [@kDSNativeAttrTypePrefix stringByAppendingString:key];
|
|
}
|
|
id value = [attribs objectForKey:niceKey];
|
|
if (value != nil) {
|
|
[attribsFiltered setObject:value forKey:niceKey];
|
|
}
|
|
}
|
|
attribs = [[attribsFiltered copy] autorelease];
|
|
}
|
|
|
|
NS_HANDLER
|
|
[localException retain];
|
|
[pool release];
|
|
[[localException autorelease] raise];
|
|
NS_ENDHANDLER
|
|
|
|
[attribs retain];
|
|
[pool release];
|
|
|
|
return [attribs autorelease];
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Utility methods
|
|
#pragma mark ******** Utility methods ********
|
|
|
|
- (tDirStatus) modify:(tAttrCAM)inAction withKey:(NSString*)inKey withValues:(NSArray*)inValues
|
|
{
|
|
tDirStatus nError = eDSReadOnly;
|
|
tDirStatus firstError = eDSNoErr;
|
|
NSUInteger index = NSNotFound;
|
|
NSDictionary *valuesDict = nil;
|
|
NSArray *oldValues = nil;
|
|
|
|
if (![[NSString stringWithUTF8String:[_record getType]] hasSuffix:@":Plugins"]) {
|
|
return eDSReadOnly;
|
|
}
|
|
|
|
if (![inKey isEqualToString:@kDS1AttrFunctionalState]
|
|
&& ![[@kDSStdAttrTypePrefix stringByAppendingString:inKey] isEqualToString:@kDS1AttrFunctionalState])
|
|
{
|
|
return eDSReadOnly;
|
|
}
|
|
|
|
NS_DURING
|
|
switch (inAction)
|
|
{
|
|
case ATTR_CREATE:
|
|
if ([inValues count] == 1) {
|
|
nError = [self setPluginEnabled:[inValues lastObject]];
|
|
}
|
|
break;
|
|
case ATTR_APPEND:
|
|
case ATTR_MERGE:
|
|
case ATTR_DELETE:
|
|
// these are not supported
|
|
break;
|
|
case ATTR_CHANGE:
|
|
valuesDict = [self getDictionary: [NSArray arrayWithObject:@kDS1AttrFunctionalState]];
|
|
oldValues = (NSArray*)[valuesDict objectForKey:@kDS1AttrFunctionalState];
|
|
if ([oldValues count] == 1 && [[inValues objectAtIndex:0] isEqual:[oldValues objectAtIndex:0]]) {
|
|
nError = [self setPluginEnabled:[inValues objectAtIndex:1]];
|
|
} else {
|
|
nError = eDSAttributeValueNotFound;
|
|
}
|
|
break;
|
|
case ATTR_CHANGE_INDEX:
|
|
index = [[inValues objectAtIndex:0] intValue];
|
|
if (index == 0) {
|
|
nError = [self setPluginEnabled:[inValues objectAtIndex:1]];
|
|
}
|
|
break;
|
|
}
|
|
NS_HANDLER
|
|
if ([localException isKindOfClass:[DSoException class]])
|
|
{
|
|
nError = [(DSoException*)localException status];
|
|
firstError = nError;
|
|
}
|
|
else
|
|
[localException raise];
|
|
NS_ENDHANDLER
|
|
|
|
return nError;
|
|
}
|
|
|
|
- (tDirStatus)setPluginEnabled:(NSString*)newState
|
|
{
|
|
BOOL newStateBool;
|
|
|
|
if ([newState isEqualToString:@"Active"])
|
|
{
|
|
newStateBool = YES;
|
|
}
|
|
else if ([newState isEqualToString:@"Inactive"]) {
|
|
newStateBool = NO;
|
|
}
|
|
else
|
|
{
|
|
return eDSReadOnly;
|
|
}
|
|
|
|
[(DSoNodeConfig*)[_record node] setPlugin:[_record getName] enabled:newStateBool withAuthorization:&_authExternalForm];
|
|
|
|
return eDSNoErr;
|
|
}
|
|
|
|
@end
|