int
main(int argc, char *const *argv)
{
	plan_tests(6);

	ok(tests_begin(argc, argv), "setup");

	UInt32 didGetNotification = 0;
	ok_status(SecKeychainAddCallback(callbackFunction, kSecAddEventMask,
		&didGetNotification), "add callback");

	SecKeychainRef keychain;
	ok_status(SecKeychainCreate("test", 4, "test", FALSE, NULL, &keychain),
			"create keychain");
	SecKeychainItemRef itemRef;
	ok_status(SecKeychainAddGenericPassword(keychain,
		sizeof(account), account,
		sizeof(service), service,
		sizeof(password), password,
		&itemRef),
		"add generic password, release and wait for callback");
	//checkContent(itemRef);
	CFRelease(itemRef);
	CFRelease(keychain);

	if (argc > 1 && !strcmp(argv[1], "-l")) {
		printf("pid: %d\n", getpid());
		sleep(100);
	}
	ok(tests_end(1), "cleanup");
	ok_leaks("leaks");

	return 0;
}
Exemple #2
0
OSStatus OTMacKeychain::AddSecret(
    SecKeychainRef keychain, uint32_t serviceNameLength,
    const char* serviceName, uint32_t accountNameLength,
    const char* accountName, uint32_t passwordLength, const void* passwordData,
    SecKeychainItemRef* itemRef) const
{
    return SecKeychainAddGenericPassword(
        keychain, serviceNameLength, serviceName, accountNameLength,
        accountName, passwordLength, passwordData, itemRef);
}
char *keychain_add(char *service, char *account, char *pass) {
    OSStatus status = SecKeychainAddGenericPassword(
        NULL,
        strlen(service), service,
        strlen(account), account,
        strlen(pass), pass,
        NULL
    );
    if (status) return get_error(status);
    return NULL;
}
bool pfMacPasswordStore::SetPassword(const plString& username, const plString& password)
{
    plString service = GetServerDisplayName();

    return SecKeychainAddGenericPassword(nullptr,
                                         service.GetSize(),
                                         service.c_str(),
                                         username.GetSize(),
                                         username.c_str(),
                                         password.GetSize(),
                                         password.c_str(),
                                         nullptr) == errSecSuccess;
}
Exemple #5
0
/* Implementation of svn_auth__password_set_t that stores
   the password in the OS X KeyChain. */
