/*
* call-seq:
* get_init_creds_keytab([principal][,keytab])
*
* Call krb5_get_init_creds_keytab() to get credentials based on a keytab. With no parameters, gets the default principal (probably the username@DEFAULT_REALM) from the default keytab (as configured in /etc/krb5.conf). With one parameter, get the named principal from the default keytab (as configured in /etc/krb5.conf). With two parameters, get the named principal from the named keytab. Returns true on success, raises Krb5Auth::Krb5::Exception on failure.
*/
static VALUE Krb5_get_init_creds_keytab(int argc, VALUE *argv, VALUE self)
{
char *princ;
char *keytab_name;
struct ruby_krb5 *kerb;
krb5_error_code krbret;
krb5_keytab keytab;
keytab = NULL;
if (argc == 0) {
keytab_name = NULL;
princ = NULL;
}
else if (argc == 1) {
Check_Type(argv[0], T_STRING);
princ = STR2CSTR(argv[0]);
keytab_name = NULL;
}
else if (argc == 2) {
Check_Type(argv[0], T_STRING);
Check_Type(argv[1], T_STRING);
princ = STR2CSTR(argv[0]);
keytab_name = STR2CSTR(argv[1]);
}
else {
rb_raise(rb_eRuntimeError, "Invalid arguments");
}
Data_Get_Struct(self, struct ruby_krb5, kerb);
if (!kerb) {
NOSTRUCT_EXCEPT();
return Qfalse;
}
if (keytab_name != NULL) {
krbret = krb5_kt_resolve(kerb->ctx, keytab_name, &keytab);
if (krbret) {
goto failed_keytab;
}
}
// implicit else: if we weren't passed a keytab name, just leave keytab as
// NULL to use the default
if (princ != NULL) {
krbret = krb5_parse_name(kerb->ctx, princ, &kerb->princ);
}
else {
// if we weren't passed a principal, we just get the default principal
// (which is generally the hostname)
krbret = krb5_sname_to_principal(kerb->ctx, NULL, NULL, KRB5_NT_SRV_HST,
&kerb->princ);
}
if (krbret) {
goto failed_keytab;
}
krbret = krb5_get_init_creds_keytab(kerb->ctx, &kerb->creds, kerb->princ,
keytab, 0, NULL, NULL);
if (krbret) {
goto failed_keytab;
}
if (keytab)
krb5_kt_close(kerb->ctx, keytab);
return Qtrue;
failed_keytab:
if (keytab)
krb5_kt_close(kerb->ctx, keytab);
Krb5_register_error(krbret);
// we will never reach here, since Krb5_register_error will rb_raise(). just
// leave it to shut the compiler up
return Qfalse;
}