static krb5_error_code init_context_from_config_file(krb5_context context) { krb5_error_code ret; const char * tmp; char **s; krb5_enctype *tmptypes; INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew"); INIT_FIELD(context, time, kdc_timeout, 30, "kdc_timeout"); INIT_FIELD(context, time, host_timeout, 3, "host_timeout"); INIT_FIELD(context, int, max_retries, 3, "max_retries"); INIT_FIELD(context, string, http_proxy, NULL, "http_proxy"); ret = krb5_config_get_bool_default(context, NULL, FALSE, "libdefaults", "allow_weak_crypto", NULL); if (ret) { krb5_enctype_enable(context, ETYPE_DES_CBC_CRC); krb5_enctype_enable(context, ETYPE_DES_CBC_MD4); krb5_enctype_enable(context, ETYPE_DES_CBC_MD5); krb5_enctype_enable(context, ETYPE_DES_CBC_NONE); krb5_enctype_enable(context, ETYPE_DES_CFB64_NONE); krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE); } ret = set_etypes (context, "default_etypes", &tmptypes); if(ret) return ret; free(context->etypes); context->etypes = tmptypes; ret = set_etypes (context, "default_etypes_des", &tmptypes); if(ret) return ret; free(context->etypes_des); context->etypes_des = tmptypes; ret = set_etypes (context, "default_as_etypes", &tmptypes); if(ret) return ret; free(context->as_etypes); context->as_etypes = tmptypes; ret = set_etypes (context, "default_tgs_etypes", &tmptypes); if(ret) return ret; free(context->tgs_etypes); context->tgs_etypes = tmptypes; ret = set_etypes (context, "permitted_enctypes", &tmptypes); if(ret) return ret; free(context->permitted_enctypes); context->permitted_enctypes = tmptypes; /* default keytab name */ tmp = NULL; if(!issuid()) tmp = getenv("KRB5_KTNAME"); if(tmp != NULL) context->default_keytab = tmp; else INIT_FIELD(context, string, default_keytab, KEYTAB_DEFAULT, "default_keytab_name"); INIT_FIELD(context, string, default_keytab_modify, NULL, "default_keytab_modify_name"); INIT_FIELD(context, string, time_fmt, "%Y-%m-%dT%H:%M:%S", "time_format"); INIT_FIELD(context, string, date_fmt, "%Y-%m-%d", "date_format"); INIT_FIELD(context, bool, log_utc, FALSE, "log_utc"); /* init dns-proxy slime */ tmp = krb5_config_get_string(context, NULL, "libdefaults", "dns_proxy", NULL); if(tmp) roken_gethostby_setup(context->http_proxy, tmp); krb5_free_host_realm (context, context->default_realms); context->default_realms = NULL; { krb5_addresses addresses; char **adr, **a; krb5_set_extra_addresses(context, NULL); adr = krb5_config_get_strings(context, NULL, "libdefaults", "extra_addresses", NULL); memset(&addresses, 0, sizeof(addresses)); for(a = adr; a && *a; a++) { ret = krb5_parse_address(context, *a, &addresses); if (ret == 0) { krb5_add_extra_addresses(context, &addresses); krb5_free_addresses(context, &addresses); } } krb5_config_free_strings(adr); krb5_set_ignore_addresses(context, NULL); adr = krb5_config_get_strings(context, NULL, "libdefaults", "ignore_addresses", NULL); memset(&addresses, 0, sizeof(addresses)); for(a = adr; a && *a; a++) { ret = krb5_parse_address(context, *a, &addresses); if (ret == 0) { krb5_add_ignore_addresses(context, &addresses); krb5_free_addresses(context, &addresses); } } krb5_config_free_strings(adr); } INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces"); INIT_FIELD(context, int, fcache_vno, 0, "fcache_version"); /* prefer dns_lookup_kdc over srv_lookup. */ INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup"); INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc"); INIT_FIELD(context, int, large_msg_size, 1400, "large_message_size"); INIT_FIELD(context, int, max_msg_size, 1000 * 1024, "maximum_message_size"); INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname"); INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac"); if (context->default_cc_name) free(context->default_cc_name); context->default_cc_name = NULL; context->default_cc_name_set = 0; s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL); if(s) { char **p; if (context->debug_dest) krb5_closelog(context, context->debug_dest); krb5_initlog(context, "libkrb5", &context->debug_dest); for(p = s; *p; p++) krb5_addlog_dest(context, context->debug_dest, *p); krb5_config_free_strings(s); } tmp = krb5_config_get_string(context, NULL, "libdefaults", "check-rd-req-server", NULL); if (tmp == NULL && !issuid()) tmp = getenv("KRB5_CHECK_RD_REQ_SERVER"); if(tmp) { if (strcasecmp(tmp, "ignore") == 0) context->flags |= KRB5_CTX_F_RD_REQ_IGNORE; } ret = krb5_config_get_bool_default(context, NULL, TRUE, "libdefaults", "fcache_strict_checking", NULL); if (ret) context->flags |= KRB5_CTX_F_FCACHE_STRICT_CHECKING; return 0; }
int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_ccache ccache; krb5_principal principal = NULL; int optidx = 0; krb5_deltat ticket_life = 0; #ifdef HAVE_SIGACTION struct sigaction sa; #endif setprogname(argv[0]); setlocale(LC_ALL, ""); bindtextdomain("heimdal_kuser", HEIMDAL_LOCALEDIR); textdomain("heimdal_kuser"); ret = krb5_init_context(&context); if (ret == KRB5_CONFIG_BADFORMAT) errx(1, "krb5_init_context failed to parse configuration file"); else if (ret) errx(1, "krb5_init_context failed: %d", ret); if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage(1); if (help_flag) usage(0); if (version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; /* * Open the keytab now, we use the keytab to determine the principal's * realm when the requested principal has no realm. */ if (use_keytab || keytab_str) { if (keytab_str) ret = krb5_kt_resolve(context, keytab_str, &kt); else ret = krb5_kt_default(context, &kt); if (ret) krb5_err(context, 1, ret, "resolving keytab"); } if (pk_enterprise_flag) { ret = krb5_pk_enterprise_cert(context, pk_user_id, argv[0], &principal, &ent_user_id); if (ret) krb5_err(context, 1, ret, "krb5_pk_enterprise_certs"); pk_user_id = NULL; } else if (anonymous_flag) { ret = krb5_make_principal(context, &principal, argv[0], KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, NULL); if (ret) krb5_err(context, 1, ret, "krb5_make_principal"); krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN); } else if (use_keytab || keytab_str) { get_princ_kt(context, &principal, argv[0]); } else { get_princ(context, &principal, argv[0]); } if (fcache_version) krb5_set_fcache_version(context, fcache_version); if (renewable_flag == -1) /* this seems somewhat pointless, but whatever */ krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), "renewable", FALSE, &renewable_flag); if (do_afslog == -1) krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), "afslog", TRUE, &do_afslog); if (cred_cache) ret = krb5_cc_resolve(context, cred_cache, &ccache); else { if (argc > 1) { char s[1024]; ret = krb5_cc_new_unique(context, NULL, NULL, &ccache); if (ret) krb5_err(context, 1, ret, "creating cred cache"); snprintf(s, sizeof(s), "%s:%s", krb5_cc_get_type(context, ccache), krb5_cc_get_name(context, ccache)); setenv("KRB5CCNAME", s, 1); } else { ret = krb5_cc_cache_match(context, principal, &ccache); if (ret) { const char *type; ret = krb5_cc_default(context, &ccache); if (ret) krb5_err(context, 1, ret, N_("resolving credentials cache", "")); /* * Check if the type support switching, and we do, * then do that instead over overwriting the current * default credential */ type = krb5_cc_get_type(context, ccache); if (krb5_cc_support_switch(context, type)) { krb5_cc_close(context, ccache); ret = get_switched_ccache(context, type, principal, &ccache); } } } } if (ret) krb5_err(context, 1, ret, N_("resolving credentials cache", "")); #ifndef NO_AFS if (argc > 1 && k_hasafs()) k_setpag(); #endif if (lifetime) { int tmp = parse_time(lifetime, "s"); if (tmp < 0) errx(1, N_("unparsable time: %s", ""), lifetime); ticket_life = tmp; } if (addrs_flag == 0 && extra_addresses.num_strings > 0) krb5_errx(context, 1, N_("specifying both extra addresses and " "no addresses makes no sense", "")); { int i; krb5_addresses addresses; memset(&addresses, 0, sizeof(addresses)); for(i = 0; i < extra_addresses.num_strings; i++) { ret = krb5_parse_address(context, extra_addresses.strings[i], &addresses); if (ret == 0) { krb5_add_extra_addresses(context, &addresses); krb5_free_addresses(context, &addresses); } } free_getarg_strings(&extra_addresses); } if (renew_flag || validate_flag) { ret = renew_validate(context, renew_flag, validate_flag, ccache, server_str, ticket_life); #ifndef NO_AFS if (ret == 0 && server_str == NULL && do_afslog && k_hasafs()) krb5_afslog(context, ccache, NULL, NULL); #endif exit(ret != 0); } ret = get_new_tickets(context, principal, ccache, ticket_life, 1); if (ret) exit(1); #ifndef NO_AFS if (ret == 0 && server_str == NULL && do_afslog && k_hasafs()) krb5_afslog(context, ccache, NULL, NULL); #endif if (argc > 1) { struct renew_ctx ctx; time_t timeout; timeout = ticket_lifetime(context, ccache, principal, server_str, NULL) / 2; ctx.context = context; ctx.ccache = ccache; ctx.principal = principal; ctx.ticket_life = ticket_life; ctx.timeout = timeout; #ifdef HAVE_SIGACTION memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_handler = handle_siginfo; sigaction(SIGINFO, &sa, NULL); #endif ret = simple_execvp_timed(argv[1], argv+1, renew_func, &ctx, timeout); #define EX_NOEXEC 126 #define EX_NOTFOUND 127 if (ret == EX_NOEXEC) krb5_warnx(context, N_("permission denied: %s", ""), argv[1]); else if (ret == EX_NOTFOUND) krb5_warnx(context, N_("command not found: %s", ""), argv[1]); krb5_cc_destroy(context, ccache); #ifndef NO_AFS if (k_hasafs()) k_unlog(); #endif } else { krb5_cc_close(context, ccache); ret = 0; } krb5_free_principal(context, principal); if (kt) krb5_kt_close(context, kt); krb5_free_context(context); return ret; }
int main (int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_ccache ccache; krb5_principal principal; int optidx = 0; krb5_deltat ticket_life = 0; int parseflags = 0; setprogname (argv[0]); setlocale (LC_ALL, ""); #if defined(HEIMDAL_LOCALEDIR) bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); textdomain("heimdal_kuser"); #endif ret = krb5_init_context (&context); if (ret == KRB5_CONFIG_BADFORMAT) errx (1, "krb5_init_context failed to parse configuration file"); else if (ret) errx(1, "krb5_init_context failed: %d", ret); if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if(version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (canonicalize_flag) parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE; if (argv[0]) { ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal); if (ret) krb5_err (context, 1, ret, "krb5_parse_name"); } else { ret = krb5_get_default_principal (context, &principal); if (ret) krb5_err (context, 1, ret, "krb5_get_default_principal"); } if(fcache_version) krb5_set_fcache_version(context, fcache_version); if(renewable_flag == -1) /* this seems somewhat pointless, but whatever */ krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), "renewable", FALSE, &renewable_flag); #ifndef HEIMDAL_SMALLER if(get_v4_tgt == -1) krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), "krb4_get_tickets", FALSE, &get_v4_tgt); #endif if(do_afslog == -1) krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), "afslog", TRUE, &do_afslog); if(cred_cache) ret = krb5_cc_resolve(context, cred_cache, &ccache); else { if(argc > 1) { char s[1024]; ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache); if(ret) krb5_err(context, 1, ret, "creating cred cache"); snprintf(s, sizeof(s), "%s:%s", krb5_cc_get_type(context, ccache), krb5_cc_get_name(context, ccache)); setenv("KRB5CCNAME", s, 1); #ifndef HEIMDAL_SMALLER if (get_v4_tgt) { int fd; if (asprintf(&krb4_cc_name, "%s_XXXXXX", TKT_ROOT) < 0) krb5_errx(context, 1, "out of memory"); if((fd = mkstemp(krb4_cc_name)) >= 0) { close(fd); setenv("KRBTKFILE", krb4_cc_name, 1); } else { free(krb4_cc_name); krb4_cc_name = NULL; } } #endif } else { ret = krb5_cc_cache_match(context, principal, &ccache); if (ret) ret = krb5_cc_default (context, &ccache); } } if (ret) krb5_err (context, 1, ret, N_("resolving credentials cache", "")); if(argc > 1 && k_hasafs ()) k_setpag(); if (lifetime) { int tmp = parse_time (lifetime, "s"); if (tmp < 0) errx (1, N_("unparsable time: %s", ""), lifetime); ticket_life = tmp; } if(addrs_flag == 0 && extra_addresses.num_strings > 0) krb5_errx(context, 1, N_("specifying both extra addresses and " "no addresses makes no sense", "")); { int i; krb5_addresses addresses; memset(&addresses, 0, sizeof(addresses)); for(i = 0; i < extra_addresses.num_strings; i++) { ret = krb5_parse_address(context, extra_addresses.strings[i], &addresses); if (ret == 0) { krb5_add_extra_addresses(context, &addresses); krb5_free_addresses(context, &addresses); } } free_getarg_strings(&extra_addresses); } if(renew_flag || validate_flag) { ret = renew_validate(context, renew_flag, validate_flag, ccache, server_str, ticket_life); exit(ret != 0); } #ifndef HEIMDAL_SMALLER if(!convert_524) #endif get_new_tickets(context, principal, ccache, ticket_life, 1); #ifndef HEIMDAL_SMALLER if(get_v4_tgt || convert_524) do_524init(context, ccache, NULL, server_str); #endif if(do_afslog && k_hasafs()) krb5_afslog(context, ccache, NULL, NULL); if(argc > 1) { struct renew_ctx ctx; time_t timeout; timeout = ticket_lifetime(context, ccache, principal, server_str) / 2; ctx.context = context; ctx.ccache = ccache; ctx.principal = principal; ctx.ticket_life = ticket_life; ret = simple_execvp_timed(argv[1], argv+1, renew_func, &ctx, timeout); #define EX_NOEXEC 126 #define EX_NOTFOUND 127 if(ret == EX_NOEXEC) krb5_warnx(context, N_("permission denied: %s", ""), argv[1]); else if(ret == EX_NOTFOUND) krb5_warnx(context, N_("command not found: %s", ""), argv[1]); krb5_cc_destroy(context, ccache); #ifndef HEIMDAL_SMALLER _krb5_krb_dest_tkt(context, krb4_cc_name); #endif if(k_hasafs()) k_unlog(); } else { krb5_cc_close (context, ccache); ret = 0; } krb5_free_principal(context, principal); krb5_free_context (context); return ret; }