static svn_error_t *
keychain_password_set(svn_boolean_t *done,
                      apr_hash_t *creds,
                      const char *realmstring,
                      const char *username,
                      const char *password,
                      apr_hash_t *parameters,
                      svn_boolean_t non_interactive,
                      apr_pool_t *pool)
{
  OSStatus status;
  SecKeychainItemRef item;

  if (non_interactive)
    SecKeychainSetUserInteractionAllowed(FALSE);

  status = SecKeychainFindGenericPassword(NULL, (int) strlen(realmstring),
                                          realmstring, username == NULL
                                            ? 0
                                            : (int) strlen(username),
                                          username, 0, NULL, &item);
  if (status)
    {
      if (status == errSecItemNotFound)
        status = SecKeychainAddGenericPassword(NULL, (int) strlen(realmstring),
                                               realmstring, username == NULL
                                                 ? 0
                                                 : (int) strlen(username),
                                               username, (int) strlen(password),
                                               password, NULL);
    }
  else
    {
      status = SecKeychainItemModifyAttributesAndData(item, NULL,
                                                      (int) strlen(password),
                                                      password);
      CFRelease(item);
    }

  if (non_interactive)
    SecKeychainSetUserInteractionAllowed(TRUE);

  *done = (status == 0);

  return SVN_NO_ERROR;
}
void SoundCloudCAPI_DefaultAuthenticationSave(SoundCloudCAPI *api)
{
    SecKeychainItemRef ref;
    const char *data=SoundCloudCAPI_GetCredentials(api);
    const char *service=api->apiBaseURL;
    CFStringRef bundleName=CFBundleGetIdentifier(CFBundleGetMainBundle());
    const char *name=CFStringGetCStringPtr(bundleName,kCFStringEncodingMacRoman);


    OSErr status=SecKeychainFindGenericPassword(NULL,strlen(name),name,strlen(service),service,0,0,&ref);
    if (status) status=SecKeychainAddGenericPassword(NULL,strlen(name),name,strlen(service),service,strlen(data),data,0);
    else		{
        status=SecKeychainItemModifyAttributesAndData(ref,NULL,strlen(data),data);
        CFRelease(ref);
    }
    if (status)	sc_log(api,SoundCloudCAPI_LogLevel_Errors,"Failed to save token, with err: %d\n",status);
}
Exemple #7
0
int main(int argc, char **argv) {
  if ((argc < 3) || (argc > 4)) {
    printf("Usage: %s <service> <account> [<password>]\n", argv[0]);
    return 1;
  }

  const char *service  = argv[1];
  const char *login    = argv[2];
  const char *password = argc == 4 ? argv[3] : NULL;

  void *buf;
  UInt32 len;
  SecKeychainItemRef item;

  if (password != NULL) {
    if (key_exists_p(service, login, &item) == 0) {
      SecKeychainItemDelete(item);
    }

    OSStatus create_key = SecKeychainAddGenericPassword(
      NULL, strlen(service), service, strlen(login), login, strlen(password),
      password, &item
    );

    if (create_key != 0) {
      fprintf(stderr, "Boxen Keychain Helper: Encountered error code: %d\n", create_key);
      return 1;
    }

  } else {
    OSStatus find_key = SecKeychainFindGenericPassword(
      NULL, strlen(service), service, strlen(login), login, &len, &buf, &item);

    if (find_key != 0) {
      fprintf(stderr, "Boxen Keychain Helper: Encountered error code: %d\n", find_key);
      return 1;
    }

    fwrite(buf, 1, len, stdout);
  }

  return 0;
}
//Call SecKeychainAddGenericPassword to add a new password to the keychain:
OSStatus WBKeychainAddGenericPassword(SecKeychainRef keychain, CFStringRef service, CFStringRef account, CFStringRef password, SecKeychainItemRef *itemRef) {
  OSStatus status;
  char *serviceStr = (char *)__WBCFStringCopyUTF8Characters(service);
  char *accountStr = (char *)__WBCFStringCopyUTF8Characters(account);
  char *passwordStr = (char *)__WBCFStringCopyUTF8Characters(password);
  require_action_string(serviceStr != NULL && accountStr != NULL && passwordStr != NULL, bail, status = paramErr, "Unable to get service or account characters");

  status = SecKeychainAddGenericPassword(keychain,
                                         (UInt32)strlen(serviceStr), serviceStr,
                                         (UInt32)strlen(accountStr), accountStr,
                                         (UInt32)strlen(passwordStr), passwordStr,
                                         itemRef);

bail:
    if (serviceStr) free(serviceStr);
  if (accountStr) free(accountStr);
  if (passwordStr) free(passwordStr);
  return status;
}
Exemple #9
0
SEXP store_password(SEXP svc, SEXP usr, SEXP pwd) {
    OSStatus status;
    SecKeychainRef kc = NULL; /* default */
    const char *un, *sn, *pw;
    char *svc_name;
    int l;

    if (TYPEOF(svc) != STRSXP || LENGTH(svc) != 1) Rf_error("Invalid service name");

    if (TYPEOF(pwd) != STRSXP || LENGTH(pwd) != 1) Rf_error("Invalid password");
    pw = Rf_translateCharUTF8(STRING_ELT(pwd, 0));

    if (usr == R_NilValue) {
        un = getlogin();
        if (!un) Rf_error("Unable to get current user name via getlogin()");
    } else {
        if (TYPEOF(usr) != STRSXP || LENGTH(usr) != 1)
            Rf_error("Invalid user name (must be a character vector of length one)");
        un = Rf_translateCharUTF8(STRING_ELT(usr, 0));
    }

    sn = Rf_translateCharUTF8(STRING_ELT(svc, 0));
    l = strlen(sn);
    if (l > sizeof(buf) - 16) {
        svc_name = (char*) malloc(l + 16);
        if (!svc_name) Rf_error("Cannot allocate memory for service name");
    } else svc_name = buf;

    /* we are enforcing R.keychain. prefix to avoid abuse to access other system keys */
    strcpy(svc_name, SEC_PREFIX);
    strcat(svc_name, sn);

    status = SecKeychainAddGenericPassword(kc,
                                           strlen(svc_name), svc_name,
                                           strlen(un), un,
                                           strlen(pw), pw,
                                           NULL);
    if (svc_name != buf) free(svc_name);
    chk_status(status, "add");

    return R_NilValue;
}
/* Implementation of OSXKeychain.addGenericPassword(). See the Java docs for
 * explanations of the parameters.
 */
