Add even more of the source
This should be about everything needed to build so far?
This commit is contained in:
parent
af3619d4fa
commit
849723c9cf
547 changed files with 149239 additions and 0 deletions
646
APIModules/QTSSDSAuthModule/DSAccessChecker.cpp
Normal file
646
APIModules/QTSSDSAuthModule/DSAccessChecker.cpp
Normal file
|
@ -0,0 +1,646 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (c) 1999-2005 Apple Computer, Inc. All Rights Reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DSAccessChecker.cpp
|
||||
|
||||
Contains: Class definition for access checking via Open Directory
|
||||
|
||||
Created By: Dan Sinema
|
||||
|
||||
Created: Jan 14, 2005
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Directory Service code added by Dan Sinema
|
||||
*
|
||||
* Jan 14, 2005 - Cleaned up code and added more comments.
|
||||
* Nov 8, 2004 - Finsihed final code. Added group support.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// ANSI / POSIX Headers
|
||||
#include <grp.h>
|
||||
#include <membership.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// STL Headers
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
// Project Headers
|
||||
#include "SafeStdLib.h"
|
||||
#include "StrPtrLen.h"
|
||||
#include "StringParser.h"
|
||||
#include "ResizeableStringFormatter.h"
|
||||
|
||||
#include "DSAccessChecker.h"
|
||||
#include "DSDataList.h"
|
||||
#include "QTAccessFile.h"
|
||||
|
||||
#define DEBUG_DSACCESS 0
|
||||
#define debug_printf if (DEBUG_DSACCESS) ::qtss_printf
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
|
||||
#if OSX_OD_API
|
||||
#define OD_API 1
|
||||
#define DS_API 0
|
||||
#else
|
||||
#define OD_API 0
|
||||
#define DS_API 1
|
||||
#endif
|
||||
#else
|
||||
#define OD_API 0
|
||||
#define DS_API 1
|
||||
#endif
|
||||
|
||||
// Framework Headers
|
||||
#if DS_API
|
||||
#include <DirectoryService/DirectoryService.h>
|
||||
using namespace DirectoryServices;
|
||||
#endif
|
||||
|
||||
#if OD_API
|
||||
#include <OpenDirectory/OpenDirectory.h>
|
||||
#endif
|
||||
|
||||
#if __LP64__
|
||||
#define ds_API_PTR UInt32*
|
||||
#else
|
||||
#define ds_API_PTR long unsigned int*
|
||||
#endif
|
||||
|
||||
|
||||
#pragma mark DSAccessChecker class globals
|
||||
|
||||
const char* DSAccessChecker::kDefaultAccessFileName = "qtaccess";
|
||||
|
||||
|
||||
#pragma mark DSAccessChecker class implementation
|
||||
#if DS_API
|
||||
|
||||
// Find a list of records that match the given criteria.
|
||||
static SInt32 _GetRecordList(
|
||||
tDirReference inDSRef,
|
||||
const char *inDomain,
|
||||
const char *inRecName,
|
||||
const char *inRecType,
|
||||
tDataList *inAttrType,
|
||||
tDirNodeReference *outNodeRef,
|
||||
tDataBuffer **outDataBuff,
|
||||
UInt32 *outRecCount )
|
||||
{
|
||||
SInt32 status = eDSNoErr;
|
||||
tDataBuffer *pDataBuff = NULL;
|
||||
tDirNodeReference nodeRef = 0;
|
||||
tContextData context = NULL;
|
||||
UInt32 nodeCount = 0;
|
||||
tDataList *nodeName = NULL;
|
||||
UInt32 recCount = 0;
|
||||
|
||||
*outNodeRef = 0;
|
||||
*outDataBuff = NULL;
|
||||
*outRecCount = 0;
|
||||
|
||||
pDataBuff = ::dsDataBufferAllocate( inDSRef, 4096 );
|
||||
if (pDataBuff == NULL)
|
||||
{
|
||||
// We need the buffer for locating the node for which the user object resides
|
||||
debug_printf("QTSSODAuthModule: Unable to allocate buffer.\n");
|
||||
return eDSAllocationFailed;
|
||||
}
|
||||
|
||||
// This is the default action with no domain: use the Search node.
|
||||
status = ::dsFindDirNodes( inDSRef, pDataBuff, NULL, eDSSearchNodeName, (ds_API_PTR) &nodeCount, &context );
|
||||
if ( context != NULL )
|
||||
{
|
||||
::dsReleaseContinueData( inDSRef, context );
|
||||
context = NULL;
|
||||
}
|
||||
|
||||
// Check for failure of the dsFindDirNodes
|
||||
// Node count less than 1 means no node found...doh!
|
||||
if ( nodeCount < 1 )
|
||||
{
|
||||
status = eDSNodeNotFound;
|
||||
}
|
||||
if ( status != eDSNoErr )
|
||||
{
|
||||
goto cleanupBadGetRecordList;
|
||||
}
|
||||
|
||||
// Extract the name of the found node.
|
||||
status = ::dsGetDirNodeName( inDSRef, pDataBuff, 1, &nodeName );
|
||||
if (status == eDSNoErr)
|
||||
{
|
||||
// Open the node so we can do the DS magic
|
||||
status = ::dsOpenDirNode( inDSRef, nodeName, &nodeRef );
|
||||
::dsDataListDeallocate( inDSRef, nodeName );
|
||||
std::free( nodeName );
|
||||
nodeName = NULL;
|
||||
}
|
||||
|
||||
if (status != eDSNoErr)
|
||||
{
|
||||
// Bail if we cannot open the node.
|
||||
debug_printf("QTSSODAuthModule: Could not open node - error: %"_S32BITARG_"\n", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Specify what we are looking for...
|
||||
// pRecName: the passed name of the record
|
||||
// pRecType: the passed name of the record type
|
||||
// pAttrType: attributes to return to the caller
|
||||
DSDataList recName( inDSRef, inRecName );
|
||||
DSDataList recType( inDSRef, inRecType );
|
||||
|
||||
recCount = 1;
|
||||
|
||||
// Find the record that matchs the above criteria
|
||||
status = ::dsGetRecordList( nodeRef, pDataBuff, recName, eDSExact, recType, inAttrType, 0, (ds_API_PTR)&recCount, &context );
|
||||
if ( context != NULL )
|
||||
{
|
||||
::dsReleaseContinueData( inDSRef, context );
|
||||
context = NULL;
|
||||
}
|
||||
if ( recCount == 0 )
|
||||
{
|
||||
status = eDSRecordNotFound;
|
||||
debug_printf("QTSSODAuthModule: No records found.\n");
|
||||
}
|
||||
else if ( status != eDSNoErr )
|
||||
{
|
||||
debug_printf("QTSSODAuthModule: No records found - error: %"_S32BITARG_"\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
if ( status == eDSNoErr )
|
||||
{
|
||||
*outNodeRef = nodeRef;
|
||||
*outDataBuff = pDataBuff;
|
||||
*outRecCount = recCount;
|
||||
return eDSNoErr;
|
||||
}
|
||||
|
||||
cleanupBadGetRecordList:
|
||||
if ( nodeRef != 0 )
|
||||
{
|
||||
::dsCloseDirNode( nodeRef );
|
||||
}
|
||||
|
||||
// This variable is guaranteed to be valid because the function would
|
||||
// have returned if it was bad.
|
||||
::dsDataBufferDeAllocate( inDSRef, pDataBuff );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static SInt32 _FindRecordNode(
|
||||
tDirReference inDSRef,
|
||||
const char *inDomain,
|
||||
const char *inRecName,
|
||||
const char *inRecType,
|
||||
tDataList *outHomeNodeName )
|
||||
{
|
||||
tDataBuffer *pRecBuff = NULL;
|
||||
tDirNodeReference nodeRef = 0;
|
||||
SInt32 status = eDSNoErr;
|
||||
UInt32 attrIndex = 0;
|
||||
UInt32 recCount = 0;
|
||||
tRecordEntry *pRecEntry = NULL;
|
||||
tAttributeListRef attrListRef = 0;
|
||||
|
||||
if ( outHomeNodeName == NULL )
|
||||
{
|
||||
return eDSNullDataList;
|
||||
}
|
||||
std::memset( outHomeNodeName, 0, sizeof( *outHomeNodeName) );
|
||||
|
||||
// A Username and Password is needed, if either one is not present then bail!
|
||||
if ( inRecName == NULL )
|
||||
{
|
||||
return eDSInvalidRecordName;
|
||||
}
|
||||
if ( inRecType == NULL )
|
||||
{
|
||||
return eDSInvalidRecordType;
|
||||
}
|
||||
|
||||
status = ::_GetRecordList( inDSRef, inDomain, inRecName, inRecType,
|
||||
DSDataList (inDSRef, kDSNAttrMetaNodeLocation),
|
||||
&nodeRef, &pRecBuff, &recCount );
|
||||
if ( status != eDSNoErr )
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
// Get the record entry out of the list, there should only be one record!
|
||||
status = ::dsGetRecordEntry( nodeRef, pRecBuff, 1, &attrListRef, &pRecEntry );
|
||||
if ( status != eDSNoErr )
|
||||
{
|
||||
// These variables are guaranteed to be valid because the function would
|
||||
// have returned if they were bad.
|
||||
::dsCloseDirNode( nodeRef );
|
||||
::dsDataBufferDeAllocate( inDSRef, pRecBuff );
|
||||
return status;
|
||||
}
|
||||
|
||||
// Now loop through attributes of the entry...looking for kDSNAttrMetaNodeLocation and kDSNAttrRecordName
|
||||
for ( attrIndex = 1; (attrIndex <= pRecEntry->fRecordAttributeCount) && (status == eDSNoErr); attrIndex++ )
|
||||
{
|
||||
tAttributeEntryPtr pAttrEntry = NULL;
|
||||
tAttributeValueListRef valueRef = 0;
|
||||
|
||||
status = ::dsGetAttributeEntry( nodeRef, pRecBuff, attrListRef, attrIndex, &valueRef, &pAttrEntry );
|
||||
if ( ( status != eDSNoErr ) || ( pAttrEntry == NULL ) )
|
||||
continue;
|
||||
// Test for kDSNAttrMetaNodeLocation
|
||||
if ( std::strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrMetaNodeLocation ) == 0 )
|
||||
{
|
||||
tAttributeValueEntry *pValueEntry = NULL;
|
||||
|
||||
// If it matches then get the value of the attribute
|
||||
status = ::dsGetAttributeValue( nodeRef, pRecBuff, 1, valueRef, &pValueEntry );
|
||||
if ( ( status == eDSNoErr ) && ( pValueEntry != NULL ) )
|
||||
{
|
||||
// Store the node location in outHomeNodeName
|
||||
if ( outHomeNodeName->fDataNodeCount != 0 )
|
||||
{
|
||||
debug_printf("QTSSODAuthModule: Multiple user locations found!?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ::dsBuildListFromPathAlloc( inDSRef, outHomeNodeName, pValueEntry->fAttributeValueData.fBufferData, "/" );
|
||||
::dsDeallocAttributeValueEntry( inDSRef, pValueEntry );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::dsDeallocAttributeEntry( inDSRef, pAttrEntry );
|
||||
::dsCloseAttributeValueList( valueRef );
|
||||
}
|
||||
|
||||
// Cleanup dsGetRecordEntry() return values.
|
||||
::dsCloseAttributeList( attrListRef );
|
||||
::dsDeallocRecordEntry( inDSRef, pRecEntry );
|
||||
::dsCloseDirNode( nodeRef );
|
||||
::dsDataBufferDeAllocate( inDSRef, pRecBuff );
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark "Public Methods"
|
||||
// Now the class proper.
|
||||
DSAccessChecker::DSAccessChecker()
|
||||
{
|
||||
}
|
||||
|
||||
DSAccessChecker::~DSAccessChecker()
|
||||
{
|
||||
#if DEBUG
|
||||
debug_printf("QTSSODAuthModule: Access checker object destroyed.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 //OD_API notes
|
||||
/*
|
||||
This is Leopard or later code so some check before using OD based code is needed.
|
||||
Implement this api for digest auth.
|
||||
*/
|
||||
|
||||
#include <OpenDirectory/OpenDirectoryPriv.h>
|
||||
/System/Library/PrivateFrameworks/OpenDirectory.framework/Frameworks/CFOpenDirectory.framework/CFOpenDirectory
|
||||
CFErrorRef outError = NULL;
|
||||
ODNodeRef cfNode = ODNodeCreateWithNodeType( kCFAllocatorDefault, kODSessionDefault, kODTypeAuthenticationSearchNode, NULL );
|
||||
if (cfNode)
|
||||
{
|
||||
ODRecordRef cfUserRecord = ODNodeCopyRecord( kCFAllocatorDefault, cfNode, CFSTR("username"), NULL );
|
||||
|
||||
if (cfUserRecord != NULL)
|
||||
{
|
||||
CFArrayRef authItems = CFArrayCreate.... ( username, server challenge, client response, http method);
|
||||
|
||||
// for DIGEST_MD5
|
||||
if (ODRecordVerifyPasswordExtended( cfUserRecord, CFSTR(kDSStdAuthDIGEST_MD5), authItems, NULL, NULL, &outError ))
|
||||
{
|
||||
}
|
||||
|
||||
// this for password
|
||||
if (ODRecordVerifyPassword( cfUserRecord, CFSTR("password") ) )
|
||||
{
|
||||
}
|
||||
CFRelease( cfUserRecord );
|
||||
CFRelease( autItems );
|
||||
}
|
||||
CFRelease( cfNode );
|
||||
}
|
||||
|
||||
|
||||
// kDSStdAuthDIGEST_MD5
|
||||
* user name in UTF8 encoding,
|
||||
* server challenge in UTF8 encoding,
|
||||
* client response data,
|
||||
* HTTP method in UTF8 encoding
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if OD_API
|
||||
Bool16 DSAccessChecker::CheckPassword(const char* inUsername, const char* inPassword)
|
||||
{
|
||||
Bool16 checkedResult = false;
|
||||
CFErrorRef outError = NULL;
|
||||
debug_printf("DSAccessChecker::CheckPassword userName=%s password=%s\n", inUsername,inPassword);
|
||||
|
||||
ODNodeRef cfNodeRef= ODNodeCreateWithNodeType( kCFAllocatorDefault, kODSessionDefault, kODTypeAuthenticationSearchNode, NULL );
|
||||
|
||||
//static ODRecordRef _ODNodeCopyRecord( ODNodeRef inNodeRef, CFStringRef inRecordType, CFStringRef inRecordName, CFArrayRef inAttributes, CFErrorRef *outError );
|
||||
|
||||
|
||||
CFStringRef cfPassword = CFStringCreateWithCString(kCFAllocatorDefault, inPassword, kCFStringEncodingUTF8);
|
||||
CFStringRef cfUsername = CFStringCreateWithCString(kCFAllocatorDefault, inUsername, kCFStringEncodingUTF8);
|
||||
|
||||
CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) };
|
||||
CFArrayRef reqAttrs = CFArrayCreate(NULL, vals,1, &kCFTypeArrayCallBacks);
|
||||
|
||||
ODRecordRef cfUserRecord = ODNodeCopyRecord(cfNodeRef, CFSTR(kDSStdRecordTypeUsers), cfUsername, reqAttrs, &outError );
|
||||
if (cfNodeRef && cfUserRecord && cfPassword && cfUsername)
|
||||
{
|
||||
// this for password
|
||||
if ( ODRecordVerifyPassword( cfUserRecord, cfPassword , NULL ) )
|
||||
{ checkedResult = true;
|
||||
debug_printf("DSAccessChecker::CheckPassword ODRecordVerifyPassword user is authenticated\n");
|
||||
}
|
||||
else
|
||||
{ debug_printf("DSAccessChecker::CheckPassword ODRecordVerifyPassword user failed to authenticate\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (reqAttrs) CFRelease( reqAttrs );
|
||||
if (cfUserRecord) CFRelease( cfUserRecord );
|
||||
if (cfPassword) CFRelease( cfPassword );
|
||||
if (cfUsername) CFRelease( cfUsername );
|
||||
if (cfNodeRef) CFRelease( cfNodeRef );
|
||||
|
||||
return checkedResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Bool16 DSAccessChecker::CheckDigest(const char* inUsername, const char* inServerChallenge, const char* inClientResponse, const char* inMethod)
|
||||
{
|
||||
Bool16 checkedResult = false;
|
||||
CFErrorRef outError = NULL;
|
||||
CFArrayRef outItems = NULL;
|
||||
|
||||
if (NULL == inUsername || NULL == inServerChallenge || NULL == inClientResponse )
|
||||
return false;
|
||||
|
||||
ResizeableStringFormatter challengeString;
|
||||
challengeString.Put((char*) inServerChallenge);
|
||||
challengeString.PutTerminator();
|
||||
char* challengeCString= challengeString.GetBufPtr();
|
||||
|
||||
ResizeableStringFormatter responseString;
|
||||
responseString.Put( (char*)inClientResponse);
|
||||
responseString.PutTerminator();
|
||||
char* responseCString= responseString.GetBufPtr();
|
||||
|
||||
ODNodeRef cfNode = ODNodeCreateWithNodeType( kCFAllocatorDefault, kODSessionDefault, kODTypeAuthenticationSearchNode, NULL );
|
||||
debug_printf("DSAccessChecker::CheckDigest \nuserName=[%s] \nchallenge=[%s] \nresponse=[%s] \nmethod=[%s]\n", inUsername,challengeCString, responseCString,inMethod);
|
||||
|
||||
|
||||
CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) };
|
||||
CFArrayRef reqAttrs = CFArrayCreate(NULL, vals,1, &kCFTypeArrayCallBacks);
|
||||
|
||||
CFStringRef cfUsername = CFStringCreateWithCString(kCFAllocatorDefault, inUsername, kCFStringEncodingUTF8);
|
||||
ODRecordRef cfUserRecord = ODNodeCopyRecord(cfNode, CFSTR(kDSStdRecordTypeUsers), cfUsername, reqAttrs, &outError );
|
||||
CFRelease( cfUsername );
|
||||
cfUsername = NULL;
|
||||
|
||||
enum { kNumAuthValues=4 };
|
||||
CFStringRef cfStringArray[kNumAuthValues];
|
||||
cfStringArray[0] = CFStringCreateWithCString(kCFAllocatorDefault, inUsername, kCFStringEncodingUTF8);
|
||||
cfStringArray[1] = CFStringCreateWithCString(kCFAllocatorDefault, challengeCString, kCFStringEncodingUTF8);
|
||||
cfStringArray[2] = CFStringCreateWithCString(kCFAllocatorDefault, responseCString, kCFStringEncodingUTF8);
|
||||
cfStringArray[3] = CFStringCreateWithCString(kCFAllocatorDefault, inMethod, kCFStringEncodingUTF8);
|
||||
|
||||
CFArrayRef cfAuthItems = CFArrayCreate(kCFAllocatorDefault, (const void **) &cfStringArray,kNumAuthValues, &kCFTypeArrayCallBacks);
|
||||
|
||||
if (cfNode && cfUserRecord && cfAuthItems)
|
||||
{
|
||||
debug_printf("DSAccessChecker::CheckDigest call ODRecordVerifyPasswordExtended\n");
|
||||
// for DIGEST_MD5
|
||||
if (ODRecordVerifyPasswordExtended( cfUserRecord, CFSTR(kDSStdAuthDIGEST_MD5), cfAuthItems, &outItems, NULL, &outError ))
|
||||
{
|
||||
checkedResult = true;
|
||||
debug_printf("DSAccessChecker::CheckDigest SUCCESS ODRecordVerifyPasswordExtended response=%d\n",outError);
|
||||
}
|
||||
else
|
||||
{ debug_printf("DSAccessChecker::CheckDigest ODRecordVerifyPasswordExtended response=%d\n", outError ? CFErrorGetCode(outError) : -1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < kNumAuthValues; i++)
|
||||
CFRelease(cfStringArray[i]);
|
||||
|
||||
if (reqAttrs) CFRelease( reqAttrs );
|
||||
if (cfAuthItems) CFRelease( cfAuthItems );
|
||||
if (cfUserRecord) CFRelease( cfUserRecord );
|
||||
if (cfNode) CFRelease( cfNode );
|
||||
if (outItems) CFRelease( outItems );
|
||||
if (outError) CFRelease( outError );
|
||||
|
||||
return checkedResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if DS_API
|
||||
|
||||
Bool16 DSAccessChecker::CheckPassword(const char* inUsername, const char* inPassword)
|
||||
{
|
||||
tDirReference dsRef = 0;
|
||||
tDataList userNode = { 0, NULL };
|
||||
tDirNodeReference nodeRef = 0;
|
||||
SInt32 status = eDSNoErr;
|
||||
|
||||
// A Username and Password is needed, if either one is not present then bail!
|
||||
if ( inUsername == NULL )
|
||||
{
|
||||
debug_printf("QTSSODAuthModule: Username required.\n");
|
||||
return false;
|
||||
}
|
||||
if ( inPassword == NULL )
|
||||
{
|
||||
debug_printf("QTSSODAuthModule: Password required.\n");
|
||||
return false;
|
||||
}
|
||||
status = ::dsOpenDirService( &dsRef );
|
||||
if ( status != eDSNoErr )
|
||||
{
|
||||
// Some DS error, tell the admin what the error is and bail.
|
||||
// Error can be found in DirectoryService man page.
|
||||
debug_printf("QTSSODAuthModule: Could not open Directory Services - error: %"_S32BITARG_"", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
status = _FindRecordNode( dsRef, NULL, inUsername, kDSStdRecordTypeUsers, &userNode );
|
||||
if ( status != eDSNoErr )
|
||||
{
|
||||
debug_printf("QTSSODAuthModule: Could not find user node.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now that we know the node location of the user object, lets open that node.
|
||||
status = ::dsOpenDirNode( dsRef, &userNode, &nodeRef );
|
||||
::dsDataListDeallocate( dsRef, &userNode );
|
||||
|
||||
if ( status == eDSNoErr )
|
||||
{
|
||||
UInt32 uiLen = std::strlen( inUsername );
|
||||
tDataNode *pAuthType = ::dsDataNodeAllocateString( dsRef, kDSStdAuthNodeNativeClearTextOK );
|
||||
tDataBuffer *pStepBuff = ::dsDataBufferAllocate( dsRef, 128 );
|
||||
tDataBuffer *pAuthBuff = ::dsDataBufferAllocate( dsRef, ( sizeof( UInt32 ) + sizeof( UInt32 ) + uiLen + std::strlen( inPassword ) ) );
|
||||
|
||||
if ( ( pStepBuff != NULL ) && ( pAuthType != NULL ) && ( pAuthBuff != NULL ) )
|
||||
{
|
||||
UInt32 uiCurr = 0;
|
||||
|
||||
// Copy username (that is passed into this function) into buffer for dsDoDirNodeAuth()
|
||||
std::memcpy( &(pAuthBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( UInt32 ) );
|
||||
uiCurr += sizeof( UInt32 );
|
||||
std::memcpy( &(pAuthBuff->fBufferData[ uiCurr ]), inUsername, uiLen );
|
||||
uiCurr += uiLen;
|
||||
|
||||
// Copy password into a buffer for dsDoDirNodeAuth()
|
||||
uiLen = std::strlen( inPassword );
|
||||
std::memcpy( &(pAuthBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( UInt32 ) );
|
||||
uiCurr += sizeof( UInt32 );
|
||||
std::memcpy( &(pAuthBuff->fBufferData[ uiCurr ]), inPassword, uiLen );
|
||||
uiCurr += uiLen;
|
||||
|
||||
pAuthBuff->fBufferLength = uiCurr;
|
||||
|
||||
// Perform the authentication
|
||||
status = ::dsDoDirNodeAuth( nodeRef, pAuthType, 1, pAuthBuff, pStepBuff, NULL );
|
||||
// Since the buffer held a name & password, clear it immediately.
|
||||
std::memset( pAuthBuff, 0, pAuthBuff->fBufferSize );
|
||||
}
|
||||
// Free the auth buffer.
|
||||
if ( pAuthBuff != NULL )
|
||||
{
|
||||
::dsDataBufferDeAllocate( dsRef, pAuthBuff );
|
||||
}
|
||||
// Free the ignored step buffer.
|
||||
if ( pStepBuff != NULL )
|
||||
{
|
||||
::dsDataBufferDeAllocate( dsRef, pStepBuff );
|
||||
}
|
||||
// Free the auth string.
|
||||
if ( pAuthType != NULL )
|
||||
{
|
||||
::dsDataNodeDeAllocate( dsRef, pAuthType );
|
||||
}
|
||||
::dsCloseDirNode( nodeRef );
|
||||
}
|
||||
::dsCloseDirService( dsRef );
|
||||
|
||||
if( status == eDSNoErr )
|
||||
{
|
||||
debug_printf("QTSSODAuthModule: Authentication is good.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// For admins running QTSS in debug
|
||||
debug_printf("QTSSODAuthModule: OD returned %"_S32BITARG_" status.\n", status);
|
||||
debug_printf("QTSSODAuthModule: Authentication failed.\n");
|
||||
// If the Authentication failed then return false, which boots the user...
|
||||
return false;
|
||||
}
|
||||
|
||||
Bool16 DSAccessChecker::CheckDigest(const char* inUsername, const char* inServerChallenge, const char* inClientResponse, const char* inMethod)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark "Protected Methods"
|
||||
|
||||
Bool16 DSAccessChecker::CheckGroupMembership(const char* inUsername, const char* inGroupName)
|
||||
{
|
||||
// In Tiger, group membership is painfully simple: we ask memberd for it!
|
||||
struct passwd *user = NULL;
|
||||
struct group *group = NULL;
|
||||
uuid_t userID;
|
||||
uuid_t groupID;
|
||||
int isMember = 0;
|
||||
|
||||
// Look up the user using the POSIX APIs: only care about the UID.
|
||||
user = getpwnam(inUsername);
|
||||
endpwent();
|
||||
if ( user == NULL )
|
||||
return false;
|
||||
uuid_clear(userID);
|
||||
if ( mbr_uid_to_uuid(user->pw_uid, userID) )
|
||||
return false;
|
||||
|
||||
// Look up the group using the POSIX APIs: only care about the GID.
|
||||
group = getgrnam(inGroupName);
|
||||
endgrent();
|
||||
if ( group == NULL )
|
||||
return false;
|
||||
uuid_clear(groupID);
|
||||
if ( mbr_gid_to_uuid(group->gr_gid, groupID) )
|
||||
return false;
|
||||
|
||||
// mbr_check_membership() returns 0 on success and error code on failure.
|
||||
if ( mbr_check_membership(userID, groupID, &isMember) )
|
||||
return false;
|
||||
return (bool)isMember;
|
||||
}
|
||||
|
||||
|
70
APIModules/QTSSDSAuthModule/DSAccessChecker.h
Normal file
70
APIModules/QTSSDSAuthModule/DSAccessChecker.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DSAccessChecker.h
|
||||
|
||||
Contains: Class definition for access checking via Open Directory
|
||||
|
||||
Created By: Dan Sinema
|
||||
|
||||
Created: Jan 14, 2005
|
||||
*/
|
||||
|
||||
#ifndef _QTSSACCESSCHECKER_H_
|
||||
#define _QTSSACCESSCHECKER_H_
|
||||
|
||||
// STL Headers
|
||||
#include <cstdio> // for struct FILE
|
||||
#include <string>
|
||||
#include "QTAccessFile.h"
|
||||
|
||||
|
||||
class DSAccessChecker
|
||||
{
|
||||
/*
|
||||
Access check logic:
|
||||
|
||||
If "modAccess_enabled" == "enabled,
|
||||
|
||||
*/
|
||||
|
||||
public:
|
||||
static const char* kDefaultAccessFileName;
|
||||
|
||||
DSAccessChecker();
|
||||
virtual ~DSAccessChecker();
|
||||
|
||||
Bool16 CheckPassword(const char* inUsername, const char* inPassword);
|
||||
Bool16 CheckDigest(const char* inUsername, const char* inServerChallenge, const char* inClientResponse, const char* inMethod);
|
||||
|
||||
|
||||
protected:
|
||||
Bool16 CheckGroupMembership(const char* inUsername, const char* inGroupName);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //_QTSSACCESSCHECKER_H_
|
91
APIModules/QTSSDSAuthModule/DSWrappers/CDirService.cpp
Normal file
91
APIModules/QTSSDSAuthModule/DSWrappers/CDirService.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: CDirService.h
|
||||
|
||||
Contains: Implements DSException.
|
||||
|
||||
Created By: chris jalbert
|
||||
|
||||
Created: 26 July 2000
|
||||
*/
|
||||
|
||||
|
||||
// This file is only meaningful if exceptions are enabled.
|
||||
#if USE_EXCEPTIONS
|
||||
|
||||
// STL and Std C++ Library Headers
|
||||
#include <cstdlib> // for abs()
|
||||
#include <stdexcept> // for standard exceptions
|
||||
|
||||
// Project Headers
|
||||
#include "CDirService.h"
|
||||
|
||||
using namespace DirectoryServices ;
|
||||
using namespace std ;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ¥ CDirService Class Globals
|
||||
// These private typedefs, globals, and functions are not declared statically
|
||||
// in the class definition because I want to hide the implementation details
|
||||
// and reduce unrelated dependencies in the class header.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const char * const _DSErr = "DirectoryService error: " ;
|
||||
|
||||
/*
|
||||
* Convert an UInt32 to ASCII for printf purposes, returning
|
||||
* a pointer to the first character of the string representation.
|
||||
* Borrowed from vfprintf.c.
|
||||
*/
|
||||
static char *_ltoa (
|
||||
SInt32 val,
|
||||
char *endp)
|
||||
{
|
||||
register char *cp = endp ;
|
||||
register SInt32 sval = std::abs (val) ;
|
||||
|
||||
// Terminate the string.
|
||||
*--cp = '\0' ;
|
||||
|
||||
do {
|
||||
*--cp = '0' + (sval % 10) ;
|
||||
sval /= 10 ;
|
||||
} while (sval != 0) ;
|
||||
|
||||
// Handle signed values.
|
||||
if (val < 0)
|
||||
*--cp = '-' ;
|
||||
return cp ;
|
||||
}
|
||||
|
||||
DSException::DSException (tDirStatus err)
|
||||
: inherited (string (_DSErr) + _ltoa (err, &mErrStr[sizeof (mErrStr)])),
|
||||
mErr (err)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* USE_EXCEPTIONS */
|
87
APIModules/QTSSDSAuthModule/DSWrappers/CDirService.h
Normal file
87
APIModules/QTSSDSAuthModule/DSWrappers/CDirService.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: CDirService.h
|
||||
|
||||
Contains: Defines DSException.
|
||||
|
||||
Created By: chris jalbert
|
||||
|
||||
Created: 26 July 2000
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CDirService_h
|
||||
#define _CDirService_h
|
||||
|
||||
// Framework Headers
|
||||
#include <DirectoryService/DirServicesTypes.h>
|
||||
|
||||
namespace DirectoryServices {
|
||||
|
||||
const tDirReference kDSDirRefNull = 0 ;
|
||||
|
||||
// This file is only meaningful if exceptions are enabled.
|
||||
#if __EXCEPTIONS
|
||||
|
||||
// STL and Std C++ Library Headers
|
||||
#include <stdexcept> // for standard exceptions
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ¥ DSException - exception class that wraps a tDirStatus result code.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class DSException : public std::runtime_error {
|
||||
public:
|
||||
typedef std::runtime_error inherited ;
|
||||
DSException ( tDirStatus err ) ;
|
||||
tDirStatus status ( void ) const { return mErr ; }
|
||||
private:
|
||||
tDirStatus mErr ;
|
||||
char mErrStr [12] ;
|
||||
} ;
|
||||
#define throw_ds_error(err) throw DSException(err)
|
||||
|
||||
#else /* __EXCEPTIONS */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ¥ DSException - with exceptions disabled, this is dummy code.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class DSException {
|
||||
public:
|
||||
DSException ( tDirStatus ) { }
|
||||
} ;
|
||||
|
||||
// Define away the throw spec.
|
||||
#define throw(spec)
|
||||
#define throw_ds_error(err)
|
||||
|
||||
#endif /* __EXCEPTIONS */
|
||||
|
||||
} // namespace DirectoryServices
|
||||
|
||||
#endif /* _CDirService_h */
|
94
APIModules/QTSSDSAuthModule/DSWrappers/DSBuffer.cpp
Normal file
94
APIModules/QTSSDSAuthModule/DSWrappers/DSBuffer.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DSBuffer.cpp
|
||||
|
||||
Contains: Class implementation for Open Directory buffers
|
||||
(wraps tDataBufferPtr)
|
||||
|
||||
Created By: chris jalbert
|
||||
|
||||
Created: 28 November 2000
|
||||
*/
|
||||
|
||||
|
||||
// ANSI / POSIX headers
|
||||
|
||||
// STL and Std C++ Library Headers
|
||||
#include <stdexcept> // for standard exceptions
|
||||
|
||||
// Framework Headers
|
||||
#include <DirectoryService/DirServices.h>
|
||||
|
||||
// Project Headers
|
||||
#include "DSBuffer.h"
|
||||
|
||||
|
||||
using namespace DirectoryServices ;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ¥ DSBuffer Class Globals
|
||||
// These private typedefs, globals, and functions are not declared statically
|
||||
// in the class definition because I want to hide the implementation details
|
||||
// and reduce unrelated dependencies in the class header.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ¥ DSBuffer Protected Instance Methods
|
||||
// ----------------------------------------------------------------------------
|
||||
#pragma mark **** DSBuffer Protected Instance Methods ****
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ¥ÊGrow
|
||||
// All memory management (even in the c'tors) are handled in this method.
|
||||
// An inNewSize value of 0 implies the use of the default buffer size!
|
||||
// To leave the buffer alone, call with an argument value of 1.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
tDataBufferPtr DSBuffer::grow ( size_t inNewSize )
|
||||
{
|
||||
if (!inNewSize)
|
||||
inNewSize = kDefaultSize ;
|
||||
if (mBuffer && (inNewSize <= mBuffer->fBufferSize))
|
||||
return mBuffer ;
|
||||
|
||||
register size_t ulTemp = 16 ;
|
||||
if (inNewSize == kDefaultSize)
|
||||
ulTemp = inNewSize ;
|
||||
else
|
||||
for ( ; ulTemp < inNewSize ; ulTemp <<= 1) ;
|
||||
|
||||
register tDataBufferPtr bufNew = ::dsDataBufferAllocate (mDirRef, ulTemp) ;
|
||||
if (!bufNew)
|
||||
throw_ds_error (eDSAllocationFailed) ;
|
||||
if (mBuffer && (ulTemp = mBuffer->fBufferLength))
|
||||
std::memcpy (bufNew->fBufferData, mBuffer->fBufferData, ulTemp) ;
|
||||
else
|
||||
ulTemp = 0 ;
|
||||
bufNew->fBufferLength = ulTemp ;
|
||||
::dsDataBufferDeAllocate (mDirRef, mBuffer) ;
|
||||
return (mBuffer = bufNew) ;
|
||||
}
|
125
APIModules/QTSSDSAuthModule/DSWrappers/DSBuffer.h
Normal file
125
APIModules/QTSSDSAuthModule/DSWrappers/DSBuffer.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DSBuffer.h
|
||||
|
||||
Contains: Class definition for Open Directory buffers
|
||||
(wraps tDataBufferPtr)
|
||||
|
||||
Created By: chris jalbert
|
||||
|
||||
Created: 26 July 2000
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DSBuffer_h
|
||||
#define _DSBuffer_h
|
||||
|
||||
|
||||
// Framework Headers
|
||||
#include <DirectoryService/DirServicesTypes.h>
|
||||
#include <DirectoryService/DirServicesUtils.h>
|
||||
|
||||
// Project Headers
|
||||
#include "CDirService.h"
|
||||
|
||||
|
||||
namespace DirectoryServices {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ¥ DSBuffer - a wrapper for tDataBufferPtr.
|
||||
// This should be considered a private class, primarily used by DSNode.
|
||||
// All methods except Grow() are inlined for performance reasons (sorry).
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class DSBuffer
|
||||
{
|
||||
public:
|
||||
/**** Typedefs, enums, and constants. ****/
|
||||
enum { kDefaultSize = 128 } ;
|
||||
|
||||
public:
|
||||
/**** Instance methods. ****/
|
||||
// ctor and dtor.
|
||||
DSBuffer ( tDirReference inDirRef = 0,
|
||||
size_t inBufferSize = kDefaultSize ) throw (DSException)
|
||||
: mDirRef (inDirRef), mBuffer (0)
|
||||
{ if (!grow (inBufferSize)) throw_ds_error (eDSAllocationFailed) ; }
|
||||
~DSBuffer ( void ) throw ()
|
||||
{ if (mBuffer) ::dsDataBufferDeAllocate (mDirRef, mBuffer) ; }
|
||||
|
||||
// Inline accessors.
|
||||
size_t capacity ( void ) const throw ()
|
||||
{ return (size_t) mBuffer->fBufferSize ; }
|
||||
size_t size ( void ) const throw ()
|
||||
{ return (size_t) mBuffer->fBufferSize ; }
|
||||
size_t length ( void ) const throw ()
|
||||
{ return (size_t) mBuffer->fBufferLength ; }
|
||||
const char *c_str ( void ) const throw ()
|
||||
{ return (const char *) mBuffer->fBufferData ; }
|
||||
const void *data ( void ) const throw ()
|
||||
{ return (const void *) mBuffer->fBufferData ; }
|
||||
|
||||
// Inline setters.
|
||||
void clear ( void ) throw ()
|
||||
{ mBuffer->fBufferLength = 0 ; }
|
||||
void resize ( size_t inLength ) throw (DSException)
|
||||
{ if (inLength > mBuffer->fBufferSize)
|
||||
throw_ds_error (eDSBufferTooSmall) ;
|
||||
mBuffer->fBufferLength = inLength ; }
|
||||
void set ( const char *inString ) throw (DSException)
|
||||
{ clear () ; append (inString) ; }
|
||||
void set ( const void *inData, size_t inLength ) throw (DSException)
|
||||
{ clear () ; append (inData, inLength) ; }
|
||||
void append ( const char *inString ) throw (DSException)
|
||||
{ append ((const void *) inString, 1 + strlen (inString)) ; }
|
||||
void append ( const void *inData, size_t inLength ) throw (DSException)
|
||||
{ grow (mBuffer->fBufferLength + inLength) ;
|
||||
char *cpBuf = mBuffer->fBufferData + mBuffer->fBufferLength ;
|
||||
std::memcpy (cpBuf, inData, inLength) ;
|
||||
mBuffer->fBufferLength += inLength ; }
|
||||
|
||||
// Casting operators.
|
||||
tDataBufferPtr operator->() throw ()
|
||||
{ return mBuffer ; }
|
||||
operator tDataBufferPtr() const throw ()
|
||||
{ return mBuffer ; }
|
||||
operator const char*() const throw ()
|
||||
{ return this->c_str () ; }
|
||||
operator const void*() const throw ()
|
||||
{ return this->data () ; }
|
||||
|
||||
protected:
|
||||
/**** Instance methods accessible only to class and subclasses. ****/
|
||||
tDataBufferPtr grow ( size_t inNewSize ) throw (DSException) ;
|
||||
|
||||
/**** Instance data. ****/
|
||||
tDirReference mDirRef ;
|
||||
tDataBufferPtr mBuffer ;
|
||||
} ;
|
||||
|
||||
} // namespace DirectoryServices
|
||||
|
||||
#endif /* _DSBuffer_h */
|
140
APIModules/QTSSDSAuthModule/DSWrappers/DSDataList.h
Normal file
140
APIModules/QTSSDSAuthModule/DSWrappers/DSDataList.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DSDataList.h
|
||||
|
||||
Contains: Class definition for Open Directory data list
|
||||
(wraps tDataListPtr)
|
||||
|
||||
Created By: chris jalbert
|
||||
|
||||
Created: 26 July 2000
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DSDataList_h
|
||||
#define _DSDataList_h
|
||||
|
||||
// ANSI / POSIX Headers
|
||||
#include <stdarg.h> // for varargs stuff
|
||||
#include <string.h> // for memset()
|
||||
|
||||
// STL and Std C++ Library Headers
|
||||
#include <memory> // for auto_ptr<>
|
||||
|
||||
// Framework Headers
|
||||
#include <DirectoryService/DirServicesTypes.h>
|
||||
#include <DirectoryService/DirServicesUtils.h>
|
||||
|
||||
// Project Headers
|
||||
#include "DSDataNode.h"
|
||||
|
||||
|
||||
namespace DirectoryServices {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ¥ DSDataList - simple wrapper for tDataBufferPtr.
|
||||
// This should be considered a private class, primarily used by DSNode.
|
||||
// All methods are inlined for performance reasons (sorry).
|
||||
// Logically, a tDataList is a collection of tDataNode's, so this
|
||||
// implementation offers GetCount() and operator[](u_long) methods.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class DSDataList
|
||||
{
|
||||
public:
|
||||
/**** Instance methods. ****/
|
||||
// ctor and dtor.
|
||||
/* Not used anywhere and conflicts with next ctor, which is more useful.
|
||||
DSDataList ( tDirReference inDirRef,
|
||||
const char *inString, ... ) throw (DSException)
|
||||
: mDirRef (inDirRef)
|
||||
{ va_list args ; va_start (args, inString) ;
|
||||
std::memset (&mList, 0, sizeof (mList)) ;
|
||||
tDirStatus nError = ::dsBuildListFromStringsAllocV (
|
||||
inDirRef, &mList, inString, args) ;
|
||||
va_end (args) ;
|
||||
if (nError) throw_ds_error (nError) ; }
|
||||
*/
|
||||
DSDataList ( tDirReference inDirRef,
|
||||
const char *inPath ) throw (DSException)
|
||||
: mDirRef (inDirRef)
|
||||
{ std::memset (&mList, 0, sizeof (mList)) ;
|
||||
tDirStatus nError = ::dsBuildListFromPathAlloc (inDirRef, &mList, inPath, "/") ;
|
||||
if (nError) throw_ds_error (nError) ; }
|
||||
DSDataList ( const DSDataList& inOrg ) throw (DSException)
|
||||
: mDirRef (inOrg.mDirRef)
|
||||
{ tDataList *dlp = ::dsDataListCopyList (inOrg.mDirRef, &inOrg.mList) ;
|
||||
if (!dlp) throw_ds_error (eDSAllocationFailed) ;
|
||||
mList = *dlp ; std::free (dlp) ; }
|
||||
// The following constructor changes the ownership of the list buffer!
|
||||
DSDataList ( tDirReference inDirRef,
|
||||
tDataListPtr inList = 0 ) throw (DSException)
|
||||
: mDirRef (inDirRef)
|
||||
{ if (inList) {
|
||||
mList = *inList ; std::memset (inList, 0, sizeof (mList)) ;
|
||||
} else std::memset (&mList, 0, sizeof (mList)) ; }
|
||||
~DSDataList ( void ) throw ()
|
||||
{ ::dsDataListDeallocate (mDirRef, &mList) ; }
|
||||
|
||||
// Inline accessors.
|
||||
UInt32 count ( void ) const throw ()
|
||||
{ return ::dsDataListGetNodeCount (&mList) ; }
|
||||
size_t length ( void ) const throw ()
|
||||
{ return (size_t) ::dsGetDataLength (&mList) ; }
|
||||
// GetPath()'s return value will be freed when it goes out of scope.
|
||||
// If it is important, COPY IT to another auto_ptr (which will
|
||||
// properly invalidate the original).
|
||||
std::auto_ptr<const char> path ( const char *inSep = "/" ) const
|
||||
{ return std::auto_ptr<const char> (::dsGetPathFromList (mDirRef,
|
||||
&mList, inSep)) ; }
|
||||
|
||||
// Casting operators.
|
||||
operator tDataListPtr() throw ()
|
||||
{ return &mList ; }
|
||||
operator const tDataList*() const throw ()
|
||||
{ return &mList ; }
|
||||
DSDataNode* operator[] ( UInt32 inIndex ) const throw (DSException)
|
||||
{ tDataNodePtr dnTemp ;
|
||||
tDirStatus nError = ::dsDataListGetNodeAlloc (
|
||||
mDirRef, &mList, inIndex, &dnTemp) ;
|
||||
if (nError) throw_ds_error (nError) ;
|
||||
return new DSDataNode (mDirRef, dnTemp) ; }
|
||||
|
||||
// Setters.
|
||||
void append ( const char *inString ) throw (DSException)
|
||||
{ tDirStatus nError = ::dsAppendStringToListAlloc (
|
||||
mDirRef, &mList, inString) ;
|
||||
if (nError) throw_ds_error (nError) ; }
|
||||
|
||||
protected:
|
||||
/**** Instance data. ****/
|
||||
tDirReference mDirRef ;
|
||||
tDataList mList ;
|
||||
} ;
|
||||
|
||||
} // namespace DirectoryServices
|
||||
|
||||
#endif /* _DSDataList_h */
|
118
APIModules/QTSSDSAuthModule/DSWrappers/DSDataNode.h
Normal file
118
APIModules/QTSSDSAuthModule/DSWrappers/DSDataNode.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: DSDataNode.h
|
||||
|
||||
Contains: Class definition for Open Directory data node
|
||||
(wraps tDataNodePtr)
|
||||
|
||||
Created By: chris jalbert
|
||||
|
||||
Created: 26 July 2000
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DSDataNode_h
|
||||
#define _DSDataNode_h
|
||||
|
||||
|
||||
// Framework Headers
|
||||
#include <DirectoryService/DirServicesTypes.h>
|
||||
#include <DirectoryService/DirServicesUtils.h>
|
||||
|
||||
// Project Headers
|
||||
#include "CDirService.h"
|
||||
|
||||
|
||||
namespace DirectoryServices {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ¥ DSDataNode - simple wrapper for tDataBufferPtr.
|
||||
// This should be considered a private class, primarily used by DSNode.
|
||||
// All methods are inlined for performance reasons (sorry).
|
||||
// tDataNode's are identical to tDataBuffer's in implementation, however,
|
||||
// nodes are treated as opaque objects with DS accessor functions. As a
|
||||
// result, DSDataNode is not a subclass of DSBuffer.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class DSDataNode
|
||||
{
|
||||
public:
|
||||
/**** Instance methods. ****/
|
||||
// ctor and dtor.
|
||||
DSDataNode ( tDirReference inDirRef,
|
||||
size_t inBufSize,
|
||||
size_t inBufUsed,
|
||||
const void *inData ) throw (DSException)
|
||||
: mDirRef (inDirRef),
|
||||
mNode (::dsDataNodeAllocateBlock (inDirRef,
|
||||
(UInt32) inBufSize, (UInt32) inBufUsed,
|
||||
(void *) inData))
|
||||
{ if (!mNode) throw_ds_error (eDSAllocationFailed) ; }
|
||||
DSDataNode ( tDirReference inDirRef,
|
||||
const char *inString ) throw (DSException)
|
||||
: mDirRef (inDirRef),
|
||||
mNode (::dsDataNodeAllocateString (inDirRef, inString))
|
||||
{ if (!mNode) throw_ds_error (eDSAllocationFailed) ; }
|
||||
// Used by DSDataList
|
||||
DSDataNode ( tDirReference inDirRef,
|
||||
tDataNode *inNode ) throw (DSException)
|
||||
: mDirRef (inDirRef), mNode (inNode)
|
||||
{ if (!mNode) throw_ds_error (eDSAllocationFailed) ; }
|
||||
// Something of a "copy" constructor
|
||||
DSDataNode ( tDirReference inDirRef,
|
||||
const tDataNode *inNode ) throw (DSException)
|
||||
: mDirRef (inDirRef),
|
||||
mNode (::dsDataNodeAllocateBlock (inDirRef,
|
||||
inNode->fBufferSize, inNode->fBufferLength,
|
||||
(void *) inNode->fBufferData))
|
||||
{ if (!mNode) throw_ds_error (eDSAllocationFailed) ; }
|
||||
~DSDataNode ( void ) throw ()
|
||||
{ if (mNode) ::dsDataNodeDeAllocate (mDirRef, mNode) ; }
|
||||
|
||||
// Inline accessors.
|
||||
size_t capacity ( void ) const throw ()
|
||||
{ return (size_t) ::dsDataNodeGetSize (mNode) ; }
|
||||
size_t size ( void ) const throw ()
|
||||
{ return (size_t) ::dsDataNodeGetSize (mNode) ; }
|
||||
size_t length ( void ) const throw ()
|
||||
{ return (size_t) ::dsDataNodeGetLength (mNode) ; }
|
||||
void resize ( size_t inLength ) throw (DSException)
|
||||
{ tDirStatus nError = ::dsDataNodeSetLength (mNode, inLength) ;
|
||||
if (nError) throw_ds_error (nError) ; }
|
||||
|
||||
// Casting operators.
|
||||
operator tDataNodePtr() const throw ()
|
||||
{ return mNode ; }
|
||||
|
||||
protected:
|
||||
/**** Instance data. ****/
|
||||
tDirReference mDirRef ;
|
||||
tDataNodePtr mNode ;
|
||||
} ;
|
||||
|
||||
} // namespace DirectoryServices
|
||||
|
||||
#endif /* _DSDataNode_h */
|
528
APIModules/QTSSDSAuthModule/QTSSDSAuthModule.cpp
Normal file
528
APIModules/QTSSDSAuthModule/QTSSDSAuthModule.cpp
Normal file
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: QTSSODSAuthModule.cpp
|
||||
|
||||
Contains: Implementation of QTSSDSAuthModule, a modified version of the AuthenticateRequestModule
|
||||
is sample code.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "QTSSDSAuthModule.h"
|
||||
|
||||
|
||||
#include "../../defaultPaths.h"
|
||||
#include "DSAccessChecker.h"
|
||||
#include "StrPtrLen.h"
|
||||
#include "QTSSModuleUtils.h"
|
||||
#include "OSArrayObjectDeleter.h"
|
||||
#include "SafeStdLib.h"
|
||||
#include "QTSSMemoryDeleter.h"
|
||||
#include "QTSS_Private.h"
|
||||
#include "OS.h"
|
||||
|
||||
//#define SACL 1
|
||||
#if OSX_SACL
|
||||
extern "C"
|
||||
{
|
||||
#include <membershipPriv.h>
|
||||
}
|
||||
#include <membership.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
// ATTRIBUTES
|
||||
|
||||
// STATIC DATA
|
||||
|
||||
const UInt32 kBuffLen = 512;
|
||||
#define MODPREFIX_ "modDSAuth_"
|
||||
#define AUTHDEBUG 0
|
||||
#define debug_printf if (AUTHDEBUG) qtss_printf
|
||||
|
||||
|
||||
static QTSS_ModulePrefsObject sPrefs = NULL;
|
||||
static QTSS_PrefsObject sServerPrefs = NULL;
|
||||
static OSMutex* sAuthMutex = NULL;
|
||||
static Bool16 sDefaultAuthenticationEnabled = true;
|
||||
static Bool16 sAuthenticationEnabled = true;
|
||||
static char* sDefaultAccessFileName = "qtaccess";
|
||||
static char* sAccessFileName = NULL;
|
||||
static Bool16 sAllowGuestDefaultEnabled = true;
|
||||
static Bool16 sDefaultGuestEnabled = true;
|
||||
|
||||
|
||||
// FUNCTION PROTOTYPES
|
||||
|
||||
static QTSS_Error QTSSDSAuthModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams);
|
||||
static QTSS_Error Register();
|
||||
static QTSS_Error Initialize(QTSS_Initialize_Params* inParams);
|
||||
static QTSS_Error Shutdown();
|
||||
static QTSS_Error RereadPrefs();
|
||||
static QTSS_Error AuthenticateRTSPRequest(QTSS_RTSPAuth_Params* inParams);
|
||||
static QTSS_Error Authorize(QTSS_StandardRTSP_Params* inParams);
|
||||
static Bool16 AuthenticateRequest(QTSS_StandardRTSP_Params* inParams, const char* pathBuff, const char* movieRootDir, StrPtrLen* ioRealmName, Bool16* foundUserPtr);
|
||||
|
||||
|
||||
static int check_sacl(const char *inUser);
|
||||
#define kSACLNotAuthorized 0
|
||||
#define kSACLAuthorized 1
|
||||
#define kSACLUnknownUser 2
|
||||
#define kSACLAnyUser 3
|
||||
|
||||
// FUNCTION IMPLEMENTATIONS
|
||||
|
||||
|
||||
QTSS_Error QTSSDSAuthModule_Main(void* inPrivateArgs)
|
||||
{
|
||||
printf("QTSSDSAuthModule_Main\n");
|
||||
#if OSX_SACL
|
||||
printf("QTSSDSAuthModule_Main OSX_SACL\n");
|
||||
#endif
|
||||
#if OSX_OD_API
|
||||
printf("QTSSDSAuthModule_Main OSX_OD_API\n");
|
||||
#endif
|
||||
|
||||
return _stublibrary_main(inPrivateArgs, QTSSDSAuthModuleDispatch);
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error QTSSDSAuthModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams)
|
||||
{
|
||||
switch (inRole)
|
||||
{
|
||||
case QTSS_Register_Role:
|
||||
return Register();
|
||||
case QTSS_Initialize_Role:
|
||||
return Initialize(&inParams->initParams);
|
||||
case QTSS_RereadPrefs_Role:
|
||||
return RereadPrefs();
|
||||
case QTSS_RTSPAuthenticate_Role:
|
||||
if (sAuthenticationEnabled)
|
||||
return AuthenticateRTSPRequest(&inParams->rtspAthnParams);
|
||||
case QTSS_RTSPAuthorize_Role:
|
||||
if (sAuthenticationEnabled)
|
||||
return Authorize(&inParams->rtspRequestParams);
|
||||
case QTSS_Shutdown_Role:
|
||||
return Shutdown();
|
||||
}
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
QTSS_Error Register()
|
||||
{
|
||||
// Do role & attribute setup
|
||||
(void)QTSS_AddRole(QTSS_Initialize_Role);
|
||||
(void)QTSS_AddRole(QTSS_RereadPrefs_Role);
|
||||
(void)QTSS_AddRole(QTSS_RTSPAuthenticate_Role);
|
||||
(void)QTSS_AddRole(QTSS_RTSPAuthorize_Role);
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
QTSS_Error Initialize(QTSS_Initialize_Params* inParams)
|
||||
{
|
||||
// Setup module utils
|
||||
QTSSModuleUtils::Initialize(inParams->inMessages, inParams->inServer, inParams->inErrorLogStream);
|
||||
sPrefs = QTSSModuleUtils::GetModulePrefsObject(inParams->inModule);
|
||||
sServerPrefs = inParams->inPrefs;
|
||||
sAuthMutex = new OSMutex();
|
||||
|
||||
RereadPrefs();
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
QTSS_Error Shutdown()
|
||||
{
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
char* GetCheckedFileName()
|
||||
{
|
||||
char *result = NULL;
|
||||
static char *badChars = "/'\"";
|
||||
char theBadCharMessage[] = "' '";
|
||||
char *theBadChar = NULL;
|
||||
result = QTSSModuleUtils::GetStringAttribute(sPrefs, MODPREFIX_"dsaccessfilename", sDefaultAccessFileName);
|
||||
StrPtrLen searchStr(result);
|
||||
|
||||
theBadChar = strpbrk(searchStr.Ptr, badChars);
|
||||
if ( theBadChar!= NULL)
|
||||
{
|
||||
theBadCharMessage[1] = theBadChar[0];
|
||||
QTSSModuleUtils::LogErrorStr(qtssWarningVerbosity,MODPREFIX_"found invalid DS access file name in prefs");
|
||||
|
||||
delete[] result;
|
||||
result = new char[::strlen(sDefaultAccessFileName) + 2];
|
||||
::strcpy(result, sDefaultAccessFileName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QTSS_Error RereadPrefs()
|
||||
{
|
||||
OSMutexLocker locker(sAuthMutex);
|
||||
QTSSModuleUtils::GetAttribute(sPrefs, MODPREFIX_"enabled", qtssAttrDataTypeBool16,
|
||||
&sAuthenticationEnabled, &sDefaultAuthenticationEnabled, sizeof(sAuthenticationEnabled));
|
||||
|
||||
QTSSModuleUtils::GetAttribute(sServerPrefs,"enable_allow_guest_default", qtssAttrDataTypeBool16,
|
||||
&sAllowGuestDefaultEnabled,(void *)&sDefaultGuestEnabled, sizeof(sAllowGuestDefaultEnabled));
|
||||
|
||||
delete [] sAccessFileName;
|
||||
sAccessFileName = GetCheckedFileName();
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
Bool16 AuthenticateRequest(QTSS_StandardRTSP_Params* inParams,
|
||||
const char* pathBuff,
|
||||
const char* movieRootDir,
|
||||
StrPtrLen* ioRealmName,
|
||||
Bool16* foundUserPtr)
|
||||
{
|
||||
if (foundUserPtr)
|
||||
*foundUserPtr = false;
|
||||
|
||||
if (ioRealmName) //Set Value to Empty for now use whatever is set by access file or the default
|
||||
{
|
||||
ioRealmName->Ptr[0] = '\0';
|
||||
ioRealmName->Len = 0;
|
||||
}
|
||||
QTSS_Error theErr = QTSS_NoErr;
|
||||
|
||||
char passwordBuff[kBuffLen];
|
||||
StrPtrLen passwordStr(passwordBuff, kBuffLen -1);
|
||||
|
||||
char nameBuff[kBuffLen];
|
||||
StrPtrLen nameStr(nameBuff, kBuffLen -1);
|
||||
|
||||
theErr = QTSS_GetValue (inParams->inRTSPRequest,qtssRTSPReqUserName,0, (void *) nameStr.Ptr, &nameStr.Len);
|
||||
if ( (QTSS_NoErr != theErr) || (nameStr.Len >= kBuffLen) )
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRequest() Username Error - %"_S32BITARG_"\n", theErr);
|
||||
return false;
|
||||
}
|
||||
theErr = QTSS_GetValue (inParams->inRTSPRequest,qtssRTSPReqUserPassword,0, (void *) passwordStr.Ptr, &passwordStr.Len);
|
||||
if ( (QTSS_NoErr != theErr) || (passwordStr.Len >= kBuffLen) )
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRequest() Password Error - %"_S32BITARG_"\n", theErr);
|
||||
return false;
|
||||
}
|
||||
nameBuff[nameStr.Len] = '\0';
|
||||
passwordBuff[passwordStr.Len] = '\0';
|
||||
|
||||
//
|
||||
// Use the name and password to check access
|
||||
DSAccessChecker accessChecker;
|
||||
if ( !accessChecker.CheckPassword( nameBuff, passwordBuff) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (foundUserPtr)
|
||||
*foundUserPtr = true;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QTSS_Error AuthenticateRTSPRequest(QTSS_RTSPAuth_Params* inParams)
|
||||
{
|
||||
OSMutexLocker locker(sAuthMutex);
|
||||
|
||||
QTSS_RTSPRequestObject theRTSPRequest = inParams->inRTSPRequest;
|
||||
QTSS_AuthScheme authScheme = qtssAuthNone;
|
||||
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest start\n");
|
||||
|
||||
if ( (NULL == inParams) || (NULL == inParams->inRTSPRequest) )
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest inParams NULL\n");
|
||||
return QTSS_RequestFailed;
|
||||
}
|
||||
|
||||
|
||||
// Get the user profile object from the request object
|
||||
QTSS_UserProfileObject theUserProfile = NULL;
|
||||
UInt32 len = sizeof(QTSS_UserProfileObject);
|
||||
QTSS_Error theErr = QTSS_GetValue(theRTSPRequest, qtssRTSPReqUserProfile, 0, (void*)&theUserProfile, &len);
|
||||
Assert(len == sizeof(QTSS_UserProfileObject));
|
||||
if (theErr != QTSS_NoErr)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - username error is %"_S32BITARG_"\n", theErr);
|
||||
return theErr;
|
||||
}
|
||||
char* nameBuff = NULL;
|
||||
theErr = QTSS_GetValueAsString(theUserProfile, qtssUserName, 0, &nameBuff);
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - username is %s\n", nameBuff);
|
||||
OSCharArrayDeleter usernameBufDeleter(nameBuff);
|
||||
if (theErr != QTSS_NoErr)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - theUserProfile nameBuff error is %"_S32BITARG_"\n", theErr);
|
||||
}
|
||||
|
||||
|
||||
len = sizeof(authScheme);
|
||||
theErr = QTSS_GetValue(theRTSPRequest, qtssRTSPReqAuthScheme, 0, (void*)&authScheme, &len);
|
||||
|
||||
if (theErr != QTSS_NoErr)
|
||||
return theErr;
|
||||
|
||||
DSAccessChecker accessChecker;
|
||||
Bool16 allowed = true;
|
||||
Bool16 foundUser = true;
|
||||
Bool16 authHandled = true;
|
||||
|
||||
if ( authScheme == qtssAuthDigest)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - authScheme = qtssAuthDigest\n");
|
||||
|
||||
char* challengeBuff = NULL;
|
||||
(void) QTSS_GetValueAsString(theRTSPRequest, qtssRTSPReqDigestChallenge, 0, &challengeBuff);
|
||||
OSCharArrayDeleter challengeDeleter(challengeBuff);
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - Server Challenge =%s\n",challengeBuff);
|
||||
|
||||
char* responseBuff = NULL;
|
||||
(void) QTSS_GetValueAsString(theRTSPRequest, qtssRTSPReqDigestResponse, 0, &responseBuff);
|
||||
OSCharArrayDeleter responseDeleter(responseBuff);
|
||||
|
||||
char* methodBuff = NULL;
|
||||
(void) QTSS_GetValueAsString(theRTSPRequest, qtssRTSPReqMethodStr, 0, &methodBuff);
|
||||
OSCharArrayDeleter methodDeleter(methodBuff);
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - Server Method =%s\n",methodBuff);
|
||||
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - username is %s challenge=%s response=%s method=%s\n", nameBuff, challengeBuff, responseBuff, methodBuff);
|
||||
if ( false == accessChecker.CheckDigest(nameBuff, challengeBuff, responseBuff, methodBuff) )
|
||||
{ debug_printf("QTSSDSAuthModule CheckDigest returned false\n");
|
||||
}
|
||||
else
|
||||
{ debug_printf("QTSSDSAuthModule CheckDigest returned true\n");
|
||||
(void) QTSSModuleUtils::AuthorizeRequest(theRTSPRequest,&allowed,&foundUser,&authHandled);
|
||||
}
|
||||
|
||||
}
|
||||
if ( authScheme == qtssAuthBasic)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - authScheme = qtssAuthBasic\n");
|
||||
|
||||
|
||||
char passwordBuff[kBuffLen];
|
||||
StrPtrLen passwordStr(passwordBuff, kBuffLen -1);
|
||||
|
||||
char nameBuff[kBuffLen];
|
||||
StrPtrLen nameStr(nameBuff, kBuffLen -1);
|
||||
|
||||
theErr = QTSS_GetValue (inParams->inRTSPRequest,qtssRTSPReqUserName,0, (void *) nameStr.Ptr, &nameStr.Len);
|
||||
if ( (QTSS_NoErr != theErr) || (nameStr.Len >= kBuffLen) )
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRequest() Username Error - %"_S32BITARG_"\n", theErr);
|
||||
return false;
|
||||
}
|
||||
theErr = QTSS_GetValue (inParams->inRTSPRequest,qtssRTSPReqUserPassword,0, (void *) passwordStr.Ptr, &passwordStr.Len);
|
||||
if ( (QTSS_NoErr != theErr) || (passwordStr.Len >= kBuffLen) )
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRequest() Password Error - %"_S32BITARG_"\n", theErr);
|
||||
}
|
||||
nameBuff[nameStr.Len] = '\0';
|
||||
passwordBuff[passwordStr.Len] = '\0';
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - username is %s\n", nameBuff);
|
||||
debug_printf("QTSSDSAuthModule:AuthenticateRTSPRequest - password is %s\n", passwordBuff);
|
||||
if ( !accessChecker.CheckPassword(nameBuff, passwordBuff) )
|
||||
{ debug_printf("QTSSDSAuthModule CheckPassword returned false\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule CheckPassword returned true\n");
|
||||
(void) QTSSModuleUtils::AuthorizeRequest(theRTSPRequest,&allowed,&foundUser,&authHandled);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int check_sacl(const char *inUser)
|
||||
{
|
||||
|
||||
#if OSX_SACL
|
||||
int mbrErr = ENOENT;
|
||||
int isMember = 0;
|
||||
uuid_t user_uuid;
|
||||
|
||||
uuid_t uu;
|
||||
mbrErr = mbr_uid_to_uuid(geteuid(), uu);
|
||||
if (0 == mbrErr)
|
||||
{
|
||||
mbrErr = mbr_check_service_membership(uu, "qtss", &isMember);
|
||||
if (ENOENT == mbrErr) //no acl exists so allow any user.
|
||||
return kSACLAnyUser;
|
||||
}
|
||||
|
||||
if( (mbrErr = mbr_user_name_to_uuid(inUser, user_uuid)) != 0)
|
||||
{
|
||||
return kSACLUnknownUser;
|
||||
}
|
||||
|
||||
if((mbrErr = mbr_check_service_membership(user_uuid, "qtss", &isMember)) != 0)
|
||||
{
|
||||
if(mbrErr == ENOENT){ // no ACL exists
|
||||
return kSACLAuthorized;
|
||||
} else {
|
||||
return kSACLNotAuthorized;
|
||||
}
|
||||
}
|
||||
|
||||
if(isMember == kSACLAuthorized)
|
||||
{
|
||||
return kSACLAuthorized;
|
||||
}
|
||||
|
||||
|
||||
return kSACLNotAuthorized;
|
||||
#else
|
||||
return kSACLAuthorized;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
QTSS_Error Authorize(QTSS_StandardRTSP_Params* inParams)
|
||||
{
|
||||
|
||||
OSMutexLocker locker(sAuthMutex);
|
||||
|
||||
|
||||
QTSS_RTSPRequestObject theRTSPRequest = inParams->inRTSPRequest;
|
||||
|
||||
if ( (NULL == inParams) || (NULL == inParams->inRTSPRequest) )
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule - Authorize inParams: Error");
|
||||
return QTSS_RequestFailed;
|
||||
}
|
||||
|
||||
//get the local file path
|
||||
char* pathBuffStr = NULL;
|
||||
QTSS_Error theErr = QTSS_GetValueAsString(theRTSPRequest, qtssRTSPReqLocalPath, 0, &pathBuffStr);
|
||||
QTSSCharArrayDeleter pathBuffDeleter(pathBuffStr);
|
||||
if (theErr != QTSS_NoErr)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule - Authorize [QTSS_GetValueAsString]: Error %"_S32BITARG_"", theErr);
|
||||
return QTSS_RequestFailed;
|
||||
}
|
||||
//get the root movie directory
|
||||
char* movieRootDirStr = NULL;
|
||||
theErr = QTSS_GetValueAsString(theRTSPRequest,qtssRTSPReqRootDir, 0, &movieRootDirStr);
|
||||
OSCharArrayDeleter movieRootDeleter(movieRootDirStr);
|
||||
if (theErr != QTSS_NoErr)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule - Authorize[QTSS_GetValueAsString]: Error %"_S32BITARG_"", theErr);
|
||||
return false;
|
||||
}
|
||||
//check if this user is allowed to see this movie
|
||||
|
||||
DSAccessFile accessFile;
|
||||
Bool16 allowNoAccessFiles = sAllowGuestDefaultEnabled; //no access files allowed means allowing guest access (unknown users)
|
||||
Bool16 allowAnyUser = false;
|
||||
QTSS_ActionFlags noAction = ~qtssActionFlagsRead; //only handle read
|
||||
QTSS_ActionFlags authorizeAction = QTSSModuleUtils::GetRequestActions(theRTSPRequest);
|
||||
Bool16 authorized =false;
|
||||
Bool16 saclUser = false;
|
||||
|
||||
char *name = NULL;
|
||||
(void) QTSS_GetValueAsString (theRTSPRequest,qtssRTSPReqUserName,0, &name);
|
||||
OSCharArrayDeleter nameDeleter(name);
|
||||
if (sAllowGuestDefaultEnabled) // if guest access is on, sacls are ignored.
|
||||
{
|
||||
authorized = true;
|
||||
}
|
||||
else
|
||||
{ int result = check_sacl(name);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case kSACLAuthorized: authorized = true;
|
||||
break;
|
||||
|
||||
case kSACLUnknownUser: authorized = false; //set this to true to allow file based and other non-directory service users access, when SACLs are enabled in the system for QTSS.
|
||||
break;
|
||||
|
||||
case kSACLNotAuthorized: authorized = false;
|
||||
break;
|
||||
|
||||
case kSACLAnyUser: authorized = true;
|
||||
break;
|
||||
|
||||
default: authorized = false;
|
||||
}
|
||||
|
||||
|
||||
debug_printf("QTSSDSAuthModule:Authorize sacl_check result=%d for %s authorized = %d\n",result, name, authorized);
|
||||
if (false == authorized)
|
||||
saclUser = true;
|
||||
}
|
||||
|
||||
Bool16 foundUser = false;
|
||||
Bool16 passwordOK = false; //::AuthenticateRequest(inParams, pathBuffStr, movieRootDirStr, &sRealmNameStr, &foundUser);
|
||||
if (authorized) //have to be authorized by sacls or guest first before qtaccess file checks can allow or disallow.
|
||||
{
|
||||
theErr = accessFile.AuthorizeRequest(inParams,allowNoAccessFiles, noAction, authorizeAction,&authorized, &allowAnyUser);
|
||||
debug_printf("QTSSDSAuthModule:Authorize AuthorizeRequest() returned authorized=%d allowAnyUser=%d\n", authorized, allowAnyUser);
|
||||
|
||||
}
|
||||
|
||||
debug_printf("QTSSDSAuthModule:Authorize AuthenticateRequest() returned passwordOK=%d foundUser=%d authorized=%d allowAnyUser=%d\n", passwordOK ,foundUser, authorized,allowAnyUser);
|
||||
|
||||
Bool16 allowRequest = authorized;
|
||||
Bool16 authHandled = true;
|
||||
|
||||
if(!(authorizeAction & qtssActionFlagsRead)) //not for us
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:Authorize(qtssActionFlagsRead) not handled do nothing.\n");
|
||||
}
|
||||
else if (allowRequest)
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:Authorize() succeeded.\n");
|
||||
theErr = QTSSModuleUtils::AuthorizeRequest(theRTSPRequest, &allowRequest, &foundUser, &authHandled);
|
||||
debug_printf("QTSSDSAuthModule:Authorize allowRequest=%d founduser=%d authHandled=%d\n", allowRequest, foundUser, authHandled);
|
||||
}
|
||||
else //request denied
|
||||
{
|
||||
debug_printf("QTSSDSAuthModule:Authorize() failed.\n");
|
||||
foundUser = saclUser;
|
||||
authHandled = true;
|
||||
theErr = QTSSModuleUtils::AuthorizeRequest(theRTSPRequest, &allowRequest, &foundUser, &authHandled);
|
||||
debug_printf("QTSSDSAuthModule:Authorize allowRequest=%d founduser=%d authHandled=%d saclUser=%d\n", allowRequest, foundUser, authHandled,saclUser);
|
||||
}
|
||||
|
||||
|
||||
return theErr;
|
||||
}
|
46
APIModules/QTSSDSAuthModule/QTSSDSAuthModule.h
Normal file
46
APIModules/QTSSDSAuthModule/QTSSDSAuthModule.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* 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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: QTSSODAuthModule.h
|
||||
|
||||
Contains: This is a modified version of the QTSSAccessModule also released with
|
||||
QTSS 2.0. It has been modified to shrink the linespacing so that
|
||||
the code can fit on slides. Also, this module issues redirects to
|
||||
an error movie.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _QTSSDSAUTHMODULE_H__
|
||||
#define _QTSSDSAUTHMODULE_H__
|
||||
|
||||
#include "QTSS.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
QTSS_Error QTSSDSAuthModule_Main(void* inPrivateArgs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue