예제 #1
0
파일: dseditgroup.c 프로젝트: aosm/DSTools
static bool isLegacyGroup( ODRecordRef inRecordRef, CFArrayRef* outShortNameMembers )
{
	CFIndex		shortNameMembersCount = 0;
	CFIndex		guidMembersCount = 0;
	
	CFArrayRef shortNameMembers = ODRecordCopyValues( inRecordRef, kODAttributeTypeGroupMembership, NULL );
	if ( shortNameMembers != NULL )
	{
		shortNameMembersCount = CFArrayGetCount( shortNameMembers );
		if ( outShortNameMembers != NULL )
		{
			*outShortNameMembers = shortNameMembers;
			CFRetain( shortNameMembers );
		}
		
		CFRelease( shortNameMembers );
	}
	
	CFArrayRef guidMembers = ODRecordCopyValues( inRecordRef, kODAttributeTypeGroupMembers, NULL );
	if ( guidMembers != NULL ) {
		guidMembersCount = CFArrayGetCount( guidMembers );
		CFRelease( guidMembers );
	}
	
	return ( guidMembersCount == 0 && shortNameMembersCount > 0 );
}
예제 #2
0
파일: AFPUsers.c 프로젝트: aosm/bootp
static uid_t
uid_from_odrecord(ODRecordRef record)
{
    uid_t		uid = -2;
    CFArrayRef		values	= NULL;

    values = ODRecordCopyValues(record, CFSTR(kDS1AttrUniqueID), NULL);
    if ((values != NULL) && (CFArrayGetCount(values) > 0)) {
	char		buf[64];
	char *		end;
	CFStringRef	uidStr;
	unsigned long	val;

	uidStr = CFArrayGetValueAtIndex(values, 0);
	(void) _SC_cfstring_to_cstring(uidStr, buf, sizeof(buf),
				       kCFStringEncodingASCII);
	errno = 0;
	val = strtoul(buf, &end, 0);
	if ((buf[0] != '\0') && (*end == '\0') && (errno == 0)) {
	    uid = (uid_t)val;
	}
    }
    my_CFRelease(&values);
    return (uid);
}
예제 #3
0
// MARK: -
// MARK: Open Directory
CFTypeRef WBODRecordCopyFirstValue(ODRecordRef record, ODAttributeType attribute) {
  CFArrayRef values = ODRecordCopyValues(record, attribute, NULL);
  if (!values) return NULL;

  CFTypeRef result = NULL;
  if (CFArrayGetCount(values) > 0)
    result = CFRetain(CFArrayGetValueAtIndex(values, 0));

  CFRelease(values);
  return result;
}
예제 #4
0
파일: odkerb.c 프로젝트: aosm/ChatServer
int
odkerb_get_fabricated_im_handle(ODRecordRef userRecord, CFStringRef allegedShortName, CFStringRef realm, char im_handle[], size_t im_handle_size)
{
    int retval = -1;
    CFArrayRef cfShortNames = NULL;
    CFStringRef cfIMHandle = NULL;
    CFErrorRef cfError = NULL;
    CFStringRef shortName = allegedShortName;

    ODKERB_PARAM_ASSERT(allegedShortName != NULL);
    ODKERB_PARAM_ASSERT(realm != NULL);
    ODKERB_PARAM_ASSERT(im_handle != 0);
    ODKERB_PARAM_ASSERT(im_handle_size > 0);

    *im_handle = '\0';

    if (userRecord != NULL) {
        /* attempt to get the primary short name from the user record */

        cfShortNames = ODRecordCopyValues(userRecord, kODAttributeTypeRecordName, &cfError);
        if (cfShortNames == NULL || cfError != NULL) {
            ODKERB_LOG_CFERROR(LOG_DEBUG, "Unable to find the short names", cfError);
            /* ignore this error, use the passed in allegedShortName parameter */
        }
        else if (CFArrayGetCount(cfShortNames) == 0) {
            ODKERB_LOG_CFSTRING(LOG_DEBUG, "Unable to find the short names", allegedShortName);
            /* ignore this error, use the passed in allegedShortName parameter */
        }
        else {
            CFStringRef cfShortName = CFArrayGetValueAtIndex(cfShortNames, 0);
            assert(cfShortName != 0);

            shortName = cfShortName;
        }
    }

    cfIMHandle = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@@%@"), shortName, realm);
    if (cfIMHandle == NULL) {
        ODKERB_LOG_ERRNO(LOG_ERR, ENOMEM);
        goto failure;
    }

    if (CFStringGetCString(cfIMHandle, im_handle, im_handle_size-1, kCFStringEncodingUTF8) == FALSE)
        goto failure;

    retval = 0;
failure:
    CF_SAFE_RELEASE(cfError);
    CF_SAFE_RELEASE(cfIMHandle);
    CF_SAFE_RELEASE(cfShortNames);

    return retval;
}
예제 #5
0
/* Can return NULL */
int
od_record_attribute_create_cfarray(ODRecordRef record, CFStringRef attrib,  CFArrayRef *out)
{
	int retval = PAM_SUCCESS;

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

	*out = ODRecordCopyValues(record, attrib, NULL);

cleanup:
	if (PAM_SUCCESS != retval) {
		if (NULL != out) {
			CFRelease(out);
		}
	}
	return retval;
}
예제 #6
0
/* ------------------------------------------------------------------
 *	get_attr_from_record ()
 */
static CFStringRef get_attr_from_record ( ODRecordRef in_rec_ref, CFStringRef in_attr )
{
	CFErrorRef cf_err_ref = NULL;
	CFArrayRef cf_arry_values = ODRecordCopyValues( in_rec_ref, in_attr, &cf_err_ref );
	if ( !cf_arry_values )
		return( NULL );

	if ( CFArrayGetCount( cf_arry_values ) > 1 ) {
		msg_error( "aod: multiple attribute values (%d) found in record user record: %s for attribute: %s",
					(int)CFArrayGetCount( cf_arry_values ),
					CFStringGetCStringPtr( ODRecordGetRecordName( in_rec_ref ), kCFStringEncodingUTF8 ),
					CFStringGetCStringPtr( in_attr, kCFStringEncodingUTF8 ) );
		CFRelease( cf_arry_values );
		return( NULL );
	}
	CFStringRef cf_str_out = CFArrayGetValueAtIndex( cf_arry_values, 0 );
	CFRetain( cf_str_out );

	CFRelease( cf_arry_values );

	return( cf_str_out );
} /*  get_attr_from_record */
예제 #7
0
파일: dseditgroup.c 프로젝트: aosm/DSTools
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;
			}
		}
예제 #8
0
파일: ns_od.c 프로젝트: RomiPierre/osx
/*
 * Looks for kODAttributeTypeRecordName and
 * kODAttributeTypeAutomountInformation; if it finds them, it calls
 * the specified callback with that information.
 */
static callback_ret_t
od_process_record_attributes(ODRecordRef record, callback_fn callback,
    void *udata)
{
	CFErrorRef error;
	char *errstring;
	CFArrayRef keys;
	CFStringRef key;
	CFArrayRef values;
	CFStringRef value;
	callback_ret_t ret;

	if (trace > 1) {
		trace_prt(1,
		"od_process_record_attributes entered\n");
	}

	/*
	 * Get kODAttributeTypeRecordName and
	 * kODAttributeTypeAutomountInformation for this record.
	 *
	 * Even though LDAP allows for multiple values per attribute, we take
	 * only the 1st value for each attribute because the automount data is
	 * organized as such (same as NIS+).
	 */
	error = NULL;
	keys = ODRecordCopyValues(record, kODAttributeTypeRecordName, &error);
	if (keys == NULL) {
		if (error != NULL) {
			errstring = od_get_error_string(error);
			pr_msg("od_process_record_attributes: can't get kODAttributeTypeRecordName attribute for record: %s",
			    errstring);
			free(errstring);
			return (OD_CB_ERROR);
		} else {
			/*
			 * We just reject records missing the attributes
			 * we need.
			 */
			pr_msg("od_process_record_attributes: record has no kODAttributeTypeRecordName attribute");
			return (OD_CB_REJECTED);
		}
	}
	if (CFArrayGetCount(keys) == 0) {
		/*
		 * We just reject records missing the attributes
		 * we need.
		 */
		CFRelease(keys);
		pr_msg("od_process_record_attributes: record has no kODAttributeTypeRecordName attribute");
		return (OD_CB_REJECTED);
	}
	key = CFArrayGetValueAtIndex(keys, 0);
	error = NULL;
	values = ODRecordCopyValues(record,
	    kODAttributeTypeAutomountInformation, &error);
	if (values == NULL) {
		CFRelease(keys);
		if (error != NULL) {
			errstring = od_get_error_string(error);
			pr_msg("od_process_record_attributes: can't get kODAttributeTypeAutomountInformation attribute for record: %s",
			    errstring);
			free(errstring);
			return (OD_CB_ERROR);
		} else {
			/*
			 * We just reject records missing the attributes
			 * we need.
			 */
			pr_msg("od_process_record_attributes: record has no kODAttributeTypeAutomountInformation attribute");
			return (OD_CB_REJECTED);
		}
	}
	if (CFArrayGetCount(values) == 0) {
		/*
		 * We just reject records missing the attributes
		 * we need.
		 */
		CFRelease(values);
		CFRelease(keys);
		pr_msg("od_process_record_attributes: record has no kODAttributeTypeRecordName attribute");
		return (OD_CB_REJECTED);
	}
	value = CFArrayGetValueAtIndex(values, 0);

	/*
	 * We have both of the attributes we need.
	 */
	ret = (*callback)(key, value, udata);
	CFRelease(values);
	CFRelease(keys);
	return (ret);
}
예제 #9
0
파일: dumpammap.c 프로젝트: RomiPierre/osx
/*
 * Looks for kODAttributeTypeRecordName and
 * kODAttributeTypeAutomountInformation; if it finds them, it prints them.
 */