JNIEXPORT void JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1addGenericPassword(JNIEnv* env, jobject obj, jstring serviceName, jstring accountName, jstring password) {
	OSStatus status;
	jstring_unpacked service_name;
	jstring_unpacked account_name;
	jstring_unpacked service_password;

	/* Unpack the params */
	jstring_unpack(env, serviceName, &service_name);
	jstring_unpack(env, accountName, &account_name);
	jstring_unpack(env, password, &service_password);
	/* check for allocation failures */
	if (service_name.str == NULL || 
	    account_name.str == NULL || 
		service_password.str == NULL) {
		jstring_unpacked_free(env, serviceName, &service_name);
		jstring_unpacked_free(env, accountName, &account_name);
		jstring_unpacked_free(env, password, &service_password);
		return;
	}

	/* Add the details to the keychain. */
	status = SecKeychainAddGenericPassword(
		NULL,
		service_name.len,
		service_name.str,
		account_name.len,
		account_name.str,
		service_password.len,
		service_password.str,
		NULL
	);
	if (status != errSecSuccess) {
		throw_osxkeychainexception(env, status);
	}

	/* Clean up. */
	jstring_unpacked_free(env, serviceName, &service_name);
	jstring_unpacked_free(env, accountName, &account_name);
	jstring_unpacked_free(env, password, &service_password);
}
Exemple #11
0
/*	Creates or updates a keychain item to match new details.
*/
void keychain_update_password(const char *origServer, const char *origUser, const char *server, const char *username, const char *password)
{
	if (!strlen(server) || !strlen(username))
		return;

	void *s1 = NULL;
	
	BADGE_HOSTNAME(server);
	
	SecKeychainItemRef origItem = NULL;
	OSStatus status;
	
	if (strlen(origServer) && strlen(origUser))
	{
		s1 = (void*)BADGE_HOSTNAME(origServer);
		origItem = get_password_details(origServer, origUser, NULL, 0);
	}
	
	SecKeychainItemRef newItem  = get_password_details(server, username, NULL, 0);
	
	if (origItem || newItem)
	{
		// Modify the existing password
		SecKeychainItemRef keychainItem = (origItem) ? origItem : newItem;
			
		// use 7 instead of kSecLabelItemAttr because of a Carbon bug
		//	details: http://lists.apple.com/archives/apple-cdsa/2006//May/msg00037.html
		
		SecKeychainAttribute attrs[] =
		{
				{kSecAccountItemAttr, strlen(username), (void*)username},
				{7, strlen(server), (void*)server},
				{kSecServiceItemAttr, strlen(server), (void*)server}
		};
		
		SecKeychainAttributeList list = { sizeof(attrs) / sizeof(attrs[0]), attrs };
			
		status = SecKeychainItemModifyAttributesAndData(keychainItem, &list, strlen(password), password);
		
		if (status != noErr) 
			EXTENDED_KC_ERR(status, "editing an existing password");
	}
	else
	{
		// Password doesn't exist, create it
		status = SecKeychainAddGenericPassword (
					NULL,              // default keychain
					strlen(server),    // length of service name
					server,            // service name
					strlen(username),  // length of account name
					username,          // account name
					strlen(password),  // length of password
					password,          // pointer to password data
					NULL               // the item reference
					);
		
		if (status != noErr) 
			EXTENDED_KC_ERR(status, "saving a new password");
    }
	
	free(s1);
	free((void*)server);
}
void tests(void)
{
	SecKeychainRef keychain = NULL;
	ok_status(SecKeychainCreate("test", 4, "test", FALSE, NULL, &keychain),
		"create keychain");
	ok_status(test_sec_event_register(kSecEveryEventMask),
		"register for all events");
	int item_num;
	int item_count = 9;
	for (item_num = 0; item_num < item_count; ++item_num)
	{
		char account[64];
		sprintf(account, "account-%d", item_num);
		ok_status(SecKeychainAddGenericPassword(keychain, 7, "service",
			strlen(account), account, 4, "test", NULL),
			"add generic password");
	}
	SecKeychainAttribute attrs[] =
	{ { kSecAccountItemAttr } };
	SecKeychainAttributeList attrList =
	{ sizeof(attrs) / sizeof(*attrs), attrs };

	for (item_num = 0; item_num < item_count - 2; ++item_num)
	{
		char account[64];
		sprintf(account, "account-%d", item_num);
		SecKeychainItemRef item = NULL;
		is_sec_event(kSecAddEvent, NULL, &item, NULL, "got add event");

		SKIP: {
			skip("no item", 3, item != NULL);

			ok_status(SecKeychainItemCopyContent(item, NULL, &attrList, NULL,
				NULL), "get content");
			
			eq_stringn(account, strlen(account), attrs[0].data, attrs[0].length,
				"account name in notification matches");
			ok_status(SecKeychainItemFreeContent(&attrList, NULL),
				"free content");
		}
	}

	for (; item_num < item_count; ++item_num)
	{
		char account[64];
		sprintf(account, "account-%d", item_num);
		SecKeychainItemRef item = NULL;
		is_sec_event(kSecAddEvent, NULL, &item, NULL, "got add event");

		SKIP: {
			skip("no item", 3, item != NULL);

			ok_status(SecKeychainItemCopyContent(item, NULL, &attrList, NULL,
				NULL), "get content");
			eq_stringn(account, strlen(account), attrs[0].data, attrs[0].length,
				"account name in notification matches");
			ok_status(SecKeychainItemFreeContent(&attrList, NULL),
				"free content");
		}
	}
	
	ok(tests_end(1), "cleanup");
}
Exemple #13
0
static krb5_error_code
get_new_tickets(krb5_context context,
		krb5_principal principal,
		krb5_ccache ccache,
		krb5_deltat ticket_life,
		int interactive)
{
    krb5_error_code ret;
    krb5_get_init_creds_opt *opt;
    krb5_creds cred;
    char passwd[256];
    krb5_deltat start_time = 0;
    krb5_deltat renew = 0;
    const char *renewstr = NULL;
    krb5_enctype *enctype = NULL;
    krb5_ccache tempccache;
    krb5_init_creds_context icc;
    krb5_keytab kt = NULL;
    int will_use_keytab =  (use_keytab || keytab_str);
    krb5_prompter_fct prompter = NULL;
    int need_prompt;

    passwd[0] = '\0';

    if (password_file) {
	FILE *f;

	if (strcasecmp("STDIN", password_file) == 0)
	    f = stdin;
	else
	    f = fopen(password_file, "r");
	if (f == NULL)
	    krb5_errx(context, 1, "Failed to open the password file %s",
		      password_file);

	if (fgets(passwd, sizeof(passwd), f) == NULL)
	    krb5_errx(context, 1,
		      N_("Failed to read password from file %s", ""),
		      password_file);
	if (f != stdin)
	    fclose(f);
	passwd[strcspn(passwd, "\n")] = '\0';
    }

#if defined(__APPLE__) && !defined(__APPLE_TARGET_EMBEDDED__)
    if (passwd[0] == '\0' && !will_use_keytab && home_directory_flag) {
	const char *realm;
	OSStatus osret;
	UInt32 length;
	void *buffer;
	char *name;

	realm = krb5_principal_get_realm(context, principal);

	ret = krb5_unparse_name_flags(context, principal,
				      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret)
	    goto nopassword;

	osret = SecKeychainFindGenericPassword(NULL, (UInt32)strlen(realm), realm,
					       (UInt32)strlen(name), name,
					       &length, &buffer, &passwordItem);
	free(name);
	if (osret != noErr)
	    goto nopassword;

	if (length < sizeof(passwd) - 1) {
	    memcpy(passwd, buffer, length);
	    passwd[length] = '\0';
	}
	SecKeychainItemFreeContent(NULL, buffer);
    nopassword:
	do { } while(0);
    }
#endif

    need_prompt = !(pk_user_id || ent_user_id || anonymous_flag || will_use_keytab || passwd[0] != '\0') && interactive;
    if (need_prompt)
	prompter = krb5_prompter_posix;
    else
	prompter = krb5_prompter_print_only;

    memset(&cred, 0, sizeof(cred));

    ret = krb5_get_init_creds_opt_alloc (context, &opt);
    if (ret)
	krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");

    krb5_get_init_creds_opt_set_default_flags(context, "kinit",
	krb5_principal_get_realm(context, principal), opt);

    if(forwardable_flag != -1)
	krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);

    if(proxiable_flag != -1)
	krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
    if(anonymous_flag)
	krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
    if (pac_flag != -1)
	krb5_get_init_creds_opt_set_pac_request(context, opt,
						pac_flag ? TRUE : FALSE);
    if (canonicalize_flag)
	krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
    if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag)
	krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
    if (pk_user_id || ent_user_id || anonymous_flag) {
	ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
						 principal,
						 pk_user_id,
						 pk_x509_anchors,
						 NULL,
						 NULL,
						 pk_use_enckey ? 2 : 0 |
						 anonymous_flag ? 4 : 0,
						 interactive ? krb5_prompter_posix : krb5_prompter_print_only,
						 NULL,
						 passwd);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
	if (ent_user_id)
	    krb5_get_init_creds_opt_set_pkinit_user_cert(context, opt, ent_user_id);
    }

    if (addrs_flag != -1)
	krb5_get_init_creds_opt_set_addressless(context, opt,
						addrs_flag ? FALSE : TRUE);

    if (renew_life == NULL && renewable_flag)
	renewstr = "1 month";
    if (renew_life)
	renewstr = renew_life;
    if (renewstr) {
	renew = parse_time (renewstr, "s");
	if (renew < 0)
	    errx (1, "unparsable time: %s", renewstr);

	krb5_get_init_creds_opt_set_renew_life (opt, renew);
    }

    if(ticket_life != 0)
	krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life);

    if(start_str) {
	int tmp = parse_time (start_str, "s");
	if (tmp < 0)
	    errx (1, N_("unparsable time: %s", ""), start_str);

	start_time = tmp;
    }

    if(etype_str.num_strings) {
	int i;

	enctype = malloc(etype_str.num_strings * sizeof(*enctype));
	if(enctype == NULL)
	    errx(1, "out of memory");
	for(i = 0; i < etype_str.num_strings; i++) {
	    ret = krb5_string_to_enctype(context,
					 etype_str.strings[i],
					 &enctype[i]);
	    if(ret)
		krb5_err(context, 1, ret, "unrecognized enctype: %s",
			 etype_str.strings[i]);
	}
	krb5_get_init_creds_opt_set_etype_list(opt, enctype,
					       etype_str.num_strings);
    }

    ret = krb5_init_creds_init(context, principal,
			       prompter, NULL,
			       start_time, opt, &icc);
    if (ret)
	krb5_err (context, 1, ret, "krb5_init_creds_init");

    if (server_str) {
	ret = krb5_init_creds_set_service(context, icc, server_str);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_init_creds_set_service");
    }

    if (kdc_hostname)
	krb5_init_creds_set_kdc_hostname(context, icc, kdc_hostname);

    if (fast_armor_cache_string) {
	krb5_ccache fastid;
	
	ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_cc_resolve(FAST cache)");
	
	ret = krb5_init_creds_set_fast_ccache(context, icc, fastid);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_init_creds_set_fast_ccache");
    }

    if(will_use_keytab) {
	if(keytab_str)
	    ret = krb5_kt_resolve(context, keytab_str, &kt);
	else
	    ret = krb5_kt_default(context, &kt);
	if (ret)
	    krb5_err (context, 1, ret, "resolving keytab");

	ret = krb5_init_creds_set_keytab(context, icc, kt);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_init_creds_set_keytab");
    }

    if (passwd[0] == '\0' && need_prompt) {
	char *p, *prompt;

	krb5_unparse_name(context, principal, &p);
	asprintf (&prompt, N_("%s's Password: "******""), p);
	free(p);

	if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
	    memset(passwd, 0, sizeof(passwd));
	    errx(1, "failed to read password");
	}
	free (prompt);
    }

    if (passwd[0]) {
	ret = krb5_init_creds_set_password(context, icc, passwd);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_init_creds_set_password");
    }

    ret = krb5_init_creds_get(context, icc);

