From: snacktime Date: 2006-09-17T06:39:34+09:00 Subject: C code works with rubyinline, doesn't with C extension 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 '' builder.include '' builder.include '' 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 #include #include 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)