#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Inline ( C => 'DATA', LIBS => '-lkrb5', ); my $oldpw = shift or die "USAGE: test.pl oldpw newpw"; my $newpw = shift or die "USAGE: test.pl oldpw newpw"; my $ret = change_password($oldpw, $newpw); $oldpw = $newpw = ""; undef($oldpw); undef($newpw); print "change_password returned $ret\n"; print " :" . change_password_error($ret) . "\n"; __DATA__ __C__ #include #include #include static krb5_error_code error_code = 0; static char error_text[1024] = ""; char *change_password_error(int error_number) { static char buf[1024]; char *text[] = { /* 0 */ "success", /* 1 */ "krb5_init_context failed", /* 2 */ "krb5_parse_name failed", /* 3 */ "krb5_get_init_creds_opt_alloc failed", /* 4 */ "krb5_get_init_creds failed", /* 5 */ "krb5_change_password failed", /* 6 */ "krb5_change_password failed", }; if(error_number > 6) { sprintf(buf, "Unknown error code: %d", error_number); } else { if(error_code) { sprintf(buf, "%s: %s", text[error_number], error_message(error_code) ); } else if(strlen(error_text)) { sprintf(buf, "%s: %s", text[error_number], error_text ); } else { sprintf(buf, "%s", text[error_number]); } } return(buf); } int change_password(char* oldpw, char* newpw) { krb5_context context; krb5_principal princ; krb5_get_init_creds_opt *opts = NULL; krb5_creds creds; int result_code; krb5_data result_code_string; krb5_data result_string; error_code = krb5_init_context(&context); if ( error_code ) return(1); error_code = krb5_parse_name(context, "billyb", &princ); if ( error_code ) return(2); error_code = krb5_get_init_creds_password( context, &creds, princ, oldpw, NULL, NULL, 0, "kadmin/changepw", NULL ); if ( error_code ) return(4); error_code = krb5_change_password(context, &creds, newpw, &result_code, &result_code_string, &result_string); if ( error_code ) return(5); if(result_code) { if( result_code_string.length + result_string.length + 5 > sizeof(error_text) ) { sprintf(error_text, "buffer overrun"); } else { printf("setting error_text\n"); sprintf(error_text, "%.*s%s%.*s", (int) result_code_string.length, result_code_string.data, result_string.length?": ":"", (int) result_string.length, result_string.data ? result_string.data : "" ); } return(6); } if (result_string.data != NULL) free(result_string.data); if (result_code_string.data != NULL) free(result_code_string.data); return(0); }