#ifdef __APPLE__
    /*
     * Save password in Keychain
     */
    if (ret == 0 && keychain_flag && passwordItem == NULL) {
	krb5_error_code ret2;
	const char *realm;
	char *name;

	realm = krb5_principal_get_realm(context, principal);
	ret2 = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret2 == 0) {
	    (void)SecKeychainAddGenericPassword(NULL,
						(UInt32)strlen(realm), realm,
						(UInt32)strlen(name), name,
						(UInt32)strlen(passwd), passwd,
						NULL);
	    free(name);
	}
    }
#endif

    memset(passwd, 0, sizeof(passwd));

    switch(ret){
    case 0:
	break;
    case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
	exit(1);
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KRB_AP_ERR_MODIFIED:
    case KRB5KDC_ERR_PREAUTH_FAILED:
    case KRB5_GET_IN_TKT_LOOP:
#ifdef __APPLE__
	if (passwordItem)
	    SecKeychainItemDelete(passwordItem);
#endif
	krb5_errx(context, 1, N_("Password incorrect", ""));
    case KRB5KRB_AP_ERR_V4_REPLY:
	krb5_errx(context, 1, N_("Looks like a Kerberos 4 reply", ""));
    case KRB5KDC_ERR_KEY_EXPIRED:
	krb5_errx(context, 1, N_("Password expired", ""));
    default:
	krb5_err(context, 1, ret, "krb5_get_init_creds");
    }

    ret = krb5_init_creds_get_creds(context, icc, &cred);
    if (ret)
	krb5_err(context, 1, ret, "krb5_init_creds_get_creds");

    krb5_process_last_request(context, opt, icc);

    ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache),
			     NULL, &tempccache);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_new_unique");

    ret = krb5_init_creds_store(context, icc, tempccache);
    if (ret)
	krb5_err(context, 1, ret, "krb5_init_creds_store");

    ret = krb5_init_creds_store_config(context, icc, tempccache);
    if (ret)
	krb5_warn(context, ret, "krb5_init_creds_store_config");

    ret = krb5_init_creds_warn_user(context, icc);
    if (ret)
	krb5_warn(context, ret, "krb5_init_creds_warn_user");

