/* 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;
}
Exemple #2
0
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;
}