if (opts->principal_name)
{
- if (opts->anonymous) {
- code = krb5_build_principal_ext(k5->ctx, &k5->me, strlen(opts->principal_name),
- opts->principal_name,
- strlen(KRB5_WELLKNOWN_NAMESTR), KRB5_WELLKNOWN_NAMESTR,
- strlen(KRB5_ANONYMOUS_PRINCSTR),
- KRB5_ANONYMOUS_PRINCSTR, 0);
- if (code) {
- com_err(progname, code, "while setting up anonymous principal");
- return 0;
- }
- } else {
- /* Use specified name */
- if ((code = krb5_parse_name_flags(k5->ctx, opts->principal_name,
- flags, &k5->me))) {
- com_err(progname, code, "when parsing name %s",
- opts->principal_name);
- return 0;
- }
+ /* Use specified name */
+ if ((code = krb5_parse_name_flags(k5->ctx, opts->principal_name,
+ flags, &k5->me))) {
+ com_err(progname, code, "when parsing name %s",
+ opts->principal_name);
+ return 0;
}
}
else
{
/* No principal name specified */
if (opts->anonymous) {
- fprintf(stderr, "%s: please specify realm for anonymous authentication\n", progname);
- return 0;
- }
- if (opts->action == INIT_KT) {
- /* Use the default host/service name */
- code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
- KRB5_NT_SRV_HST, &k5->me);
+ char *defrealm;
+ code = krb5_get_default_realm(k5->ctx, &defrealm);
if (code) {
- com_err(progname, code,
- "when creating default server principal name");
+ com_err(progname, code, "while getting default realm");
return 0;
}
- if (k5->me->realm.data[0] == 0) {
- code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
- if (code == 0)
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
- "(principal %s)", k5->name);
- else
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
- "for local services");
+ code = krb5_build_principal_ext(k5->ctx, &k5->me,
+ strlen(defrealm), defrealm,
+ strlen(KRB5_WELLKNOWN_NAMESTR), KRB5_WELLKNOWN_NAMESTR,
+ strlen(KRB5_ANONYMOUS_PRINCSTR), KRB5_ANONYMOUS_PRINCSTR,
+ 0);
+ krb5_free_default_realm( k5->ctx, defrealm);
+ if (code) {
+ com_err(progname, code, "while building principal");
return 0;
}
} else {
- /* Get default principal from cache if one exists */
- code = krb5_cc_get_principal(k5->ctx, k5->cc,
- &k5->me);
- if (code)
- {
- char *name = get_name_from_os();
- if (!name)
- {
- fprintf(stderr, "Unable to identify user\n");
+ if (opts->action == INIT_KT) {
+ /* Use the default host/service name */
+ code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
+ KRB5_NT_SRV_HST, &k5->me);
+ if (code) {
+ com_err(progname, code,
+ "when creating default server principal name");
return 0;
}
- if ((code = krb5_parse_name_flags(k5->ctx, name,
- flags, &k5->me)))
- {
- com_err(progname, code, "when parsing name %s",
- name);
+ if (k5->me->realm.data[0] == 0) {
+ code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
+ if (code == 0)
+ com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
+ "(principal %s)", k5->name);
+ else
+ com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
+ "for local services");
return 0;
}
+ } else {
+ /* Get default principal from cache if one exists */
+ code = krb5_cc_get_principal(k5->ctx, k5->cc,
+ &k5->me);
+ if (code)
+ {
+ char *name = get_name_from_os();
+ if (!name)
+ {
+ fprintf(stderr, "Unable to identify user\n");
+ return 0;
+ }
+ if ((code = krb5_parse_name_flags(k5->ctx, name,
+ flags, &k5->me)))
+ {
+ com_err(progname, code, "when parsing name %s",
+ name);
+ return 0;
+ }
+ }
}
}
}
krb5_get_init_creds_opt_set_proxiable(options, 0);
if (opts->canonicalize)
krb5_get_init_creds_opt_set_canonicalize(options, 1);
+ if (opts->anonymous)
+ krb5_get_init_creds_opt_set_anonymous(options, 1);
if (opts->addresses)
{
krb5_address **addresses = NULL;
#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
#define KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT 0x0100
#define KRB5_GET_INIT_CREDS_OPT_CANONICALIZE 0x0200
+#define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS 0x0400
krb5_error_code KRB5_CALLCONV
krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opt,
int canonicalize);
+/**
+ * Request anonymous credentials from the KDC. If the client name looks like
+ * "@REALM" (an empty principal name), then fully anonymous credentials are
+ * requested. If the client name looks like "name@REALM," then credentials
+ * tied to a specific realm are requested.
+ *
+ * Credentials tied to a specific realm are not supported in this version.
+ *
+ * Note that anonymous credentials are only a request; clients must verify that
+ * credentials are anonymous if that is a requirement.
+ */
+krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt *opt,
+ int anonymous);
+
void KRB5_CALLCONV
krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
krb5_enctype *etype_list,
*/
canon_req = ((request->kdc_options & KDC_OPT_CANONICALIZE) != 0) ||
(krb5_princ_type(context, request->client) == KRB5_NT_ENTERPRISE_PRINCIPAL)
- || (krb5_principal_compare_any_realm(context, request->client,
- krb5_anonymous_principal()));
+ || (request->kdc_options & KDC_OPT_REQUEST_ANONYMOUS);
if (canon_req) {
canon_ok = IS_TGS_PRINC(context, request->server) &&
IS_TGS_PRINC(context, as_reply->enc_part2->server);
if ((!canon_ok ) && (request->kdc_options &KDC_OPT_REQUEST_ANONYMOUS))
- canon_ok = krb5_principal_compare(context, as_reply->client,
+ canon_ok = krb5_principal_compare_any_realm(context, as_reply->client,
krb5_anonymous_principal());
} else
canon_ok = 0;
}
/*Anonymous*/
+ if(opte->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) {
+ ctx->request->kdc_options |= KDC_OPT_REQUEST_ANONYMOUS;
+ /*Remap @REALM to WELLKNOWN/ANONYMOUS@REALM*/
+ if (client->length == 1 && client->data[0].length ==0) {
+ krb5_principal new_client;
+ code = krb5_build_principal_ext(context, &new_client, client->realm.length,
+ client->realm.data,
+ strlen(KRB5_WELLKNOWN_NAMESTR),
+ KRB5_WELLKNOWN_NAMESTR,
+ strlen(KRB5_ANONYMOUS_PRINCSTR),
+ KRB5_ANONYMOUS_PRINCSTR,
+ 0);
+ if (code)
+ goto cleanup;
+ krb5_free_principal(context, ctx->request->client);
+ ctx->request->client = new_client;
+ krb5_princ_type(context, ctx->request->client) = KRB5_NT_WELLKNOWN;
+ }
+ }
+ /*We will also handle anonymous if the input principal is the anonymous principal*/
if (krb5_principal_compare_any_realm(context, ctx->request->client,
krb5_anonymous_principal())) {
ctx->request->kdc_options |= KDC_OPT_REQUEST_ANONYMOUS;