/* Inspired by krb5_verify_user from Heimdal */ static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server) { krb5_creds creds; krb5_get_init_creds_opt gic_options; krb5_error_code ret; char *name = NULL; memset(&creds, 0, sizeof(creds)); ret = krb5_unparse_name(context, principal, &name); if (ret == 0) { #ifdef PRINTFS printf("Trying to get TGT for user %s\n", name); #endif free(name); } krb5_get_init_creds_opt_init(&gic_options); ret = krb5_get_init_creds_password(context, &creds, principal, (char *)password, NULL, NULL, 0, NULL, &gic_options); if (ret) { set_basicauth_error(context, ret); goto end; } end: krb5_free_cred_contents(context, &creds); return ret; }
static int store_gss_creds(gss_store_state *state, char *princ_name, gss_cred_id_t delegated_cred) { OM_uint32 maj_stat, min_stat; krb5_error_code problem; const char * temp_ccname = "FILE:/tmp/krb5cc_pykerberos_XXXXXX"; int ret = 1; problem = krb5_init_context(&state->context); if (problem) { PyErr_SetObject(BasicAuthException_class, Py_BuildValue("((s:i))", "Cannot initialize Kerberos5 context", problem)); return 0; } int name_len = strlen(temp_ccname); state->ccache_name = (char *)malloc(name_len + 1); strcpy(state->ccache_name, temp_ccname); int fd = mkstemp(state->ccache_name + strlen("FILE:")); if (fd < 0) { PyErr_SetObject(BasicAuthException_class, Py_BuildValue("(s:s)", "Error in mkstemp", strerror(errno))); ret = 0; goto end; } close(fd); problem = krb5_cc_resolve(state->context, state->ccache_name, &state->ccache); if (problem) { set_basicauth_error(state->context, problem); ret = 0; goto end; } problem = krb5_parse_name(state->context, princ_name, &state->client); if (problem) { set_basicauth_error(state->context, problem); goto end; } problem = krb5_cc_initialize(state->context, state->ccache, state->client); if (problem) { set_basicauth_error(state->context, problem); ret = 0; goto end; } maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, state->ccache); if (GSS_ERROR(maj_stat)) { set_gss_error(maj_stat, min_stat); ret = 0; goto end; } ret = 1; return ret; end: if (state->client != NULL) krb5_free_principal(state->context, state->client); if (state->ccache != NULL) krb5_cc_destroy(state->context, state->ccache); krb5_free_context(state->context); return ret; }
int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *service, const char *default_realm) { krb5_context kcontext = NULL; krb5_error_code code; krb5_principal client = NULL; krb5_principal server = NULL; int ret = 0; char *name = NULL; char *p = NULL; code = krb5_init_context(&kcontext); if (code) { PyErr_SetObject(BasicAuthException_class, Py_BuildValue("((s:i))", "Cannot initialize Kerberos5 context", code)); return 0; } ret = krb5_parse_name (kcontext, service, &server); if (ret) { set_basicauth_error(kcontext, ret); ret = 0; goto end; } code = krb5_unparse_name(kcontext, server, &name); if (code) { set_basicauth_error(kcontext, code); ret = 0; goto end; } #ifdef PRINTFS printf("Using %s as server principal for password verification\n", name); #endif free(name); name = NULL; name = (char *)malloc(256); p = strchr(user, '@'); if (p == NULL) { snprintf(name, 256, "%s@%s", user, default_realm); } else { snprintf(name, 256, "%s", user); } code = krb5_parse_name(kcontext, name, &client); if (code) { set_basicauth_error(kcontext, code); ret = 0; goto end; } code = verify_krb5_user(kcontext, client, pswd, server); if (code) { ret = 0; goto end; } ret = 1; end: #ifdef PRINTFS printf("kerb_authenticate_user_krb5pwd ret=%d user=%s authtype=%s\n", ret, user, "Basic"); #endif if (name) free(name); if (client) krb5_free_principal(kcontext, client); if (server) krb5_free_principal(kcontext, server); krb5_free_context(kcontext); return ret; }