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)