Exemplo n.º 1
0
int
odkerb_copy_user_record_with_short_name(CFStringRef shortName, ODNodeRef searchNode, ODRecordRef *out)
{
    static CFTypeRef cfVals[2];
    static CFArrayRef cfReqAttrs = NULL;
    int retval = -1;
    CFErrorRef cfError = NULL;

    ODKERB_PARAM_ASSERT(shortName != NULL);
    ODKERB_PARAM_ASSERT(searchNode != NULL);
    ODKERB_PARAM_ASSERT(out != 0);

    *out = NULL;

    if (cfReqAttrs == NULL) {
        /* hint for should be fetched */
        cfVals[0] = kODAttributeTypeOriginalNodeName;
        cfVals[1] = kODAttributeTypeIMHandle;
        cfReqAttrs = CFArrayCreate(NULL, cfVals, 1, &kCFTypeArrayCallBacks);
    }

    ODRecordRef cfUserRecord = ODNodeCopyRecord(searchNode, kODRecordTypeUsers,
                                                shortName, cfReqAttrs, &cfError);
    if (cfUserRecord == NULL || cfError != NULL) {
        ODKERB_LOG_CFERROR(LOG_DEBUG, "Unable to find the user record", cfError);
        goto failure;
    }

    *out = cfUserRecord;

    retval = 0;
failure:
    CF_SAFE_RELEASE(cfError);

    return retval;
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
    int				ch;
	char		   *operation		= nil;
	bool			bReadOption		= false;
	bool			bCreateOption   = false;
	bool			bDeleteOption   = false;
	bool			bEditOption		= false;
	bool			bInteractivePwd = false;
	bool			bNoVerify		= false;
	bool			bVerbose		= false;
	bool			bCheckMemberOption	= false;
	char		   *nodename		= nil;
	char		   *username		= nil;
	bool			bDefaultUser	= false;
	bool			bCompList		= false;
	char		   *password		= nil;
	char		   *addrecordname   = nil;
	char		   *delrecordname   = nil;
	char		   *recordtype		= nil;
	char		   *gid				= nil;
	char		   *guid			= nil;
	char		   *smbSID			= nil;
	char		   *realname		= nil;
	char		   *keyword			= nil;
	char		   *comment			= nil;
	char		   *timeToLive		= nil;
	char		   *groupname		= nil;
	char		   *member			= nil;
	char		   *format			= nil;	//be either "l" for legacy or "n" for new group format
	const char	   *grouptype		= NULL;
	int				exitcode		= 0;
	uuid_t			uuid;
    
	ODNodeRef			aDSNodeRef		= NULL;
	ODNodeRef			aDSSearchRef	= NULL;
	bool				bContinueAdd	= false;
	char			   *groupRecordName	= nil;
	__block ODRecordRef	aGroupRecRef	= NULL;
	__block ODRecordRef	aGroupRecRef2	= NULL;
	CFErrorRef			aErrorRef		= NULL;
	char				*errorTok		= NULL;

	if (argc < 2)
	{
		usage();
		exit(0);
	}
	
	if ( strcmp(argv[1], "-appleversion") == 0 )
        dsToolAppleVersionExit( argv[0] );
	
    while ((ch = getopt(argc, argv, "LT:o:pqvn:m:u:P:a:d:t:i:g:r:k:c:s:S:f:?h")) != -1) {
        switch (ch) {
            case 'o':
                operation = strdup(optarg);
                if (operation != nil)
                {
                    if ( strcasecmp(operation, "read") == 0 )
                    {
                        bReadOption = true;
                    }
                    else if ( strcasecmp(operation, "create") == 0 )
                    {
                        bCreateOption = true;
                    }
                    else if ( strcasecmp(operation, "delete") == 0 )
                    {
                        bDeleteOption = true;
                    }
                    else if ( strcasecmp(operation, "edit") == 0 )
                    {
                        bEditOption = true;
                    }
                    else if ( strcasecmp(operation, "checkmember") == 0 )
                    {
                        bCheckMemberOption = true;
                    }
                }
				break;
            case 'p':
                bInteractivePwd = true;
                break;
            case 'q':
                bNoVerify = true;
                break;
            case 'v':
                bVerbose = true;
                break;
            case 'm':
                member = strdup(optarg);
                break;
            case 'n':
                nodename = strdup(optarg);
                break;
            case 'u':
                username = strdup(optarg);
                break;
            case 'P':
                password = strdup(optarg);
                break;
            case 'a':
                addrecordname = strdup(optarg);
                break;
            case 'd':
                delrecordname = strdup(optarg);
                break;
            case 't':
                recordtype = strdup(optarg);
                break;
			case 'T':
				grouptype = optarg;
				break;
			case 'L':
				bCompList = true;
				break;
            case 'i':
				strtol( optarg, &errorTok, 10 );
				if ( errorTok == NULL || errorTok[0] == '\0' ) {
					gid = strdup(optarg);
				}
				else {
					printf( "GID contains non-numeric characters\n" );
					return EX_USAGE;
				}
                break;
            case 'g':
				uuid_clear( uuid );
				
				// don't allow malformed UUIDs nor an empty one
				if ( uuid_parse(optarg, uuid) == 0 && uuid_is_null(uuid) == false ) {
					guid = strdup(optarg);
				}
				else {
					printf( "GUID provided is not a valid UUID\n" );
					return EX_USAGE;
				}
                break;
            case 'r':
                realname = strdup(optarg);
                break;
            case 'k':
                keyword = strdup(optarg);
                break;
            case 'c':
                comment = strdup(optarg);
                break;
            case 's':
                timeToLive = strdup(optarg);
                break;
            case 'S':
                smbSID = strdup(optarg);
                break;
            case 'f':
                format = strdup(optarg);
                break;
            case '?':
            case 'h':
            default:
			{
				usage();
				return EX_USAGE;
			}
        }
    }
	
	argc -= optind;
	argv += optind;
	
	if (argc == 0)
	{
		printErrorOrMessage( NULL, "No group name provided", bVerbose );
		return EX_USAGE;
	}
	
	groupname = strdup( argv[0] );
	
	if (!bCreateOption && !bDeleteOption && !bEditOption && !bCheckMemberOption)
	{
		bReadOption = true; //default option
	}
	
	if (username == nil)
	{
		struct passwd* pw = NULL;
		pw = getpwuid(getuid());
		if (pw != NULL && pw->pw_name != NULL && pw->pw_name[0] != '\0')
		{
			username = strdup(pw->pw_name);
		}
		else
		{
			printf("***Username <-u username> must be explicitly provided in this shell***\n");
			usage();
			exit(0);
		}
		bDefaultUser = true;
	}
    
	if (bVerbose)
	{
		printf("dseditgroup verbose mode\n");
		printf("Options selected by user:\n");
		if (bReadOption)
			printf("Read option selected\n");
		if (bCreateOption)
			printf("Create option selected\n");
		if (bDeleteOption)
			printf("Delete option selected\n");
		if (bEditOption)
			printf("Edit option selected\n");
		if (bCheckMemberOption)
			printf("Checking membership selected\n");
		if (bInteractivePwd)
			printf("Interactive password option selected\n");
		if (bNoVerify)
			printf("User verification is disabled\n");
		if (nodename)
			printf("Nodename provided as <%s>\n", nodename);
		if (username && !bDefaultUser)
			printf("Username provided as <%s>\n", username);
		else
			printf("Username determined to be <%s>\n", username);
		if ( password && !bInteractivePwd )
			printf("Password provided as <%s>\n", password);
		if (addrecordname)
			printf("Recordname to be added provided as <%s>\n", addrecordname);
		if (delrecordname)
			printf("Recordname to be deleted provided as <%s>\n", delrecordname);
		if (recordtype)
			printf("Recordtype provided as <%s>\n", recordtype);
		if (grouptype)
			printf("Grouptype provided as <%s>\n", grouptype);
		if (gid)
			printf("GID provided as <%s>\n", gid);
		if (guid)
			printf("GUID provided as <%s>\n", guid);
		if (smbSID)
			printf("SID provided as <%s>\n", smbSID);
		if (realname)
			printf("Realname provided as <%s>\n", realname);
		if (keyword)
			printf("Keyword provided as <%s>\n", keyword);
		if (comment)
			printf("Comment provided as <%s>\n", comment);
		if (timeToLive)
			printf("TimeToLive provided as <%s>\n", timeToLive);
		if (groupname)
			printf("Groupname provided as <%s>\n", groupname);
		if (bCompList)
			printf("Will maintain computer lists when applicable\n" );
		printf("\n");
	}
	
	ODRecordType (^mapRecTypeWithDefault)(const char *, ODRecordType) = ^(const char *inType, ODRecordType inDefault) {
		if ( inType != NULL )
		{
			if ( strcasecmp(inType, "user") == 0) {
				return kODRecordTypeUsers;
			}
			else if ( strcasecmp(inType, "group") == 0) {
				return kODRecordTypeGroups;
			}
			else if ( strcasecmp(inType, "computer") == 0) {
				return kODRecordTypeComputers;
			}
			else if ( strcasecmp(inType, "computergroup") == 0 ) {
				return kODRecordTypeComputerGroups;
			}
		}
		
		return inDefault;
	};
    
	if (bCheckMemberOption == false &&
		bReadOption == false &&
		(!bNoVerify && ( !bDefaultUser && ( (password == nil) || bInteractivePwd ) ) || (bDefaultUser && bInteractivePwd)) )
	{
		password = read_passphrase("Please enter user password:"******"." we default to the local node by passing nil as the node name to getNodeRef
			aDSNodeRef = aLocalNodeRef;
			bIsLocalNode = true;
        }
		else
		{
            // otherwise we pass the provided nodename to getNodeRef
			CFStringRef cfNodeName = CFStringCreateWithCString( kCFAllocatorDefault, nodename, kCFStringEncodingUTF8 );
			if ( cfNodeName != NULL ) {
				aDSNodeRef = ODNodeCreateWithName( kCFAllocatorDefault, kODSessionDefault, cfNodeName, &aErrorRef );
				CFRelease( cfNodeName );
				if (aDSNodeRef == NULL) {
					exitcode = printErrorOrMessage(NULL, "Error locating specified node.", bVerbose);
					break;
				}
				
				if ( CFEqual(ODNodeGetName(aDSNodeRef), ODNodeGetName(aLocalNodeRef)) == true ) {
					bIsLocalNode = true;
				}
			}
			else {
				exitcode = printErrorOrMessage( NULL, "Error parsing node name.", bVerbose );
				break;
			}
        }
		
		if ( aDSNodeRef == NULL ) {
			exitcode = printErrorOrMessage( &aErrorRef, "getNodeRef failed to obtain a node reference", bVerbose );
			break;
		}
		
		aDSSearchRef = ODNodeCreateWithNodeType( kCFAllocatorDefault, kODSessionDefault, kODNodeTypeAuthentication, &aErrorRef );
		
		CFStringRef groupNameCF = CFStringCreateWithCString( kCFAllocatorDefault, groupname, kCFStringEncodingUTF8 );
		if ( groupNameCF == NULL ) {
			exitcode = EX_SOFTWARE;
			printErrorOrMessage( NULL, "Unable to parse groupname", bVerbose );
			break;
		}
		
		CFArrayRef attribs = CFArrayCreate( kCFAllocatorDefault, (CFTypeRef *) &kODAttributeTypeStandardOnly, 1, &kCFTypeArrayCallBacks );
		if ( attribs == NULL ) {
			exitcode = EX_SOFTWARE;
			printErrorOrMessage( NULL, "Unable to allocate array", bVerbose );
			break;
		}

		ODRecordType grpType = mapRecTypeWithDefault( grouptype, kODRecordTypeGroups );
		
		bool (^isLocalNode)(ODRecordRef record) = ^(ODRecordRef record) {
			CFArrayRef values = ODRecordCopyValues( record, kODAttributeTypeMetaNodeLocation, NULL );
			if ( values != NULL ) {
				
				if ( CFArrayGetCount(values) > 0 && CFEqual(CFArrayGetValueAtIndex(values, 0), ODNodeGetName(aLocalNodeRef)) == true ) {
					return (bool) true;
				}
				
				CFRelease( values );
			}
			
			return (bool) false;
		};
		
		aGroupRecRef = ODNodeCopyRecord( aDSNodeRef, grpType, groupNameCF, attribs, NULL );
		if ( aGroupRecRef != NULL ) {
			bIsLocalNode = isLocalNode( aGroupRecRef );
		}
		
		/* The group must already exist unless -o create is specified. */
		if (aGroupRecRef == NULL && !bCreateOption) {
			exitcode = printErrorOrMessage(NULL, "Group not found.", bVerbose);
			break;
		}

		if ( bCompList == true && grpType == kODRecordTypeComputerGroups )
		{
			aGroupRecRef2 = ODNodeCopyRecord( aDSNodeRef, kODRecordTypeComputerLists, groupNameCF, NULL, NULL );
			if ( aGroupRecRef2 != NULL && isLocalNode(aGroupRecRef2) == true )
			{
				// if we got a group record, let's see if it is also local node
				if ( bIsLocalNode == false && aGroupRecRef != NULL )
				{
					if ( bVerbose == true ) {
						printf( "Skipping Computer list because it's on a different node\n" );
						CFRelease( aGroupRecRef2 );
						aGroupRecRef2 = NULL;
					}
				}
				else {
					bIsLocalNode = true;
				}
			}
		}
		
		if ( geteuid() == 0 && bIsLocalNode == true && (username == NULL || password == NULL) )
		{
			// we are running as root and no password or name provided
			if ( bVerbose == true ) {
				printf( "Skipping authentication because user has effective ID 0\n" );
			}
		}
		else if ( bDeleteOption == true || bCreateOption == true || bEditOption == true )
		{
			// need to auth for changes
			if (username == NULL || password == NULL) {
				exitcode = printErrorOrMessage(NULL, "Username and password must be provided.", bVerbose);
				break;
			}

			bool bSuccess = false;
			CFStringRef user = CFStringCreateWithCString(NULL, username, kCFStringEncodingUTF8);
			CFStringRef pass = CFStringCreateWithCString(NULL, password, kCFStringEncodingUTF8);
			
			/*
			 * aDSNodeRef may be /Search unless we're creating a new group. Fortunately,
			 * we can authenticate with the specific group(s) most of the time. We still
			 * authenticate with the node directly when the specified group doesn't exist.
			 * As noted above, this is only allowed when creating a new group, in which
			 * case aDSNodeRef cannot be /Search.
			 */
			if (aGroupRecRef != NULL) {
				bSuccess = ODRecordSetNodeCredentials(aGroupRecRef, user, pass, &aErrorRef);
				if (aGroupRecRef2 != NULL) {
					ODRecordSetNodeCredentials(aGroupRecRef2, user, pass, &aErrorRef);
				}
			} else {
				bSuccess = ODNodeSetCredentials(aDSNodeRef, NULL, user, pass, &aErrorRef);
			}

			CFRelease(user);
			CFRelease(pass);

			if (!bSuccess) {
				exitcode = printErrorOrMessage(&aErrorRef, "Failed to set credentials.", bVerbose);
				break;
			}
		}
		
		CFErrorRef (^deleteRecords)(void) = ^(void) {
			CFErrorRef error = NULL;
			if ( aGroupRecRef != NULL )
			{
				if ( ODRecordDelete(aGroupRecRef, &error) == false ) {
					return error;
				}
				
				CFRelease( aGroupRecRef );
				aGroupRecRef = NULL;
			}
			
			if ( aGroupRecRef2 != NULL )
			{
				if ( ODRecordDelete(aGroupRecRef2, &error) == false ) {
					return error;
				}
				
				CFRelease( aGroupRecRef2 );
				aGroupRecRef2 = NULL;
			}
			
			return error;
		};
		
		if ( bReadOption == true || bDeleteOption == true )
		{
			if ( aGroupRecRef != NULL || aGroupRecRef2 != NULL )
			{
				if ( bDeleteOption == true && aGroupRecRef != NULL ) {
					printErrorOrMessage( NULL, "Group record below will be deleted:", bVerbose );
				}
				
				CFDictionaryRef cfDetails = ODRecordCopyDetails( aGroupRecRef, NULL, NULL );
				if ( cfDetails != NULL ) {
					CFDictionaryApplyFunction( cfDetails, printDictionary, NULL );
					CFRelease( cfDetails );
				}
				
				if ( bDeleteOption == true && (aErrorRef = deleteRecords()) != NULL ) {
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to delete record", bVerbose );
					break;
				}
			}
			else
			{
				exitcode = printErrorOrMessage( NULL, "Group was not found.", bVerbose );
				break;
			}
		}
		else if (bCreateOption)
		{
			if ( aGroupRecRef != NULL || aGroupRecRef2 != NULL )
			{
				char responseValue[8] = {0};
				if (!bNoVerify)
				{
					printf("Create called on existing record - do you want to overwrite, y or n : ");
					scanf( "%c", responseValue );
					printf("\n");
				}
				
				if (bNoVerify || (responseValue[0] == 'y') || (responseValue[0] == 'Y'))
				{
					if ( (aErrorRef = deleteRecords()) != NULL ) {
						exitcode = printErrorOrMessage( &aErrorRef, "Unable to replace the record", bVerbose );
						break;
					}
				}
				else
				{
					exitcode = EX_CANTCREAT;
					printErrorOrMessage( NULL, "Operation cancelled because record could not be replaced", bVerbose );
					break;
				}
			}
			
			if ( aGroupRecRef == NULL )
			{
				aGroupRecRef = ODNodeCreateRecord( aDSNodeRef, grpType, groupNameCF, NULL, &aErrorRef );
				if ( aGroupRecRef != NULL )
				{
					groupRecordName = strdup(groupname);
					bContinueAdd = true;
					
					// if creating ComputerGroups allow creation of ComputerLists if -L specified
					if ( bCompList == true && grpType == kODRecordTypeComputerGroups ) {
						aGroupRecRef2 = ODNodeCreateRecord( aDSNodeRef, kODRecordTypeComputerLists, groupNameCF, NULL, NULL );
					}
				}
				else
				{
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to create the record", bVerbose );
					break;
				}
			}
		}
		else if (bEditOption)
		{
			if ( aGroupRecRef != NULL ) {
				bContinueAdd = true;
			}
			else {
				printErrorOrMessage( NULL, "Record not found", bVerbose );
				break;
			}
		}
		else if (bCheckMemberOption)
		{
			if ( aGroupRecRef != NULL )
			{
				const char *user = (member ? : username);
				CFStringRef memberCF = CFStringCreateWithCString( kCFAllocatorDefault, user, kCFStringEncodingUTF8 );
				if ( memberCF == NULL ) {
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to to allocate string", bVerbose );
					break;
				}
				
				ODRecordRef memberRec = ODNodeCopyRecord( aDSSearchRef, kODRecordTypeUsers, memberCF, NULL, &aErrorRef );
				if ( memberRec == NULL ) {
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to find the user record", bVerbose );
					break;
				}
				
				if ( ODRecordContainsMember(aGroupRecRef, memberRec, &aErrorRef) == true ) {
					// return default exitcode of 0 if they are a member
					printf("yes %s is a member of %s\n", user, groupname);
					exitcode = EX_OK;
				}
				else {
					printf("no %s is NOT a member of %s\n", user, groupname);
					exitcode = EX_NOUSER;
				}
				
				CFRelease( memberRec );
				CFRelease( memberCF );
			}
			else
			{
				exitcode = printErrorOrMessage( NULL, "Invalid group name", bVerbose );
				break;
			}
		}
Exemplo n.º 3
0
int
od_record_create(pam_handle_t *pamh, ODRecordRef *record, CFStringRef cfUser)
{
	int retval = PAM_SERVICE_ERR;
	const int attr_num = 5;

	ODNodeRef cfNode = NULL;
	CFErrorRef cferror = NULL;
	CFArrayRef attrs = NULL;
	CFTypeRef cfVals[attr_num];

	if (NULL == record || NULL == cfUser) {
		openpam_log(PAM_LOG_DEBUG, "NULL argument passed");
		retval = PAM_SERVICE_ERR;
		goto cleanup;
	}

#ifdef OPENDIRECTORY_CACHE
#define CFRECORDNAME_CACHE "CFRecordName"
#define CFRECORDNAME_NAME CFSTR("name")
#define CFRECORDNAME_RECORD CFSTR("record")

	CFDictionaryRef cfdict;
	CFStringRef cachedUser;

	if (pam_get_data(pamh, CFRECORDNAME_CACHE, (void *)&cfdict) == PAM_SUCCESS &&
	    (CFGetTypeID(cfdict) == CFDictionaryGetTypeID()) &&
	    (cachedUser = CFDictionaryGetValue(cfdict, CFRECORDNAME_NAME)) != NULL &&
	    CFGetTypeID(cachedUser) == CFStringGetTypeID() &&
	    CFStringCompare(cfUser, cachedUser, 0) == kCFCompareEqualTo &&
	    (*record = (ODRecordRef)CFDictionaryGetValue(cfdict, CFRECORDNAME_RECORD)) != NULL)
	{
		CFRetain(*record);
		return PAM_SUCCESS;
	}
#endif /* OPENDIRECTORY_CACHE */

	int current_iterations = 0;

	cfNode = ODNodeCreateWithNodeType(kCFAllocatorDefault,
					  kODSessionDefault,
					  eDSAuthenticationSearchNodeName,
					  &cferror);
	if (NULL == cfNode || NULL != cferror) {
		openpam_log(PAM_LOG_ERROR, "ODNodeCreateWithNodeType failed.");
		retval = PAM_SERVICE_ERR;
		goto cleanup;
	}

	cfVals[0] = kODAttributeTypeAuthenticationAuthority;
	cfVals[1] = kODAttributeTypeHomeDirectory;
	cfVals[2] = kODAttributeTypeNFSHomeDirectory;
	cfVals[3] = kODAttributeTypeUserShell;
	cfVals[4] = kODAttributeTypeUniqueID;
	attrs = CFArrayCreate(kCFAllocatorDefault, cfVals, (CFIndex)attr_num, &kCFTypeArrayCallBacks);
	if (NULL == attrs) {
		openpam_log(PAM_LOG_DEBUG, "CFArrayCreate() failed");
		retval = PAM_BUF_ERR;
		goto cleanup;
	}

	retval = PAM_SERVICE_ERR;
	while (current_iterations <= kMaxIterationCount) {
		CFIndex unreachable_count = 0;
		CFArrayRef unreachable_nodes = ODNodeCopyUnreachableSubnodeNames(cfNode, NULL);
		if (unreachable_nodes) {
			unreachable_count = CFArrayGetCount(unreachable_nodes);
			CFRelease(unreachable_nodes);
			openpam_log(PAM_LOG_DEBUG, "%lu OD nodes unreachable.", unreachable_count);
		}

		*record = ODNodeCopyRecord(cfNode, kODRecordTypeUsers, cfUser, attrs, &cferror);
		if (*record)
			break;
		if (0 == unreachable_count)
			break;

		openpam_log(PAM_LOG_DEBUG, "Waiting %d seconds for nodes to become reachable", kWaitSeconds);
		sleep(kWaitSeconds);
		++current_iterations;
	}

	if (*record) {
#ifdef OPENDIRECTORY_CACHE
		const void *keys[] = { CFRECORDNAME_NAME, CFRECORDNAME_RECORD };
		const void *values[] = { cfUser, *record };
		CFDictionaryRef dict;
		
		dict = CFDictionaryCreate(NULL, keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		if (dict)
			pam_set_data(pamh, CFRECORDNAME_CACHE, (void *)dict, cleanup_cache);
#endif /* OPENDIRECTORY_CACHE */
		retval = PAM_SUCCESS;
	} else {
		retval = PAM_USER_UNKNOWN;
	}

	if (current_iterations > 0) {
		char *wt = NULL, *found = NULL;
		int retval2;

		if (*record)
			found = "failure";
		else
			found = "success";

		retval2 = asprintf(&wt, "%d", kWaitSeconds * current_iterations);
		if (-1 == retval2) {
			openpam_log(PAM_LOG_DEBUG, "Failed to convert current wait time to string.");
			retval = PAM_BUF_ERR;
			goto cleanup;
		}


		aslmsg m = asl_new(ASL_TYPE_MSG);
		asl_set(m, "com.apple.message.domain", "com.apple.pam_modules.odAvailableWaitTime" );
		asl_set(m, "com.apple.message.signature", "wait_time");
		asl_set(m, "com.apple.message.value", wt);
		asl_set(m, "com.apple.message.result", found);
		asl_log(NULL, m, ASL_LEVEL_NOTICE, "OD nodes online delay: %ss. User record lookup: %s.", wt, found);
		asl_free(m);
		free(wt);
	}

cleanup:
	if (NULL != attrs) {
		CFRelease(attrs);
	}

	if (NULL != cferror) {
		CFRelease(cferror);
	}

	if (NULL != cfNode) {
		CFRelease(cfNode);
	}

	if (PAM_SUCCESS != retval) {
		openpam_log(PAM_LOG_ERROR, "failed: %d", retval);
		if (NULL != *record) {
			CFRelease(*record);
			*record = NULL;
		}
	}

	return retval;
}
Exemplo n.º 4
0
int
odkerb_copy_search_node_with_config_record_name(CFStringRef configRecordName, ODNodeRef *out)
{
    static CFTypeRef cfVals[2];
    static CFArrayRef cfReqAttrs = NULL;
    int retval = -1;
    ODRecordRef cfConfigRecord = NULL;
    CFArrayRef cfOriginalNodeNames = NULL;
    CFErrorRef cfError = NULL;

    ODKERB_PARAM_ASSERT(configRecordName != NULL);
    ODKERB_PARAM_ASSERT(out != 0);

    *out = NULL;

    if (odkerb_configure_search_node() != 0)
        goto failure;

    if (cfReqAttrs == NULL) {
        /* hint for should be fetched */
        cfVals[0] = kODAttributeTypeOriginalNodeName;
        cfVals[1] = kODAttributeTypeIMHandle;
        cfReqAttrs = CFArrayCreate(NULL, cfVals, 1, &kCFTypeArrayCallBacks);
    }

    cfConfigRecord = ODNodeCopyRecord(gSearchNode, kODRecordTypeConfiguration,
                                      configRecordName, cfReqAttrs, &cfError);
    if (cfConfigRecord == NULL || cfError != NULL) {
        ODKERB_LOG_CFERROR(LOG_ERR, "Unable to find the configuration record", cfError);
        goto failure;
    }

    cfOriginalNodeNames = ODRecordCopyValues(cfConfigRecord, kODAttributeTypeOriginalNodeName, &cfError);
    if (cfOriginalNodeNames == NULL || cfError != NULL) {
        ODKERB_LOG_CFERROR(LOG_ERR, "Unable to find the original node name", cfError);
        goto failure;
    }
    else if (CFArrayGetCount(cfOriginalNodeNames) == 0) {
        ODKERB_LOG_CFSTRING(LOG_ERR, "Unable to find the original node name", configRecordName);
        goto failure;
    }
    else if (CFArrayGetCount(cfOriginalNodeNames) > 1) {
        ODKERB_LOG_CFSTRING(LOG_DEBUG, "Too many original node names, using the first", configRecordName);
    }

    CFStringRef cfNodeName = CFArrayGetValueAtIndex(cfOriginalNodeNames, 0);
    if (cfNodeName == NULL) {
        ODKERB_LOG(LOG_ERR, "Missing original node name");
        goto failure;
    }

    ODNodeRef cfSearchNode2 = ODNodeCreateWithName(kCFAllocatorDefault, kODSessionDefault,
                                                   cfNodeName, &cfError);
    if (cfSearchNode2 == NULL || cfError != NULL) {
        ODKERB_LOG_CFERROR(LOG_ERR, "Unable to create the search record", cfError);
        goto failure;
    }

    *out = cfSearchNode2;

    retval = 0;
failure:
    if (cfError != NULL)
        odkerb_possibly_reset_search_node(cfError);
    CF_SAFE_RELEASE(cfError);
    CF_SAFE_RELEASE(cfOriginalNodeNames);
    CF_SAFE_RELEASE(cfConfigRecord);

    return retval;
}