/* * call-seq: * krb.set_default_realm(realm = nil) * * Sets the default realm to +realm+. If no argument is provided, then the * default realm in your krb5.conf file is used. */ static VALUE rkrb5_set_default_realm(int argc, VALUE* argv, VALUE self){ RUBY_KRB5* ptr; VALUE v_realm; char* realm; krb5_error_code kerror; Data_Get_Struct(self, RUBY_KRB5, ptr); rb_scan_args(argc, argv, "01", &v_realm); if(NIL_P(v_realm)){ realm = NULL; } else{ Check_Type(v_realm, T_STRING); realm = StringValueCStr(v_realm); } kerror = krb5_set_default_realm(ptr->ctx, realm); if(kerror) rb_raise(cKrb5Exception, "krb5_set_default_realm: %s", error_message(kerror)); return self; }
/* * Serialize krb5_context. */ static krb5_error_code ser_kcontext_test(krb5_context kcontext, int verbose) { krb5_error_code kret; profile_t sprofile; char dbname[128]; snprintf(dbname, sizeof(dbname), "temp_%d", (int) getpid()); sprofile = kcontext->profile; kcontext->profile = (profile_t) NULL; if (!(kret = ser_data(verbose, "> Context with no profile", (krb5_pointer) kcontext, KV5M_CONTEXT))) { kcontext->profile = sprofile; if (!(kret = ser_data(verbose, "> Context with no realm", (krb5_pointer) kcontext, KV5M_CONTEXT)) && !(kret = krb5_set_default_realm(kcontext, "this.is.a.test"))) { if (!(kret = ser_data(verbose, "> Context with default realm", (krb5_pointer) kcontext, KV5M_CONTEXT))) { if (verbose) printf("* krb5_context test succeeded\n"); } } } if (kret) printf("* krb5_context test failed\n"); return(kret); }
krb5_error_code smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx, struct tevent_context *ev, struct loadparm_context *lp_ctx, krb5_context *_krb5_context) { krb5_error_code ret; char **config_files; const char *config_file, *realm; krb5_context krb5_ctx; initialize_krb5_error_table(); ret = krb5_init_context(&krb5_ctx); if (ret) { DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); return ret; } config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf"); if (!config_file) { krb5_free_context(krb5_ctx); return ENOMEM; } /* Use our local krb5.conf file by default */ ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files); if (ret) { DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n", smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx))); krb5_free_context(krb5_ctx); return ret; } ret = krb5_set_config_files(krb5_ctx, config_files); krb5_free_config_files(config_files); if (ret) { DEBUG(1,("krb5_set_config_files failed (%s)\n", smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx))); krb5_free_context(krb5_ctx); return ret; } realm = lp_realm(lp_ctx); if (realm != NULL) { ret = krb5_set_default_realm(krb5_ctx, realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx))); krb5_free_context(krb5_ctx); return ret; } } *_krb5_context = krb5_ctx; return 0; }
static void test_set_default_realm(krb5_context ctx, char *realm) { krb5_error_code retval; retval = krb5_set_default_realm(ctx, realm); if (retval) { com_err("krb5_set_default_realm", retval, 0); return; } printf("krb5_set_default_realm(%s)\n", realm); }
int main(int argc, char **argv) { krb5_context ctx, ctx2; krb5_plugin_initvt_fn *mods; const krb5_enctype etypes1[] = { ENCTYPE_DES3_CBC_SHA1, 0 }; const krb5_enctype etypes2[] = { ENCTYPE_AES128_CTS_HMAC_SHA1_96, ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 }; krb5_prompt_type ptypes[] = { KRB5_PROMPT_TYPE_PASSWORD }; /* Copy a default context and verify the result. */ check(krb5_init_context(&ctx) == 0); check(krb5_copy_context(ctx, &ctx2) == 0); check_context(ctx2, ctx); krb5_free_context(ctx2); /* Set non-default values for all of the propagated fields in ctx. */ ctx->allow_weak_crypto = TRUE; check(krb5_set_default_in_tkt_ktypes(ctx, etypes1) == 0); check(krb5_set_default_tgs_enctypes(ctx, etypes2) == 0); check(krb5_set_debugging_time(ctx, 1234, 5678) == 0); check(krb5_cc_set_default_name(ctx, "defccname") == 0); check(krb5_set_default_realm(ctx, "defrealm") == 0); ctx->clockskew = 18; ctx->kdc_req_sumtype = CKSUMTYPE_NIST_SHA; ctx->default_ap_req_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES128; ctx->default_safe_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES256; ctx->kdc_default_options = KDC_OPT_FORWARDABLE; ctx->library_options = 0; ctx->profile_secure = TRUE; ctx->udp_pref_limit = 2345; ctx->use_conf_ktypes = TRUE; ctx->ignore_acceptor_hostname = TRUE; ctx->dns_canonicalize_hostname = CANONHOST_FALSE; free(ctx->plugin_base_dir); check((ctx->plugin_base_dir = strdup("/a/b/c/d")) != NULL); /* Also set some of the non-propagated fields. */ ctx->prompt_types = ptypes; check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &mods) == 0); k5_plugin_free_modules(ctx, mods); k5_setmsg(ctx, ENOMEM, "nooooooooo"); krb5_set_trace_callback(ctx, trace, ctx); /* Copy the intentionally messy context and verify the result. */ check(krb5_copy_context(ctx, &ctx2) == 0); check_context(ctx2, ctx); krb5_free_context(ctx2); krb5_free_context(ctx); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_get_default_realms (krb5_context context, krb5_realm **realms) { if (context->default_realms == NULL) { krb5_error_code ret = krb5_set_default_realm (context, NULL); if (ret) return KRB5_CONFIG_NODEFREALM; } return krb5_copy_host_realm (context, context->default_realms, realms); }
fnasso_error fnasso_kdc_init(fnasso_context *ctx) { F_BEGIN(); krb5_error_code kerberos_error; krb5_context *context; if (!ctx->kdc) { ctx->kdc = (fnasso_kdc*) calloc(1, sizeof(fnasso_kdc)); } if (!ctx->kdc->kctx) { context = ctx->kdc->kctx = (krb5_context *) malloc(sizeof (krb5_context)); kerberos_error = krb5_init_context(context); if (kerberos_error) { fnasso_kdc_free(ctx); E_RETURN(FNASSO_ERR_EXTERNAL, "krb5_init_context", error_message(kerberos_error)); } DEBUG("krb5_init_context OK"); } else { context = ctx->kdc->kctx; DEBUG("context allready initialized"); } // Setup the right roaming kerberos realm if (ctx->roaming_realm) { EVENT("found kerberos roaming realm (%s), overwriting default realm", ctx->roaming_realm); kerberos_error = krb5_set_default_realm(*context, ctx->roaming_realm); if (kerberos_error) { fnasso_kdc_free(ctx); E_RETURN(FNASSO_ERR_EXTERNAL, "krb5_set_default_realm", error_message(kerberos_error)); } DEBUG("krb5_set_default_realm OK"); } else { WARN("default realm not found in context, using default realm from /etc/krb5.conf"); } RETURN(FNASSO_ERR_NONE); }
int main(int argc, char **argv) { struct testcase *t; krb5_context context; krb5_error_code ret; int val = 0; ret = krb5_init_context (&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); /* to enable realm-less principal name above */ krb5_set_default_realm(context, ""); for (t = tests; t->principal_name; ++t) { krb5_keyblock key; krb5_principal principal; int i; ret = krb5_parse_name (context, t->principal_name, &principal); if (ret) krb5_err (context, 1, ret, "krb5_parse_name %s", t->principal_name); ret = krb5_string_to_key (context, t->enctype, t->password, principal, &key); if (ret) krb5_err (context, 1, ret, "krb5_string_to_key"); krb5_free_principal (context, principal); if (memcmp (key.keyvalue.data, t->res, key.keyvalue.length) != 0) { const unsigned char *p = key.keyvalue.data; printf ("string_to_key(%s, %s) failed\n", t->principal_name, t->password); printf ("should be: "); for (i = 0; i < key.keyvalue.length; ++i) printf ("%02x", t->res[i]); printf ("\nresult was: "); for (i = 0; i < key.keyvalue.length; ++i) printf ("%02x", p[i]); printf ("\n"); val = 1; } krb5_free_keyblock_contents(context, &key); } krb5_free_context(context); return val; }
static krb5_context e2k_kerberos_context_new (const char *domain) { krb5_context ctx; char *realm; if (krb5_init_context (&ctx) != 0) return NULL; realm = g_ascii_strup (domain, strlen (domain)); krb5_set_default_realm (ctx, realm); g_free (realm); return ctx; }
void ceo_krb5_init() { krb5_error_code retval; set_com_err_hook(com_err_hk); debug("krb5: initializing context"); retval = krb5_init_context(&context); if (retval) com_err(prog, retval, "while initializing krb5"); retval = krb5_set_default_realm(context, krb5_realm); if (retval) com_err(prog, retval, "while setting default realm"); }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_get_default_realm(krb5_context context, krb5_realm *realm) { krb5_error_code ret; char *res; if (context->default_realms == NULL || context->default_realms[0] == NULL) { krb5_clear_error_message(context); ret = krb5_set_default_realm (context, NULL); if (ret) return ret; } res = strdup (context->default_realms[0]); if (res == NULL) return krb5_enomem(context); *realm = res; return 0; }
fnasso_error fnasso_context_set_roaming_realm(fnasso_context *ctx, const char* roaming_realm) { F_BEGIN(); krb5_error_code kerberos_error; if (!ctx) E_RETURN(FNASSO_ERR_NO_CONTEXT_SUPPLIED); if (!roaming_realm) { if (ctx->roaming_realm) free(ctx->roaming_realm); ctx->roaming_realm = NULL; EVENT("roaming realm restored to default realm in /etc/krb5.conf"); } else { if (strlen(roaming_realm)) { ctx->roaming_realm = (char *) realloc(ctx->roaming_realm, strlen(roaming_realm) + 1); strcpy(ctx->roaming_realm, roaming_realm); EVENT("roaming realm is now (%s)", ctx->roaming_realm); } else { E_RETURN(FNASSO_ERR_NO_ROAMING_REALM); } } if (ctx->kdc && ctx->kdc->kctx) { EVENT("updating current KDC default realm"); kerberos_error = krb5_set_default_realm(*ctx->kdc->kctx, ctx->roaming_realm); if (kerberos_error) { fnasso_kdc_free(ctx); E_RETURN(FNASSO_ERR_EXTERNAL, "krb5_set_default_realm", error_message(kerberos_error)); } DEBUG("krb5_set_default_realm OK"); } RETURN(FNASSO_ERR_NONE); }
int afscp_SetDefaultRealm(const char *realmname) { char *newdefrealm; #ifdef HAVE_KERBEROS /* krb5_error_code k5ec; */ krb5_context k5con; int code; if (realmname == NULL) { if (defrealm != NULL) free(defrealm); defrealm = NULL; return 0; } code = krb5_init_context(&k5con); /* see aklog.c main() */ if (code != 0) { return -1; } /* k5ec = */ krb5_set_default_realm(k5con, realmname); /* if (k5ec != KRB5KDC_ERR_NONE) { * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE); * return -1; * } */ /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */ #endif /* HAVE_KERBEROS */ newdefrealm = strdup(realmname); if (newdefrealm == NULL) { return -1; } if (defrealm != NULL) free(defrealm); defrealm = newdefrealm; return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_get_default_realm(krb5_context context, krb5_realm *realm) { krb5_error_code ret; char *res; if (context->default_realms == NULL || context->default_realms[0] == NULL) { krb5_clear_error_message(context); ret = krb5_set_default_realm (context, NULL); if (ret) return ret; } res = strdup (context->default_realms[0]); if (res == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } *realm = res; return 0; }
NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, const char *realm, time_t time_offset, const DATA_BLOB *ticket, char **principal, struct PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key, bool use_replay_cache) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; NTSTATUS pac_ret; DATA_BLOB auth_data; krb5_context context = NULL; krb5_auth_context auth_context = NULL; krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; krb5_keyblock *keyblock = NULL; time_t authtime; krb5_error_code ret = 0; int flags = 0; krb5_principal host_princ = NULL; krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; bool auth_ok = False; bool got_auth_data = False; struct named_mutex *mutex = NULL; ZERO_STRUCT(packet); ZERO_STRUCT(auth_data); *principal = NULL; *pac_data = NULL; *ap_rep = data_blob_null; *session_key = data_blob_null; initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } if (time_offset != 0) { krb5_set_real_time(context, time(NULL) + time_offset, 0); } ret = krb5_set_default_realm(context, realm); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); goto out; } /* This whole process is far more complex than I would like. We have to go through all this to allow us to store the secret internally, instead of using /etc/krb5.keytab */ ret = krb5_auth_con_init(context, &auth_context); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); goto out; } krb5_auth_con_getflags( context, auth_context, &flags ); if ( !use_replay_cache ) { /* Disable default use of a replay cache */ flags &= ~KRB5_AUTH_CONTEXT_DO_TIME; krb5_auth_con_setflags( context, auth_context, flags ); } if (asprintf(&host_princ_s, "%s$", global_myname()) == -1) { goto out; } strlower_m(host_princ_s); ret = smb_krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("ads_verify_ticket: smb_krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); goto out; } if ( use_replay_cache ) { /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 code surrounding the replay cache... */ mutex = grab_named_mutex(talloc_tos(), "replay cache mutex", 10); if (mutex == NULL) { DEBUG(1,("ads_verify_ticket: unable to protect " "replay cache with mutex.\n")); ret = KRB5_CC_IO; goto out; } /* JRA. We must set the rcache here. This will prevent replay attacks. */ ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache " "failed (%s)\n", error_message(ret))); goto out; } ret = krb5_auth_con_setrcache(context, auth_context, rcache); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache " "failed (%s)\n", error_message(ret))); goto out; } } /* Try secrets.tdb first and fallback to the krb5.keytab if necessary */ auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, ticket, &tkt, &keyblock, &ret); if (!auth_ok && (ret == KRB5KRB_AP_ERR_TKT_NYV || ret == KRB5KRB_AP_ERR_TKT_EXPIRED || ret == KRB5KRB_AP_ERR_SKEW)) { goto auth_failed; } if (!auth_ok && lp_use_kerberos_keytab()) { auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &tkt, &keyblock, &ret); } if ( use_replay_cache ) { TALLOC_FREE(mutex); #if 0 /* Heimdal leaks here, if we fix the leak, MIT crashes */ if (rcache) { krb5_rc_close(context, rcache); } #endif } auth_failed: if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); /* Try map the error return in case it's something like * a clock skew error. */ sret = krb5_to_nt_status(ret); if (NT_STATUS_IS_OK(sret) || NT_STATUS_EQUAL(sret,NT_STATUS_UNSUCCESSFUL)) { sret = NT_STATUS_LOGON_FAILURE; } DEBUG(10,("ads_verify_ticket: returning error %s\n", nt_errstr(sret) )); goto out; } authtime = get_authtime_from_tkt(tkt); client_principal = get_principal_from_tkt(tkt); ret = krb5_mk_rep(context, auth_context, &packet); if (ret) { DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", error_message(ret))); goto out; } *ap_rep = data_blob(packet.data, packet.length); if (packet.data) { kerberos_free_data_contents(context, &packet); ZERO_STRUCT(packet); } get_krb5_smb_session_key(context, auth_context, session_key, True); dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif /* continue when no PAC is retrieved or we couldn't decode the PAC (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, or Kerberos tickets encrypted using a DES key) - Guenther */ got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt); if (!got_auth_data) { DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n")); } if (got_auth_data) { pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); if (!NT_STATUS_IS_OK(pac_ret)) { DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret))); *pac_data = NULL; } data_blob_free(&auth_data); } #if 0 #if defined(HAVE_KRB5_TKT_ENC_PART2) /* MIT */ if (tkt->enc_part2) { file_save("/tmp/authdata.dat", tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); } #else /* Heimdal */ if (tkt->ticket.authorization_data) { file_save("/tmp/authdata.dat", tkt->ticket.authorization_data->val->ad_data.data, tkt->ticket.authorization_data->val->ad_data.length); } #endif #endif if ((ret = smb_krb5_unparse_name(context, client_principal, principal))) { DEBUG(3,("ads_verify_ticket: smb_krb5_unparse_name failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } sret = NT_STATUS_OK; out: TALLOC_FREE(mutex); if (!NT_STATUS_IS_OK(sret)) { data_blob_free(&auth_data); } if (!NT_STATUS_IS_OK(sret)) { data_blob_free(ap_rep); } if (host_princ) { krb5_free_principal(context, host_princ); } if (keyblock) { krb5_free_keyblock(context, keyblock); } if (tkt != NULL) { krb5_free_ticket(context, tkt); } SAFE_FREE(host_princ_s); if (auth_context) { krb5_auth_con_free(context, auth_context); } if (context) { krb5_free_context(context); } return sret; }
int main(int argc, char **argv) { krb5_error_code ret; char **files; int optidx = 0; int i; krb5_log_facility *logfacility; krb5_keytab keytab; krb5_socket_t sfd = rk_INVALID_SOCKET; setprogname(argv[0]); ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); if (getarg(args, num_args, argc, argv, &optidx)) { warnx("error at argument `%s'", argv[optidx]); usage(1); } if (help_flag) usage (0); if (version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (config_file == NULL) { asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); if (config_file == NULL) errx(1, "out of memory"); } ret = krb5_prepend_config_files_default(config_file, &files); if (ret) krb5_err(context, 1, ret, "getting configuration files"); ret = krb5_set_config_files(context, files); krb5_free_config_files(files); if(ret) krb5_err(context, 1, ret, "reading configuration files"); ret = krb5_openlog(context, "kadmind", &logfacility); if (ret) krb5_err(context, 1, ret, "krb5_openlog"); ret = krb5_set_warn_dest(context, logfacility); if (ret) krb5_err(context, 1, ret, "krb5_set_warn_dest"); ret = krb5_kt_register(context, &hdb_kt_ops); if(ret) krb5_err(context, 1, ret, "krb5_kt_register"); ret = krb5_kt_resolve(context, keytab_str, &keytab); if(ret) krb5_err(context, 1, ret, "krb5_kt_resolve"); kadm5_setup_passwd_quality_check (context, check_library, check_function); for (i = 0; i < policy_libraries.num_strings; i++) { ret = kadm5_add_passwd_quality_verifier(context, policy_libraries.strings[i]); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); } ret = kadm5_add_passwd_quality_verifier(context, NULL); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); if(debug_flag) { int debug_port; if(port_str == NULL) debug_port = krb5_getportbyname (context, "kerberos-adm", "tcp", 749); else debug_port = htons(atoi(port_str)); mini_inetd(debug_port, &sfd); } else { #ifdef _WIN32 pidfile(NULL); start_server(context, port_str); #else struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; socklen_t sa_size = sizeof(__ss); /* * Check if we are running inside inetd or not, if not, start * our own server. */ if(roken_getsockname(STDIN_FILENO, sa, &sa_size) < 0 && rk_SOCK_ERRNO == ENOTSOCK) { pidfile(NULL); start_server(context, port_str); } #endif /* _WIN32 */ sfd = STDIN_FILENO; } if(realm) krb5_set_default_realm(context, realm); /* XXX */ kadmind_loop(context, keytab, sfd); return 0; }
int main(int argc, char **argv) { krb5_error_code ret; char **files; int optidx = 0; int e, i; krb5_log_facility *logfacility; krb5_keytab keytab; setprogname(argv[0]); ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); while((e = getarg(args, num_args, argc, argv, &optidx))) warnx("error at argument `%s'", argv[optidx]); if (help_flag) usage (0); if (version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (config_file == NULL) { asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); if (config_file == NULL) errx(1, "out of memory"); } ret = krb5_prepend_config_files_default(config_file, &files); if (ret) krb5_err(context, 1, ret, "getting configuration files"); ret = krb5_set_config_files(context, files); krb5_free_config_files(files); if(ret) krb5_err(context, 1, ret, "reading configuration files"); ret = krb5_openlog(context, "kadmind", &logfacility); if (ret) krb5_err(context, 1, ret, "krb5_openlog"); ret = krb5_set_warn_dest(context, logfacility); if (ret) krb5_err(context, 1, ret, "krb5_set_warn_dest"); ret = krb5_kt_register(context, &hdb_kt_ops); if(ret) krb5_err(context, 1, ret, "krb5_kt_register"); ret = krb5_kt_resolve(context, keytab_str, &keytab); if(ret) krb5_err(context, 1, ret, "krb5_kt_resolve"); kadm5_setup_passwd_quality_check (context, check_library, check_function); for (i = 0; i < policy_libraries.num_strings; i++) { ret = kadm5_add_passwd_quality_verifier(context, policy_libraries.strings[i]); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); } ret = kadm5_add_passwd_quality_verifier(context, NULL); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); { int fd = 0; struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; socklen_t sa_size = sizeof(__ss); krb5_auth_context ac = NULL; int debug_port; if(debug_flag) { if(port_str == NULL) debug_port = krb5_getportbyname (context, "kerberos-adm", "tcp", 749); else debug_port = htons(atoi(port_str)); mini_inetd(debug_port); } else if(roken_getsockname(STDIN_FILENO, sa, &sa_size) < 0 && errno == ENOTSOCK) { parse_ports(context, port_str ? port_str : "+"); pidfile(NULL); start_server(context); } if(realm) krb5_set_default_realm(context, realm); /* XXX */ kadmind_loop(context, ac, keytab, fd); } return 0; }
/* * Initialize a realm control structure from the alternate profile or from * the specified defaults. * * After we're complete here, the essence of the realm is embodied in the * realm data and we should be all set to begin operation for that realm. */ static krb5_error_code init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname, krb5_enctype def_enctype, char *def_udp_ports, char *def_tcp_ports, krb5_boolean def_manual, krb5_boolean def_restrict_anon, char **db_args, char *no_refrls, char *host_based_srvcs) { krb5_error_code kret; krb5_boolean manual; krb5_realm_params *rparams; int kdb_open_flags; krb5_kvno mkvno = IGNORE_VNO; memset(rdp, 0, sizeof(kdc_realm_t)); if (!realm) { kret = EINVAL; goto whoops; } rdp->realm_name = strdup(realm); if (rdp->realm_name == NULL) { kret = ENOMEM; goto whoops; } kret = krb5int_init_context_kdc(&rdp->realm_context); if (kret) { kdc_err(NULL, kret, _("while getting context for realm %s"), realm); goto whoops; } kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name, &rparams); if (kret) { kdc_err(rdp->realm_context, kret, _("while reading realm parameters")); goto whoops; } /* Handle profile file name */ if (rparams && rparams->realm_profile) { rdp->realm_profile = strdup(rparams->realm_profile); if (!rdp->realm_profile) { kret = ENOMEM; goto whoops; } } /* Handle master key name */ if (rparams && rparams->realm_mkey_name) rdp->realm_mpname = strdup(rparams->realm_mkey_name); else rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : strdup(KRB5_KDB_M_NAME); if (!rdp->realm_mpname) { kret = ENOMEM; goto whoops; } /* Handle KDC ports */ if (rparams && rparams->realm_kdc_ports) rdp->realm_ports = strdup(rparams->realm_kdc_ports); else rdp->realm_ports = strdup(def_udp_ports); if (!rdp->realm_ports) { kret = ENOMEM; goto whoops; } if (rparams && rparams->realm_kdc_tcp_ports) rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports); else rdp->realm_tcp_ports = strdup(def_tcp_ports); if (!rdp->realm_tcp_ports) { kret = ENOMEM; goto whoops; } /* Handle stash file */ if (rparams && rparams->realm_stash_file) { rdp->realm_stash = strdup(rparams->realm_stash_file); if (!rdp->realm_stash) { kret = ENOMEM; goto whoops; } manual = FALSE; } else manual = def_manual; if (rparams && rparams->realm_restrict_anon_valid) rdp->realm_restrict_anon = rparams->realm_restrict_anon; else rdp->realm_restrict_anon = def_restrict_anon; /* Handle master key type */ if (rparams && rparams->realm_enctype_valid) rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype; else rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; /* Handle reject-bad-transit flag */ if (rparams && rparams->realm_reject_bad_transit_valid) rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit; else rdp->realm_reject_bad_transit = 1; /* Handle ticket maximum life */ rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ? rparams->realm_max_life : KRB5_KDB_MAX_LIFE; /* Handle ticket renewable maximum life */ rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ? rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE; /* Handle KDC referrals */ kret = handle_referral_params(rparams, no_refrls, host_based_srvcs, rdp); if (kret == ENOMEM) goto whoops; if (rparams) krb5_free_realm_params(rdp->realm_context, rparams); /* * We've got our parameters, now go and setup our realm context. */ /* Set the default realm of this context */ if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { kdc_err(rdp->realm_context, kret, _("while setting default realm to %s"), realm); goto whoops; } /* first open the database before doing anything */ kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC; if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) { kdc_err(rdp->realm_context, kret, _("while initializing database for realm %s"), realm); goto whoops; } /* Assemble and parse the master key name */ if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, rdp->realm_name, (char **) NULL, &rdp->realm_mprinc))) { kdc_err(rdp->realm_context, kret, _("while setting up master key name %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } /* * Get the master key (note, may not be the most current mkey). */ if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, rdp->realm_mkey.enctype, manual, FALSE, rdp->realm_stash, &mkvno, NULL, &rdp->realm_mkey))) { kdc_err(rdp->realm_context, kret, _("while fetching master key %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc, &rdp->realm_mkey, mkvno, &rdp->mkey_list))) { kdc_err(rdp->realm_context, kret, _("while fetching master keys list for realm %s"), realm); goto whoops; } /* Set up the keytab */ if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL, &rdp->realm_keytab))) { kdc_err(rdp->realm_context, kret, _("while resolving kdb keytab for realm %s"), realm); goto whoops; } /* Preformat the TGS name */ if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, strlen(realm), realm, KRB5_TGS_NAME, realm, (char *) NULL))) { kdc_err(rdp->realm_context, kret, _("while building TGS name for realm %s"), realm); goto whoops; } if (!rkey_init_done) { krb5_data seed; /* * If all that worked, then initialize the random key * generators. */ seed.length = rdp->realm_mkey.length; seed.data = (char *)rdp->realm_mkey.contents; if ((kret = krb5_c_random_add_entropy(rdp->realm_context, KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed))) goto whoops; rkey_init_done = 1; } whoops: /* * If we choked, then clean up any dirt we may have dropped on the floor. */ if (kret) { finish_realm(rdp); } return(kret); }
/* * Initialize a realm control structure from the alternate profile or from * the specified defaults. * * After we're complete here, the essence of the realm is embodied in the * realm data and we should be all set to begin operation for that realm. */ static krb5_error_code init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm, char *def_mpname, krb5_enctype def_enctype, char *def_udp_listen, char *def_tcp_listen, krb5_boolean def_manual, krb5_boolean def_restrict_anon, char **db_args, char *no_referral, char *hostbased) { krb5_error_code kret; krb5_boolean manual; int kdb_open_flags; char *svalue = NULL; const char *hierarchy[4]; krb5_kvno mkvno = IGNORE_VNO; memset(rdp, 0, sizeof(kdc_realm_t)); if (!realm) { kret = EINVAL; goto whoops; } hierarchy[0] = KRB5_CONF_REALMS; hierarchy[1] = realm; hierarchy[3] = NULL; rdp->realm_name = strdup(realm); if (rdp->realm_name == NULL) { kret = ENOMEM; goto whoops; } kret = krb5int_init_context_kdc(&rdp->realm_context); if (kret) { kdc_err(NULL, kret, _("while getting context for realm %s"), realm); goto whoops; } if (time_offset != 0) (void)krb5_set_time_offsets(rdp->realm_context, time_offset, 0); /* Handle master key name */ hierarchy[2] = KRB5_CONF_MASTER_KEY_NAME; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_mpname)) { rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : strdup(KRB5_KDB_M_NAME); } if (!rdp->realm_mpname) { kret = ENOMEM; goto whoops; } /* Handle KDC addresses/ports */ hierarchy[2] = KRB5_CONF_KDC_LISTEN; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen)) { /* Try the old kdc_ports configuration option. */ hierarchy[2] = KRB5_CONF_KDC_PORTS; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen)) rdp->realm_listen = strdup(def_udp_listen); } if (!rdp->realm_listen) { kret = ENOMEM; goto whoops; } hierarchy[2] = KRB5_CONF_KDC_TCP_LISTEN; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_tcp_listen)) { /* Try the old kdc_tcp_ports configuration option. */ hierarchy[2] = KRB5_CONF_KDC_TCP_PORTS; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_tcp_listen)) rdp->realm_tcp_listen = strdup(def_tcp_listen); } if (!rdp->realm_tcp_listen) { kret = ENOMEM; goto whoops; } /* Handle stash file */ hierarchy[2] = KRB5_CONF_KEY_STASH_FILE; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_stash)) manual = def_manual; else manual = FALSE; hierarchy[2] = KRB5_CONF_RESTRICT_ANONYMOUS_TO_TGT; if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &rdp->realm_restrict_anon)) rdp->realm_restrict_anon = def_restrict_anon; /* Handle master key type */ hierarchy[2] = KRB5_CONF_MASTER_KEY_TYPE; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &svalue) || krb5_string_to_enctype(svalue, &rdp->realm_mkey.enctype)) rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; free(svalue); svalue = NULL; /* Handle reject-bad-transit flag */ hierarchy[2] = KRB5_CONF_REJECT_BAD_TRANSIT; if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &rdp->realm_reject_bad_transit)) rdp->realm_reject_bad_transit = TRUE; /* Handle assume des-cbc-crc is supported for session keys */ hierarchy[2] = KRB5_CONF_DES_CRC_SESSION_SUPPORTED; if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &rdp->realm_assume_des_crc_sess)) rdp->realm_assume_des_crc_sess = TRUE; /* Handle ticket maximum life */ hierarchy[2] = KRB5_CONF_MAX_LIFE; if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxlife)) rdp->realm_maxlife = KRB5_KDB_MAX_LIFE; /* Handle ticket renewable maximum life */ hierarchy[2] = KRB5_CONF_MAX_RENEWABLE_LIFE; if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxrlife)) rdp->realm_maxrlife = KRB5_KDB_MAX_RLIFE; /* Handle KDC referrals */ hierarchy[2] = KRB5_CONF_NO_HOST_REFERRAL; (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue); kret = combine(no_referral, svalue, &rdp->realm_no_referral); if (kret) goto whoops; free(svalue); svalue = NULL; hierarchy[2] = KRB5_CONF_HOST_BASED_SERVICES; (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue); kret = combine(hostbased, svalue, &rdp->realm_hostbased); if (kret) goto whoops; free(svalue); svalue = NULL; /* * We've got our parameters, now go and setup our realm context. */ /* Set the default realm of this context */ if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { kdc_err(rdp->realm_context, kret, _("while setting default realm to %s"), realm); goto whoops; } /* first open the database before doing anything */ kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC; if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) { kdc_err(rdp->realm_context, kret, _("while initializing database for realm %s"), realm); goto whoops; } /* Assemble and parse the master key name */ if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, rdp->realm_name, (char **) NULL, &rdp->realm_mprinc))) { kdc_err(rdp->realm_context, kret, _("while setting up master key name %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } /* * Get the master key (note, may not be the most current mkey). */ if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, rdp->realm_mkey.enctype, manual, FALSE, rdp->realm_stash, &mkvno, NULL, &rdp->realm_mkey))) { kdc_err(rdp->realm_context, kret, _("while fetching master key %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc, &rdp->realm_mkey))) { kdc_err(rdp->realm_context, kret, _("while fetching master keys list for realm %s"), realm); goto whoops; } /* Set up the keytab */ if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL, &rdp->realm_keytab))) { kdc_err(rdp->realm_context, kret, _("while resolving kdb keytab for realm %s"), realm); goto whoops; } /* Preformat the TGS name */ if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, strlen(realm), realm, KRB5_TGS_NAME, realm, (char *) NULL))) { kdc_err(rdp->realm_context, kret, _("while building TGS name for realm %s"), realm); goto whoops; } if (!rkey_init_done) { krb5_data seed; /* * If all that worked, then initialize the random key * generators. */ seed.length = rdp->realm_mkey.length; seed.data = (char *)rdp->realm_mkey.contents; if ((kret = krb5_c_random_add_entropy(rdp->realm_context, KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed))) goto whoops; rkey_init_done = 1; } whoops: /* * If we choked, then clean up any dirt we may have dropped on the floor. */ if (kret) { finish_realm(rdp); } return(kret); }
int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_auth_context ac = NULL; krb5_principal c1, c2; krb5_authenticator authent; krb5_keytab keytab; krb5_socket_t sock = rk_INVALID_SOCKET; HDB *db = NULL; int optidx = 0; char *tmp_db; krb5_log_facility *fac; int nprincs; setprogname(argv[0]); ret = krb5_init_context(&context); if(ret) exit(1); ret = krb5_openlog(context, "hpropd", &fac); if(ret) errx(1, "krb5_openlog"); krb5_set_warn_dest(context, fac); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if(local_realm != NULL) krb5_set_default_realm(context, local_realm); if(help_flag) usage(0); if(version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (argc != 0) usage(1); if (database == NULL) database = hdb_default_db(context); if(from_stdin) { sock = STDIN_FILENO; } else { struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; socklen_t sin_len = sizeof(ss); char addr_name[256]; krb5_ticket *ticket; char *server; sock = STDIN_FILENO; #ifdef SUPPORT_INETD if (inetd_flag == -1) { if (getpeername (sock, sa, &sin_len) < 0) { inetd_flag = 0; } else { inetd_flag = 1; } } #else inetd_flag = 0; #endif if (!inetd_flag) { mini_inetd (krb5_getportbyname (context, "hprop", "tcp", HPROP_PORT), &sock); } sin_len = sizeof(ss); if(getpeername(sock, sa, &sin_len) < 0) krb5_err(context, 1, errno, "getpeername"); if (inet_ntop(sa->sa_family, socket_get_address (sa), addr_name, sizeof(addr_name)) == NULL) strlcpy (addr_name, "unknown address", sizeof(addr_name)); krb5_log(context, fac, 0, "Connection from %s", addr_name); ret = krb5_kt_register(context, &hdb_kt_ops); if(ret) krb5_err(context, 1, ret, "krb5_kt_register"); if (ktname != NULL) { ret = krb5_kt_resolve(context, ktname, &keytab); if (ret) krb5_err (context, 1, ret, "krb5_kt_resolve %s", ktname); } else { ret = krb5_kt_default (context, &keytab); if (ret) krb5_err (context, 1, ret, "krb5_kt_default"); } ret = krb5_recvauth(context, &ac, &sock, HPROP_VERSION, NULL, 0, keytab, &ticket); if(ret) krb5_err(context, 1, ret, "krb5_recvauth"); ret = krb5_unparse_name(context, ticket->server, &server); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name"); if (strncmp(server, "hprop/", 5) != 0) krb5_errx(context, 1, "ticket not for hprop (%s)", server); free(server); krb5_free_ticket (context, ticket); ret = krb5_auth_con_getauthenticator(context, ac, &authent); if(ret) krb5_err(context, 1, ret, "krb5_auth_con_getauthenticator"); ret = krb5_make_principal(context, &c1, NULL, "kadmin", "hprop", NULL); if(ret) krb5_err(context, 1, ret, "krb5_make_principal"); _krb5_principalname2krb5_principal(context, &c2, authent->cname, authent->crealm); if(!krb5_principal_compare(context, c1, c2)) { char *s; ret = krb5_unparse_name(context, c2, &s); if (ret) s = unparseable_name; krb5_errx(context, 1, "Unauthorized connection from %s", s); } krb5_free_principal(context, c1); krb5_free_principal(context, c2); ret = krb5_kt_close(context, keytab); if(ret) krb5_err(context, 1, ret, "krb5_kt_close"); } if(!print_dump) { asprintf(&tmp_db, "%s~", database); ret = hdb_create(context, &db, tmp_db); if(ret) krb5_err(context, 1, ret, "hdb_create(%s)", tmp_db); ret = db->hdb_open(context, db, O_RDWR | O_CREAT | O_TRUNC, 0600); if(ret) krb5_err(context, 1, ret, "hdb_open(%s)", tmp_db); } nprincs = 0; while(1){ krb5_data data; hdb_entry_ex entry; if(from_stdin) { ret = krb5_read_message(context, &sock, &data); if(ret != 0 && ret != HEIM_ERR_EOF) krb5_err(context, 1, ret, "krb5_read_message"); } else { ret = krb5_read_priv_message(context, ac, &sock, &data); if(ret) krb5_err(context, 1, ret, "krb5_read_priv_message"); } if(ret == HEIM_ERR_EOF || data.length == 0) { if(!from_stdin) { data.data = NULL; data.length = 0; krb5_write_priv_message(context, ac, &sock, &data); } if(!print_dump) { ret = db->hdb_close(context, db); if(ret) krb5_err(context, 1, ret, "db_close"); ret = db->hdb_rename(context, db, database); if(ret) krb5_err(context, 1, ret, "db_rename"); } break; } memset(&entry, 0, sizeof(entry)); ret = hdb_value2entry(context, &data, &entry.entry); krb5_data_free(&data); if(ret) krb5_err(context, 1, ret, "hdb_value2entry"); if(print_dump) hdb_print_entry(context, db, &entry, stdout); else { ret = db->hdb_store(context, db, 0, &entry); if(ret == HDB_ERR_EXISTS) { char *s; ret = krb5_unparse_name(context, entry.entry.principal, &s); if (ret) s = strdup(unparseable_name); krb5_warnx(context, "Entry exists: %s", s); free(s); } else if(ret) krb5_err(context, 1, ret, "db_store"); else nprincs++; } hdb_free_entry(context, &entry); } if (!print_dump) krb5_log(context, fac, 0, "Received %d principals", nprincs); if (inetd_flag == 0) rk_closesocket(sock); exit(0); }
OM_uint32 GSSAPI_CALLCONV _gsskrb5_set_sec_context_option (OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_OID desired_object, const gss_buffer_t value) { krb5_context context; OM_uint32 maj_stat; GSSAPI_KRB5_INIT (&context); if (value == GSS_C_NO_BUFFER) { *minor_status = EINVAL; return GSS_S_FAILURE; } if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) { gsskrb5_ctx ctx; int flag; if (*context_handle == GSS_C_NO_CONTEXT) { *minor_status = EINVAL; return GSS_S_NO_CONTEXT; } maj_stat = get_bool(minor_status, value, &flag); if (maj_stat != GSS_S_COMPLETE) return maj_stat; ctx = (gsskrb5_ctx)*context_handle; HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (flag) ctx->more_flags |= COMPAT_OLD_DES3; else ctx->more_flags &= ~COMPAT_OLD_DES3; ctx->more_flags |= COMPAT_OLD_DES3_SELECTED; HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) { int flag; maj_stat = get_bool(minor_status, value, &flag); if (maj_stat != GSS_S_COMPLETE) return maj_stat; krb5_set_dns_canonicalize_hostname(context, flag); return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) { char *str; maj_stat = get_string(minor_status, value, &str); if (maj_stat != GSS_S_COMPLETE) return maj_stat; maj_stat = _gsskrb5_register_acceptor_identity(minor_status, str); free(str); return maj_stat; } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) { char *str; maj_stat = get_string(minor_status, value, &str); if (maj_stat != GSS_S_COMPLETE) return maj_stat; if (str == NULL) { *minor_status = 0; return GSS_S_CALL_INACCESSIBLE_READ; } krb5_set_default_realm(context, str); free(str); *minor_status = 0; return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) { *minor_status = EINVAL; return GSS_S_FAILURE; } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) { char *str; maj_stat = get_string(minor_status, value, &str); if (maj_stat != GSS_S_COMPLETE) return maj_stat; if (str == NULL) { *minor_status = 0; return GSS_S_CALL_INACCESSIBLE_READ; } *minor_status = krb5_cc_set_default_name(context, str); free(str); if (*minor_status) return GSS_S_FAILURE; return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) { OM_uint32 offset; time_t t; maj_stat = get_int32(minor_status, value, &offset); if (maj_stat != GSS_S_COMPLETE) return maj_stat; t = time(NULL) + offset; krb5_set_real_time(context, t, 0); *minor_status = 0; return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) { krb5_timestamp sec; int32_t usec; time_t t; t = time(NULL); krb5_us_timeofday (context, &sec, &usec); maj_stat = set_int32(minor_status, value, sec - t); if (maj_stat != GSS_S_COMPLETE) return maj_stat; *minor_status = 0; return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_PLUGIN_REGISTER_X)) { struct gsskrb5_krb5_plugin c; if (value->length != sizeof(c)) { *minor_status = EINVAL; return GSS_S_FAILURE; } memcpy(&c, value->value, sizeof(c)); krb5_plugin_register(context, c.type, c.name, c.symbol); *minor_status = 0; return GSS_S_COMPLETE; } *minor_status = EINVAL; return GSS_S_FAILURE; }
int kt_get(struct get_options *opt, int argc, char **argv) { krb5_error_code ret = 0; krb5_keytab keytab; void *kadm_handle = NULL; krb5_enctype *etypes = NULL; size_t netypes = 0; size_t i; int a, j; unsigned int failed = 0; if((keytab = ktutil_open_keytab()) == NULL) return 1; if(opt->realm_string) krb5_set_default_realm(context, opt->realm_string); if (opt->enctypes_strings.num_strings != 0) { etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes)); if (etypes == NULL) { krb5_warnx(context, "malloc failed"); goto out; } netypes = opt->enctypes_strings.num_strings; for(i = 0; i < netypes; i++) { ret = krb5_string_to_enctype(context, opt->enctypes_strings.strings[i], &etypes[i]); if(ret) { krb5_warnx(context, "unrecognized enctype: %s", opt->enctypes_strings.strings[i]); goto out; } } } for(a = 0; a < argc; a++){ krb5_principal princ_ent; kadm5_principal_ent_rec princ; int mask = 0; krb5_keyblock *keys; int n_keys; int created = 0; krb5_keytab_entry entry; ret = krb5_parse_name(context, argv[a], &princ_ent); if (ret) { krb5_warn(context, ret, "can't parse principal %s", argv[a]); failed++; continue; } memset(&princ, 0, sizeof(princ)); princ.principal = princ_ent; mask |= KADM5_PRINCIPAL; princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; mask |= KADM5_ATTRIBUTES; princ.princ_expire_time = 0; mask |= KADM5_PRINC_EXPIRE_TIME; if(kadm_handle == NULL) { const char *r; if(opt->realm_string != NULL) r = opt->realm_string; else r = krb5_principal_get_realm(context, princ_ent); kadm_handle = open_kadmin_connection(opt->principal_string, r, opt->admin_server_string, opt->server_port_integer); if(kadm_handle == NULL) break; } ret = kadm5_create_principal(kadm_handle, &princ, mask, "x"); if(ret == 0) created = 1; else if(ret != KADM5_DUP) { krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]); krb5_free_principal(context, princ_ent); failed++; continue; } ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys); if (ret) { krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]); krb5_free_principal(context, princ_ent); failed++; continue; } ret = kadm5_get_principal(kadm_handle, princ_ent, &princ, KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES); if (ret) { krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]); for (j = 0; j < n_keys; j++) krb5_free_keyblock_contents(context, &keys[j]); krb5_free_principal(context, princ_ent); failed++; continue; } if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX)) krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]); princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); mask = KADM5_ATTRIBUTES; if(created) { princ.kvno = 1; mask |= KADM5_KVNO; } ret = kadm5_modify_principal(kadm_handle, &princ, mask); if (ret) { krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]); for (j = 0; j < n_keys; j++) krb5_free_keyblock_contents(context, &keys[j]); krb5_free_principal(context, princ_ent); failed++; continue; } for(j = 0; j < n_keys; j++) { int do_add = TRUE; if (netypes) { size_t k; do_add = FALSE; for (k = 0; k < netypes; ++k) if (keys[j].keytype == etypes[k]) { do_add = TRUE; break; } } if (do_add) { entry.principal = princ_ent; entry.vno = princ.kvno; entry.keyblock = keys[j]; entry.timestamp = time (NULL); ret = krb5_kt_add_entry(context, keytab, &entry); if (ret) krb5_warn(context, ret, "krb5_kt_add_entry"); } krb5_free_keyblock_contents(context, &keys[j]); } kadm5_free_principal_ent(kadm_handle, &princ); krb5_free_principal(context, princ_ent); } out: free(etypes); if (kadm_handle) kadm5_destroy(kadm_handle); krb5_kt_close(context, keytab); return ret != 0 || failed > 0; }
/* * Store the given private key (key) and certificate (cert) * into the Kerberos 5 credentials cache. The "lifetime" * of the certificate is also given in notBefore, and notAfter. */ int store_in_cc(RSA *key, BYTE *cert, DWORD cert_length, char *realm, ASN1_UTCTIME *notBefore, ASN1_UTCTIME *notAfter, #if defined(KX509_LIB) char *tkt_cache_name, #endif char **err_msg) { krb5_context k5_context; krb5_ccache cc; krb5_creds fake_creds; DWORD key_length; krb5_error_code k5_rc = 0; int retcode = KX509_STATUS_GOOD; BYTE *ptr = NULL; BYTE *memptr = NULL; /* * Use fake_creds.ticket for private key and * fake_creds.second_ticket for certificate */ memset(&fake_creds, '\0', sizeof(fake_creds)); if (k5_rc = krb5_init_context(&k5_context)) { log_printf("store_in_cc: unable to initialize Kerberos 5 context (%d)\n", k5_rc); *err_msg = "Error initializing kerberos 5 environment."; return KX509_STATUS_CLNT_FIX; } #if 0 /* DON'T NEED THIS, and it is a private function anyway... */ if (k5_rc = krb5_set_default_realm(k5_context, realm)) { log_printf("store_in_cc: failed to malloc space for k5 default_realm\n"); *err_msg = "Try re-authenticating. " "Hopefully temporary client-side problem"; return KX509_STATUS_CLNT_FIX; } #endif #if defined(KX509_LIB) if (k5_rc = krb5_cc_resolve(k5_context, tkt_cache_name, &cc)) { log_printf("store_in_cc: failed to resolve credential cache (%d)\n", k5_rc); *err_msg = "Try re-authenticating. " "Could not resolve your credential cache name."; return KX509_STATUS_CLNT_FIX; } #else if (k5_rc = krb5_cc_default(k5_context, &cc)) { log_printf("store_in_cc: failed to resolve credential cache (%d)\n", k5_rc); *err_msg = "Try re-authenticating. " "Could not resolve your credential cache name."; return KX509_STATUS_CLNT_FIX; } #endif #if defined(HAVE_HEIMDAL) if (k5_rc = krb5_make_principal(k5_context, &fake_creds.server, realm, KX509_CC_PRINCIPAL, KX509_CC_INSTANCE, NULL)) #else if (k5_rc = krb5_sname_to_principal(k5_context, KX509_CC_INSTANCE, KX509_CC_PRINCIPAL, KRB5_NT_UNKNOWN, &fake_creds.server)) #endif { log_printf("store_in_cc: unable to create server principal from sname (%d)\n", k5_rc); *err_msg = "Internal error with kerberos while creating fake server principal."; retcode = KX509_STATUS_CLNT_FIX; goto close_and_return; } #if defined(CC_REMOVE_IMPLEMENTED) /* * We really want to clear out any old private key/certificate entries * from the credentials cache. However, the function to do that is * not defined... */ if (k5_rc = kx509_clear_old_certificates(k5_context, cc, fake_creds)) { log_printf("store_in_cc: couldn't clear out old certificate " "from cred cache (%d)\n", k5_rc); *err_msg = "Error removing old certificate from your kerberos credentials cache."; retcode = KX509_STATUS_CLNT_FIX; goto close_and_return; } #endif /* CC_REMOVE_IMPLEMENTED */ if (k5_rc = krb5_cc_get_principal(k5_context, cc, &fake_creds.client)) { log_printf("store_in_cc: unable to create client principal from sname (%d)\n", k5_rc); *err_msg = "Internal error with kerberos while creating fake client principal."; retcode = KX509_STATUS_CLNT_FIX; goto close_and_return; } /* * Get the DER-encoded length of the private key. * Allocate storage to hold the private key and certificate. */ key_length = i2d_RSAPrivateKey(key, NULL); /* Get DER-encoded len of Private Key */ if (key_length <= 0) { log_printf("store_in_cc: unable to determine length of " "encoded private key (%d)\n", key_length); *err_msg = "Error determining encoded length of private key."; retcode = KX509_STATUS_CLNT_FIX; goto close_and_return; } ptr = Malloc(key_length + cert_length); if (!ptr) { log_printf("store_in_cc: error allocating %d bytes for " "private key (%d) and certificate (%d)\n", key_length+cert_length, key_length, cert_length); *err_msg = "Error allocating storage for private key and certificate."; retcode = KX509_STATUS_CLNT_FIX; goto close_and_return; } memptr = ptr; /* Save a ptr to the allocated area for later when we free it */ fake_creds.ticket.data = (char *)ptr; fake_creds.ticket.length = i2d_RSAPrivateKey(key, &ptr); /* Note that i2d_RSAPrivateKey() updates ptr!!! */ memcpy(ptr, cert, cert_length); fake_creds.second_ticket.data = (char *)ptr; fake_creds.second_ticket.length = cert_length; /* Set up the ticket lifetime according to the certificate lifetime */ fake_creds.times.starttime = utc2unix(notBefore, NULL); fake_creds.times.endtime = utc2unix(notAfter, NULL); /* * Store the fake ticket (containing the private key * and certificate) into the credentials cache. */ #if defined(WRITE_CERT) /* Write the key-pair and certificate to file (code lifted from kxlist -p) */ if (k5_rc = materialize_cert(k5_context, cc, &fake_creds)) #else /* WRITE_CERT */ /* Store the key-pair and certificate into the K5 credentials cache as a mock ticket */ if (k5_rc = krb5_cc_store_cred(k5_context, cc, &fake_creds)) #endif /* WRITE_CERT */ { log_printf("store_in_cc: krb5_cc_store_cred returned %0d\n", k5_rc); *err_msg = "Try re-authenticating. " "Currently unable to write your Kerberos credentials cache."; retcode = KX509_STATUS_CLNT_FIX; goto close_and_return; } close_and_return: if (memptr) { Free(memptr); memptr = NULL; } krb5_cc_close(k5_context, cc); /* ignore return code from close */ return(retcode); }
OM_uint32 _gsskrb5_set_sec_context_option (OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_OID desired_object, const gss_buffer_t value) { OM_uint32 maj_stat; GSSAPI_KRB5_INIT (); if (value == GSS_C_NO_BUFFER) { *minor_status = EINVAL; return GSS_S_FAILURE; } if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) { gsskrb5_ctx ctx; int flag; if (*context_handle == GSS_C_NO_CONTEXT) { *minor_status = EINVAL; return GSS_S_NO_CONTEXT; } maj_stat = get_bool(minor_status, value, &flag); if (maj_stat != GSS_S_COMPLETE) return maj_stat; ctx = (gsskrb5_ctx)*context_handle; HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (flag) ctx->more_flags |= COMPAT_OLD_DES3; else ctx->more_flags &= ~COMPAT_OLD_DES3; ctx->more_flags |= COMPAT_OLD_DES3_SELECTED; HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) { int flag; maj_stat = get_bool(minor_status, value, &flag); if (maj_stat != GSS_S_COMPLETE) return maj_stat; krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag); return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) { char *str; if (value == NULL || value->length == 0) { str = NULL; } else { str = malloc(value->length + 1); if (str) { *minor_status = 0; return GSS_S_UNAVAILABLE; } memcpy(str, value->value, value->length); str[value->length] = '\0'; } _gsskrb5_register_acceptor_identity(str); free(str); *minor_status = 0; return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) { char *str; if (value == NULL || value->length == 0) { *minor_status = 0; return GSS_S_CALL_INACCESSIBLE_READ; } str = malloc(value->length + 1); if (str) { *minor_status = 0; return GSS_S_UNAVAILABLE; } memcpy(str, value->value, value->length); str[value->length] = '\0'; krb5_set_default_realm(_gsskrb5_context, str); free(str); *minor_status = 0; return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) { if (value == NULL || value->length == 0) { krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL); } else { struct gsskrb5_send_to_kdc c; if (value->length != sizeof(c)) { *minor_status = EINVAL; return GSS_S_FAILURE; } memcpy(&c, value->value, sizeof(c)); krb5_set_send_to_kdc_func(_gsskrb5_context, (krb5_send_to_kdc_func)c.func, c.ptr); } *minor_status = 0; return GSS_S_COMPLETE; } *minor_status = EINVAL; return GSS_S_FAILURE; }
int main(int argc, char **argv) { krb5_error_code ret; char **files; kadm5_config_params conf; int optidx = 0; int exit_status = 0; setprogname(argv[0]); ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if (version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (config_file == NULL) { asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); if (config_file == NULL) errx(1, "out of memory"); } ret = krb5_prepend_config_files_default(config_file, &files); if (ret) krb5_err(context, 1, ret, "getting configuration files"); ret = krb5_set_config_files(context, files); krb5_free_config_files(files); if(ret) krb5_err(context, 1, ret, "reading configuration files"); memset(&conf, 0, sizeof(conf)); if(realm) { krb5_set_default_realm(context, realm); /* XXX should be fixed some other way */ conf.realm = realm; conf.mask |= KADM5_CONFIG_REALM; } if (admin_server) { conf.admin_server = admin_server; conf.mask |= KADM5_CONFIG_ADMIN_SERVER; } if (server_port) { conf.kadmind_port = htons(server_port); conf.mask |= KADM5_CONFIG_KADMIND_PORT; } if (keyfile) { conf.stash_file = keyfile; conf.mask |= KADM5_CONFIG_STASH_FILE; } if(local_flag) { int i; kadm5_setup_passwd_quality_check (context, check_library, check_function); for (i = 0; i < policy_libraries.num_strings; i++) { ret = kadm5_add_passwd_quality_verifier(context, policy_libraries.strings[i]); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); } ret = kadm5_add_passwd_quality_verifier(context, NULL); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); ret = kadm5_s_init_with_password_ctx(context, KADM5_ADMIN_SERVICE, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); } else if (mit_flag) { ret = kadm5_mit_init_with_password_ctx(context, client_name, NULL, &conf, 0, 0, &kadm_handle); } else if (ad_flag) { if (client_name == NULL) krb5_errx(context, 1, "keytab mode require principal name"); ret = kadm5_ad_init_with_password_ctx(context, client_name, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); } else if (keytab) { if (client_name == NULL) krb5_errx(context, 1, "keytab mode require principal name"); ret = kadm5_c_init_with_skey_ctx(context, client_name, keytab, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); } else ret = kadm5_c_init_with_password_ctx(context, client_name, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); if(ret) krb5_err(context, 1, ret, "kadm5_init_with_password"); signal(SIGINT, SIG_IGN); /* ignore signals for now, the sl command parser will handle SIGINT its own way; we should really take care of this in each function, f.i `get' might be interruptable, but not `create' */ if (argc != 0) { ret = sl_command (commands, argc, argv); if(ret == -1) krb5_warnx (context, "unrecognized command: %s", argv[0]); else if (ret == -2) ret = 0; if(ret != 0) exit_status = 1; } else { while(!exit_seen) { ret = sl_command_loop(commands, "kadmin> ", NULL); if (ret == -2) exit_seen = 1; else if (ret != 0) exit_status = 1; } } kadm5_destroy(kadm_handle); krb5_free_context(context); return exit_status; }
static void test_enterprise(krb5_context context) { krb5_error_code ret; char *unparsed; krb5_principal p; ret = krb5_set_default_realm(context, "SAMBA.ORG"); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); ret = krb5_parse_name_flags(context, "[email protected]@WIN.SU.SE", KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p); if (ret) krb5_err(context, 1, ret, "krb5_parse_name_flags"); ret = krb5_unparse_name(context, p, &unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name"); krb5_free_principal(context, p); if (strcmp(unparsed, "lha\\@[email protected]") != 0) krb5_errx(context, 1, "enterprise name failed 1"); free(unparsed); /* * */ ret = krb5_parse_name_flags(context, "lha\\@[email protected]", KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p); if (ret) krb5_err(context, 1, ret, "krb5_parse_name_flags"); ret = krb5_unparse_name(context, p, &unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name"); krb5_free_principal(context, p); if (strcmp(unparsed, "lha\\@su.se\\@[email protected]") != 0) krb5_errx(context, 1, "enterprise name failed 2: %s", unparsed); free(unparsed); /* * */ ret = krb5_parse_name_flags(context, "lha\\@[email protected]", 0, &p); if (ret) krb5_err(context, 1, ret, "krb5_parse_name_flags"); ret = krb5_unparse_name(context, p, &unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name"); krb5_free_principal(context, p); if (strcmp(unparsed, "lha\\@[email protected]") != 0) krb5_errx(context, 1, "enterprise name failed 3"); free(unparsed); /* * */ ret = krb5_parse_name_flags(context, "*****@*****.**", KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p); if (ret) krb5_err(context, 1, ret, "krb5_parse_name_flags"); ret = krb5_unparse_name(context, p, &unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name"); krb5_free_principal(context, p); if (strcmp(unparsed, "lha\\@[email protected]") != 0) krb5_errx(context, 1, "enterprise name failed 2: %s", unparsed); free(unparsed); }
int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_ccache ccache = NULL; HDB *db = NULL; int optidx = 0; int type, exit_code; setprogname(argv[0]); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if(help_flag) usage(0); if(version_flag){ print_version(NULL); exit(0); } ret = krb5_init_context(&context); if(ret) exit(1); /* We may be reading an old database encrypted with a DES master key. */ ret = krb5_allow_weak_crypto(context, 1); if(ret) krb5_err(context, 1, ret, "krb5_allow_weak_crypto"); if(local_realm) krb5_set_default_realm(context, local_realm); if(encrypt_flag && decrypt_flag) krb5_errx(context, 1, "only one of `--encrypt' and `--decrypt' is meaningful"); if(source_type != NULL) { type = parse_source_type(source_type); if(type == 0) krb5_errx(context, 1, "unknown source type `%s'", source_type); } else type = HPROP_HEIMDAL; if(!to_stdout) get_creds(context, &ccache); if(decrypt_flag || encrypt_flag) { ret = hdb_read_master_key(context, mkeyfile, &mkey5); if(ret && ret != ENOENT) krb5_err(context, 1, ret, "hdb_read_master_key"); if(ret) krb5_errx(context, 1, "No master key file found"); } switch(type) { case HPROP_MIT_DUMP: if (database == NULL) krb5_errx(context, 1, "no dump file specified"); break; case HPROP_HEIMDAL: ret = hdb_create (context, &db, database); if(ret) krb5_err(context, 1, ret, "hdb_create: %s", database); ret = db->hdb_open(context, db, O_RDONLY, 0); if(ret) krb5_err(context, 1, ret, "db->hdb_open"); break; default: krb5_errx(context, 1, "unknown dump type `%d'", type); break; } if (to_stdout) exit_code = dump_database (context, type, database, db); else exit_code = propagate_database (context, type, database, db, ccache, optidx, argc, argv); if(ccache != NULL) krb5_cc_destroy(context, ccache); if(db != NULL) (*db->hdb_destroy)(context, db); krb5_free_context(context); return exit_code; }
static int CommandProc(struct cmd_syndesc *as, void *arock) { krb5_principal princ = 0; char *cell, *pname, **hrealms, *service; char service_temp[MAXKTCREALMLEN + 20]; krb5_creds incred[1], mcred[1], *outcred = 0, *afscred; krb5_ccache cc = 0; #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC krb5_get_init_creds_opt *gic_opts; #else krb5_get_init_creds_opt gic_opts[1]; #endif char *tofree = NULL, *outname; int code; char *what; int i, dosetpag, evil, noprdb, id; #ifdef AFS_RXK5 int authtype; #endif krb5_data enc_part[1]; krb5_prompter_fct pf = NULL; char *pass = 0; void *pa = 0; struct kp_arg klog_arg[1]; char passwd[BUFSIZ]; struct afsconf_cell cellconfig[1]; static char rn[] = "klog"; /*Routine name */ static int Pipe = 0; /* reading from a pipe */ static int Silent = 0; /* Don't want error messages */ int writeTicketFile = 0; /* write ticket file to /tmp */ service = 0; memset(incred, 0, sizeof *incred); /* blow away command line arguments */ for (i = 1; i < zero_argc; i++) memset(zero_argv[i], 0, strlen(zero_argv[i])); zero_argc = 0; memset(klog_arg, 0, sizeof *klog_arg); /* first determine quiet flag based on -silent switch */ Silent = (as->parms[aSILENT].items ? 1 : 0); if (Silent) { afs_set_com_err_hook(silent_errors); } if ((code = krb5_init_context(&k5context))) { afs_com_err(rn, code, "while initializing Kerberos 5 library"); KLOGEXIT(code); } if ((code = rx_Init(0))) { afs_com_err(rn, code, "while initializing rx"); KLOGEXIT(code); } initialize_U_error_table(); /*initialize_krb5_error_table();*/ initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); /* initialize_rx_error_table(); */ if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) { afs_com_err(rn, 0, "can't get afs configuration (afsconf_Open(%s))", AFSDIR_CLIENT_ETC_DIRPATH); KLOGEXIT(1); } /* * Enable DES enctypes, which are currently still required for AFS. * krb5_allow_weak_crypto is MIT Kerberos 1.8. krb5_enctype_enable is * Heimdal. */ #if defined(HAVE_KRB5_ENCTYPE_ENABLE) i = krb5_enctype_valid(k5context, ETYPE_DES_CBC_CRC); if (i) krb5_enctype_enable(k5context, ETYPE_DES_CBC_CRC); #elif defined(HAVE_KRB5_ALLOW_WEAK_CRYPTO) krb5_allow_weak_crypto(k5context, 1); #endif /* Parse remaining arguments. */ dosetpag = !! as->parms[aSETPAG].items; Pipe = !! as->parms[aPIPE].items; writeTicketFile = !! as->parms[aTMP].items; noprdb = !! as->parms[aNOPRDB].items; evil = (always_evil&1) || !! as->parms[aUNWRAP].items; #ifdef AFS_RXK5 authtype = 0; if (as->parms[aK5].items) authtype |= FORCE_RXK5; if (as->parms[aK4].items) authtype |= FORCE_RXKAD; if (!authtype) authtype |= env_afs_rxk5_default(); #endif cell = as->parms[aCELL].items ? as->parms[aCELL].items->data : 0; if ((code = afsconf_GetCellInfo(tdir, cell, "afsprot", cellconfig))) { if (cell) afs_com_err(rn, code, "Can't get cell information for '%s'", cell); else afs_com_err(rn, code, "Can't get determine local cell!"); KLOGEXIT(code); } if (as->parms[aKRBREALM].items) { code = krb5_set_default_realm(k5context, as->parms[aKRBREALM].items->data); if (code) { afs_com_err(rn, code, "Can't make <%s> the default realm", as->parms[aKRBREALM].items->data); KLOGEXIT(code); } } else if ((code = krb5_get_host_realm(k5context, cellconfig->hostName[0], &hrealms))) { afs_com_err(rn, code, "Can't get realm for host <%s> in cell <%s>\n", cellconfig->hostName[0], cellconfig->name); KLOGEXIT(code); } else { if (hrealms && *hrealms) { code = krb5_set_default_realm(k5context, *hrealms); if (code) { afs_com_err(rn, code, "Can't make <%s> the default realm", *hrealms); KLOGEXIT(code); } } if (hrealms) krb5_free_host_realm(k5context, hrealms); } id = getuid(); if (as->parms[aPRINCIPAL].items) { pname = as->parms[aPRINCIPAL].items->data; } else { /* No explicit name provided: use Unix uid. */ struct passwd *pw; pw = getpwuid(id); if (pw == 0) { afs_com_err(rn, 0, "Can't figure out your name from your user id (%d).", id); if (!Silent) fprintf(stderr, "%s: Try providing the user name.\n", rn); KLOGEXIT(1); } pname = pw->pw_name; } code = krb5_parse_name(k5context, pname, &princ); if (code) { afs_com_err(rn, code, "Can't parse principal <%s>", pname); KLOGEXIT(code); } if (as->parms[aPASSWORD].items) { /* * Current argument is the desired password string. Remember it in * our local buffer, and zero out the argument string - anyone can * see it there with ps! */ strncpy(passwd, as->parms[aPASSWORD].items->data, sizeof(passwd)); memset(as->parms[aPASSWORD].items->data, 0, strlen(as->parms[aPASSWORD].items->data)); pass = passwd; } /* Get the password if it wasn't provided. */ if (!pass) { if (Pipe) { strncpy(passwd, getpipepass(), sizeof(passwd)); pass = passwd; } else { pf = klog_prompter; pa = klog_arg; } } service = 0; #ifdef AFS_RXK5 if (authtype & FORCE_RXK5) { tofree = get_afs_krb5_svc_princ(cellconfig); snprintf(service_temp, sizeof service_temp, "%s", tofree); } else #endif snprintf (service_temp, sizeof service_temp, "afs/%s", cellconfig->name); klog_arg->pp = &pass; klog_arg->pstore = passwd; klog_arg->allocated = sizeof(passwd); /* XXX should allow k5 to prompt in most cases -- what about expired pw?*/ #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC code = krb5_get_init_creds_opt_alloc(k5context, &gic_opts); if (code) { afs_com_err(rn, code, "Can't allocate get_init_creds options"); KLOGEXIT(code); } #else krb5_get_init_creds_opt_init(gic_opts); #endif for (;;) { code = krb5_get_init_creds_password(k5context, incred, princ, pass, pf, /* prompter */ pa, /* data */ 0, /* start_time */ 0, /* in_tkt_service */ gic_opts); if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) break; } memset(passwd, 0, sizeof(passwd)); if (code) { char *r = 0; if (krb5_get_default_realm(k5context, &r)) r = 0; if (r) afs_com_err(rn, code, "Unable to authenticate in realm %s", r); else afs_com_err(rn, code, "Unable to authenticate to use cell %s", cellconfig->name); if (r) free(r); KLOGEXIT(code); } for (;;writeTicketFile = 0) { if (writeTicketFile) { what = "getting default ccache"; code = krb5_cc_default(k5context, &cc); } else { what = "krb5_cc_resolve"; code = krb5_cc_resolve(k5context, "MEMORY:core", &cc); if (code) goto Failed; } what = "initializing ccache"; code = krb5_cc_initialize(k5context, cc, princ); if (code) goto Failed; what = "writing Kerberos ticket file"; code = krb5_cc_store_cred(k5context, cc, incred); if (code) goto Failed; if (writeTicketFile) fprintf(stderr, "Wrote ticket file to %s\n", krb5_cc_get_name(k5context, cc)); break; Failed: if (code) afs_com_err(rn, code, "%s", what); if (writeTicketFile) { if (cc) { krb5_cc_close(k5context, cc); cc = 0; } continue; } KLOGEXIT(code); } for (service = service_temp;;service = "afs") { memset(mcred, 0, sizeof *mcred); mcred->client = princ; code = krb5_parse_name(k5context, service, &mcred->server); if (code) { afs_com_err(rn, code, "Unable to parse service <%s>\n", service); KLOGEXIT(code); } if (tofree) { free(tofree); tofree = 0; } if (!(code = krb5_unparse_name(k5context, mcred->server, &outname))) tofree = outname; else outname = service; code = krb5_get_credentials(k5context, 0, cc, mcred, &outcred); krb5_free_principal(k5context, mcred->server); if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || service != service_temp) break; #ifdef AFS_RXK5 if (authtype & FORCE_RXK5) break; #endif } afscred = outcred; if (code) { afs_com_err(rn, code, "Unable to get credentials to use %s", outname); KLOGEXIT(code); } #ifdef AFS_RXK5 if (authtype & FORCE_RXK5) { struct ktc_principal aserver[1]; int viceid = 555; memset(aserver, 0, sizeof *aserver); strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1); code = ktc_SetK5Token(k5context, aserver, afscred, viceid, dosetpag); if (code) { afs_com_err(rn, code, "Unable to store tokens for cell %s\n", cellconfig->name); KLOGEXIT(1); } } else #endif { struct ktc_principal aserver[1], aclient[1]; struct ktc_token atoken[1]; memset(atoken, 0, sizeof *atoken); if (evil) { size_t elen = enc_part->length; atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY; if (afs_krb5_skip_ticket_wrapper(afscred->ticket.data, afscred->ticket.length, (char **) &enc_part->data, &elen)) { afs_com_err(rn, 0, "Can't unwrap %s AFS credential", cellconfig->name); KLOGEXIT(1); } } else { atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5; *enc_part = afscred->ticket; } atoken->startTime = afscred->times.starttime; atoken->endTime = afscred->times.endtime; if (tkt_DeriveDesKey(get_creds_enctype(afscred), get_cred_keydata(afscred), get_cred_keylen(afscred), &atoken->sessionKey)) { afs_com_err(rn, 0, "Cannot derive DES key from enctype %i of length %u", get_creds_enctype(afscred), (unsigned)get_cred_keylen(afscred)); KLOGEXIT(1); } memcpy(atoken->ticket, enc_part->data, atoken->ticketLen = enc_part->length); memset(aserver, 0, sizeof *aserver); strncpy(aserver->name, "afs", 4); strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1); memset(aclient, 0, sizeof *aclient); i = realm_len(k5context, afscred->client); if (i > MAXKTCREALMLEN-1) i = MAXKTCREALMLEN-1; memcpy(aclient->cell, realm_data(k5context, afscred->client), i); if (!noprdb) { int viceid = 0; k5_to_k4_name(k5context, afscred->client, aclient); code = whoami(atoken, cellconfig, aclient, &viceid); if (code) { afs_com_err(rn, code, "Can't get your viceid for cell %s", cellconfig->name); *aclient->name = 0; } else snprintf(aclient->name, MAXKTCNAMELEN-1, "AFS ID %d", viceid); } if (!*aclient->name) k5_to_k4_name(k5context, afscred->client, aclient); code = ktc_SetToken(aserver, atoken, aclient, dosetpag); if (code) { afs_com_err(rn, code, "Unable to store tokens for cell %s\n", cellconfig->name); KLOGEXIT(1); } } krb5_free_principal(k5context, princ); krb5_free_cred_contents(k5context, incred); if (outcred) krb5_free_creds(k5context, outcred); if (cc) krb5_cc_close(k5context, cc); if (tofree) free(tofree); return 0; }
static void test_princ(krb5_context context) { const char *princ = "*****@*****.**"; const char *princ_short = "lha"; const char *noquote; krb5_error_code ret; char *princ_unparsed; char *princ_reformed = NULL; const char *realm; krb5_principal p, p2; ret = krb5_parse_name(context, princ, &p); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); ret = krb5_unparse_name(context, p, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (strcmp(princ, princ_unparsed)) { krb5_errx(context, 1, "%s != %s", princ, princ_unparsed); } free(princ_unparsed); ret = krb5_unparse_name_flags(context, p, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (strcmp(princ_short, princ_unparsed)) krb5_errx(context, 1, "%s != %s", princ_short, princ_unparsed); free(princ_unparsed); realm = krb5_principal_get_realm(context, p); if (asprintf(&princ_reformed, "%s@%s", princ_short, realm) < 0 || princ_reformed == NULL) errx(1, "malloc"); ret = krb5_parse_name(context, princ_reformed, &p2); free(princ_reformed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (!krb5_principal_compare(context, p, p2)) { krb5_errx(context, 1, "p != p2"); } krb5_free_principal(context, p2); ret = krb5_set_default_realm(context, "SU.SE"); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); ret = krb5_unparse_name_flags(context, p, KRB5_PRINCIPAL_UNPARSE_SHORT, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (strcmp(princ_short, princ_unparsed)) krb5_errx(context, 1, "'%s' != '%s'", princ_short, princ_unparsed); free(princ_unparsed); ret = krb5_parse_name(context, princ_short, &p2); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (!krb5_principal_compare(context, p, p2)) krb5_errx(context, 1, "p != p2"); krb5_free_principal(context, p2); ret = krb5_unparse_name(context, p, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (strcmp(princ, princ_unparsed)) krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed); free(princ_unparsed); ret = krb5_set_default_realm(context, "SAMBA.ORG"); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); ret = krb5_parse_name(context, princ_short, &p2); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (krb5_principal_compare(context, p, p2)) krb5_errx(context, 1, "p == p2"); if (!krb5_principal_compare_any_realm(context, p, p2)) krb5_errx(context, 1, "(ignoring realms) p != p2"); ret = krb5_unparse_name(context, p2, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (strcmp(princ, princ_unparsed) == 0) krb5_errx(context, 1, "%s == %s", princ, princ_unparsed); free(princ_unparsed); krb5_free_principal(context, p2); ret = krb5_parse_name(context, princ, &p2); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (!krb5_principal_compare(context, p, p2)) krb5_errx(context, 1, "p != p2"); ret = krb5_unparse_name(context, p2, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (strcmp(princ, princ_unparsed)) krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed); free(princ_unparsed); krb5_free_principal(context, p2); ret = krb5_unparse_name_flags(context, p, KRB5_PRINCIPAL_UNPARSE_SHORT, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name_short"); if (strcmp(princ, princ_unparsed) != 0) krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed); free(princ_unparsed); ret = krb5_unparse_name(context, p, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name_short"); if (strcmp(princ, princ_unparsed)) krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed); free(princ_unparsed); ret = krb5_parse_name_flags(context, princ, KRB5_PRINCIPAL_PARSE_NO_REALM, &p2); if (!ret) krb5_err(context, 1, ret, "Should have failed to parse %s a " "short name", princ); ret = krb5_parse_name_flags(context, princ_short, KRB5_PRINCIPAL_PARSE_NO_REALM, &p2); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); ret = krb5_unparse_name_flags(context, p2, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &princ_unparsed); krb5_free_principal(context, p2); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name_norealm"); if (strcmp(princ_short, princ_unparsed)) krb5_errx(context, 1, "'%s' != '%s'", princ_short, princ_unparsed); free(princ_unparsed); ret = krb5_parse_name_flags(context, princ_short, KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &p2); if (!ret) krb5_err(context, 1, ret, "Should have failed to parse %s " "because it lacked a realm", princ_short); ret = krb5_parse_name_flags(context, princ, KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &p2); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); if (!krb5_principal_compare(context, p, p2)) krb5_errx(context, 1, "p != p2"); ret = krb5_unparse_name_flags(context, p2, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &princ_unparsed); krb5_free_principal(context, p2); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name_norealm"); if (strcmp(princ_short, princ_unparsed)) krb5_errx(context, 1, "'%s' != '%s'", princ_short, princ_unparsed); free(princ_unparsed); krb5_free_principal(context, p); /* test quoting */ princ = "test\\ [email protected]"; noquote = "test [email protected]"; ret = krb5_parse_name_flags(context, princ, 0, &p); if (ret) krb5_err(context, 1, ret, "krb5_parse_name"); ret = krb5_unparse_name_flags(context, p, 0, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name_flags"); if (strcmp(princ, princ_unparsed)) krb5_errx(context, 1, "q '%s' != '%s'", princ, princ_unparsed); free(princ_unparsed); ret = krb5_unparse_name_flags(context, p, KRB5_PRINCIPAL_UNPARSE_DISPLAY, &princ_unparsed); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name_flags"); if (strcmp(noquote, princ_unparsed)) krb5_errx(context, 1, "nq '%s' != '%s'", noquote, princ_unparsed); free(princ_unparsed); krb5_free_principal(context, p); }
int main(int argc, char **argv) { struct testcase *t; krb5_context context; krb5_error_code ret; int val = 0; ret = krb5_init_context (&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); /* to enable realm-less principal name above */ krb5_set_default_realm(context, ""); for (t = tests; t->input_string; ++t) { krb5_principal princ; int i, j; char name_buf[1024]; char *s; ret = krb5_parse_name(context, t->input_string, &princ); if (ret) krb5_err (context, 1, ret, "krb5_parse_name %s", t->input_string); if (strcmp (t->realm, princ->realm) != 0) { printf ("wrong realm (\"%s\" should be \"%s\")" " for \"%s\"\n", princ->realm, t->realm, t->input_string); val = 1; } if (t->ncomponents != princ->name.name_string.len) { printf ("wrong number of components (%u should be %u)" " for \"%s\"\n", princ->name.name_string.len, t->ncomponents, t->input_string); val = 1; } else { for (i = 0; i < t->ncomponents; ++i) { if (strcmp(t->comp_val[i], princ->name.name_string.val[i]) != 0) { printf ("bad component %d (\"%s\" should be \"%s\")" " for \"%s\"\n", i, princ->name.name_string.val[i], t->comp_val[i], t->input_string); val = 1; } } } for (j = 0; j < strlen(t->output_string); ++j) { ret = krb5_unparse_name_fixed(context, princ, name_buf, j); if (ret != ERANGE) { printf ("unparse_name %s with length %d should have failed\n", t->input_string, j); val = 1; break; } } ret = krb5_unparse_name_fixed(context, princ, name_buf, sizeof(name_buf)); if (ret) krb5_err (context, 1, ret, "krb5_unparse_name_fixed"); if (strcmp (t->output_string, name_buf) != 0) { printf ("failed comparing the re-parsed" " (\"%s\" should be \"%s\")\n", name_buf, t->output_string); val = 1; } ret = krb5_unparse_name(context, princ, &s); if (ret) krb5_err (context, 1, ret, "krb5_unparse_name"); if (strcmp (t->output_string, s) != 0) { printf ("failed comparing the re-parsed" " (\"%s\" should be \"%s\"\n", s, t->output_string); val = 1; } free(s); if (!t->realmp) { for (j = 0; j < strlen(t->input_string); ++j) { ret = krb5_unparse_name_fixed_short(context, princ, name_buf, j); if (ret != ERANGE) { printf ("unparse_name_short %s with length %d" " should have failed\n", t->input_string, j); val = 1; break; } } ret = krb5_unparse_name_fixed_short(context, princ, name_buf, sizeof(name_buf)); if (ret) krb5_err (context, 1, ret, "krb5_unparse_name_fixed"); if (strcmp (t->input_string, name_buf) != 0) { printf ("failed comparing the re-parsed" " (\"%s\" should be \"%s\")\n", name_buf, t->input_string); val = 1; } ret = krb5_unparse_name_short(context, princ, &s); if (ret) krb5_err (context, 1, ret, "krb5_unparse_name_short"); if (strcmp (t->input_string, s) != 0) { printf ("failed comparing the re-parsed" " (\"%s\" should be \"%s\"\n", s, t->input_string); val = 1; } free(s); } krb5_free_principal (context, princ); } krb5_free_context(context); return val; }