So I’ve blatantly stolen some code from a perl module to do simple
kerberos authentication and not being the most adept C programmer I
have something I can’t figure out.
The following code using rubyinline works fine. The code below that
which is just a ruby c extension segfaults on the call to
krb5_free_cred_contents(ctx, &creds). If I comment it out then it
works. This is on Freebsd 6.1 using MIT kerberos, ruby 1.8.5 with the
latest RubyInline.
require ‘rubygems’
require ‘inline’
class Krb
inline(:C) do |builder|
builder.include ‘<krb5.h>’
builder.include ‘<stdio.h>’
builder.include ‘<strings.h>’
builder.add_compile_flags “-I/usr/local/include -L/usr/local/lib
-lkrb5 -lk5crypto -lcom_err”
builder.c "
int _krb5_auth(char* user, char* pass)
{
int krbret;
krb5_context ctx;
krb5_creds creds;
krb5_principal princ;
int ret = 0;
/* Initialize krb5 context...
*/
if ((krbret = krb5_init_context(&ctx))) {
return krbret;
}
memset(&creds, 0, sizeof(krb5_creds));
/* Get principal name...
*/
if ((krbret = krb5_parse_name(ctx, user, &princ))) {
ret = krbret;
krb5_free_context(ctx);
}
/* Check the user's pasword...
*/
if ((krbret = krb5_get_init_creds_password(
ctx, &creds, princ, pass, 0, NULL, 0, NULL, NULL))) {
ret = krbret;
krb5_free_cred_contents(ctx, &creds);
krb5_free_principal(ctx, princ);
}
return ret;
}"
end
end
k = Krb.new
res = k._krb5_auth(‘test’,‘test’)
p res
#include “ruby.h”
#include <krb5.h>
#include <stdio.h>
#include <strings.h>
static VALUE _krb5_auth(VALUE self, VALUE _user, VALUE _pass) {
char * user = STR2CSTR(_user);
char * pass = STR2CSTR(_pass);
int krbret;
krb5_context ctx;
krb5_creds creds;
krb5_principal princ;
int ret = 0;
if ((krbret = krb5_init_context(&ctx))) {
return INT2FIX(krbret);
}
memset(&creds, 0, sizeof(krb5_creds));
if ((krbret = krb5_parse_name(ctx, user, &princ))) {
ret = krbret;
krb5_free_context(ctx);
}
if ((krbret = krb5_get_init_creds_password(
ctx, &creds, princ, pass, 0, NULL, 0, NULL, NULL))) {
ret = krbret;
/* krb5_free_cred_contents(ctx, &creds); Uncomment this to
get a segfault*/
krb5_free_principal(ctx, princ);
}
return INT2FIX(ret);
}
void Init_krb() {
VALUE Krb = rb_define_class(“Krb”, rb_cObject);
rb_define_method(Krb, “krb5_auth”, _krb5_auth,2);
}
require ‘mkmf’
extension_name = ‘krb’
dir_config("/usr/local/lib","/usr/local/include")
have_library(“krb5”,“krb5_init_context”)
have_library(“k5crypto”,“krb5_encrypt”)
have_library(“com_err”,“com_err”)
create_makefile(extension_name)