Heimdal-Kadm5-0.08/0000755000175000017500000000000011335075045012712 5ustar leifjleifjHeimdal-Kadm5-0.08/typemap0000644000175000017500000000054211332636472014321 0ustar leifjleifjTYPEMAP shandle_t * T_shandle_t sprincipal_t * T_sprincipal_t INPUT T_shandle_t $var = sv2server_handle($arg) T_sprincipal_t $var = sv2sprincipal($arg) OUTPUT T_shandle_t sv_setref_pv($arg, \"Heimdal::Kadm5::SHandle\", (void *)$var); T_sprincipal_t sv_setref_pv($arg, \"Heimdal::Kadm5::Principal\", (void *)$var); Heimdal-Kadm5-0.08/MANIFEST0000644000175000017500000000023611335075045014044 0ustar leifjleifjChanges Kadm5.pm Kadm5.xs Makefile.PL MANIFEST README test.pl consts.h typemap META.yml Module meta-data (added by MakeMaker) Heimdal-Kadm5-0.08/META.yml0000644000175000017500000000067311335075045014171 0ustar leifjleifj--- #YAML:1.0 name: Heimdal-Kadm5 version: 0.08 abstract: Perl extension for adminstration of Heimdal Kerberos servers (kadmin) license: ~ author: - Leif Johansson generated_by: ExtUtils::MakeMaker version 6.42 distribution_type: module requires: meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 Heimdal-Kadm5-0.08/consts.h0000644000175000017500000003006011333623163014371 0ustar leifjleifj/* * Copyright (c) 2003, Stockholms Universitet * (Stockholm University, Stockholm Sweden) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the university nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ static double constant(char *name, int arg) { errno = 0; switch (*name) { case 'A': break; case 'B': break; case 'C': break; case 'D': break; case 'E': break; case 'F': break; case 'G': break; case 'H': break; case 'I': break; case 'J': break; case 'K': if (strEQ(name, "KRB5_KDB_DISALLOW_ALL_TIX")) #ifdef KRB5_KDB_DISALLOW_ALL_TIX return KRB5_KDB_DISALLOW_ALL_TIX; #else goto not_there; #endif if (strEQ(name, "KADM5_API_VERSION_1")) #ifdef KADM5_API_VERSION_1 return KADM5_API_VERSION_1; #else goto not_there; #endif if (strEQ(name, "KADM5_API_VERSION_2")) #ifdef KADM5_API_VERSION_2 return KADM5_API_VERSION_2; #else goto not_there; #endif if (strEQ(name, "KADM5_ATTRIBUTES")) #ifdef KADM5_ATTRIBUTES return KADM5_ATTRIBUTES; #else goto not_there; #endif if (strEQ(name, "KADM5_AUX_ATTRIBUTES")) #ifdef KADM5_AUX_ATTRIBUTES return KADM5_AUX_ATTRIBUTES; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ACL_FILE")) #ifdef KADM5_CONFIG_ACL_FILE return KADM5_CONFIG_ACL_FILE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ADBNAME")) #ifdef KADM5_CONFIG_ADBNAME return KADM5_CONFIG_ADBNAME; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ADB_LOCKFILE")) #ifdef KADM5_CONFIG_ADB_LOCKFILE return KADM5_CONFIG_ADB_LOCKFILE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ADMIN_KEYTAB")) #ifdef KADM5_CONFIG_ADMIN_KEYTAB return KADM5_CONFIG_ADMIN_KEYTAB; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ADMIN_SERVER")) #ifdef KADM5_CONFIG_ADMIN_SERVER return KADM5_CONFIG_ADMIN_SERVER; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_DBNAME")) #ifdef KADM5_CONFIG_DBNAME return KADM5_CONFIG_DBNAME; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_DICT_FILE")) #ifdef KADM5_CONFIG_DICT_FILE return KADM5_CONFIG_DICT_FILE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ENCTYPE")) #ifdef KADM5_CONFIG_ENCTYPE return KADM5_CONFIG_ENCTYPE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_ENCTYPES")) #ifdef KADM5_CONFIG_ENCTYPES return KADM5_CONFIG_ENCTYPES; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_EXPIRATION")) #ifdef KADM5_CONFIG_EXPIRATION return KADM5_CONFIG_EXPIRATION; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_FLAGS")) #ifdef KADM5_CONFIG_FLAGS return KADM5_CONFIG_FLAGS; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_KADMIND_PORT")) #ifdef KADM5_CONFIG_KADMIND_PORT return KADM5_CONFIG_KADMIND_PORT; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_MAX_LIFE")) #ifdef KADM5_CONFIG_MAX_LIFE return KADM5_CONFIG_MAX_LIFE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_MAX_RLIFE")) #ifdef KADM5_CONFIG_MAX_RLIFE return KADM5_CONFIG_MAX_RLIFE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_MKEY_FROM_KEYBOARD")) #ifdef KADM5_CONFIG_MKEY_FROM_KEYBOARD return KADM5_CONFIG_MKEY_FROM_KEYBOARD; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_MKEY_NAME")) #ifdef KADM5_CONFIG_MKEY_NAME return KADM5_CONFIG_MKEY_NAME; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_PROFILE")) #ifdef KADM5_CONFIG_PROFILE return KADM5_CONFIG_PROFILE; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_REALM")) #ifdef KADM5_CONFIG_REALM return KADM5_CONFIG_REALM; #else goto not_there; #endif if (strEQ(name, "KADM5_CONFIG_STASH_FILE")) #ifdef KADM5_CONFIG_STASH_FILE return KADM5_CONFIG_STASH_FILE; #else goto not_there; #endif if (strEQ(name, "KADM5_FAIL_AUTH_COUNT")) #ifdef KADM5_FAIL_AUTH_COUNT return KADM5_FAIL_AUTH_COUNT; #else goto not_there; #endif if (strEQ(name, "KADM5_KEY_DATA")) #ifdef KADM5_KEY_DATA return KADM5_KEY_DATA; #else goto not_there; #endif if (strEQ(name, "KADM5_KVNO")) #ifdef KADM5_KVNO return KADM5_KVNO; #else goto not_there; #endif if (strEQ(name, "KADM5_LAST_FAILED")) #ifdef KADM5_LAST_FAILED return KADM5_LAST_FAILED; #else goto not_there; #endif if (strEQ(name, "KADM5_LAST_PWD_CHANGE")) #ifdef KADM5_LAST_PWD_CHANGE return KADM5_LAST_PWD_CHANGE; #else goto not_there; #endif if (strEQ(name, "KADM5_LAST_SUCCESS")) #ifdef KADM5_LAST_SUCCESS return KADM5_LAST_SUCCESS; #else goto not_there; #endif if (strEQ(name, "KADM5_MAX_LIFE")) #ifdef KADM5_MAX_LIFE return KADM5_MAX_LIFE; #else goto not_there; #endif if (strEQ(name, "KADM5_MAX_RLIFE")) #ifdef KADM5_MAX_RLIFE return KADM5_MAX_RLIFE; #else goto not_there; #endif if (strEQ(name, "KADM5_MKVNO")) #ifdef KADM5_MKVNO return KADM5_MKVNO; #else goto not_there; #endif if (strEQ(name, "KADM5_MOD_NAME")) #ifdef KADM5_MOD_NAME return KADM5_MOD_NAME; #else goto not_there; #endif if (strEQ(name, "KADM5_MOD_TIME")) #ifdef KADM5_MOD_TIME return KADM5_MOD_TIME; #else goto not_there; #endif if (strEQ(name, "KADM5_POLICY")) #ifdef KADM5_POLICY return KADM5_POLICY; #else goto not_there; #endif if (strEQ(name, "KADM5_POLICY_CLR")) #ifdef KADM5_POLICY_CLR return KADM5_POLICY_CLR; #else goto not_there; #endif if (strEQ(name, "KADM5_POLICY_NORMAL_MASK")) #ifdef KADM5_POLICY_NORMAL_MASK return KADM5_POLICY_NORMAL_MASK; #else goto not_there; #endif if (strEQ(name, "KADM5_PRINCIPAL")) #ifdef KADM5_PRINCIPAL return KADM5_PRINCIPAL; #else goto not_there; #endif if (strEQ(name, "KADM5_PRINCIPAL_NORMAL_MASK")) #ifdef KADM5_PRINCIPAL_NORMAL_MASK return KADM5_PRINCIPAL_NORMAL_MASK; #else goto not_there; #endif if (strEQ(name, "KADM5_PRINC_EXPIRE_TIME")) #ifdef KADM5_PRINC_EXPIRE_TIME return KADM5_PRINC_EXPIRE_TIME; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_ADD")) #ifdef KADM5_PRIV_ADD return KADM5_PRIV_ADD; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_ALL")) #ifdef KADM5_PRIV_ALL return KADM5_PRIV_ALL; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_CPW")) #ifdef KADM5_PRIV_CPW return KADM5_PRIV_CPW; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_DELETE")) #ifdef KADM5_PRIV_DELETE return KADM5_PRIV_DELETE; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_GET")) #ifdef KADM5_PRIV_GET return KADM5_PRIV_GET; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_LIST")) #ifdef KADM5_PRIV_LIST return KADM5_PRIV_LIST; #else goto not_there; #endif if (strEQ(name, "KADM5_PRIV_MODIFY")) #ifdef KADM5_PRIV_MODIFY return KADM5_PRIV_MODIFY; #else goto not_there; #endif if (strEQ(name, "KADM5_PW_EXPIRATION")) #ifdef KADM5_PW_EXPIRATION return KADM5_PW_EXPIRATION; #else goto not_there; #endif if (strEQ(name, "KADM5_PW_HISTORY_NUM")) #ifdef KADM5_PW_HISTORY_NUM return KADM5_PW_HISTORY_NUM; #else goto not_there; #endif if (strEQ(name, "KADM5_PW_MAX_LIFE")) #ifdef KADM5_PW_MAX_LIFE return KADM5_PW_MAX_LIFE; #else goto not_there; #endif if (strEQ(name, "KADM5_PW_MIN_CLASSES")) #ifdef KADM5_PW_MIN_CLASSES return KADM5_PW_MIN_CLASSES; #else goto not_there; #endif if (strEQ(name, "KADM5_PW_MIN_LENGTH")) #ifdef KADM5_PW_MIN_LENGTH return KADM5_PW_MIN_LENGTH; #else goto not_there; #endif if (strEQ(name, "KADM5_PW_MIN_LIFE")) #ifdef KADM5_PW_MIN_LIFE return KADM5_PW_MIN_LIFE; #else goto not_there; #endif if (strEQ(name, "KADM5_REF_COUNT")) #ifdef KADM5_REF_COUNT return KADM5_REF_COUNT; #else goto not_there; #endif if (strEQ(name, "KADM5_STRUCT_VERSION")) #ifdef KADM5_STRUCT_VERSION return KADM5_STRUCT_VERSION; #else goto not_there; #endif if (strEQ(name, "KADM5_TL_DATA")) #ifdef KADM5_TL_DATA return KADM5_TL_DATA; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_ALL_TIX")) #ifdef KRB5_KDB_DISALLOW_ALL_TIX return KRB5_KDB_DISALLOW_ALL_TIX; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_DUP_SKEY")) #ifdef KRB5_KDB_DISALLOW_DUP_SKEY return KRB5_KDB_DISALLOW_DUP_SKEY; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_FORWARDABLE")) #ifdef KRB5_KDB_DISALLOW_FORWARDABLE return KRB5_KDB_DISALLOW_FORWARDABLE; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_POSTDATED")) #ifdef KRB5_KDB_DISALLOW_POSTDATED return KRB5_KDB_DISALLOW_POSTDATED; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_PROXIABLE")) #ifdef KRB5_KDB_DISALLOW_PROXIABLE return KRB5_KDB_DISALLOW_PROXIABLE; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_RENEWABLE")) #ifdef KRB5_KDB_DISALLOW_RENEWABLE return KRB5_KDB_DISALLOW_RENEWABLE; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_SVR")) #ifdef KRB5_KDB_DISALLOW_SVR return KRB5_KDB_DISALLOW_SVR; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_DISALLOW_TGT_BASED")) #ifdef KRB5_KDB_DISALLOW_TGT_BASED return KRB5_KDB_DISALLOW_TGT_BASED; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_NEW_PRINC")) #ifdef KRB5_KDB_NEW_PRINC return KRB5_KDB_NEW_PRINC; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_PWCHANGE_SERVICE")) #ifdef KRB5_KDB_PWCHANGE_SERVICE return KRB5_KDB_PWCHANGE_SERVICE; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_REQUIRES_HW_AUTH")) #ifdef KRB5_KDB_REQUIRES_HW_AUTH return KRB5_KDB_REQUIRES_HW_AUTH; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_REQUIRES_PRE_AUTH")) #ifdef KRB5_KDB_REQUIRES_PRE_AUTH return KRB5_KDB_REQUIRES_PRE_AUTH; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_REQUIRES_PWCHANGE")) #ifdef KRB5_KDB_REQUIRES_PWCHANGE return KRB5_KDB_REQUIRES_PWCHANGE; #else goto not_there; #endif if (strEQ(name, "KRB5_KDB_SUPPORT_DESMD5")) #ifdef KRB5_KDB_SUPPORT_DESMD5 return KRB5_KDB_SUPPORT_DESMD5; #else goto not_there; #endif break; case 'L': break; case 'M': break; case 'N': break; case 'O': break; case 'P': break; case 'Q': break; case 'R': break; case 'S': break; case 'T': break; case 'U': if (strEQ(name, "USE_KADM5_API_VERSION")) #ifdef USE_KADM5_API_VERSION return USE_KADM5_API_VERSION; #else goto not_there; #endif break; case 'V': break; case 'W': break; case 'X': break; case 'Y': break; case 'Z': break; } errno = EINVAL; return 0; not_there: errno = ENOENT; return 0; } Heimdal-Kadm5-0.08/README0000644000175000017500000000474711335075036013606 0ustar leifjleifjHeimdal/Kadm5 version 0.08 ========================== Heimdal::Kadm5 is a Perl XS wrapper around the Heimdal Kerberos administrative client library (libkadm5clnt). Heimdal is a free slightly less export challenged implementation of Kerberos5 by Assar Westerlund and Johan Danielsson. This module exposes the API used to administer a Kerberos realm: add, remove, and list principals, create keytabs, change keys, and similar operations. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires the Kerberos administration client library for Heimdal (libkadm5clnt) and its corresponding header files. It finds the path to the library and header files using krb5-config. Only Heimdal is supported. This module will not work with MIT Kerberos and its Kerberos administration client library, despite similarities in library and header file names. COPYRIGHT AND LICENCE Copyright (c) 2003, Stockholms Universitet (Stockholm University, Stockholm Sweden) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the university nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Heimdal-Kadm5-0.08/Changes0000644000175000017500000000134011335075036014203 0ustar leifjleifjRevision history for Perl extension Heimdal::Kadm5. 0.01 Sun Feb 9 22:01:22 2003 - original version; created by h2xs 1.21 with options -n Heimdal::Kadm5 0.04 Wed Nov 19 23:43:39 CET 2003 - patches from Alf Wachsman 0.07 Thu Dec 10 17:56:28 PST 2009 - Changed dump() to better model get kadmin command output - Fixed bug with modifyPrincipal not checking for empty mask and setting it to 0 if empty - Added Alf Wachsman patch to delete enctypes from a principal 0.08 Wed Jan 13 13:12:51 PST 2010 - Additions to dump() for parsing out attributes and ticket lifetimes - getAttributeNames to give an array of attributes by name - Wrapped some code and perldocs Heimdal-Kadm5-0.08/Kadm5.pm0000644000175000017500000006066211335075036014223 0ustar leifjleifj# # Copyright (c) 2003, Stockholms Universitet # (Stockholm University, Stockholm Sweden) # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the university nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # $Id$ # package Heimdal::Kadm5; use strict; no strict qw(refs); use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD); require Exporter; require DynaLoader; require AutoLoader; @ISA = qw(Exporter DynaLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT_OK = qw( KADM5_ADMIN_SERVICE KADM5_API_VERSION_1 KADM5_API_VERSION_2 KADM5_ATTRIBUTES KADM5_AUX_ATTRIBUTES KADM5_CHANGEPW_SERVICE KADM5_CONFIG_ACL_FILE KADM5_CONFIG_ADBNAME KADM5_CONFIG_ADB_LOCKFILE KADM5_CONFIG_ADMIN_KEYTAB KADM5_CONFIG_ADMIN_SERVER KADM5_CONFIG_DBNAME KADM5_CONFIG_DICT_FILE KADM5_CONFIG_ENCTYPE KADM5_CONFIG_ENCTYPES KADM5_CONFIG_EXPIRATION KADM5_CONFIG_FLAGS KADM5_CONFIG_KADMIND_PORT KADM5_CONFIG_MAX_LIFE KADM5_CONFIG_MAX_RLIFE KADM5_CONFIG_MKEY_FROM_KEYBOARD KADM5_CONFIG_MKEY_NAME KADM5_CONFIG_PROFILE KADM5_CONFIG_REALM KADM5_CONFIG_STASH_FILE KADM5_FAIL_AUTH_COUNT KADM5_HIST_PRINCIPAL KADM5_KEY_DATA KADM5_KVNO KADM5_LAST_FAILED KADM5_LAST_PWD_CHANGE KADM5_LAST_SUCCESS KADM5_MAX_LIFE KADM5_MAX_RLIFE KADM5_MKVNO KADM5_MOD_NAME KADM5_MOD_TIME KADM5_POLICY KADM5_POLICY_CLR KADM5_POLICY_NORMAL_MASK KADM5_PRINCIPAL KADM5_PRINCIPAL_NORMAL_MASK KADM5_PRINC_EXPIRE_TIME KADM5_PRIV_ADD KADM5_PRIV_ALL KADM5_PRIV_CPW KADM5_PRIV_DELETE KADM5_PRIV_GET KADM5_PRIV_LIST KADM5_PRIV_MODIFY KADM5_PW_EXPIRATION KADM5_PW_HISTORY_NUM KADM5_PW_MAX_LIFE KADM5_PW_MIN_CLASSES KADM5_PW_MIN_LENGTH KADM5_PW_MIN_LIFE KADM5_REF_COUNT KADM5_STRUCT_VERSION KADM5_TL_DATA KRB5_KDB_DISALLOW_ALL_TIX KRB5_KDB_DISALLOW_DUP_SKEY KRB5_KDB_DISALLOW_FORWARDABLE KRB5_KDB_DISALLOW_POSTDATED KRB5_KDB_DISALLOW_PROXIABLE KRB5_KDB_DISALLOW_RENEWABLE KRB5_KDB_DISALLOW_SVR KRB5_KDB_DISALLOW_TGT_BASED KRB5_KDB_NEW_PRINC KRB5_KDB_PWCHANGE_SERVICE KRB5_KDB_REQUIRES_HW_AUTH KRB5_KDB_REQUIRES_PRE_AUTH KRB5_KDB_REQUIRES_PWCHANGE KRB5_KDB_SUPPORT_DESMD5 USE_KADM5_API_VERSION ); $VERSION = '0.08'; sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() # XS function. If a constant is not found then control is passed # to the AUTOLOAD in AutoLoader. my $constname; ($constname = $AUTOLOAD) =~ s/.*:://; croak "& not defined" if $constname eq 'constant'; my $val = constant($constname, @_ ? $_[0] : 0); if ($! != 0) { if ($! =~ /Invalid/) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { croak "Your vendor has not defined Heimdal::Kadm5 macro $constname"; } } eval "sub $AUTOLOAD { $val } }"; goto &$AUTOLOAD; } bootstrap Heimdal::Kadm5 $VERSION; package Heimdal::Kadm5; # Preloaded methods go here. package Heimdal::Kadm5::Client; @Heimdal::Kadm5::Client::ISA = qw(Heimdal::Kadm5); use vars qw($KADMIN_SERVICE); $KADMIN_SERVICE = 'kadmin/admin'; sub new { my $self = shift; my $class = ref $self || $self; my %opts = @_; my $me = bless \%opts,$class; my $client = $me->{'Principal'} or die "[Heimdal::Kadm5] Heimdal::Kadm5::Client::new missing required \'Principal\' parameter"; my $keytab = $me->{'Keytab'} ? $me->{'Keytab'} : ''; my $password = $me->{'Password'} ? $me->{'Password'} : ''; # warn %opts; eval { $me->{'_handle'} = Heimdal::Kadm5::SHandle->new(\%opts); if ($keytab) { $me->handle->c_init_with_skey($client,$keytab,$KADMIN_SERVICE,0,0); } else { $me->handle->c_init_with_password($client,$password,$KADMIN_SERVICE,0,0); } $me->{'_privs'} = $me->handle->c_get_privs(); }; if ($@) { my $err = $@; if ($me->{RaiseError}) { die $@; } warn $err; warn "Unable to initialize a Heimdal::Kadm5::Client instance\n"; return undef; } $me; } sub privs { $_[0]->{'_privs'}; } my %pnames = ( Heimdal::Kadm5::KADM5_PRIV_ADD() => 'add', Heimdal::Kadm5::KADM5_PRIV_CPW() => 'cpw', Heimdal::Kadm5::KADM5_PRIV_DELETE() => 'delete', Heimdal::Kadm5::KADM5_PRIV_LIST() => 'list', Heimdal::Kadm5::KADM5_PRIV_GET() => 'get', Heimdal::Kadm5::KADM5_PRIV_MODIFY() => 'modify' ); sub getPriviledges { my $mask = $_[0]->privs; my @p; foreach my $bit (keys %pnames) { push(@p,$pnames{$bit}) if ($mask & $bit); } return (wantarray ? @p : join(', ',@p)); } sub handle { $_[0]->{'_handle'}; } sub makePrincipal { my $principal = Heimdal::Kadm5::Principal->new(handle($_[0])); $principal->setPrincipal($_[1]); $principal; } sub getPrincipals { my $self = shift; $self->handle->c_get_principals(@_); } sub getPrincipal { my $self = shift; my $princ = shift; my $mask = shift; $mask = (Heimdal::Kadm5::KADM5_PRINCIPAL_NORMAL_MASK()|Heimdal::Kadm5::KADM5_KEY_DATA()|Heimdal::Kadm5::KADM5_TL_DATA()) unless $mask; $self->handle->c_get_principal($princ,$mask); } sub disablePrincipal { my $self = shift; my $name = shift; die "[Heimdal::Kadm5] Disable whom" unless $name; eval { my $principal = $self->getPrincipal($name); my $attrs = $principal->getAttributes; $attrs |= Heimdal::Kadm5::KRB5_KDB_DISALLOW_ALL_TIX(); $principal->setAttributes($attrs); $self->modifyPrincipal($principal); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to disable $name\n"; return undef; } 1; } sub enablePrincipal { my $self = shift; my $name = shift; die "[Heimdal::Kadm5] Enable whom" unless $name; eval { my $principal = $self->getPrincipal($name); my $attrs = $principal->getAttributes; $attrs &= (~Heimdal::Kadm5::KRB5_KDB_DISALLOW_ALL_TIX()); $principal->setAttributes($attrs); $self->modifyPrincipal($principal); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to enable $name\n"; return undef; } 1; } sub modifyPrincipal { my ($self,$principal,$mask) = @_; $mask = 0 unless $mask; eval { $self->handle->c_modify_principal($principal,$mask); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } my $name = $principal->getPrincipal; warn $err; warn "Unable to modify $name\n"; return undef; } 1; } sub changePassword { my ($self,$name,$password) = @_; eval { $self->handle->c_chpass_principal($name,$password); undef $password; }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to change password for $name\n"; return undef; } 1; } sub createPrincipal { my $self = shift; my $principal = shift; my $password = shift; my $mask = shift; my $name = $principal->getPrincipal; die "[Heimdal::Kadm5] Create whom?" unless $name; eval { $self->handle->c_create_principal($principal,$password,$mask); undef $password; }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to create $name\n"; return undef; } 1; } sub renamePrincipal { my ($self,$source,$target) = @_; eval { $self->handle->c_rename_principal($source,$target); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to rename $source to $target\n"; return undef; } 1; } sub deletePrincipal { my ($self,$name) = @_; eval { $self->handle->c_delete_principal($name); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to delete $name\n"; return undef; } 1; } sub randKeyPrincipal { my ($self,$name) = @_; eval { $self->handle->c_randkey_principal($name); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $@; } warn $err; warn "Unable to generate random key for $name\n"; return undef; } 1; } sub extractKeytab { my $self = shift; my $principal = shift; my $keytab = shift; my $nkeys; eval { $self->handle->c_ext_keytab($principal,$keytab); }; if ($@) { my $err = $@; if ($self->{RaiseError}) { die $err; } warn $err; warn "Unable to extract keytab $keytab\n"; return undef } 1; } package Heimdal::Kadm5::Principal; # @Heimdal::Kadm5::Principal::ISA = qw(Heimdal::Kadm5::SPrincipal); use POSIX qw(strftime); use Time::Seconds; sub _sec2date { $_[0] ? strftime "%Y-%m-%d %T UTC", gmtime($_[0]): 'never'; } # Convert seconds into a days and weeks format for ticket lifetime and # maximum lifetime. # TODO: This assumes you have an even number of days, and will fail at # anything like '25 hours'. The handling should be improved. sub _sec2days { my $seconds = shift; my $val = Time::Seconds->new($seconds); my $str = ''; if ($val->weeks >= 1) { if ($val->weeks == 1) { $str = $val->weeks . ' week'; } else { $str = $val->weeks . ' weeks'; } } if ($val->days % 7 == 0) { return $str; } else { $str .= ', ' if $str; return $str . $val->days . ' day' if $val->days == 1; return $str . $val->days.' days'; } } # Given a principal name, dump the information about that principal to a # given filehandle, or STDOUT if none is given. The format of the output # should be identical to that of kadmin's 'get' command. sub dump { my $sp = shift; my $io = (shift or \*STDOUT); printf $io "%21s: %s\n", 'Principal',$sp->getPrincipal; printf $io "%21s: %s\n", 'Principal expires', _sec2date($sp->getPrincExpireTime); printf $io "%21s: %s\n", 'Password expires', _sec2date($sp->getPwExpiration); printf $io "%21s: %s\n", 'Last password change', _sec2date($sp->getLastPwdChange); printf $io "%21s: %s\n", 'Max ticket life', _sec2days($sp->getMaxLife); printf $io "%21s: %s\n", 'Max renewable life', _sec2days($sp->getMaxRenewableLife); printf $io "%21s: %s\n", 'Kvno', $sp->getKvno; printf $io "%21s: %s\n", 'Mkvno', $sp->getMKvno; printf $io "%21s: %s\n", 'Last successful login', _sec2date($sp->getLastSuccess); printf $io "%21s: %s\n", 'Last failed login', _sec2date($sp->getLastFailed); printf $io "%21s: %d\n", 'Failed login count', $sp->getFailAuthCounts; printf $io "%21s: %s\n", 'Last modified', _sec2date($sp->getModDate); printf $io "%21s: %s\n", 'Modifier', $sp->getModName; printf $io "%21s: %s\n", 'Attributes', join (', ', sort $sp->getAttributeNames); my @keys; foreach my $kt (@{$sp->getKeytypes}) { push(@keys,"$kt->[0]($kt->[1])"); } printf $io "%21s: %s\n\n", 'Keytypes', join(', ',@keys); } # A wrapper around getAttributes, which translates the bitmask into an array # of attribute names and returns that array. sub getAttributeNames { my $sp = shift; my $bitmask = $sp->getAttributes; my @attrs = (); my @possible = ('KRB5_KDB_DISALLOW_ALL_TIX', 'KRB5_KDB_DISALLOW_DUP_SKEY', 'KRB5_KDB_DISALLOW_FORWARDABLE', 'KRB5_KDB_DISALLOW_POSTDATED', 'KRB5_KDB_DISALLOW_PROXIABLE', 'KRB5_KDB_DISALLOW_RENEWABLE', 'KRB5_KDB_DISALLOW_SVR', 'KRB5_KDB_DISALLOW_TGT_BASED', 'KRB5_KDB_NEW_PRINC', 'KRB5_KDB_REQUIRES_HW_AUTH', 'KRB5_KDB_REQUIRES_PRE_AUTH', 'KRB5_KDB_REQUIRES_PWCHANGE', 'KRB5_KDB_PWCHANGE_SERVICE', 'KRB5_KDB_SUPPORT_DESMD5', ); foreach my $test (@possible) { if ($bitmask & &{"Heimdal::Kadm5::$test"}()) { my $cleaned = lc ($test); $cleaned =~ s#^krb5_kdb_##; $cleaned =~ s#_#-#g; push (@attrs, $cleaned); } } return @attrs; } # Autoload methods go after =cut, and are processed by the autosplit program. package Heimdal::Kadm5; 1; __END__ # Below is the stub of documentation for your module. You better edit it! =head1 NAME Heimdal::Kadm5 - Perl extension for adminstration of Heimdal Kerberos servers (kadmin) =head1 SYNOPSIS use Heimdal::Kadm5; $client = Heimdal::Kadm5::Client->new('Client'=>'you/admin@YOUR.REALM', 'Password'=>'eatmyshorts'); foreach my $name ($client->getPrincipals('*/admin')) { my $principal = $client->getPrincipal($name); $principal->dump; } =head1 DESCRIPTION Heimdal::Kadm5 is a basic XSUB perl glue to the Heimdal (http://www.pdc.kth.se/src/heimdal) kadm5clnt library. Heimdal is a free, slightly less export challenged implementation of Kerberos5 by Assar Westerlund and Johan Danielsson. Heimdal::Kadm5 allows you to perform more administration of your kdc than you can usually pull off with the included kadmin program. Heimdal::Kadm5 should be considered alpha-code and may consequently crash and burn but should not muck up your kdc any more than kadmin itself does. =head1 OBJECTS C represents a client connection (the truly perverse may conspire to write a kadmin servlet in perl and put that in C) to a kadmin server. The main object handled by a kadmin server is a C (F). This type corresponds to the perl class C. This object is returned by the C method of C and can be created (when adding principals to the kdc) using the C method of C. Note: B>. Principals in the traditional sense of the word (i.e things of type C) are passed around as strings ('name/instance@REALM' or 'name@REALM'); =head1 METHODS In what follows $principal denotes an instance of Heimdal::Kadm5::Principal, $name denotes a principal name, $bitmask denotes an (you guessed it!) integer representing a bitmask, $seconds an integer representing seconds since the epoch (time_t value), $client a Heimdal::Kadm5::Client instance. Other variables should be even more obvious or are explained in the text. =head2 Heimdal::Kadm5::Client Minimal use: my $client = Heimdal::Kadm5::Client->new(Client=>'you'); This would connect using a password for 'you@DEFREALM'. The password is prompted on the active tty. A more complex example: my $client = Heimdal::Kadm5::Client->new( RaiseErrors => 1, Server => 'adm.somewhere.net', Port => '8899', # Required: Client => 'you/admin', Realm => 'OTHER.REALM', # --- Either --- Password => 'very secret', # --- Or --- Keytab => '$HOME/mysecret.keytab' ); Be very careful when using the Password parameter: it implies storing the password in the script or reading it from commmand line arguments or through some other means. Only use this on secured hosts, never from NFS mounted filesystems, and B using principals allowed to perform all operations on the kdc. In this case using a keytable (see L for information on how to create keytabs) is a better way to go. Normally both the Server, Port and Realm parameters are determined from the kerberos context (configuration files, DNS etc etc) but you may need to override them. If you leave out the password or set it to undef the client library will prompt you for a password. You must include the Client parameter which is usually your admin or root -instance depending on your local system of belief. If for some reason the client connection cannot be initialized undef is returned and errors are sent to warn unless the RaiseError parameter is set in which case all errors are propagated by die. my @names = $client->getPrincipals($pattern); The getPrincipals method returns a list of principals matching $pattern which is not a regular expression but rather a glob-like animal. For instance '*/admin@REALM' is an ok pattern. The elements of the list are principal names which can be used to obtain Heimdal::Kadm5::Principal object using my $principal = $client->getPrincipal($name); which returns a Heimdal::Kadm5::Principal object (see the next section for details). my $principal = $client->makePrincipal($name); The makePrincipal method takes a principal name and creates an empty Heimdal::Kadm5::Principal object. This is intended for adding principals to the kdc. After creating the principal using makePrincipal use the accessor methods in Heimdal::Kadm5::Principal to set values before adding the principal using $client->createPrincipal($principal,$password,$mask); If $mask is set this value is used to determine which elements of the principal to include in the creation. Normally this value is automatically determined by tracking the uses of the accessor methods in the Heimdal::Kadm5::Principal class. Modifications to an existing principal is done using this method: $client->createPrincipal($principal,$mask); The $mask value works in the same way as described above for createPrincipal. It is sometimes useful to disable (lock) a principal, for instance when several operations must be performed. The following methods can be used: $client->disablePrincipal($name); $client->enablePrincipal($name); Other methods which modify the kdc are and the use of which should be obvious: $client->changePassword($name, $password); $client->deletePrincipal($name); $client->renamePrincipal($name, $newname); $client->randKeyPrincipal($name); This method creates a random set of keys for the principal named $name. This is typically done for service principals. When creating a new service principal it is probably a good idea to create the principal with some initial password, disable the principal, apply the randKeyPrincipal method and then enable the principal. $client->handle->c_flush(); This method flushes all modifications to the datastore. It is called automatically when the client handle is DESTROYed if any modifications (password change, create, rename or delete has been performed); $client->extractKeytab($principal,$keytab); This method extracts the keys belonging to the principal object to the keytab (optionally) specified by the second argument. If the second argument is missing it defaults to the standard default keytab, typically F. =head2 Heimdal::Kadm5::Principal $principal->dump($io); Dumps a representation of $principal on the $io handle (which defaults to \*STDOUT). This is mostly usable for debugging or simple scripts. my $name = $principal->getPrincipal(); $principal->setPrincipal($name); Gets and sets the principal name. my $seconds = $principal->getPrincExpireTime(); $principal->setPrincExpireTime($seconds); Gets and sets the time this principal expires. my $seconds = $principal->getLastPwdChange(); Returns the last time this principal's password was changed. my $kvno = $principal->getKvno(); Returns the key version number of this principal's password. my $mkvno = $principal->getMKvno(); Returns this principal's MKvno. my $seconds = $principal->getPwExpiration(); $principal->setPwExpiration($seconds); Gets and sets the password expriation time. my $seconds = $principal->getMaxLife(); $principal->setMaxLife($seconds); Gets and sets the maximum lifetime of a ticket. my $seconds = $principal->getMaxRenewableLife(); $principal->setMaxRenewableLife($seconds); Gets and sets the maximum renewable ticket lifetime. my $name = $principal->getModName(); Returns the principal name of the last modifier of the entry. Not currently (as of heimdal 0.1g) supported by heimdal and contains undef. my $seconds = $principal->getModDate(); Returns the date of last modification of the entry. my $policyname = $principal->getPolicy(); getPolicy returns undef if no policy is set. Policies are not currently supported (as of heimdal 0.1g) and always returns undef. my $seconds = $principal->getLastSuccess(); Last time a successful authentication was done against this principal. my $seconds= $principal->getLastFailed(); Last time a failed authentication was done against this principal. my $nfailed = $principal->getFailAuthCounts(); How many failed login attempts was done against this principal. my $bitmask = $principal->getAttributes(); The bitmask of attributes for this principal. my @names = $principal->getAttributeNames(); The list of attribute names for this principal, expanded from the bitmask. my $arrayref = $principal->getKeyTypes(); getKeyTypes returns an array reference consisting of a list of array references with two elements each: [keytype,salt]. The keytype and salt are strings which describe a key associated with the principal. Note that this data may not be present depending on how the principal was obtained. my $password = $principal->getPassword(); getPassword returns the password if its saved in the Kerberos database. Not the that principal object need to fetched with the bit KADM5_TL_DATA set in the mask. =head1 Exported constants KADM5_ADMIN_SERVICE KADM5_API_VERSION_1 KADM5_API_VERSION_2 KADM5_ATTRIBUTES KADM5_AUX_ATTRIBUTES KADM5_CHANGEPW_SERVICE KADM5_CONFIG_ACL_FILE KADM5_CONFIG_ADBNAME KADM5_CONFIG_ADB_LOCKFILE KADM5_CONFIG_ADMIN_KEYTAB KADM5_CONFIG_ADMIN_SERVER KADM5_CONFIG_DBNAME KADM5_CONFIG_DICT_FILE KADM5_CONFIG_ENCTYPE KADM5_CONFIG_ENCTYPES KADM5_CONFIG_EXPIRATION KADM5_CONFIG_FLAGS KADM5_CONFIG_KADMIND_PORT KADM5_CONFIG_MAX_LIFE KADM5_CONFIG_MAX_RLIFE KADM5_CONFIG_MKEY_FROM_KEYBOARD KADM5_CONFIG_MKEY_NAME KADM5_CONFIG_PROFILE KADM5_CONFIG_REALM KADM5_CONFIG_STASH_FILE KADM5_FAIL_AUTH_COUNT KADM5_HIST_PRINCIPAL KADM5_KEY_DATA KADM5_KVNO KADM5_LAST_FAILED KADM5_LAST_PWD_CHANGE KADM5_LAST_SUCCESS KADM5_MAX_LIFE KADM5_MAX_RLIFE KADM5_MKVNO KADM5_MOD_NAME KADM5_MOD_TIME KADM5_POLICY KADM5_POLICY_CLR KADM5_POLICY_NORMAL_MASK KADM5_PRINCIPAL KADM5_PRINCIPAL_NORMAL_MASK KADM5_PRINC_EXPIRE_TIME KADM5_PRIV_ADD KADM5_PRIV_ALL KADM5_PRIV_CPW KADM5_PRIV_DELETE KADM5_PRIV_GET KADM5_PRIV_LIST KADM5_PRIV_MODIFY KADM5_PW_EXPIRATION KADM5_PW_HISTORY_NUM KADM5_PW_MAX_LIFE KADM5_PW_MIN_CLASSES KADM5_PW_MIN_LENGTH KADM5_PW_MIN_LIFE KADM5_REF_COUNT KADM5_STRUCT_VERSION KADM5_TL_DATA KRB5_KDB_DISALLOW_ALL_TIX KRB5_KDB_DISALLOW_DUP_SKEY KRB5_KDB_DISALLOW_FORWARDABLE KRB5_KDB_DISALLOW_POSTDATED KRB5_KDB_DISALLOW_PROXIABLE KRB5_KDB_DISALLOW_RENEWABLE KRB5_KDB_DISALLOW_SVR KRB5_KDB_DISALLOW_TGT_BASED KRB5_KDB_NEW_PRINC KRB5_KDB_PWCHANGE_SERVICE KRB5_KDB_REQUIRES_HW_AUTH KRB5_KDB_REQUIRES_PRE_AUTH KRB5_KDB_REQUIRES_PWCHANGE KRB5_KDB_SUPPORT_DESMD5 USE_KADM5_API_VERSION =head1 AUTHOR Leif Johansson, leifj@it.su.se =head1 SEE ALSO perl(1). =cut Heimdal-Kadm5-0.08/Makefile.PL0000644000175000017500000000147211332636472014674 0ustar leifjleifjuse ExtUtils::MakeMaker; # $Id$ my $find_krb5_config; my $lflags= '-L/pkg/heimdal/default/lib -lkrb5 -lroken -lasn1 -ldes -lkadm5clnt'; my $cflags= '-I/usr/heimdal/default/include' ; my @args = ("krb5-config", "--version"); $find_krb5_config = system(@args); if ($find_krb5_config eq 0) { $lflags = `krb5-config --libs kadm-client`; $cflags = `krb5-config --cflags kadm-client`; chomp $lflags; chomp $cflags; } printf "cflags: $cflags\n"; printf "lflags: $lflags\n"; WriteMakefile( 'NAME' => 'Heimdal::Kadm5', 'VERSION_FROM' => 'Kadm5.pm', 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? (ABSTRACT_FROM => 'Kadm5.pm', AUTHOR => 'Leif Johansson ') : ()), 'LIBS' => [ $lflags ], 'INC' => $cflags , 'DEFINE' => '', ); Heimdal-Kadm5-0.08/test.pl0000644000175000017500000000651311332636472014237 0ustar leifjleifj# # Copyright (c) 2003, Stockholms Universitet # (Stockholm University, Stockholm Sweden) # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the university nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # $Id$ # # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "0..2\n"; } END {print "not ok 1\n" unless $loaded;} #use lib './blib/lib'; use Heimdal::Kadm5 qw(/KADM5_/); $loaded = 1; print "ok 0\n"; my $mask = KADM5_PRINCIPAL_NORMAL_MASK | KADM5_KEY_DATA; print "ok 1\n"; # Ok, this test case is almost broken since there is no provisioning of # a test KDC on localhost, and there most probably is no KDC running there. # # The reason I don't just remove the test case all together is that the # visual output of the error is marginally better than not having the test # case at all. $client = Heimdal::Kadm5::Client->new(Server => 'localhost', Realm => 'EXAMPLE.COM', Principal => 'admin/admin@EXAMPLE.COM', RaiseErrors => 0 ); warn ("FAILED to create a Heimdal::Kadm5::Client object, but ignoring this\n" . "error because I can't tell if it was the normal problem that there is\n" . "no Kerberos server running on localhost, or something else :(\n") unless ($client); print "ok 2\n"; #for my $name ($client->getPrincipals('*/admin')) # { # my $princ = $client->getPrincipal($name); # warn $princ->getPrincipal; # } #$princ = $client->getPrincipal('host/njal.matematik.su.se'); #$client->extractKeytab($princ,'/tmp/trurl.keytab'); ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): Heimdal-Kadm5-0.08/Kadm5.xs0000644000175000017500000005543211333623163014236 0ustar leifjleifj/* * Copyright (c) 2003, Stockholms Universitet * (Stockholm University, Stockholm Sweden) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the university nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include #include "consts.h" typedef struct shandle_t { int modcount; void *ptr; kadm5_config_params params; krb5_context context; } shandle_t; typedef struct sprincipal_t { shandle_t *handle; int mask; kadm5_principal_ent_rec principal; } sprincipal_t; static sprincipal_t * create_sprincipal(shandle_t *handle) { sprincipal_t *p = (sprincipal_t *)safemalloc(sizeof(sprincipal_t)); memset(p,0,sizeof(*p)); p->handle = handle; return p; } static void destroy_sprincipal(sprincipal_t *spp) { kadm5_free_principal_ent(spp->handle,&spp->principal); safefree(spp); } static shandle_t * sv2server_handle(SV *sv) { if (SvROK(sv) && sv_isa(sv,"Heimdal::Kadm5::SHandle")) return (shandle_t *)SvIV(SvRV(sv)); else croak("Argument to sv2server_handle not referenced in package \"Heimdal::Kadm5::SHandle\""); } static sprincipal_t * sv2sprincipal(SV *sv) { if (SvROK(sv) && sv_isa(sv,"Heimdal::Kadm5::Principal")) return (sprincipal_t *)SvIV(SvRV(sv)); else croak("Argument to sv2kadm5_principal not referenced in package \"Heimdal::Kadm5::Principal\""); } static int set_param_strval(HV *hv, char **str, char *key) { SV **val = hv_fetch(hv, key, strlen(key), 0); //fprintf(stderr,"%s=\"%s\"\n",key,val != NULL ? SvPV_nolen(*val):"(null)"); if (val != NULL) { *str = SvPV_nolen(*val); return 1; } return 0; } static int set_param_intval(HV *hv, int *ival, char *key) { SV **val = hv_fetch(hv, key, 0, 0); if (val) { *ival = (int)SvIV(*val); return 1; } return 0; } static int not_here(s) char *s; { croak("%s not implemented on this architecture", s); return -1; } struct kadm_func { kadm5_ret_t (*chpass_principal) (void *, krb5_principal, char*); kadm5_ret_t (*create_principal) (void*, kadm5_principal_ent_t, u_int32_t, char*); kadm5_ret_t (*delete_principal) (void*, krb5_principal); kadm5_ret_t (*destroy) (void*); kadm5_ret_t (*flush) (void*); kadm5_ret_t (*get_principal) (void*, krb5_principal, kadm5_principal_ent_t, u_int32_t); kadm5_ret_t (*get_principals) (void*, const char*, char***, int*); kadm5_ret_t (*get_privs) (void*, u_int32_t*); kadm5_ret_t (*modify_principal) (void*, kadm5_principal_ent_t, u_int32_t); kadm5_ret_t (*randkey_principal) (void*, krb5_principal, krb5_keyblock**, int*); kadm5_ret_t (*rename_principal) (void*, krb5_principal, krb5_principal); kadm5_ret_t (*chpass_principal_with_key) (void *, krb5_principal, int, krb5_key_data *); }; typedef struct kadm5_client_context { krb5_context context; krb5_boolean my_context; struct kadm_func funcs; /* */ krb5_auth_context ac; char *realm; char *admin_server; int kadmind_port; int sock; char *client_name; char *service_name; krb5_prompter_fct prompter; const char *keytab; krb5_ccache ccache; kadm5_config_params *realm_params; }kadm5_client_context; MODULE = Heimdal::Kadm5::SHandle PACKAGE = Heimdal::Kadm5::SHandle PREFIX=kadm5_ PROTOTYPES: ENABLE shandle_t * new(self,sv) SV *self SV *sv CODE: { if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) { HV *hv = (HV *)SvRV(sv); shandle_t *handle = (shandle_t *)safemalloc(sizeof(shandle_t)); kadm5_ret_t ret; memset(handle,0,sizeof(*handle)); ret = krb5_init_context(&handle->context); if (ret) { safefree(handle); croak("[Heimdal::Kadm5] krb5_init_context failed: %s\n",krb5_get_err_text(handle->context, ret)); handle = NULL; goto cleanup; } if (set_param_strval(hv,&handle->params.realm,"Realm")) { /* fprintf(stderr,"Realm=\"%s\"\n",handle->params.realm); */ krb5_set_default_realm(handle->context, handle->params.realm); handle->params.mask |= KADM5_CONFIG_REALM; } /* set_param_strval(hv,&handle->params.profile,"Profile"); */ if (set_param_intval(hv,&handle->params.kadmind_port,"Port")) handle->params.mask |= KADM5_CONFIG_KADMIND_PORT; if (set_param_strval(hv,&handle->params.admin_server,"Server")) handle->params.mask |= KADM5_CONFIG_ADMIN_SERVER; cleanup: RETVAL = handle; } else { croak("[Heimdal::Kadm5] Argument to \"Heimdal::Kadm5::SHandle::new\" must be a hash-reference"); RETVAL = NULL; } } OUTPUT: RETVAL void DESTROY(handle) shandle_t *handle CODE: { if (handle->modcount > 0) { kadm5_c_flush(handle->ptr); } if (handle->ptr) kadm5_c_destroy(handle->ptr); if (handle->context) krb5_free_context(handle->context); safefree(handle); } void kadm5_c_init_with_password (handle, client_name, password, service_name, struct_version, api_version) shandle_t *handle char *client_name char *password char *service_name unsigned long struct_version unsigned long api_version CODE: { kadm5_ret_t ret = kadm5_c_init_with_password_ctx(handle->context, client_name, password, KADM5_ADMIN_SERVICE, &handle->params, struct_version, api_version, &handle->ptr); if(ret) croak("[Heimdal::Kadm5] kadm5_c_init_with_password_ctx failed: %s\n", krb5_get_err_text(handle->context, ret)); if (password != NULL && *password != '\0') ((kadm5_client_context *)handle->ptr)->prompter = NULL; } void kadm5_c_init_with_skey (handle, client_name, keytab, service_name, struct_version, api_version) shandle_t *handle char *client_name char *keytab char *service_name unsigned long struct_version unsigned long api_version CODE: { kadm5_ret_t ret = kadm5_c_init_with_skey_ctx(handle->context, client_name, keytab, KADM5_ADMIN_SERVICE, &handle->params, struct_version, api_version, &handle->ptr); if(ret) croak("[Heimdal::Kadm5] kadm5_c_init_with_skey_ctx failed: %s\n", krb5_get_err_text(handle->context, ret)); } void kadm5_c_flush(handle) shandle_t *handle CODE: { kadm5_ret_t ret = kadm5_c_flush(handle->ptr); if (ret) croak("[Heimdal::Kadm5] kadm5_c_flush failed: %s\n",krb5_get_err_text(handle->context, ret)); handle->modcount = 0; } void kadm5_c_modify_principal(handle,spp,mask) shandle_t *handle sprincipal_t *spp int mask CODE: { kadm5_ret_t ret; if (mask == 0) mask = spp->mask; ret = kadm5_c_modify_principal(handle->ptr, &spp->principal, mask); if (ret) { if (ret) croak("[Heimdal::Kadm5] kadm5_c_modify_principal failed: %s\n", krb5_get_err_text(handle->context, ret)); } handle->modcount++; } int kadm5_c_randkey_principal(handle,name) shandle_t *handle char *name CODE: { krb5_keyblock *new_keys; int n_keys, i; krb5_principal principal; krb5_error_code err; kadm5_ret_t ret; err = krb5_parse_name(handle->context, name, &principal); if (err) croak("[Heimdal::Kadm5] krb5_parse_name failed on \"%s\": %s\n", name,krb5_get_err_text(handle->context, err)); ret = kadm5_randkey_principal(handle->ptr, principal, &new_keys, &n_keys); if(ret) { krb5_free_principal(handle->context, principal); croak("[Heimdal::Kadm5] kadm5_c_randkey_principal failed: %s\n", krb5_get_err_text(handle->context, ret)); } for(i = 0; i < n_keys; i++) krb5_free_keyblock_contents(handle->context, &new_keys[i]); free(new_keys); krb5_free_principal(handle->context, principal); handle->modcount++; RETVAL = n_keys; } OUTPUT: RETVAL void kadm5_c_chpass_principal(handle,name,password) shandle_t *handle char *name char *password CODE: { kadm5_ret_t ret; krb5_error_code ret2; krb5_principal principal; ret2 = krb5_parse_name(handle->context, name, &principal); if (ret2) croak("[Heimdal::Kadm5] krb5_parse_name failed on \"%s\": %s\n", name,krb5_get_err_text(handle->context, ret2)); ret = kadm5_c_chpass_principal(handle->ptr,principal,password); if (ret) croak("[Heimdal::Kadm5] kadm5_c_chpass_principal failed on \"%s\": %s\n", name,krb5_get_err_text(handle->context, ret)); handle->modcount++; } void kadm5_c_create_principal(handle,spp,password,mask) shandle_t *handle sprincipal_t *spp char *password int mask CODE: { kadm5_ret_t ret; if (mask == 0) mask = spp->mask; ret = kadm5_c_create_principal(handle->ptr,&spp->principal,mask,password); if (ret) { char *p; krb5_error_code ret2; ret2 = krb5_unparse_name(handle->context,spp->principal.principal,&p); if (ret2) { safefree(p); croak("[Heimdal::Kadm5] krb5_unparse_name failed: %s\n", krb5_get_err_text(spp->handle->context, ret2)); } croak("[Heimdal::Kadm5] krb5_c_create_principal failed on \"%s\": %s\n", p,krb5_get_err_text(handle->context, ret)); } handle->modcount++; } void kadm5_c_rename_principal(handle, src, trg) shandle_t *handle char *src char *trg CODE: { krb5_error_code ret; krb5_principal source, target; kadm5_ret_t err; ret = krb5_parse_name(handle->context, src, &source); if (ret) { croak("[Heimdal::Kadm5] krb5_parse_name failed on \"%s\": %s\n", src,krb5_get_err_text(handle->context, ret)); } ret = krb5_parse_name(handle->context, trg, &target); if (ret) { krb5_free_principal(handle->context, target); croak("[Heimdal::Kadm5] krb5_parse_name failed on \"%s\": %s\n", trg,krb5_get_err_text(handle->context, ret)); } err = kadm5_c_rename_principal(handle->ptr, source, target); if (err) { krb5_free_principal(handle->context, source); krb5_free_principal(handle->context, target); croak("[Heimdal::Kadm5] kadm5_rename_principal \"%s\" to \"%s\" failed: %s\n", src,trg,krb5_get_err_text(handle->context, err)); } krb5_free_principal(handle->context, source); krb5_free_principal(handle->context, target); handle->modcount++; } void kadm5_c_delete_principal(handle,name) shandle_t *handle char *name CODE: { krb5_error_code ret; krb5_principal principal; kadm5_ret_t err; ret = krb5_parse_name(handle->context, name, &principal); if (ret) croak("[Heimdal::Kadm5] krb5_parse_name failed on \"%s\": %s\n", name,krb5_get_err_text(handle->context, ret)); err = kadm5_c_delete_principal(handle->ptr,principal); if (err) { krb5_free_principal(handle->context, principal); croak("[Heimdal::Kadm5] kadm5_c_delete_principal failed for \"%s\": %s\n", name,krb5_get_err_text(handle->context, err)); } handle->modcount++; krb5_free_principal(handle->context, principal); } sprincipal_t * kadm5_c_get_principal(handle, name, mask) shandle_t *handle char *name IV mask CODE: { krb5_principal principal; krb5_error_code ret; sprincipal_t *spp; ret = krb5_parse_name(handle->context, name, &principal); if (ret) croak("[Heimdal::Kadm5] krb5_parse_name failed on \"%s\": %s\n", name,krb5_get_err_text(handle->context, ret)); spp = create_sprincipal(handle); ret = kadm5_c_get_principal(handle->ptr, principal, &spp->principal, mask); if (ret) { if (ret == KADM5_UNK_PRINC) { destroy_sprincipal(spp); spp = NULL; } else { krb5_free_principal(handle->context, principal); destroy_sprincipal(spp); croak("[Heimdal::Kadm5] kadm5_c_get_principal failed for \"%s\": %s\n", name,krb5_get_err_text(handle->context, ret)); } } krb5_free_principal(handle->context,principal); RETVAL = spp; } OUTPUT: RETVAL void kadm5_c_get_principals(handle,exp) shandle_t *handle char *exp PPCODE: { char **princs; int num_princs,i; kadm5_ret_t ret; ret = kadm5_c_get_principals(handle->ptr,exp,&princs,&num_princs); if (ret) { croak("[Heimdal::Kadm5] kadm5_c_get_principals failed for \"%s\": %s\n", exp,krb5_get_err_text(handle->context, ret)); } EXTEND(SP,num_princs); for (i = 0; i < num_princs; i++) { PUSHs(sv_2mortal(newSVpv(princs[i],0))); } kadm5_free_name_list(handle->ptr,princs,&num_princs); } int kadm5_c_get_privs(handle) shandle_t *handle CODE: { int privs; kadm5_ret_t ret = kadm5_c_get_privs(handle->ptr,&privs); if (ret) { croak("[Heimdal::Kadm5] kadm5_c_get_privs failed: %s\n", krb5_get_err_text(handle->context, ret)); } RETVAL = privs; } OUTPUT: RETVAL void kadm5_c_ext_keytab(handle,spp,keytab) shandle_t *handle sprincipal_t *spp char *keytab CODE: { int i; krb5_keytab kt; krb5_error_code ret; if(keytab) ret = krb5_kt_resolve(handle->context, keytab, &kt); else ret = krb5_kt_default(handle->context, &kt); if (ret) croak("[Heimdal::Kadm5] krb5_kt_resolv failed: %s\n", krb5_get_err_text(handle->context, ret)); for(i = 0; i < spp->principal.n_key_data; i++) { krb5_keytab_entry key; krb5_key_data *k = &spp->principal.key_data[i]; key.principal = spp->principal.principal; key.vno = k->key_data_kvno; key.keyblock.keytype = k->key_data_type[0]; key.keyblock.keyvalue.length = k->key_data_length[0]; key.keyblock.keyvalue.data = k->key_data_contents[0]; ret = krb5_kt_add_entry(handle->context, kt, &key); if (ret) croak("[Heimdal::Kadm5] krb5_kt_add_entry failed: %s\n", krb5_get_err_text(handle->context, ret)); } krb5_kt_close(handle->context, kt); } MODULE = Heimdal::Kadm5::Principal PACKAGE = Heimdal::Kadm5::Principal sprincipal_t * new(self,handle) SV *self shandle_t *handle CODE: { sprincipal_t *spp = create_sprincipal(handle); RETVAL = spp; } OUTPUT: RETVAL void DESTROY(spp) sprincipal_t *spp CODE: { destroy_sprincipal(spp); } SV * getPrincipal(spp) sprincipal_t *spp CODE: { char *p; krb5_error_code ret; ret = krb5_unparse_name(spp->handle->context,spp->principal.principal,&p); if (ret) { safefree(p); croak("[Heimdal::Kadm5] krb5_unparse_name failed: %s\n", krb5_get_err_text(spp->handle->context, ret)); } RETVAL = newSVpv(p,0); } OUTPUT: RETVAL void setPrincipal(spp,p) sprincipal_t *spp char *p CODE: { krb5_error_code ret; ret = krb5_parse_name(spp->handle->context,p,&spp->principal.principal); if (ret) { croak("[Heimdal::Kadm5] krb5_parse_name failed for \"%s\": %s\n", p,krb5_get_err_text(spp->handle->context, ret)); } spp->mask |= KADM5_PRINCIPAL; } int getPrincExpireTime(spp) sprincipal_t *spp PPCODE: { XPUSHi(spp->principal.princ_expire_time); } void setPrincExpireTime(spp,val) sprincipal_t *spp IV val CODE: { spp->principal.princ_expire_time = val; spp->mask |= KADM5_PRINC_EXPIRE_TIME; } IV getLastPwdChange(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.last_pwd_change; } OUTPUT: RETVAL IV getKvno(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.kvno; } OUTPUT: RETVAL IV getMKvno(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.mkvno; } OUTPUT: RETVAL IV getPwExpiration(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.pw_expiration; } OUTPUT: RETVAL void setPwExpiration(spp,val) sprincipal_t *spp IV val CODE: { spp->principal.pw_expiration = val; spp->mask |= KADM5_PW_EXPIRATION; } IV getMaxLife(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.max_life; } OUTPUT: RETVAL void setMaxLife(spp,val) sprincipal_t *spp IV val CODE: { spp->principal.max_life = val; spp->mask |= KADM5_MAX_LIFE; } SV * getModName(spp) sprincipal_t *spp CODE: { char *p; krb5_error_code ret; ret = krb5_unparse_name(spp->handle->context,spp->principal.mod_name,&p); if (ret) { safefree(p); croak("[Heimdal::Kadm5] krb5_unparse_name failed: %s\n", krb5_get_err_text(spp->handle->context, ret)); } RETVAL = newSVpv(p,0); } OUTPUT: RETVAL IV getModDate(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.mod_date; } OUTPUT: RETVAL SV * getPolicy(spp) sprincipal_t *spp CODE: { if (spp->principal.policy) RETVAL = newSVpv(spp->principal.policy,0); else RETVAL = &PL_sv_undef; } OUTPUT: RETVAL IV getMaxRenewableLife(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.max_renewable_life; } OUTPUT: RETVAL void setMaxRenewableLife(spp,val) sprincipal_t *spp IV val CODE: { spp->principal.max_renewable_life = val; spp->mask |= KADM5_MAX_RLIFE; } IV getLastSuccess(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.last_success; } OUTPUT: RETVAL IV getLastFailed(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.last_failed; } OUTPUT: RETVAL IV getFailAuthCount(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.fail_auth_count; } OUTPUT: RETVAL IV getFailAuthCounts(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.fail_auth_count; } OUTPUT: RETVAL IV getAttributes(spp) sprincipal_t *spp CODE: { RETVAL = spp->principal.attributes; } OUTPUT: RETVAL void setAttributes(spp,val) sprincipal_t *spp IV val CODE: { spp->principal.attributes = val; spp->mask |= KADM5_ATTRIBUTES; } SV * getKeytypes(spp) sprincipal_t *spp CODE: { int i; AV *lst = newAV(); for (i = 0; i < spp->principal.n_key_data; ++i) { krb5_key_data *k = &spp->principal.key_data[i]; krb5_error_code ret; char *e_string, *s_string; SV *ksv[2]; ret = krb5_enctype_to_string (spp->handle->context, k->key_data_type[0], &e_string); if (ret) asprintf (&e_string, "unknown(%d)", k->key_data_type[0]); ksv[0] = newSVpv(e_string,0); ret = krb5_salttype_to_string (spp->handle->context, k->key_data_type[0], k->key_data_type[1], &s_string); if (ret) asprintf (&s_string, "unknown(%d)", k->key_data_type[1]); ksv[1] = newSVpv(s_string,0); av_push(lst,newRV_inc((SV *)av_make(2,ksv))); free (e_string); free (s_string); } RETVAL = newRV_inc((SV *)lst); } OUTPUT: RETVAL void delKeytypes(spp,enctype) sprincipal_t *spp char *enctype CODE: { krb5_key_data *new_key_data = malloc(spp->principal.n_key_data * sizeof(*new_key_data)); krb5_enctype *etypes = malloc(sizeof(*etypes)); int i, j; krb5_string_to_enctype(spp->handle->context, enctype, etypes); for (i = 0, j = 0; i < spp->principal.n_key_data; ++i) { krb5_key_data *key = &spp->principal.key_data[i]; if (*etypes == key->key_data_type[0]) { int16_t ignore = 1; kadm5_free_key_data (spp->handle, &ignore, key); } else { new_key_data[j++] = *key; } } free (spp->principal.key_data); spp->principal.n_key_data = j; spp->principal.key_data = new_key_data; spp->mask |= KADM5_KEY_DATA; spp->handle->modcount++; } SV * getPassword(spp) sprincipal_t *spp CODE: { #ifdef KRB5_TL_PASSWORD krb5_tl_data *tl = spp->principal.tl_data; while (tl != NULL) { if (tl->tl_data_type == KRB5_TL_PASSWORD) break; tl = tl->tl_data_next; } if (tl) RETVAL = newSVpv(tl->tl_data_contents,0); else #endif RETVAL = &PL_sv_undef; } OUTPUT: RETVAL MODULE = Heimdal::Kadm5 PACKAGE = Heimdal::Kadm5 double constant(name,arg) char * name int arg