int ext_keytab(struct ext_keytab_options *opt, int argc, char **argv) { krb5_error_code ret; int i; struct ext_keytab_data data; if (opt->keytab_string == NULL) ret = krb5_kt_default(context, &data.keytab); else ret = krb5_kt_resolve(context, opt->keytab_string, &data.keytab); if(ret){ krb5_warn(context, ret, "krb5_kt_resolve"); return 1; } for(i = 0; i < argc; i++) { ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data); if (ret) break; } krb5_kt_close(context, data.keytab); return ret != 0; }
krb5_error_code KRB5_LIB_FUNCTION krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keyblock **key) { krb5_keytab keytab; krb5_keytab_entry entry; krb5_error_code ret; if (keyprocarg) ret = krb5_kt_resolve (context, keyprocarg, &keytab); else ret = krb5_kt_default (context, &keytab); if (ret) return ret; ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry); krb5_kt_close (context, keytab); if (ret) return ret; ret = krb5_copy_keyblock (context, &entry.keyblock, key); krb5_kt_free_entry(context, &entry); return ret; }
KRB5_DEPRECATED KRB5_LIB_FUNCTION krb5_error_code KRB5_CALLCONV krb5_keytab_key_proc (krb5_context context, krb5_enctype enctype, krb5_salt salt, krb5_const_pointer keyseed, krb5_keyblock **key) { krb5_keytab_key_proc_args *args = rk_UNCONST(keyseed); krb5_keytab keytab = args->keytab; krb5_principal principal = args->principal; krb5_error_code ret; krb5_keytab real_keytab; krb5_keytab_entry entry; if(keytab == NULL) krb5_kt_default(context, &real_keytab); else real_keytab = keytab; ret = krb5_kt_get_entry (context, real_keytab, principal, 0, enctype, &entry); if (keytab == NULL) krb5_kt_close (context, real_keytab); if (ret) return ret; ret = krb5_copy_keyblock (context, &entry.keyblock, key); krb5_kt_free_entry(context, &entry); return ret; }
mit_krb5_error_code KRB5_CALLCONV krb5_kt_read_service_key(mit_krb5_context context, mit_krb5_pointer keyprocarg, mit_krb5_principal principal, mit_krb5_kvno vno, mit_krb5_enctype enctype, mit_krb5_keyblock **key) { mit_krb5_keytab keytab; mit_krb5_keytab_entry entry; mit_krb5_error_code ret; LOG_ENTRY(); if (keyprocarg) ret = krb5_kt_resolve (context, keyprocarg, &keytab); else ret = krb5_kt_default (context, &keytab); if (ret) return ret; ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry); krb5_kt_close (context, keytab); if (ret) return ret; ret = krb5_copy_keyblock (context, &entry.key, key); krb5_kt_free_entry(context, &entry); return ret; }
int kerberos5_init(Authenticator *ap, int server) { krb5_error_code ret; ret = krb5_init_context(&context); if (ret) return 0; if (server) { krb5_keytab kt; krb5_kt_cursor cursor; ret = krb5_kt_default(context, &kt); if (ret) return 0; ret = krb5_kt_start_seq_get (context, kt, &cursor); if (ret) { krb5_kt_close (context, kt); return 0; } krb5_kt_end_seq_get (context, kt, &cursor); krb5_kt_close (context, kt); str_data[3] = TELQUAL_REPLY; } else str_data[3] = TELQUAL_IS; return(1); }
krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, krb5_keytab arg_keytab, krb5_ccache ccache, krb5_creds *creds, krb5_kdc_rep **ret_as_reply) { krb5_error_code retval; krb5_gic_opt_ext *opte; char * server = NULL; krb5_keytab keytab; krb5_principal client_princ, server_princ; int use_master = 0; retval = krb5int_populate_gic_opt(context, &opte, options, addrs, ktypes, pre_auth_types, creds); if (retval) return retval; if (arg_keytab == NULL) { retval = krb5_kt_default(context, &keytab); if (retval) return retval; } else keytab = arg_keytab; retval = krb5_unparse_name( context, creds->server, &server); if (retval) goto cleanup; server_princ = creds->server; client_princ = creds->client; retval = krb5_get_init_creds (context, creds, creds->client, krb5_prompter_posix, NULL, 0, server, opte, krb5_get_as_key_keytab, (void *)keytab, &use_master, ret_as_reply); krb5_free_unparsed_name( context, server); krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte); if (retval) { goto cleanup; } if (creds->server) krb5_free_principal( context, creds->server); if (creds->client) krb5_free_principal( context, creds->client); creds->client = client_princ; creds->server = server_princ; /* store it in the ccache! */ if (ccache) if ((retval = krb5_cc_store_cred(context, ccache, creds))) goto cleanup; cleanup: if (arg_keytab == NULL) krb5_kt_close(context, keytab); return retval; }
int kssl_keytab_is_available(KSSL_CTX *kssl_ctx) { krb5_context krb5context = NULL; krb5_keytab krb5keytab = NULL; krb5_keytab_entry entry; krb5_principal princ = NULL; krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; int rc = 0; if ((krb5rc = krb5_init_context(&krb5context))) return (0); /* kssl_ctx->keytab_file == NULL ==> use Kerberos default */ if (kssl_ctx->keytab_file) { krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, &krb5keytab); if (krb5rc) goto exit; } else { krb5rc = krb5_kt_default(krb5context, &krb5keytab); if (krb5rc) goto exit; } /* the host key we are looking for */ krb5rc = krb5_sname_to_principal(krb5context, NULL, kssl_ctx->service_name ? kssl_ctx->service_name : KRB5SVC, KRB5_NT_SRV_HST, &princ); if (krb5rc) goto exit; krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, 0 /* IGNORE_VNO */, 0 /* IGNORE_ENCTYPE */, &entry); if (krb5rc == KRB5_KT_NOTFOUND) { rc = 1; goto exit; } else if (krb5rc) goto exit; krb5_kt_free_entry(krb5context, &entry); rc = 1; exit: if (krb5keytab) krb5_kt_close(krb5context, krb5keytab); if (princ) krb5_free_principal(krb5context, princ); if (krb5context) krb5_free_context(krb5context); return (rc); }
Krb5Keytab::Krb5Keytab(krb5_context context, const std::string& name) : context_(context) , keytab_(nullptr) { if (name.empty()) { krb5_error_code code = krb5_kt_default(context, &keytab_); raiseIf(context, code, "getting default keytab"); } else { krb5_error_code code = krb5_kt_resolve(context, name.c_str(), &keytab_); raiseIf(context, code, folly::to<std::string>( "failed to open keytab: ", name)); } }
/** Create and return a new connection * * libkrb5(s) can talk to the KDC over TCP. Were assuming something sane is implemented * by libkrb5 and that it does connection caching associated with contexts, so it's * worth using a connection pool to preserve connections when workers die. * * @param instance rlm_krb5 instance instance. * @return A new context or NULL on error. */ void *mod_conn_create(void *instance) { rlm_krb5_t *inst = instance; rlm_krb5_handle_t *conn; krb5_error_code ret; MEM(conn = talloc_zero(instance, rlm_krb5_handle_t)); ret = krb5_init_context(&conn->context); if (ret) { ERROR("rlm_krb5 (%s): Context initialisation failed: %s", inst->xlat_name, rlm_krb5_error(NULL, ret)); return NULL; } talloc_set_destructor(conn, _free_handle); ret = inst->keytabname ? krb5_kt_resolve(conn->context, inst->keytabname, &conn->keytab) : krb5_kt_default(conn->context, &conn->keytab); if (ret) { ERROR("Resolving keytab failed: %s", rlm_krb5_error(conn->context, ret)); goto cleanup; } #ifdef HEIMDAL_KRB5 ret = krb5_cc_new_unique(conn->context, "MEMORY", NULL, &conn->ccache); if (ret) { ERROR("rlm_krb5 (%s): Credential cache creation failed: %s", inst->xlat_name, rlm_krb5_error(conn->context, ret)); return NULL; } krb5_verify_opt_init(&conn->options); krb5_verify_opt_set_ccache(&conn->options, conn->ccache); krb5_verify_opt_set_keytab(&conn->options, conn->keytab); krb5_verify_opt_set_secure(&conn->options, true); if (inst->service) { krb5_verify_opt_set_service(&conn->options, inst->service); } #else krb5_verify_init_creds_opt_set_ap_req_nofail(inst->vic_options, true); #endif return conn; cleanup: talloc_free(conn); return NULL; }
static PyObject * k5_get_init_creds_keytab(PyObject *self, PyObject *args) { char *name, *ktname; krb5_context ctx; krb5_error_code code; krb5_keytab keytab; krb5_ccache ccache; krb5_principal principal; krb5_get_init_creds_opt options; krb5_creds creds; if (!PyArg_ParseTuple(args, "sz", &name, &ktname)) return NULL; /* Initialize parameters. */ code = krb5_init_context(&ctx); RETURN_ON_ERROR("krb5_init_context()", code); code = krb5_parse_name(ctx, name, &principal); RETURN_ON_ERROR("krb5_parse_name()", code); krb5_get_init_creds_opt_init(&options); memset(&creds, 0, sizeof (creds)); /* Resolve keytab */ if (ktname) { code = krb5_kt_resolve(ctx, ktname, &keytab); RETURN_ON_ERROR("krb5_kt_resolve()", code); } else { code = krb5_kt_default(ctx, &keytab); RETURN_ON_ERROR("krb5_kt_resolve()", code); } /* Get the credentials. */ code = krb5_get_init_creds_keytab(ctx, &creds, principal, keytab, 0, NULL, &options); RETURN_ON_ERROR("krb5_get_init_creds_keytab()", code); /* Store the credential in the credential cache. */ code = krb5_cc_default(ctx, &ccache); RETURN_ON_ERROR("krb5_cc_default()", code); code = krb5_cc_initialize(ctx, ccache, principal); RETURN_ON_ERROR("krb5_cc_initialize()", code); code = krb5_cc_store_cred(ctx, ccache, &creds); RETURN_ON_ERROR("krb5_cc_store_creds()", code); krb5_cc_close(ctx, ccache); Py_INCREF(Py_None); return Py_None; }
int server_setup(krb5_context *context, int argc, char **argv) { int port = common_setup(context, &argc, argv, server_usage); krb5_error_code ret; if(argv[argc] != NULL) server_usage(1, args, num_args); if (keytab_str != NULL) ret = krb5_kt_resolve (*context, keytab_str, &keytab); else ret = krb5_kt_default (*context, &keytab); if (ret) krb5_err (*context, 1, ret, "krb5_kt_resolve/default"); return port; }
static int k5ping(krb5_context ctx, const char *host, int socktype, krb5_principal princ, int use_kt, const char *passwd, krb5_principal sprinc) { K5BAIL_DECLS; krb5_error_code kerr; krb5_ccache ccache = NULL; krb5_keytab kt; krb5_creds creds; krb5_get_init_creds_opt *opt = NULL; VERBOSE(1, (stderr, "initiating kerberos5/%s ping to %s\n", socktype == SOCK_DGRAM ? "udp" : "tcp", host)); parse_kdc(host); current_socktype = socktype; K5BAIL(krb5_cc_resolve(ctx, "MEMORY:k5ping", &ccache)); K5BAIL(krb5_get_init_creds_opt_alloc(ctx, &opt)); krb5_get_init_creds_opt_set_tkt_life(opt, 15 * 60); if (use_kt) { K5BAIL(krb5_kt_default(ctx, &kt)); K5BAIL(krb5_get_init_creds_keytab(ctx, &creds, princ, kt, 0, NULL, opt)); } else { K5BAIL(krb5_get_init_creds_password(ctx, &creds, princ, passwd, krb5_prompter_posix, NULL, 0, NULL, opt)); } K5BAIL(krb5_cc_store_cred(ctx, ccache, &creds)); kret = kvno5(ctx, host, socktype, princ, sprinc, ccache); done: if (ccache) krb5_cc_destroy(ctx, ccache); /* XXXrcd: free a few more things here... */ /* opt. creds. */ if (croakstr[0]) fail_msg("kerberos5", socktype, host, croakstr); return kret; }
OM_uint32 _gsskrb5_register_acceptor_identity(OM_uint32 *min_stat, const char *identity) { krb5_context context; krb5_error_code ret; *min_stat = 0; ret = _gsskrb5_init(&context); if(ret) return GSS_S_FAILURE; HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); if(_gsskrb5_keytab != NULL) { krb5_kt_close(context, _gsskrb5_keytab); _gsskrb5_keytab = NULL; } if (identity == NULL) { ret = krb5_kt_default(context, &_gsskrb5_keytab); } else { /* * First check if we can the keytab as is and if it has content... */ ret = validate_keytab(context, identity, &_gsskrb5_keytab); /* * if it doesn't, lets prepend FILE: and try again */ if (ret) { char *p = NULL; ret = asprintf(&p, "FILE:%s", identity); if(ret < 0 || p == NULL) { HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); return GSS_S_FAILURE; } ret = validate_keytab(context, p, &_gsskrb5_keytab); free(p); } } HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); if(ret) { *min_stat = ret; return GSS_S_FAILURE; } return GSS_S_COMPLETE; }
static int process_keytab(krb5_context my_context, char **keytab_str, krb5_keytab *keytab) { int code; char *name = *keytab_str; if (name == NULL) { name = malloc(BUFSIZ); if (!name) { com_err(whoami, ENOMEM, "while creating keytab name"); return 1; } code = krb5_kt_default(my_context, keytab); if (code != 0) { com_err(whoami, code, "while opening default keytab"); free(name); return 1; } code = krb5_kt_get_name(my_context, *keytab, name, BUFSIZ); if (code != 0) { com_err(whoami, code, "while getting keytab name"); free(name); return 1; } } else { if (strchr(name, ':') != NULL) name = strdup(name); else if (asprintf(&name, "WRFILE:%s", name) < 0) name = NULL; if (name == NULL) { com_err(whoami, ENOMEM, "while creating keytab name"); return 1; } code = krb5_kt_resolve(my_context, name, keytab); if (code != 0) { com_err(whoami, code, "while resolving keytab %s", name); free(name); return 1; } } *keytab_str = name; return 0; }
long kerberos_server_valid () { krb5_context ctx; krb5_keytab kt; krb5_kt_cursor csr; long ret = NIL; /* make a context */ if (!krb5_init_context (&ctx)) { /* get default keytab */ if (!krb5_kt_default (ctx,&kt)) { /* can do server if have good keytab */ if (!krb5_kt_start_seq_get (ctx,kt,&csr)) ret = LONGT; krb5_kt_close (ctx,kt); /* finished with keytab */ } krb5_free_context (ctx); /* finished with context */ } return ret; }
static void setup_env (krb5_context context, krb5_keytab *kt) { krb5_error_code ret; if (keytab_file) ret = krb5_kt_resolve (context, keytab_file, kt); else ret = krb5_kt_default (context, kt); if (ret) krb5_err (context, 1, ret, "resolving keytab"); if (client_principal_str == NULL) krb5_errx (context, 1, "missing client principal"); ret = krb5_parse_name (context, client_principal_str, &client_principal); if (ret) krb5_err (context, 1, ret, "resolvning client name"); if (server_principal_str == NULL) krb5_errx (context, 1, "missing server principal"); ret = krb5_parse_name (context, server_principal_str, &server_principal); if (ret) krb5_err (context, 1, ret, "resolvning server name"); /* If no session-enc-type specified on command line and this is an afs */ /* service ticket, change default of session_enc_type to DES. */ if (session_enctype_string == NULL && strcmp("afs", *server_principal->name.name_string.val) == 0) session_enc_type = "des-cbc-crc"; if (ticket_flags_str) { int ticket_flags_int; ticket_flags_int = parse_flags(ticket_flags_str, asn1_TicketFlags_units(), 0); if (ticket_flags_int <= 0) { krb5_warnx (context, "bad ticket flags: `%s'", ticket_flags_str); print_flags_table (asn1_TicketFlags_units(), stderr); exit (1); } if (ticket_flags_int) ticket_flags = int2TicketFlags (ticket_flags_int); } }
static krb5_error_code get_keytab(krb5_keytab *keytab) { char kt_name[256]; krb5_error_code kret; HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); if (gssapi_krb5_keytab != NULL) { kret = krb5_kt_get_name(gssapi_krb5_context, gssapi_krb5_keytab, kt_name, sizeof(kt_name)); if (kret == 0) kret = krb5_kt_resolve(gssapi_krb5_context, kt_name, keytab); } else kret = krb5_kt_default(gssapi_krb5_context, keytab); HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); return (kret); }
static krb5_error_code get_key_from_keytab(krb5_context context, krb5_auth_context *auth_context, krb5_ap_req *ap_req, krb5_const_principal server, krb5_keytab keytab, krb5_keyblock **out_key) { krb5_keytab_entry entry; krb5_error_code ret; int kvno; krb5_keytab real_keytab; if(keytab == NULL) krb5_kt_default(context, &real_keytab); else real_keytab = keytab; if (ap_req->ticket.enc_part.kvno) kvno = *ap_req->ticket.enc_part.kvno; else kvno = 0; ret = krb5_kt_get_entry (context, real_keytab, server, kvno, ap_req->ticket.enc_part.etype, &entry); if(ret) goto out; ret = krb5_copy_keyblock(context, &entry.keyblock, out_key); krb5_kt_free_entry (context, &entry); out: if(keytab == NULL) krb5_kt_close(context, real_keytab); return ret; }
static krb5_error_code get_keytab(krb5_context context, krb5_keytab *keytab) { krb5_error_code kret; HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); if (_gsskrb5_keytab != NULL) { char *name = NULL; kret = krb5_kt_get_full_name(context, _gsskrb5_keytab, &name); if (kret == 0) { kret = krb5_kt_resolve(context, name, keytab); krb5_xfree(name); } } else kret = krb5_kt_default(context, keytab); HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); return (kret); }
static void setup_env (krb5_context context, krb5_keytab *kt) { krb5_error_code ret; if (keytab_file) ret = krb5_kt_resolve (context, keytab_file, kt); else ret = krb5_kt_default (context, kt); if (ret) krb5_err (context, 1, ret, "resolving keytab"); if (client_principal_str == NULL) krb5_errx (context, 1, "missing client principal"); ret = krb5_parse_name (context, client_principal_str, &client_principal); if (ret) krb5_err (context, 1, ret, "resolvning client name"); if (server_principal_str == NULL) krb5_errx (context, 1, "missing server principal"); ret = krb5_parse_name (context, server_principal_str, &server_principal); if (ret) krb5_err (context, 1, ret, "resolvning client name"); if (ticket_flags_str) { int ticket_flags_int; ticket_flags_int = parse_flags(ticket_flags_str, asn1_TicketFlags_units(), 0); if (ticket_flags_int <= 0) { krb5_warnx (context, "bad ticket flags: `%s'", ticket_flags_str); print_flags_table (asn1_TicketFlags_units(), stderr); exit (1); } if (ticket_flags_int) ticket_flags = int2TicketFlags (ticket_flags_int); } }
int main(int argc, char **argv) { krb5_context kcontext = NULL; krb5_keytab kt = NULL; krb5_keytab_entry entry; krb5_kt_cursor cursor = NULL; krb5_error_code krb5_err; int matched = 0; char svc_name[] = "host"; int svc_name_len = strlen (svc_name); krb5_err = krb5_init_context(&kcontext); if (krb5_err) { goto Error; } krb5_err = krb5_kt_default(kcontext, &kt); if (krb5_err) { goto Error; } krb5_err = krb5_kt_start_seq_get(kcontext, kt, &cursor); if (krb5_err) { goto Error; } while ((matched == 0) && (krb5_err = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) { krb5_data *nameData = krb5_princ_name (kcontext, entry.principal); if (NULL != nameData->data && svc_name_len == nameData->length && 0 == strncmp (svc_name, nameData->data, nameData->length)) { matched = 1; } krb5_free_keytab_entry_contents(kcontext, &entry); } krb5_err = krb5_kt_end_seq_get(kcontext, kt, &cursor); Error: if (NULL != kt) { krb5_kt_close (kcontext, kt); } if (NULL != kcontext) { krb5_free_context (kcontext); } // Return 0 if we got match or -1 if err or no match return (0 != krb5_err) ? -1 : matched ? 0 : -1; }
int print_keytab (const char *in_name) { krb5_error_code err = 0; krb5_keytab kt; krb5_keytab_entry entry; krb5_kt_cursor cursor; char keytab_name[BUFSIZ]; /* hopefully large enough for any type */ if (!err) { if (!in_name) { err = krb5_kt_default (kcontext, &kt); printiferr (err, "while resolving default keytab"); } else { err = krb5_kt_resolve (kcontext, in_name, &kt); printiferr (err, "while resolving keytab %s", in_name); } } if (!err) { err = krb5_kt_get_name (kcontext, kt, keytab_name, sizeof (keytab_name)); printiferr (err, "while getting keytab name"); } if (!err) { printmsg ("Keytab name: %s\n", keytab_name); } if (!err) { err = krb5_kt_start_seq_get (kcontext, kt, &cursor); printiferr (err, "while starting scan of keytab %s", keytab_name); } if (!err) { if (show_entry_timestamps) { printmsg ("KVNO Timestamp"); printfiller (' ', get_timestamp_width () - sizeof ("Timestamp") + 2); printmsg ("Principal\n"); printmsg ("---- "); printfiller ('-', get_timestamp_width ()); printmsg (" "); printfiller ('-', 78 - get_timestamp_width () - sizeof ("KVNO")); printmsg ("\n"); } else { printmsg("KVNO Principal\n"); printmsg("---- --------------------------------------------------------------------------\n"); } } while (!err) { char *principal_name = NULL; err = krb5_kt_next_entry (kcontext, kt, &entry, &cursor); if (err == KRB5_KT_END) { err = 0; break; } if (!err) { err = krb5_unparse_name (kcontext, entry.principal, &principal_name); printiferr (err, "while unparsing principal name"); } if (!err) { printmsg ("%4d ", entry.vno); if (show_entry_timestamps) { printtime (entry.timestamp); printmsg (" "); } printmsg ("%s", principal_name); if (show_enctypes) { printmsg (" (%s) ", enctype_to_string (entry.key.enctype)); } if (show_entry_DES_keys) { unsigned int i; printmsg (" (0x"); for (i = 0; i < entry.key.length; i++) { printmsg ("%02x", entry.key.contents[i]); } printmsg (")"); } printmsg ("\n"); } printiferr (err, "while scanning keytab %s", keytab_name); if (principal_name) { krb5_free_unparsed_name (kcontext, principal_name); } } if (!err) { err = krb5_kt_end_seq_get (kcontext, kt, &cursor); printiferr (err, "while ending scan of keytab %s", keytab_name); } return err ? 1 : 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, const char **argv) { krb5_context ctx; krb5_ccache ccache; krb5_creds mcreds, creds; krb5_keytab keytab; krb5_principal server; krb5_verify_init_creds_opt opts; int ret; ctx = NULL; ret = krb5_init_context(&ctx); if (ret != 0) { crit("error initializing Kerberos: %s", error_message(ret)); return ret; } ccache = NULL; ret = krb5_cc_default(ctx, &ccache); if (ret != 0) { crit("error resolving ccache: %s", error_message(ret)); return ret; } keytab = NULL; ret = krb5_kt_default(ctx, &keytab); if (ret != 0) { crit("error resolving keytab: %s", error_message(ret)); return ret; } server = NULL; memset(&mcreds, 0, sizeof(mcreds)); ret = krb5_cc_get_principal(ctx, ccache, &mcreds.client); if (ret != 0) { crit("error reading client name from ccache: %s", error_message(ret)); return ret; } ret = krb5_build_principal_ext(ctx, &mcreds.server, v5_princ_realm_length(mcreds.client), v5_princ_realm_contents(mcreds.client), KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, v5_princ_realm_length(mcreds.client), v5_princ_realm_contents(mcreds.client), 0); if (ret != 0) { crit("error building ticket granting server name: %s", error_message(ret)); return ret; } ret = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcreds, &creds); if (ret != 0) { crit("error reading ccache: %s", error_message(ret)); return ret; } krb5_cc_close(ctx, ccache); krb5_verify_init_creds_opt_init(&opts); ret = krb5_verify_init_creds(ctx, &creds, server, keytab, NULL, &opts); if (ret != 0) { crit("error verifying creds: %s", error_message(ret)); } else { printf("OK\n"); } krb5_free_context(ctx); return ret; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_rd_req_ctx(krb5_context context, krb5_auth_context *auth_context, const krb5_data *inbuf, krb5_const_principal server, krb5_rd_req_in_ctx inctx, krb5_rd_req_out_ctx *outctx) { krb5_error_code ret; krb5_ap_req ap_req; krb5_rd_req_out_ctx o = NULL; krb5_keytab id = NULL, keytab = NULL; krb5_principal service = NULL; *outctx = NULL; o = calloc(1, sizeof(*o)); if (o == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } if (*auth_context == NULL) { ret = krb5_auth_con_init(context, auth_context); if (ret) goto out; } ret = krb5_decode_ap_req(context, inbuf, &ap_req); if(ret) goto out; /* Save that principal that was in the request */ ret = _krb5_principalname2krb5_principal(context, &o->server, ap_req.ticket.sname, ap_req.ticket.realm); if (ret) goto out; if (ap_req.ap_options.use_session_key && (*auth_context)->keyblock == NULL) { ret = KRB5KRB_AP_ERR_NOKEY; krb5_set_error_message(context, ret, N_("krb5_rd_req: user to user auth " "without session key given", "")); goto out; } if (inctx && inctx->keytab) id = inctx->keytab; if((*auth_context)->keyblock){ ret = krb5_copy_keyblock(context, (*auth_context)->keyblock, &o->keyblock); if (ret) goto out; } else if(inctx && inctx->keyblock){ ret = krb5_copy_keyblock(context, inctx->keyblock, &o->keyblock); if (ret) goto out; } else { if(id == NULL) { krb5_kt_default(context, &keytab); id = keytab; } if (id == NULL) goto out; if (server == NULL) { ret = _krb5_principalname2krb5_principal(context, &service, ap_req.ticket.sname, ap_req.ticket.realm); if (ret) goto out; server = service; } ret = get_key_from_keytab(context, &ap_req, server, id, &o->keyblock); if (ret) { /* If caller specified a server, fail. */ if (service == NULL && (context->flags & KRB5_CTX_F_RD_REQ_IGNORE) == 0) goto out; /* Otherwise, fall back to iterating over the keytab. This * have serious performace issues for larger keytab. */ o->keyblock = NULL; } } if (o->keyblock) { /* * We got an exact keymatch, use that. */ ret = krb5_verify_ap_req2(context, auth_context, &ap_req, server, o->keyblock, 0, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); if (ret) goto out; } else { /* * Interate over keytab to find a key that can decrypt the request. */ krb5_keytab_entry entry; krb5_kt_cursor cursor; int done = 0, kvno = 0; memset(&cursor, 0, sizeof(cursor)); if (ap_req.ticket.enc_part.kvno) kvno = *ap_req.ticket.enc_part.kvno; ret = krb5_kt_start_seq_get(context, id, &cursor); if (ret) goto out; done = 0; while (!done) { krb5_principal p; ret = krb5_kt_next_entry(context, id, &entry, &cursor); if (ret) { _krb5_kt_principal_not_found(context, ret, id, o->server, ap_req.ticket.enc_part.etype, kvno); krb5_kt_end_seq_get(context, id, &cursor); goto out; } if (entry.keyblock.keytype != ap_req.ticket.enc_part.etype) { krb5_kt_free_entry (context, &entry); continue; } ret = krb5_verify_ap_req2(context, auth_context, &ap_req, server, &entry.keyblock, 0, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); if (ret) { krb5_kt_free_entry(context, &entry); continue; } /* * Found a match, save the keyblock for PAC processing, * and update the service principal in the ticket to match * whatever is in the keytab. */ ret = krb5_copy_keyblock(context, &entry.keyblock, &o->keyblock); if (ret) { krb5_kt_free_entry(context, &entry); krb5_kt_end_seq_get(context, id, &cursor); goto out; } ret = krb5_copy_principal(context, entry.principal, &p); if (ret) { krb5_kt_free_entry(context, &entry); krb5_kt_end_seq_get(context, id, &cursor); goto out; } krb5_free_principal(context, o->ticket->server); o->ticket->server = p; krb5_kt_free_entry(context, &entry); done = 1; } krb5_kt_end_seq_get(context, id, &cursor); } /* If there is a PAC, verify its server signature */ if (inctx == NULL || inctx->check_pac) { krb5_pac pac; krb5_data data; ret = krb5_ticket_get_authorization_data_type(context, o->ticket, KRB5_AUTHDATA_WIN2K_PAC, &data); if (ret == 0) { ret = krb5_pac_parse(context, data.data, data.length, &pac); krb5_data_free(&data); if (ret) goto out; ret = krb5_pac_verify(context, pac, o->ticket->ticket.authtime, o->ticket->client, o->keyblock, NULL); krb5_pac_free(context, pac); if (ret == 0) o->flags |= KRB5_RD_REQ_OUT_PAC_VALID; ret = 0; } else ret = 0; } out: if (ret || outctx == NULL) { krb5_rd_req_out_ctx_free(context, o); } else *outctx = o; free_AP_REQ(&ap_req); if (service) krb5_free_principal(context, service); if (keytab) krb5_kt_close(context, keytab); return ret; }
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); }
static krb5_error_code get_new_cache(krb5_context context, krb5_principal client, const char *password, krb5_prompter_fct prompter, const char *keytab, const char *server_name, krb5_ccache *ret_cache) { krb5_error_code ret; krb5_creds cred; krb5_get_init_creds_opt *opt; krb5_ccache id; ret = krb5_get_init_creds_opt_alloc (context, &opt); if (ret) return ret; krb5_get_init_creds_opt_set_default_flags(context, "kadmin", krb5_principal_get_realm(context, client), opt); krb5_get_init_creds_opt_set_forwardable (opt, FALSE); krb5_get_init_creds_opt_set_proxiable (opt, FALSE); if(password == NULL && prompter == NULL) { krb5_keytab kt; if(keytab == NULL) ret = krb5_kt_default(context, &kt); else ret = krb5_kt_resolve(context, keytab, &kt); if(ret) { krb5_get_init_creds_opt_free(context, opt); return ret; } ret = krb5_get_init_creds_keytab (context, &cred, client, kt, 0, server_name, opt); krb5_kt_close(context, kt); } else { ret = krb5_get_init_creds_password (context, &cred, client, password, prompter, NULL, 0, server_name, opt); } krb5_get_init_creds_opt_free(context, opt); switch(ret){ case 0: break; case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */ case KRB5KRB_AP_ERR_BAD_INTEGRITY: case KRB5KRB_AP_ERR_MODIFIED: return KADM5_BAD_PASSWORD; default: return ret; } ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id); if(ret) return ret; ret = krb5_cc_initialize (context, id, cred.client); if (ret) return ret; ret = krb5_cc_store_cred (context, id, &cred); if (ret) return ret; krb5_free_cred_contents (context, &cred); *ret_cache = id; return 0; }
krb5_error_code KRB5_CALLCONV krb5_get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *options) { krb5_error_code ret; int use_master; krb5_keytab keytab; struct errinfo errsave = EMPTY_ERRINFO; if (arg_keytab == NULL) { if ((ret = krb5_kt_default(context, &keytab))) return ret; } else { keytab = arg_keytab; } use_master = 0; /* first try: get the requested tkt from any kdc */ ret = get_init_creds_keytab(context, creds, client, keytab, start_time, in_tkt_service, options, &use_master); /* check for success */ if (ret == 0) goto cleanup; /* If all the kdc's are unavailable fail */ if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* if the reply did not come from the master kdc, try again with the master kdc */ if (!use_master) { use_master = 1; k5_save_ctx_error(context, ret, &errsave); ret = get_init_creds_keytab(context, creds, client, keytab, start_time, in_tkt_service, options, &use_master); if (ret == 0) goto cleanup; /* If the master is unreachable, return the error from the slave we * were able to contact. */ if (ret == KRB5_KDC_UNREACH || ret == KRB5_REALM_CANT_RESOLVE || ret == KRB5_REALM_UNKNOWN) ret = k5_restore_ctx_error(context, &errsave); } /* at this point, we have a response from the master. Since we don't do any prompting or changing for keytabs, that's it. */ cleanup: if (arg_keytab == NULL) krb5_kt_close(context, keytab); k5_clear_error(&errsave); return(ret); }
static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx, const char *realm_str, const char *princ_str, const char *keytab_name, const krb5_deltat lifetime, const char **ccname_out, time_t *expire_time_out) { char *ccname; char *realm_name = NULL; char *full_princ = NULL; char *default_realm = NULL; char *tmp_str = NULL; krb5_context context = NULL; krb5_keytab keytab = NULL; krb5_ccache ccache = NULL; krb5_principal kprinc; krb5_creds my_creds; krb5_get_init_creds_opt options; krb5_error_code krberr; krb5_timestamp kdc_time_offset; int canonicalize = 0; int kdc_time_offset_usec; int ret; krberr = krb5_init_context(&context); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to init kerberos context\n")); return krberr; } DEBUG(SSSDBG_TRACE_INTERNAL, ("Kerberos context initialized\n")); krberr = set_child_debugging(context); if (krberr != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Cannot set krb5_child debugging\n")); } if (!realm_str) { krberr = krb5_get_default_realm(context, &default_realm); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to get default realm name: %s\n", sss_krb5_get_error_message(context, krberr))); goto done; } realm_name = talloc_strdup(memctx, default_realm); krb5_free_default_realm(context, default_realm); if (!realm_name) { krberr = KRB5KRB_ERR_GENERIC; goto done; } } else { realm_name = talloc_strdup(memctx, realm_str); if (!realm_name) { krberr = KRB5KRB_ERR_GENERIC; goto done; } } DEBUG(SSSDBG_TRACE_INTERNAL, ("got realm_name: [%s]\n", realm_name)); if (princ_str) { if (!strchr(princ_str, '@')) { full_princ = talloc_asprintf(memctx, "%s@%s", princ_str, realm_name); } else { full_princ = talloc_strdup(memctx, princ_str); } } else { char hostname[512]; ret = gethostname(hostname, 511); if (ret == -1) { krberr = KRB5KRB_ERR_GENERIC; goto done; } hostname[511] = '\0'; DEBUG(SSSDBG_TRACE_LIBS, ("got hostname: [%s]\n", hostname)); ret = select_principal_from_keytab(memctx, hostname, realm_name, keytab_name, &full_princ, NULL, NULL); if (ret) { krberr = KRB5_KT_IOERR; goto done; } } if (!full_princ) { krberr = KRB5KRB_ERR_GENERIC; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, ("Principal name is: [%s]\n", full_princ)); krberr = krb5_parse_name(context, full_princ, &kprinc); if (krberr) { DEBUG(2, ("Unable to build principal: %s\n", sss_krb5_get_error_message(context, krberr))); goto done; } if (keytab_name) { krberr = krb5_kt_resolve(context, keytab_name, &keytab); } else { krberr = krb5_kt_default(context, &keytab); } DEBUG(SSSDBG_CONF_SETTINGS, ("Using keytab [%s]\n", KEYTAB_CLEAN_NAME)); if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to read keytab file [%s]: %s\n", KEYTAB_CLEAN_NAME, sss_krb5_get_error_message(context, krberr))); goto done; } /* Verify the keytab */ ret = sss_krb5_verify_keytab_ex(full_princ, keytab_name, context, keytab); if (ret) { DEBUG(SSSDBG_OP_FAILURE, ("Unable to verify principal is present in the keytab\n")); krberr = KRB5_KT_IOERR; goto done; } ccname = talloc_asprintf(memctx, "FILE:%s/ccache_%s", DB_PATH, realm_name); if (!ccname) { krberr = KRB5KRB_ERR_GENERIC; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, ("keytab ccname: [%s]\n", ccname)); krberr = krb5_cc_resolve(context, ccname, &ccache); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to set cache name: %s\n", sss_krb5_get_error_message(context, krberr))); goto done; } memset(&my_creds, 0, sizeof(my_creds)); memset(&options, 0, sizeof(options)); krb5_get_init_creds_opt_set_address_list(&options, NULL); krb5_get_init_creds_opt_set_forwardable(&options, 0); krb5_get_init_creds_opt_set_proxiable(&options, 0); krb5_get_init_creds_opt_set_tkt_life(&options, lifetime); tmp_str = getenv("KRB5_CANONICALIZE"); if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) { DEBUG(SSSDBG_CONF_SETTINGS, ("Will canonicalize principals\n")); canonicalize = 1; } sss_krb5_get_init_creds_opt_set_canonicalize(&options, canonicalize); krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc, keytab, 0, NULL, &options); if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to init credentials: %s\n", sss_krb5_get_error_message(context, krberr))); sss_log(SSS_LOG_ERR, "Failed to initialize credentials using keytab [%s]: %s. " "Unable to create GSSAPI-encrypted LDAP connection.", KEYTAB_CLEAN_NAME, sss_krb5_get_error_message(context, krberr)); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, ("credentials initialized\n")); /* Use updated principal if changed due to canonicalization. */ krberr = krb5_cc_initialize(context, ccache, my_creds.client); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to init ccache: %s\n", sss_krb5_get_error_message(context, krberr))); goto done; } krberr = krb5_cc_store_cred(context, ccache, &my_creds); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to store creds: %s\n", sss_krb5_get_error_message(context, krberr))); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, ("credentials stored\n")); #ifdef HAVE_KRB5_GET_TIME_OFFSETS krberr = krb5_get_time_offsets(context, &kdc_time_offset, &kdc_time_offset_usec); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to get KDC time offset: %s\n", sss_krb5_get_error_message(context, krberr))); kdc_time_offset = 0; } else { if (kdc_time_offset_usec > 0) { kdc_time_offset++; } } DEBUG(SSSDBG_TRACE_INTERNAL, ("Got KDC time offset\n")); #else /* If we don't have this function, just assume no offset */ kdc_time_offset = 0; #endif krberr = 0; *ccname_out = ccname; *expire_time_out = my_creds.times.endtime - kdc_time_offset; done: if (krberr != 0) KRB5_SYSLOG(krberr); if (keytab) krb5_kt_close(context, keytab); if (context) krb5_free_context(context); return krberr; }
static krb5_error_code ccache_init_system(void) { kcm_ccache ccache; krb5_error_code ret; if (system_cache_name == NULL) system_cache_name = kcm_system_config_get_string("cc_name"); ret = kcm_ccache_new(kcm_context, system_cache_name ? system_cache_name : "SYSTEM", &ccache); if (ret) return ret; ccache->flags |= KCM_FLAGS_OWNER_IS_SYSTEM; ccache->flags |= KCM_FLAGS_USE_KEYTAB; ret = parse_owners(ccache); if (ret) return ret; ret = krb5_parse_name(kcm_context, system_principal, &ccache->client); if (ret) { kcm_release_ccache(kcm_context, ccache); return ret; } if (system_server == NULL) system_server = kcm_system_config_get_string("server"); if (system_server != NULL) { ret = krb5_parse_name(kcm_context, system_server, &ccache->server); if (ret) { kcm_release_ccache(kcm_context, ccache); return ret; } } if (system_keytab == NULL) system_keytab = kcm_system_config_get_string("keytab_name"); if (system_keytab != NULL) { ret = krb5_kt_resolve(kcm_context, system_keytab, &ccache->key.keytab); } else { ret = krb5_kt_default(kcm_context, &ccache->key.keytab); } if (ret) { kcm_release_ccache(kcm_context, ccache); return ret; } if (renew_life == NULL) renew_life = kcm_system_config_get_string("renew_life"); if (renew_life == NULL) renew_life = "1 month"; if (renew_life != NULL) { ccache->renew_life = parse_time(renew_life, "s"); if (ccache->renew_life < 0) { kcm_release_ccache(kcm_context, ccache); return EINVAL; } } if (ticket_life == NULL) ticket_life = kcm_system_config_get_string("ticket_life"); if (ticket_life != NULL) { ccache->tkt_life = parse_time(ticket_life, "s"); if (ccache->tkt_life < 0) { kcm_release_ccache(kcm_context, ccache); return EINVAL; } } if (system_perms == NULL) system_perms = kcm_system_config_get_string("mode"); if (system_perms != NULL) { int mode; if (sscanf(system_perms, "%o", &mode) != 1) return EINVAL; ccache->mode = mode; } if (disallow_getting_krbtgt == -1) { disallow_getting_krbtgt = krb5_config_get_bool_default(kcm_context, NULL, FALSE, "kcm", "disallow-getting-krbtgt", NULL); } /* enqueue default actions for credentials cache */ ret = kcm_ccache_enqueue_default(kcm_context, ccache, NULL); kcm_release_ccache(kcm_context, ccache); /* retained by event queue */ return ret; }