#ifdef __APPLE__
    /*
     * Set for this case, default to * so that all processes can use
     * this cache.
     */
    {
	heim_array_t bundleacl = heim_array_create();
	heim_string_t ace;

	if (bundle_acl_strings.num_strings > 0) {
	    int i;
	    for (i = 0; i < bundle_acl_strings.num_strings; i++) {
		ace = heim_string_create(bundle_acl_strings.strings[i]);
		heim_array_append_value(bundleacl, ace);
		heim_release(ace);
	    }
	} else {
	    ace = heim_string_create("*");
	    heim_array_append_value(bundleacl, ace);
	    heim_release(ace);
	}
	krb5_cc_set_acl(context, tempccache, "kHEIMAttrBundleIdentifierACL", bundleacl);
	heim_release(bundleacl);
    }
#endif

    ret = krb5_cc_move(context, tempccache, ccache);
    if (ret) {
	(void)krb5_cc_destroy(context, tempccache);
	krb5_err (context, 1, ret, "krb5_cc_move");
    }

    if (switch_cache_flags)
	krb5_cc_switch(context, ccache);

    if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
	unsigned char d = 0;
	krb5_data data;

	if (ok_as_delegate_flag || windows_flag)
	    d |= 1;
	if (use_referrals_flag || windows_flag)
	    d |= 2;

	data.length = 1;
	data.data = &d;

	krb5_cc_set_config(context, ccache, NULL, "realm-config", &data);
    }

    if (enctype)
	free(enctype);

    krb5_init_creds_free(context, icc);
    krb5_get_init_creds_opt_free(context, opt);

    if (kt)
	krb5_kt_close(context, kt);

#ifdef __APPLE__
    if (passwordItem)
	CFRelease(passwordItem);
#endif

    return 0;
}