static callback_ret_t
od_print_record(ODRecordRef record)
{
	CFErrorRef error;
	char *errstring;
	CFArrayRef keys;
	CFStringRef key;
	CFArrayRef values;
	CFStringRef value;
	char *key_cstring, *value_cstring;

	/*
	 * Get kODAttributeTypeRecordName and
	 * kODAttributeTypeAutomountInformation for this record.
	 *
	 * Even though LDAP allows for multiple values per attribute, we take
	 * only the 1st value for each attribute because the automount data is
	 * organized as such (same as NIS+).
	 */
	error = NULL;
	keys = ODRecordCopyValues(record, kODAttributeTypeRecordName, &error);
	if (keys == NULL) {
		if (error != NULL) {
			errstring = od_get_error_string(error);
			pr_msg("od_print_record: can't get kODAttributeTypeRecordName attribute for record: %s",
			    errstring);
			free(errstring);
			return (OD_CB_ERROR);
		} else {
			/*
			 * We just reject records missing the attributes
			 * we need.
			 */
			pr_msg("od_print_record: record has no kODAttributeTypeRecordName attribute");
			return (OD_CB_REJECTED);
		}
	}
	if (CFArrayGetCount(keys) == 0) {
		/*
		 * We just reject records missing the attributes
		 * we need.
		 */
		CFRelease(keys);
		pr_msg("od_print_record: record has no kODAttributeTypeRecordName attribute");
		return (OD_CB_REJECTED);
	}
	key = CFArrayGetValueAtIndex(keys, 0);
	error = NULL;
	values = ODRecordCopyValues(record,
	    kODAttributeTypeAutomountInformation, &error);
	if (values == NULL) {
		CFRelease(keys);
		if (error != NULL) {
			errstring = od_get_error_string(error);
			pr_msg("od_print_record: can't get kODAttributeTypeAutomountInformation attribute for record: %s",
			    errstring);
			free(errstring);
			return (OD_CB_ERROR);
		} else {
			/*
			 * We just reject records missing the attributes
			 * we need.
			 */
			pr_msg("od_print_record: record has no kODAttributeTypeAutomountInformation attribute");
			return (OD_CB_REJECTED);
		}
	}
	if (CFArrayGetCount(values) == 0) {
		/*
		 * We just reject records missing the attributes
		 * we need.
		 */
		CFRelease(values);
		CFRelease(keys);
		pr_msg("od_print_record: record has no kODAttributeTypeRecordName attribute");
		return (OD_CB_REJECTED);
	}
	value = CFArrayGetValueAtIndex(values, 0);

	/*
	 * We have both of the attributes we need.
	 */
	key_cstring = od_CFStringtoCString(key);
	value_cstring = od_CFStringtoCString(value);
	printf("%s %s\n", key_cstring, value_cstring);
	free(key_cstring);
	free(value_cstring);
	CFRelease(values);
	CFRelease(keys);
	return (OD_CB_KEEPGOING);
}
예제 #10
0
파일: odkerb.c 프로젝트: aosm/ChatServer
int
odkerb_get_im_handle_with_user_record(ODRecordRef userRecord, CFStringRef imType, CFStringRef realm, CFStringRef allegedShortName, char im_handle[], size_t im_handle_size)
{
    int retval = -1;
    CFArrayRef cfIMHandles = NULL;
    CFErrorRef cfError = NULL;
    CFMutableArrayRef cfMatches = NULL;
    CFStringRef cfRealID = NULL;
    int i;

    ODKERB_PARAM_ASSERT(userRecord != NULL);
    ODKERB_PARAM_ASSERT(allegedShortName != NULL);
    ODKERB_PARAM_ASSERT(im_handle != 0);
    ODKERB_PARAM_ASSERT(im_handle_size > 0);

    *im_handle = '\0';

    cfIMHandles = ODRecordCopyValues(userRecord, kODAttributeTypeIMHandle, &cfError);
    if (cfIMHandles == NULL || cfError != NULL) {
        ODKERB_LOG_CFERROR(LOG_ERR, "Unable to obtain IM handles", cfError);
        goto failure;
    }
    else if (CFArrayGetCount(cfIMHandles) == 0) {
        ODKERB_LOG_CFSTRING(LOG_DEBUG, "No IM handles", allegedShortName);
        goto failure;
    }

    /* there could be many IM handles that look plausible, so we heuristically determine which
     * one is the most likely to be the correct one.  imagine, for instance, that the following
     * ones are available:
     *    JABBER: [email protected]
     *    JABBER: [email protected]
     *    JABBER: [email protected]
     *    YAHOO:  [email protected]
     */

    /* first, remove those of the wrong type or realm because they can't possibly be right */

    cfMatches = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, cfIMHandles);
    if (cfMatches == NULL) {
        ODKERB_LOG_ERRNO(LOG_ERR, ENOMEM);
        goto failure;
    }

    for (i = CFArrayGetCount(cfMatches) - 1; i >= 0; --i) {
        CFStringRef cfID = CFArrayGetValueAtIndex(cfMatches, i);

        if (cfID != NULL
         && odkerb_CFStringHasPrefixWithOptions(cfID, imType, kCFCompareCaseInsensitive)
         && odkerb_CFStringHasSuffixWithOptions(cfID, realm, kCFCompareCaseInsensitive))
            continue;

        /* isn't a match, so remove it from the list */
        CFArrayRemoveValueAtIndex(cfMatches, i);
    }

    CFStringRef match = NULL;

    if (CFArrayGetCount(cfMatches) == 0) {
        ODKERB_LOG_CFSTRING(LOG_INFO, "No IM handles matching type and realm", allegedShortName);
        goto failure;
    }
    else if (CFArrayGetCount(cfMatches) == 1) {
        match = CFArrayGetValueAtIndex(cfMatches, 0);
        goto found_match;
    }

    /* second, attempt to use the short name to disasmbiguate among the several choices */

    for (i = 0; i < CFArrayGetCount(cfMatches); ++i) {
        CFStringRef cfID = CFArrayGetValueAtIndex(cfMatches, i);
        if (cfID == NULL)
            continue;

        CFRange where = CFStringFind(cfID, allegedShortName, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive);
        if (where.location != kCFNotFound) {
            match = cfID;
            goto found_match;
        }
    }

    /* at this point, there are several possibilities, but none of them contain the
     * short name, so just choose the first one */
    match = CFArrayGetValueAtIndex(cfMatches, 0);

found_match:
    assert(match != NULL);

    /* the ID is the substring following the IM type specifier prefix (kIMTypeJABBER) */

    assert(CFStringGetLength(match) > CFStringGetLength(imType));

    cfRealID = CFStringCreateWithSubstring(kCFAllocatorDefault, match,
                                           CFRangeMake(CFStringGetLength(imType), CFStringGetLength(match)-CFStringGetLength(imType)));
    if (cfRealID == NULL) {
        ODKERB_LOG_ERRNO(LOG_ERR, ENOMEM);
        goto failure;
    }

    if (CFStringGetCString(cfRealID, im_handle, im_handle_size-1, kCFStringEncodingUTF8) == FALSE) {
        ODKERB_LOG_CFSTRING(LOG_ERR, "Cannot obtain IM handle string", cfRealID);
        goto failure;
    }

    retval = 0;
failure:
    CF_SAFE_RELEASE(cfError);
    CF_SAFE_RELEASE(cfRealID);
    CF_SAFE_RELEASE(cfMatches);
    CF_SAFE_RELEASE(cfIMHandles);

    return retval;
}
예제 #11
0
파일: odkerb.c 프로젝트: aosm/ChatServer
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;
}