static krb5_error_code KRB5_CALLCONV
any_remove_entry(krb5_context context,
		 krb5_keytab id,
		 krb5_keytab_entry *entry)
{
    struct any_data *a = id->data;
    krb5_error_code ret;
    int found = 0;
    while(a != NULL) {
	ret = krb5_kt_remove_entry(context, a->kt, entry);
	if(ret == 0)
	    found++;
	else {
	    if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) {
		krb5_set_error_message(context, ret,
				       N_("Failed to remove keytab "
					  "entry from %s", "keytab name"),
				       a->name);
		return ret;
	    }
	}
	a = a->next;
    }
    if(!found)
	return KRB5_KT_NOTFOUND;
    return 0;
}
Esempio n. 2
0
static krb5_error_code
any_remove_entry(krb5_context context,
		 krb5_keytab id,
		 krb5_keytab_entry *entry)
{
    struct any_data *a = id->data;
    krb5_error_code ret;
    int found = 0;
    while(a != NULL) {
	ret = krb5_kt_remove_entry(context, a->kt, entry);
	if(ret == 0)
	    found++;
	else {
	    if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) {
		krb5_set_error_string(context, "failed to remove entry from %s", 
				      a->name);
		return ret;
	    }
	}
	a = a->next;
    }
    if(!found)
	return KRB5_KT_NOTFOUND;
    return 0;
}
Esempio n. 3
0
int
kt_remove(struct remove_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab_entry entry;
    krb5_keytab keytab;
    krb5_principal principal = NULL;
    krb5_enctype enctype = 0;

    if(opt->principal_string) {
	ret = krb5_parse_name(context, opt->principal_string, &principal);
	if(ret) {
	    krb5_warn(context, ret, "%s", opt->principal_string);
	    return 1;
	}
    }
    if(opt->enctype_string) {
	ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype);
	if(ret) {
	    int t;
	    if(sscanf(opt->enctype_string, "%d", &t) == 1)
		enctype = t;
	    else {
		krb5_warn(context, ret, "%s", opt->enctype_string);
		if(principal)
		    krb5_free_principal(context, principal);
		return 1;
	    }
	}
    }
    if (!principal && !enctype && !opt->kvno_integer) {
	krb5_warnx(context,
		   "You must give at least one of "
		   "principal, enctype or kvno.");
	ret = EINVAL;
	goto out;
    }

    if((keytab = ktutil_open_keytab()) == NULL) {
	ret = 1;
	goto out;
    }

    entry.principal = principal;
    entry.keyblock.keytype = enctype;
    entry.vno = opt->kvno_integer;
    ret = krb5_kt_remove_entry(context, keytab, &entry);
    krb5_kt_close(context, keytab);
    if(ret)
	krb5_warn(context, ret, "remove");
 out:
    if(principal)
	krb5_free_principal(context, principal);
    return ret != 0;
}
krb5_error_code
_adcli_krb5_keytab_clear (krb5_context k5,
                          krb5_keytab keytab,
                          krb5_boolean (* match_func) (krb5_context,
                                                       krb5_keytab_entry *,
                                                       void *),
                          void *match_data)
{
	krb5_kt_cursor cursor;
	krb5_keytab_entry entry;
	krb5_error_code code;

	code = krb5_kt_start_seq_get (k5, keytab, &cursor);
	if (code == KRB5_KT_END || code == ENOENT)
		return 0;
	else if (code != 0)
		return code;

	for (;;) {
		code = krb5_kt_next_entry (k5, keytab, &entry, &cursor);
		if (code != 0)
			break;

		/* See if we should remove this entry */
		if (!match_func (k5, &entry, match_data)) {
			krb5_free_keytab_entry_contents (k5, &entry);
			continue;
		}

		/*
		 * Here we close the cursor, remove the entry and then
		 * start all over again from the beginning. Dumb but works.
		 */

		code = krb5_kt_end_seq_get (k5, keytab, &cursor);
		return_val_if_fail (code == 0, code);

		code = krb5_kt_remove_entry (k5, keytab, &entry);
		krb5_free_keytab_entry_contents (k5, &entry);

		if (code != 0)
			return code;

		code = krb5_kt_start_seq_get (k5, keytab, &cursor);
		return_val_if_fail (code == 0, code);
	}

	if (code == KRB5_KT_END)
		code = 0;

	krb5_kt_end_seq_get (k5, keytab, &cursor);
	return code;
}
Esempio n. 5
0
void KRB5Keytab::removeEntry(KRB5Principal &princ, krb5_kvno kvno, krb5_enctype enctype)
{
    krb5_keytab_entry entry;

    entry.principal = princ.get();
    entry.vno = kvno;
#ifdef HEIMDAL
    entry.keyblock.keytype = enctype;
#else
    entry.key.enctype = enctype;
#endif

    krb5_error_code ret = krb5_kt_remove_entry(g_context.get(), m_keytab, &entry);
    if (ret) {
        throw KRB5Exception("krb5_kt_remove_entry", ret);
    }
}
Esempio n. 6
0
static void
test_empty_keytab(krb5_context context, const char *keytab)
{
    krb5_error_code ret;
    krb5_keytab id;
    krb5_keytab_entry entry;

    ret = krb5_kt_resolve(context, keytab, &id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_resolve");

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

    krb5_kt_remove_entry(context, id, &entry);

    ret = krb5_kt_close(context, id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_close");
}
Esempio n. 7
0
static void
remove_principal(char *keytab_str, krb5_keytab keytab,
                 char *princ_str, char *kvno_str)
{
    krb5_principal princ;
    krb5_keytab_entry entry;
    krb5_kt_cursor cursor;
    enum { UNDEF, SPEC, HIGH, ALL, OLD } mode;
    int code, did_something;
    krb5_kvno kvno;

    code = krb5_parse_name(context, princ_str, &princ);
    if (code != 0) {
        com_err(whoami, code, "while parsing principal name %s", princ_str);
        return;
    }

    mode = UNDEF;
    if (kvno_str == NULL) {
        mode = HIGH;
        kvno = 0;
    } else if (strcmp(kvno_str, "all") == 0) {
        mode = ALL;
        kvno = 0;
    } else if (strcmp(kvno_str, "old") == 0) {
        mode = OLD;
        kvno = 0;
    } else {
        mode = SPEC;
        kvno = atoi(kvno_str);
    }

    /* kvno is set to specified value for SPEC, 0 otherwise */
    code = krb5_kt_get_entry(context, keytab, princ, kvno, 0, &entry);
    if (code != 0) {
        if (code == ENOENT) {
            fprintf(stderr, "%s: Keytab %s does not exist.\n",
                    whoami, keytab_str);
        } else if (code == KRB5_KT_NOTFOUND) {
            if (mode != SPEC) {
                fprintf(stderr, "%s: No entry for principal "
                        "%s exists in keytab %s\n",
                        whoami, princ_str, keytab_str);
            } else {
                fprintf(stderr, "%s: No entry for principal "
                        "%s with kvno %d exists in keytab "
                        "%s.\n", whoami, princ_str, kvno, keytab_str);
            }
        } else
            com_err(whoami, code, "while retrieving highest kvno from keytab");
        return;
    }

    /* set kvno to spec'ed value for SPEC, highest kvno otherwise */
    kvno = entry.vno;
    krb5_kt_free_entry(context, &entry);

    code = krb5_kt_start_seq_get(context, keytab, &cursor);
    if (code != 0) {
        com_err(whoami, code, "while starting keytab scan");
        return;
    }

    did_something = 0;
    while ((code = krb5_kt_next_entry(context, keytab, &entry,
                                      &cursor)) == 0) {
        if (krb5_principal_compare(context, princ, entry.principal) &&
            ((mode == ALL) ||
             (mode == SPEC && entry.vno == kvno) ||
             (mode == OLD && entry.vno != kvno) ||
             (mode == HIGH && entry.vno == kvno))) {

            /*
             * Ack!  What a kludge... the scanning functions lock
             * the keytab so entries cannot be removed while they
             * are operating.
             */
            code = krb5_kt_end_seq_get(context, keytab, &cursor);
            if (code != 0) {
                com_err(whoami, code, "while temporarily ending keytab scan");
                return;
            }
            code = krb5_kt_remove_entry(context, keytab, &entry);
            if (code != 0) {
                com_err(whoami, code, "while deleting entry from keytab");
                return;
            }
            code = krb5_kt_start_seq_get(context, keytab, &cursor);
            if (code != 0) {
                com_err(whoami, code, "while restarting keytab scan");
                return;
            }

            did_something++;
            if (!quiet)
                printf("Entry for principal %s with kvno %d "
                       "removed from keytab %s.\n",
                       princ_str, entry.vno, keytab_str);
        }
        krb5_kt_free_entry(context, &entry);
    }
    if (code && code != KRB5_KT_END) {
        com_err(whoami, code, "while scanning keytab");
        return;
    }
    code = krb5_kt_end_seq_get(context, keytab, &cursor);
    if (code) {
        com_err(whoami, code, "while ending keytab scan");
        return;
    }

    /*
     * If !did_someting then mode must be OLD or we would have
     * already returned with an error.  But check it anyway just to
     * prevent unexpected error messages...
     */
    if (!did_something && mode == OLD) {
        fprintf(stderr, "%s: There is only one entry for principal "
                "%s in keytab %s\n", whoami, princ_str, keytab_str);
    }
}
Esempio n. 8
0
/*
 * Walk the keytab, looking for entries of this principal name,
 * with KVNO other than current kvno -1.
 *
 * These entries are now stale,
 * we only keep the current and previous entries around.
 *
 * Inspired by the code in Samba3 for 'use kerberos keytab'.
 */
krb5_error_code smb_krb5_remove_obsolete_keytab_entries(TALLOC_CTX *mem_ctx,
							krb5_context context,
							krb5_keytab keytab,
							uint32_t num_principals,
							krb5_principal *principals,
							krb5_kvno kvno,
							bool *found_previous,
							const char **error_string)
{
	TALLOC_CTX *tmp_ctx;
	krb5_error_code code;
	krb5_kt_cursor cursor;

	tmp_ctx = talloc_new(mem_ctx);
	if (tmp_ctx == NULL) {
		*error_string = "Cannot allocate tmp_ctx";
		return ENOMEM;
	}

	*found_previous = true;

	code = krb5_kt_start_seq_get(context, keytab, &cursor);
	switch (code) {
	case 0:
		break;
#ifdef HEIM_ERR_OPNOTSUPP
	case HEIM_ERR_OPNOTSUPP:
#endif
	case ENOENT:
	case KRB5_KT_END:
		/* no point enumerating if there isn't anything here */
		code = 0;
		goto done;
	default:
		*error_string = talloc_asprintf(mem_ctx,
						"failed to open keytab for read of old entries: %s\n",
						smb_get_krb5_error_message(context, code, mem_ctx));
		goto done;
	}

	do {
		krb5_kvno old_kvno = kvno - 1;
		krb5_keytab_entry entry;
		bool matched = false;
		uint32_t i;

		code = krb5_kt_next_entry(context, keytab, &entry, &cursor);
		if (code) {
			break;
		}

		for (i = 0; i < num_principals; i++) {
			krb5_boolean ok;

			ok = smb_krb5_kt_compare(context,
						&entry,
						principals[i],
						0,
						0);
			if (ok) {
				matched = true;
				break;
			}
		}

		if (!matched) {
			/*
			 * Free the entry, it wasn't the one we were looking
			 * for anyway
			 */
			krb5_kt_free_entry(context, &entry);
			/* Make sure we do not double free */
			ZERO_STRUCT(entry);
			continue;
		}

		/*
		 * Delete it, if it is not kvno - 1.
		 *
		 * Some keytab files store the kvno only in 8bits. Limit the
		 * compare to 8bits, so that we don't miss old keys and delete
		 * them.
		 */
		if ((entry.vno & 0xff) != (old_kvno & 0xff)) {
			krb5_error_code rc;

			/* Release the enumeration.  We are going to
			 * have to start this from the top again,
			 * because deletes during enumeration may not
			 * always be consistent.
			 *
			 * Also, the enumeration locks a FILE: keytab
			 */
			krb5_kt_end_seq_get(context, keytab, &cursor);

			code = krb5_kt_remove_entry(context, keytab, &entry);
			krb5_kt_free_entry(context, &entry);

			/* Make sure we do not double free */
			ZERO_STRUCT(entry);

			/* Deleted: Restart from the top */
			rc = krb5_kt_start_seq_get(context, keytab, &cursor);
			if (rc != 0) {
				krb5_kt_free_entry(context, &entry);

				/* Make sure we do not double free */
				ZERO_STRUCT(entry);

				DEBUG(1, ("failed to restart enumeration of keytab: %s\n",
					  smb_get_krb5_error_message(context,
								     code,
								     tmp_ctx)));

				talloc_free(tmp_ctx);
				return rc;
			}

			if (code != 0) {
				break;
			}

		} else {
			*found_previous = true;
		}

		/* Free the entry, we don't need it any more */
		krb5_kt_free_entry(context, &entry);
		/* Make sure we do not double free */
		ZERO_STRUCT(entry);
	} while (code != 0);

	krb5_kt_end_seq_get(context, keytab, &cursor);

	switch (code) {
	case 0:
		break;
	case ENOENT:
	case KRB5_KT_END:
		code = 0;
		break;
	default:
		*error_string = talloc_asprintf(mem_ctx,
						"failed in deleting old entries for principal: %s\n",
						smb_get_krb5_error_message(context,
									   code,
									   mem_ctx));
	}

	code = 0;
done:
	talloc_free(tmp_ctx);
	return code;
}
Esempio n. 9
0
/**
 * Remove all entries that have the given principal, kvno and enctype.
 */
static krb5_error_code libnet_keytab_remove_entries(krb5_context context,
						    krb5_keytab keytab,
						    const char *principal,
						    int kvno,
						    const krb5_enctype enctype,
						    bool ignore_kvno)
{
	krb5_error_code ret;
	krb5_kt_cursor cursor;
	krb5_keytab_entry kt_entry;

	ZERO_STRUCT(kt_entry);
	ZERO_STRUCT(cursor);

	ret = krb5_kt_start_seq_get(context, keytab, &cursor);
	if (ret) {
		return 0;
	}

	while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0)
	{
		krb5_keyblock *keyp;
		char *princ_s = NULL;

		if (kt_entry.vno != kvno && !ignore_kvno) {
			goto cont;
		}

		keyp = KRB5_KT_KEY(&kt_entry);

		if (KRB5_KEY_TYPE(keyp) != enctype) {
			goto cont;
		}

		ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal,
					    &princ_s);
		if (ret) {
			DEBUG(5, ("smb_krb5_unparse_name failed (%s)\n",
				  error_message(ret)));
			goto cont;
		}

		if (strcmp(principal, princ_s) != 0) {
			goto cont;
		}

		/* match found - remove */

		DEBUG(10, ("found entry for principal %s, kvno %d, "
			   "enctype %d - trying to remove it\n",
			   princ_s, kt_entry.vno, KRB5_KEY_TYPE(keyp)));

		ret = krb5_kt_end_seq_get(context, keytab, &cursor);
		ZERO_STRUCT(cursor);
		if (ret) {
			DEBUG(5, ("krb5_kt_end_seq_get failed (%s)\n",
				  error_message(ret)));
			goto cont;
		}

		ret = krb5_kt_remove_entry(context, keytab,
					   &kt_entry);
		if (ret) {
			DEBUG(5, ("krb5_kt_remove_entry failed (%s)\n",
				  error_message(ret)));
			goto cont;
		}
		DEBUG(10, ("removed entry for principal %s, kvno %d, "
			   "enctype %d\n", princ_s, kt_entry.vno,
			   KRB5_KEY_TYPE(keyp)));

		ret = krb5_kt_start_seq_get(context, keytab, &cursor);
		if (ret) {
			DEBUG(5, ("krb5_kt_start_seq_get failed (%s)\n",
				  error_message(ret)));
			goto cont;
		}

cont:
		smb_krb5_kt_free_entry(context, &kt_entry);
		TALLOC_FREE(princ_s);
	}

	ret = krb5_kt_end_seq_get(context, keytab, &cursor);
	if (ret) {
		DEBUG(5, ("krb5_kt_end_seq_get failed (%s)\n",
			  error_message(ret)));
	}

	return ret;
}
Esempio n. 10
0
int
kt_purge(struct purge_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_kt_cursor cursor;
    krb5_keytab keytab;
    krb5_keytab_entry entry;
    int age;
    struct e *head = NULL;
    time_t judgement_day;

    age = parse_time(opt->age_string, "s");
    if(age < 0) {
	krb5_warnx(context, "unparasable time `%s'", opt->age_string);
	return 1;
    }

    if((keytab = ktutil_open_keytab()) == NULL)
	return 1;

    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    if(ret){
	krb5_warn(context, ret, "%s", keytab_string);
	goto out;
    }

    while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0) {
	add_entry (entry.principal, entry.vno, entry.timestamp, &head);
	krb5_kt_free_entry(context, &entry);
    }
    krb5_kt_end_seq_get(context, keytab, &cursor);

    judgement_day = time (NULL);

    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    if(ret){
	krb5_warn(context, ret, "%s", keytab_string);
	goto out;
    }

    while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0) {
	struct e *e = get_entry (entry.principal, head);

	if (e == NULL) {
	    krb5_warnx (context, "ignoring extra entry");
	    continue;
	}

	if (entry.vno < e->max_vno
	    && judgement_day - e->timestamp > age) {
	    if (verbose_flag) {
		char *name_str;

		krb5_unparse_name (context, entry.principal, &name_str);
		printf ("removing %s vno %d\n", name_str, entry.vno);
		free (name_str);
	    }
	    ret = krb5_kt_remove_entry (context, keytab, &entry);
	    if (ret)
		krb5_warn (context, ret, "remove");
	}
	krb5_kt_free_entry(context, &entry);
    }
    ret = krb5_kt_end_seq_get(context, keytab, &cursor);

    delete_list (head);

 out:
    krb5_kt_close (context, keytab);
    return ret != 0;
}
Esempio n. 11
0
int
kt_rename(struct rename_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab_entry entry;
    krb5_keytab keytab;
    krb5_kt_cursor cursor;
    krb5_principal from_princ, to_princ;

    ret = krb5_parse_name(context, argv[0], &from_princ);
    if(ret != 0) {
	krb5_warn(context, ret, "%s", argv[0]);
	return 1;
    }

    ret = krb5_parse_name(context, argv[1], &to_princ);
    if(ret != 0) {
	krb5_free_principal(context, from_princ);
	krb5_warn(context, ret, "%s", argv[1]);
	return 1;
    }

    if((keytab = ktutil_open_keytab()) == NULL) {
	krb5_free_principal(context, from_princ);
	krb5_free_principal(context, to_princ);
	return 1;
    }

    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    if(ret) {
	krb5_kt_close(context, keytab);
	krb5_free_principal(context, from_princ);
	krb5_free_principal(context, to_princ);
	return 1;
    }
    while(1) {
	ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
	if(ret != 0) {
	    if(ret != KRB5_CC_END && ret != KRB5_KT_END)
		krb5_warn(context, ret, "getting entry from keytab");
	    else
		ret = 0;
	    break;
	}
	if(krb5_principal_compare(context, entry.principal, from_princ)) {
	    krb5_free_principal(context, entry.principal);
	    entry.principal = to_princ;
	    ret = krb5_kt_add_entry(context, keytab, &entry);
	    if(ret) {
		entry.principal = NULL;
		krb5_kt_free_entry(context, &entry);
		krb5_warn(context, ret, "adding entry");
		break;
	    }
	    if (opt->delete_flag) {
		entry.principal = from_princ;
		ret = krb5_kt_remove_entry(context, keytab, &entry);
		if(ret) {
		    entry.principal = NULL;
		    krb5_kt_free_entry(context, &entry);
		    krb5_warn(context, ret, "removing entry");
		    break;
		}
	    }
	    entry.principal = NULL;
	}
	krb5_kt_free_entry(context, &entry);
    }
    krb5_kt_end_seq_get(context, keytab, &cursor);

    krb5_free_principal(context, from_princ);
    krb5_free_principal(context, to_princ);

    return ret != 0;
}
Esempio n. 12
0
static void
test_memory_keytab(krb5_context context, const char *keytab, const char *keytab2)
{
    krb5_error_code ret;
    krb5_keytab id, id2, id3;
    krb5_keytab_entry entry, entry2, entry3;

    ret = krb5_kt_resolve(context, keytab, &id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_resolve");

    memset(&entry, 0, sizeof(entry));
    ret = krb5_parse_name(context, "*****@*****.**", &entry.principal);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");
    entry.vno = 1;
    ret = krb5_generate_random_keyblock(context,
					ETYPE_AES256_CTS_HMAC_SHA1_96,
					&entry.keyblock);
    if (ret)
	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");

    krb5_kt_add_entry(context, id, &entry);

    ret = krb5_kt_resolve(context, keytab, &id2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_resolve");

    ret = krb5_kt_get_entry(context, id,
			    entry.principal,
			    0,
			    ETYPE_AES256_CTS_HMAC_SHA1_96,
			    &entry2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_get_entry");
    krb5_kt_free_entry(context, &entry2);

    ret = krb5_kt_close(context, id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_close");

    ret = krb5_kt_get_entry(context, id2,
			    entry.principal,
			    0,
			    ETYPE_AES256_CTS_HMAC_SHA1_96,
			    &entry2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_get_entry");
    krb5_kt_free_entry(context, &entry2);

    ret = krb5_kt_close(context, id2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_close");


    ret = krb5_kt_resolve(context, keytab2, &id3);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_resolve");

    memset(&entry3, 0, sizeof(entry3));
    ret = krb5_parse_name(context, "*****@*****.**", &entry3.principal);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");
    entry3.vno = 1;
    ret = krb5_generate_random_keyblock(context,
					ETYPE_AES256_CTS_HMAC_SHA1_96,
					&entry3.keyblock);
    if (ret)
	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");

    krb5_kt_add_entry(context, id3, &entry3);


    ret = krb5_kt_resolve(context, keytab, &id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_resolve");

    ret = krb5_kt_get_entry(context, id,
			    entry.principal,
			    0,
			    ETYPE_AES256_CTS_HMAC_SHA1_96,
			    &entry2);
    if (ret == 0)
	krb5_errx(context, 1, "krb5_kt_get_entry when if should fail");

    krb5_kt_remove_entry(context, id, &entry);

    ret = krb5_kt_close(context, id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_close");

    krb5_kt_free_entry(context, &entry);

    krb5_kt_remove_entry(context, id3, &entry3);

    ret = krb5_kt_close(context, id3);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_close");

    krb5_free_principal(context, entry3.principal);
    krb5_free_keyblock_contents(context, &entry3.keyblock);
}
Esempio n. 13
0
static void
kt_test(krb5_context context, const char *name)
{
    krb5_error_code kret;
    krb5_keytab kt;
    const char *type;
    char buf[BUFSIZ];
    char *p;
    krb5_keytab_entry kent, kent2;
    krb5_principal princ;
    krb5_kt_cursor cursor, cursor2;
    int cnt;

    kret = krb5_kt_resolve(context, name, &kt);
    CHECK(kret, "resolve");

    type = krb5_kt_get_type(context, kt);
    CHECK_STR(type, "getting kt type");
    printf("  Type is: %s\n", type);

    kret = krb5_kt_get_name(context, kt, buf, sizeof(buf));
    CHECK(kret, "get_name");
    printf("  Name is: %s\n", buf);

    /* Check that length checks fail */
    /* The buffer is allocated too small - to allow for valgrind test of
       overflows
    */
    p = malloc(strlen(buf));
    kret = krb5_kt_get_name(context, kt, p, 1);
    if(kret != KRB5_KT_NAME_TOOLONG) {
        CHECK(kret, "get_name - size 1");
    }


    kret = krb5_kt_get_name(context, kt, p, strlen(buf));
    if(kret != KRB5_KT_NAME_TOOLONG) {
        CHECK(kret, "get_name");
    }
    free(p);

    /* Try to lookup unknown principal - when keytab does not exist*/
    kret = krb5_parse_name(context, "test/[email protected]", &princ);
    CHECK(kret, "parsing principal");


    kret = krb5_kt_get_entry(context, kt, princ, 0, 0, &kent);
    if((kret != KRB5_KT_NOTFOUND) && (kret != ENOENT)) {
        CHECK(kret, "Getting non-existant entry");
    }


    /* ===================   Add entries to keytab ================= */
    /*
     * Add the following for this principal
     * enctype 1, kvno 1, key = "1"
     * enctype 2, kvno 1, key = "1"
     * enctype 1, kvno 2, key = "2"
     */
    memset(&kent, 0, sizeof(kent));
    kent.magic = KV5M_KEYTAB_ENTRY;
    kent.principal = princ;
    kent.timestamp = 327689;
    kent.vno = 1;
    kent.key.magic = KV5M_KEYBLOCK;
    kent.key.enctype = 1;
    kent.key.length = 1;
    kent.key.contents = (krb5_octet *) "1";


    kret = krb5_kt_add_entry(context, kt, &kent);
    CHECK(kret, "Adding initial entry");

    kent.key.enctype = 2;
    kret = krb5_kt_add_entry(context, kt, &kent);
    CHECK(kret, "Adding second entry");

    kent.key.enctype = 1;
    kent.vno = 2;
    kent.key.contents = (krb5_octet *) "2";
    kret = krb5_kt_add_entry(context, kt, &kent);
    CHECK(kret, "Adding third entry");

    /* Free memory */
    krb5_free_principal(context, princ);

    /* ==============   Test iterating over contents of keytab ========= */

    kret = krb5_kt_start_seq_get(context, kt, &cursor);
    CHECK(kret, "Start sequence get");


    memset(&kent, 0, sizeof(kent));
    cnt = 0;
    while((kret = krb5_kt_next_entry(context, kt, &kent, &cursor)) == 0) {
        if(((kent.vno != 1) && (kent.vno != 2)) ||
           ((kent.key.enctype != 1) && (kent.key.enctype != 2)) ||
           (kent.key.length != 1) ||
           (kent.key.contents[0] != kent.vno +'0')) {
            fprintf(stderr, "Error in read contents\n");
            exit(1);
        }

        if((kent.magic != KV5M_KEYTAB_ENTRY) ||
           (kent.key.magic != KV5M_KEYBLOCK)) {
            fprintf(stderr, "Magic number in sequence not proper\n");
            exit(1);
        }

        cnt++;
        krb5_free_keytab_entry_contents(context, &kent);
    }
    if (kret != KRB5_KT_END) {
        CHECK(kret, "getting next entry");
    }

    if(cnt != 3) {
        fprintf(stderr, "Mismatch in number of entries in keytab");
    }

    kret = krb5_kt_end_seq_get(context, kt, &cursor);
    CHECK(kret, "End sequence get");


    /* ==========================   get_entry tests ============== */

    /* Try to lookup unknown principal  - now that keytab exists*/
    kret = krb5_parse_name(context, "test3/[email protected]", &princ);
    CHECK(kret, "parsing principal");


    kret = krb5_kt_get_entry(context, kt, princ, 0, 0, &kent);
    if((kret != KRB5_KT_NOTFOUND)) {
        CHECK(kret, "Getting non-existant entry");
    }

    krb5_free_principal(context, princ);

    /* Try to lookup known principal */
    kret = krb5_parse_name(context, "test/[email protected]", &princ);
    CHECK(kret, "parsing principal");

    kret = krb5_kt_get_entry(context, kt, princ, 0, 0, &kent);
    CHECK(kret, "looking up principal");

    /* Ensure a valid answer  - we did not specify an enctype or kvno */
    if (!krb5_principal_compare(context, princ, kent.principal) ||
        ((kent.vno != 1) && (kent.vno != 2)) ||
        ((kent.key.enctype != 1) && (kent.key.enctype != 2)) ||
        (kent.key.length != 1) ||
        (kent.key.contents[0] != kent.vno +'0')) {
        fprintf(stderr, "Retrieved principal does not check\n");
        exit(1);
    }

    krb5_free_keytab_entry_contents(context, &kent);

    /* Try to lookup a specific enctype - but unspecified kvno - should give
     * max kvno
     */
    kret = krb5_kt_get_entry(context, kt, princ, 0, 1, &kent);
    CHECK(kret, "looking up principal");

    /* Ensure a valid answer  - we did specified an enctype */
    if (!krb5_principal_compare(context, princ, kent.principal) ||
        (kent.vno != 2) || (kent.key.enctype != 1) ||
        (kent.key.length != 1) ||
        (kent.key.contents[0] != kent.vno +'0')) {
        fprintf(stderr, "Retrieved principal does not check\n");

        exit(1);

    }

    krb5_free_keytab_entry_contents(context, &kent);

    /* Try to lookup unspecified enctype, but a specified kvno */

    kret = krb5_kt_get_entry(context, kt, princ, 2, 0, &kent);
    CHECK(kret, "looking up principal");

    /* Ensure a valid answer  - we did not specify a kvno */
    if (!krb5_principal_compare(context, princ, kent.principal) ||
        (kent.vno != 2) || (kent.key.enctype != 1) ||
        (kent.key.length != 1) ||
        (kent.key.contents[0] != kent.vno +'0')) {
        fprintf(stderr, "Retrieved principal does not check\n");

        exit(1);

    }

    krb5_free_keytab_entry_contents(context, &kent);



    /* Try to lookup specified enctype and kvno */

    kret = krb5_kt_get_entry(context, kt, princ, 1, 1, &kent);
    CHECK(kret, "looking up principal");

    if (!krb5_principal_compare(context, princ, kent.principal) ||
        (kent.vno != 1) || (kent.key.enctype != 1) ||
        (kent.key.length != 1) ||
        (kent.key.contents[0] != kent.vno +'0')) {
        fprintf(stderr, "Retrieved principal does not check\n");

        exit(1);

    }

    krb5_free_keytab_entry_contents(context, &kent);


    /* Try lookup with active iterators.  */
    kret = krb5_kt_start_seq_get(context, kt, &cursor);
    CHECK(kret, "Start sequence get(2)");
    kret = krb5_kt_start_seq_get(context, kt, &cursor2);
    CHECK(kret, "Start sequence get(3)");
    kret = krb5_kt_next_entry(context, kt, &kent, &cursor);
    CHECK(kret, "getting next entry(2)");
    krb5_free_keytab_entry_contents(context, &kent);
    kret = krb5_kt_next_entry(context, kt, &kent, &cursor);
    CHECK(kret, "getting next entry(3)");
    kret = krb5_kt_next_entry(context, kt, &kent2, &cursor2);
    CHECK(kret, "getting next entry(4)");
    krb5_free_keytab_entry_contents(context, &kent2);
    kret = krb5_kt_get_entry(context, kt, kent.principal, 0, 0, &kent2);
    CHECK(kret, "looking up principal(2)");
    krb5_free_keytab_entry_contents(context, &kent2);
    kret = krb5_kt_next_entry(context, kt, &kent2, &cursor2);
    CHECK(kret, "getting next entry(5)");
    if (!krb5_principal_compare(context, kent.principal, kent2.principal)) {
        fprintf(stderr, "iterators not in sync\n");
        exit(1);
    }
    krb5_free_keytab_entry_contents(context, &kent);
    krb5_free_keytab_entry_contents(context, &kent2);
    kret = krb5_kt_next_entry(context, kt, &kent, &cursor);
    CHECK(kret, "getting next entry(6)");
    kret = krb5_kt_next_entry(context, kt, &kent2, &cursor2);
    CHECK(kret, "getting next entry(7)");
    krb5_free_keytab_entry_contents(context, &kent);
    krb5_free_keytab_entry_contents(context, &kent2);
    kret = krb5_kt_end_seq_get(context, kt, &cursor);
    CHECK(kret, "ending sequence get(1)");
    kret = krb5_kt_end_seq_get(context, kt, &cursor2);
    CHECK(kret, "ending sequence get(2)");

    /* Try to lookup specified enctype and kvno  - that does not exist*/

    kret = krb5_kt_get_entry(context, kt, princ, 3, 1, &kent);
    if(kret != KRB5_KT_KVNONOTFOUND) {
        CHECK(kret, "looking up specific principal, kvno, enctype");
    }

    krb5_free_principal(context, princ);


    /* =========================   krb5_kt_remove_entry =========== */
    /* Lookup the keytab entry w/ 2 kvno - and delete version 2 -
       ensure gone */
    kret = krb5_parse_name(context, "test/[email protected]", &princ);
    CHECK(kret, "parsing principal");

    kret = krb5_kt_get_entry(context, kt, princ, 0, 1, &kent);
    CHECK(kret, "looking up principal");

    /* Ensure a valid answer  - we are looking for max(kvno) and enc=1 */
    if (!krb5_principal_compare(context, princ, kent.principal) ||
        (kent.vno != 2) || (kent.key.enctype != 1) ||
        (kent.key.length != 1) ||
        (kent.key.contents[0] != kent.vno +'0')) {
        fprintf(stderr, "Retrieved principal does not check\n");

        exit(1);

    }

    /* Delete it */
    kret = krb5_kt_remove_entry(context, kt, &kent);
    CHECK(kret, "Removing entry");

    krb5_free_keytab_entry_contents(context, &kent);
    /* And ensure gone */

    kret = krb5_kt_get_entry(context, kt, princ, 0, 1, &kent);
    CHECK(kret, "looking up principal");

    /* Ensure a valid answer - kvno should now be 1 - we deleted 2 */
    if (!krb5_principal_compare(context, princ, kent.principal) ||
        (kent.vno != 1) || (kent.key.enctype != 1) ||
        (kent.key.length != 1) ||
        (kent.key.contents[0] != kent.vno +'0')) {
        fprintf(stderr, "Delete principal check failed\n");

        exit(1);

    }
    krb5_free_keytab_entry_contents(context, &kent);

    krb5_free_principal(context, princ);

    /* =======================  Finally close =======================  */

    kret = krb5_kt_close(context, kt);
    CHECK(kret, "close");

}
Esempio n. 14
0
static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
        int kvno,
        krb5_principal *principals,
        bool delete_all_kvno,
        krb5_context context,
        krb5_keytab keytab,
        bool *found_previous,
        const char **error_string)
{
    krb5_error_code ret, ret2;
    krb5_kt_cursor cursor;
    TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);

    if (!mem_ctx) {
        return ENOMEM;
    }

    *found_previous = false;

    /* for each entry in the keytab */
    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    switch (ret) {
    case 0:
        break;
#ifdef HEIM_ERR_OPNOTSUPP
    case HEIM_ERR_OPNOTSUPP:
#endif
    case ENOENT:
    case KRB5_KT_END:
        /* no point enumerating if there isn't anything here */
        talloc_free(mem_ctx);
        return 0;
    default:
        *error_string = talloc_asprintf(parent_ctx,
                                        "failed to open keytab for read of old entries: %s\n",
                                        smb_get_krb5_error_message(context, ret, mem_ctx));
        talloc_free(mem_ctx);
        return ret;
    }

    while (!ret) {
        unsigned int i;
        bool matched = false;
        krb5_keytab_entry entry;
        ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
        if (ret) {
            break;
        }
        for (i = 0; principals[i]; i++) {
            /* if it matches our principal */
            if (smb_krb5_kt_compare(context, &entry,
                                    principals[i], 0, 0)) {
                matched = true;
                break;
            }
        }

        if (!matched) {
            /* Free the entry,
             * it wasn't the one we were looking for anyway */
            krb5_kt_free_entry(context, &entry);
            continue;
        }

        /* delete it, if it is not kvno -1 */
        if (entry.vno != (kvno - 1 )) {
            /* Release the enumeration.  We are going to
             * have to start this from the top again,
             * because deletes during enumeration may not
             * always be consistent.
             *
             * Also, the enumeration locks a FILE: keytab
             */

            krb5_kt_end_seq_get(context, keytab, &cursor);

            ret = krb5_kt_remove_entry(context, keytab, &entry);
            krb5_kt_free_entry(context, &entry);

            /* Deleted: Restart from the top */
            ret2 = krb5_kt_start_seq_get(context, keytab, &cursor);
            if (ret2) {
                krb5_kt_free_entry(context, &entry);
                DEBUG(1, ("failed to restart enumeration of keytab: %s\n",
                          smb_get_krb5_error_message(context,
                                                     ret, mem_ctx)));

                talloc_free(mem_ctx);
                return ret2;
            }

            if (ret) {
                break;
            }

        } else {
            *found_previous = true;
        }

        /* Free the entry, we don't need it any more */
        krb5_kt_free_entry(context, &entry);
    }
    krb5_kt_end_seq_get(context, keytab, &cursor);

    switch (ret) {
    case 0:
        break;
    case ENOENT:
    case KRB5_KT_END:
        ret = 0;
        break;
    default:
        *error_string = talloc_asprintf(parent_ctx,
                                        "failed in deleting old entries for principal: %s\n",
                                        smb_get_krb5_error_message(context, ret, mem_ctx));
    }
    talloc_free(mem_ctx);
    return ret;
}
Esempio n. 15
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_keytab kt;
    krb5_keytab_entry ktent;
    krb5_encrypt_block eblock;
    krb5_creds my_creds;
    krb5_get_init_creds_opt *opt;
    kadm5_principal_ent_rec princ_ent;
    krb5_principal princ, server;
    char pw[16];
    char *whoami, *principal, *authprinc, *authpwd;
    krb5_data pwdata;
    void *handle;
    int ret, test, encnum;
    unsigned int i;

    whoami = argv[0];

    if (argc < 2 || argc > 4) {
        fprintf(stderr, "Usage: %s principal [authuser] [authpwd]\n", whoami);
        exit(1);
    }
    principal = argv[1];
    authprinc = (argc > 2) ? argv[2] : argv[0];
    authpwd = (argc > 3) ? argv[3] : NULL;

    /*
     * Setup.  Initialize data structures, open keytab, open connection
     * to kadm5 server.
     */

    memset(&context, 0, sizeof(context));
    kadm5_init_krb5_context(&context);

    ret = krb5_parse_name(context, principal, &princ);
    if (ret) {
        com_err(whoami, ret, "while parsing principal name %s", principal);
        exit(1);
    }

    if((ret = krb5_build_principal_ext(context, &server,
                                       krb5_princ_realm(kcontext, princ)->length,
                                       krb5_princ_realm(kcontext, princ)->data,
                                       tgtname.length, tgtname.data,
                                       krb5_princ_realm(kcontext, princ)->length,
                                       krb5_princ_realm(kcontext, princ)->data,
                                       0))) {
        com_err(whoami, ret, "while building server name");
        exit(1);
    }

    ret = krb5_kt_default(context, &kt);
    if (ret) {
        com_err(whoami, ret, "while opening keytab");
        exit(1);
    }

    ret = kadm5_init(context, authprinc, authpwd, KADM5_ADMIN_SERVICE, NULL,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
                     &handle);
    if (ret) {
        com_err(whoami, ret, "while initializing connection");
        exit(1);
    }

    /* these pw's don't need to be secure, just different every time */
    SRAND((RAND_TYPE)time((void *) NULL));
    pwdata.data = pw;
    pwdata.length = sizeof(pw);

    /*
     * For each test:
     *
     * For each enctype in the test, construct a random password/key.
     * Assign all keys to principal with kadm5_setkey_principal.  Add
     * each key to the keytab, and acquire an initial ticket with the
     * keytab (XXX can I specify the kvno explicitly?).  If
     * krb5_get_init_creds_keytab succeeds, then the keys were set
     * successfully.
     */
    for (test = 0; tests[test] != NULL; test++) {
        krb5_keyblock *testp = tests[test];
        kadm5_key_data *extracted;
        int n_extracted, match;
        printf("+ Test %d:\n", test);

        for (encnum = 0; testp[encnum].magic != -1; encnum++) {
            for (i = 0; i < sizeof(pw); i++)
                pw[i] = (RAND() % 26) + '0'; /* XXX */

            krb5_use_enctype(context, &eblock, testp[encnum].enctype);
            ret = krb5_string_to_key(context, &eblock, &testp[encnum],
                                     &pwdata, NULL);
            if (ret) {
                com_err(whoami, ret, "while converting string to key");
                exit(1);
            }
        }

        /* now, encnum == # of keyblocks in testp */
        ret = kadm5_setkey_principal(handle, princ, testp, encnum);
        if (ret) {
            com_err(whoami, ret, "while setting keys");
            exit(1);
        }

        ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO);
        if (ret) {
            com_err(whoami, ret, "while retrieving principal");
            exit(1);
        }

        ret = kadm5_get_principal_keys(handle, princ, 0, &extracted,
                                       &n_extracted);
        if (ret) {
            com_err(whoami, ret, "while extracting keys");
            exit(1);
        }

        for (encnum = 0; testp[encnum].magic != -1; encnum++) {
            printf("+   enctype %d\n", testp[encnum].enctype);

            for (match = 0; match < n_extracted; match++) {
                if (extracted[match].key.enctype == testp[encnum].enctype)
                    break;
            }
            if (match >= n_extracted) {
                com_err(whoami, KRB5_WRONG_ETYPE, "while matching enctypes");
                exit(1);
            }
            if (extracted[match].key.length != testp[encnum].length ||
                memcmp(extracted[match].key.contents, testp[encnum].contents,
                       testp[encnum].length) != 0) {
                com_err(whoami, KRB5_KDB_NO_MATCHING_KEY, "verifying keys");
                exit(1);
            }

            memset(&ktent, 0, sizeof(ktent));
            ktent.principal = princ;
            ktent.key = testp[encnum];
            ktent.vno = princ_ent.kvno;

            ret = krb5_kt_add_entry(context, kt, &ktent);
            if (ret) {
                com_err(whoami, ret, "while adding keytab entry");
                exit(1);
            }

            memset(&my_creds, 0, sizeof(my_creds));
            my_creds.client = princ;
            my_creds.server = server;

            ktypes[0] = testp[encnum].enctype;
            ret = krb5_get_init_creds_opt_alloc(context, &opt);
            if (ret) {
                com_err(whoami, ret, "while allocating gic opts");
                exit(1);
            }
            krb5_get_init_creds_opt_set_etype_list(opt, ktypes, 1);
            ret = krb5_get_init_creds_keytab(context, &my_creds, princ,
                                             kt, 0, NULL /* in_tkt_service */,
                                             opt);
            krb5_get_init_creds_opt_free(context, opt);
            if (ret) {
                com_err(whoami, ret, "while acquiring initial ticket");
                exit(1);
            }
            krb5_free_cred_contents(context, &my_creds);

            /* since I can't specify enctype explicitly ... */
            ret = krb5_kt_remove_entry(context, kt, &ktent);
            if (ret) {
                com_err(whoami, ret, "while removing keytab entry");
                exit(1);
            }
        }

        (void)kadm5_free_kadm5_key_data(context, n_extracted, extracted);
    }

    ret = krb5_kt_close(context, kt);
    if (ret) {
        com_err(whoami, ret, "while closing keytab");
        exit(1);
    }

    ret = kadm5_destroy(handle);
    if (ret) {
        com_err(whoami, ret, "while closing kadmin connection");
        exit(1);
    }

    krb5_free_principal(context, princ);
    krb5_free_principal(context, server);
    krb5_free_context(context);
    return 0;
}
Esempio n. 16
0
static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
					  struct cli_credentials *machine_account,
					  struct smb_krb5_context *smb_krb5_context,
					  krb5_keytab keytab, BOOL *found_previous)
{
	krb5_error_code ret, ret2;
	krb5_kt_cursor cursor;
	krb5_principal princ;
	int kvno;
	TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
	const char *princ_string;
	if (!mem_ctx) {
		return ENOMEM;
	}

	*found_previous = False;
	princ_string = cli_credentials_get_principal(machine_account, mem_ctx);

	/* Get the principal we will store the new keytab entries under */
	ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ);
	if (ret) {
		DEBUG(1,("update_keytab: makeing krb5 principal failed (%s)\n",
			 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
						    ret, mem_ctx)));
		talloc_free(mem_ctx);
		return ret;
	}

	kvno = cli_credentials_get_kvno(machine_account);

	/* for each entry in the keytab */
	ret = krb5_kt_start_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);
	switch (ret) {
	case 0:
		break;
	case HEIM_ERR_OPNOTSUPP:
	case ENOENT:
	case KRB5_KT_END:
		/* no point enumerating if there isn't anything here */
		talloc_free(mem_ctx);
		return 0;
	default:
		DEBUG(1,("failed to open keytab for read of old entries: %s\n",
			 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
						    ret, mem_ctx)));
		talloc_free(mem_ctx);
		return ret;
	}

	while (!ret) {
		krb5_keytab_entry entry;
		ret = krb5_kt_next_entry(smb_krb5_context->krb5_context, keytab, &entry, &cursor);
		if (ret) {
			break;
		}
		/* if it matches our principal */
		if (!krb5_kt_compare(smb_krb5_context->krb5_context, &entry, princ, 0, 0)) {
			/* Free the entry, it wasn't the one we were looking for anyway */
			krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
			continue;
		}

		/* delete it, if it is not kvno -1 */
		if (entry.vno != (kvno - 1 )) {
			/* Release the enumeration.  We are going to
			 * have to start this from the top again,
			 * because deletes during enumeration may not
			 * always be consistant.
			 *
			 * Also, the enumeration locks a FILE: keytab
			 */
		
			krb5_kt_end_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);

			ret = krb5_kt_remove_entry(smb_krb5_context->krb5_context, keytab, &entry);
			krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);

			/* Deleted: Restart from the top */
			ret2 = krb5_kt_start_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);
			if (ret2) {
				krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
				DEBUG(1,("failed to restart enumeration of keytab: %s\n",
					 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
								    ret, mem_ctx)));
				
				talloc_free(mem_ctx);
				return ret2;
			}

			if (ret) {
				break;
			}
			
		} else {
			*found_previous = True;
		}
		
		/* Free the entry, we don't need it any more */
		krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
		
		
	}
	krb5_kt_end_seq_get(smb_krb5_context->krb5_context, keytab, &cursor);

	switch (ret) {
	case 0:
		break;
	case ENOENT:
	case KRB5_KT_END:
		ret = 0;
		break;
	default:
		DEBUG(1,("failed in deleting old entries for principal: %s: %s\n",
			 princ_string, 
			 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
						    ret, mem_ctx)));
	}
	talloc_free(mem_ctx);
	return ret;
}