darling-DSTools/dscl/PathRecordConfig.m
Andrew Hyatt b1d05a7ba1 Build the one utility we need for now
It's for Homebrew
2017-04-07 18:59:54 -07:00

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