7
use OpenAFS::ConfigUtils;
9
my $path = $OpenAFS::Dirpath::openafsdirpath;
11
'mit' => 'OpenAFS::Auth::MIT',
12
#'heimdal' => 'OpenAFS::Auth::Heimdal',
13
'kaserver' => 'OpenAFS::Auth::Kaserver',
16
my $bos = "$path->{'afssrvbindir'}/bos";
17
my $aklog = "$path->{'afswsbindir'}/aklog";
18
my $tokens = "$path->{'afswsbindir'}/tokens";
19
my $asetkey = "$path->{'afssrvbindir'}/asetkey";
20
my $kas = "$path->{'afssrvsbindir'}/kas";
21
my $klog = "$path->{'afswsbindir'}/klog";
24
# Create an auth type for the specified Kerberos implementation.
27
# type -- Kerberos implementation: mit, heimdal, kaserver
28
# keytab -- path and name of the keytab file for mit and heimdal
29
# cell -- cell name. if not specified, attempts to find the
30
# cell name in the ThisCell configuration file.
31
# realm -- realm name. if not specified, assume the realm name
32
# is the same as the cell name, in uppercase.
35
# my $auth = OpenAFS::Auth::create(
37
# 'keytab'=>'/path/to/file/krb5.keytab');
39
# $auth->authorize('admin');
45
if (defined $parms->{'type'}) {
46
$type = $parms->{'type'};
49
my $class = $classes->{$type};
51
die "Unsupported kerberos type: $type\n";
53
return $class->new(@_);
57
# Create an auth instance.
68
# user specified values
72
$self = bless($self, $class);
74
# attempt get default values.
75
unless ($self->{'cell'}) {
77
$self->{'cell'} = $self->_lookup_cell_name();
80
unless ($self->{'realm'}) {
81
if ($self->{'cell'}) {
82
my $cell = $self->{'cell'};
83
($self->{'realm'} = $cell) =~ tr[a-z][A-Z];
86
unless ($self->{'keytab'}) {
87
$self->{'keytab'} = "$path->{'afsconfdir'}/krb5.keytab";
90
# kerberos type specific sanity checks.
91
$self->_sanity_check();
94
print "debug: Auth::create()\n";
95
foreach my $k (sort keys(%$self)) {
96
print "debug: $k => $self->{$k}\n";
103
# Returns the cell name from the ThisCell configuration file.
105
sub _lookup_cell_name {
108
open(CELL, "$path->{'afsconfdir'}/ThisCell")
109
or die "error: Cannot open $path->{'afsconfdir'}/ThisCell: $!\n";
117
# Placeholder for make_keyfile. Sub-classes should override.
125
# Make the krb.conf file if the realm name is different
126
# than the cell name. The syntax is something like,
129
# UMICH.EDU fear.ifs.umich.edu admin server
130
# UMICH.EDU surprise.ifs.umich.edu
131
# UMICH.EDU ruthless.ifs.umich.edu
133
sub make_krb_config {
135
my $cell = $self->{'cell'};
136
my $realm = $self->{'realm'};
138
if ($realm && $realm ne $cell) {
139
unless ( -d $path->{'afsconfdir'} ) {
140
die "error: OpenAFS configuration directory '$path->{'afsconfdir'}' is missing.\n";
142
unless ( -w $path->{'afsconfdir'} ) {
143
die "error: Write access to the configuration directory '$path->{'afsconfdir'}' is required.\n";
145
print "debug: Making $path->{'afsconfdir'}/krb.conf file for realm $realm\n" if $self->{'debug'};
146
open(KRB, "> $path->{'afsconfdir'}/krb.conf") or die "error: Failed to open $path->{'afsconfdir'}/krb.conf, $!\n";
147
print KRB "$realm\n";
153
# Enable/disable debug messages.
158
$self->{'debug'} = shift;
160
return $self->{'debug'};
164
# check_program($prog) - verify the program is installed.
169
unless ( -f $program ) {
170
die "error: Missing program: $program\n";
172
unless ( -x $program ) {
173
die "error: Not executable: $program\n";
177
#------------------------------------------------------------------------------------
178
# MIT Kerberos authorization commands.
180
package OpenAFS::Auth::MIT;
182
use OpenAFS::Dirpath;
183
use OpenAFS::ConfigUtils;
184
our @ISA = ("OpenAFS::Auth");
188
# Sanity checks before we get started.
193
$self->check_program($aklog);
194
$self->check_program($tokens);
195
$self->check_program($asetkey);
197
unless ($self->{'realm'}) {
198
die "error: Missing realm parameter Auth::create().\n";
200
unless ($self->{'keytab'}) {
201
die "error: Missing keytab parameter Auth::create().\n";
203
unless ( -f $self->{'keytab'} ) {
204
die "error: Kerberos keytab file not found: $self->{'keytab'}\n";
207
print "debug: Verifying the keytab and admin name, $self->{'admin'}.\n" if $self->debug;
208
run("kinit -k -t $self->{'keytab'} $self->{'admin'}");
210
print "debug: Getting the afs principal and kvno from the keytab.\n" if $self->debug;
211
$self->_prepare_make_keyfile();
215
# Read the keytab to find the kvno of the afs principal.
217
sub _prepare_make_keyfile {
220
# Run klist to get the kvno of the afs key. Search for afs/cellname@REALM
221
# then afs@REALM. klist must be in the path.
228
print "debug: reading $self->{'keytab'} to find afs kvno\n";
230
open(KLIST, "klist -k $self->{'keytab'} |") or die "make_keyfile: Failed to run klist.";
233
next if /^Keytab/; # skip headers
236
($kvno, $principal) = split;
238
print "debug: kvno=$kvno principal=$principal\n";
240
$keys{$principal} = $kvno;
243
my $cell = $self->{'cell'};
244
my $realm = $self->{'realm'};
245
foreach my $principal ("afs/$cell\@$realm", "afs\@$realm") {
247
print "debug: searching for $principal\n";
249
if (defined $keys{$principal}) {
250
$afs_principal = $principal;
251
$afs_kvno = $keys{$afs_principal};
253
print "debug: found principal=$afs_principal kvno=$afs_kvno\n";
259
die "error: Could not find an afs key matching 'afs/$cell\@$realm' or ".
260
"'afs/$cell' in keytab $self->{'keytab'}\n";
263
$self->{'afs_principal'} = $afs_principal;
264
$self->{'afs_kvno'} = $afs_kvno;
268
# Create the KeyFile from the Kerberos keytab file. The keytab file
269
# should be created using the Kerberos kadmin command (or with the kadmin.local command
270
# as root on the KDC). See the OpenAFS asetkey man page for details.
275
# The current asetkey implementation requires the ThisCell and CellServDB files
276
# to be present but they really are not needed to create the KeyFile. A check is done here
277
# rather than in the _sanity_checks() because the ThisCell/CellServerDB are created later in
278
# the process of creating the new cell.
279
unless ( -d $path->{'afsconfdir'} ) {
280
die "error: OpenAFS configuration directory '$path->{'afsconfdir'}' is missing.\n";
282
unless ( -w $path->{'afsconfdir'} ) {
283
die "error: Write access to the OpenAFS configuration directory '$path->{'afsconfdir'}' is required.\n";
285
unless ( -f "$path->{'afsconfdir'}/ThisCell" ) {
286
die "error: OpenAFS configuration file is required, $path->{'afsconfdir'}/ThisCell\n";
288
unless ( -f "$path->{'afsconfdir'}/CellServDB" ) {
289
die "error: OpenAFS configuration file is required, $path->{'afsconfdir'}/CellServDB\n";
292
run("$asetkey add $self->{'afs_kvno'} $self->{'keytab'} $self->{'afs_principal'}");
296
# Get kerberos ticket and AFS token for the user.
300
my $principal = shift || $self->{'admin'};
302
$opt_aklog .= " -d" if $self->debug;
304
run("kinit -k -t $self->{'keytab'} $principal");
305
run("$aklog $opt_aklog");
310
#------------------------------------------------------------------------------------
311
package OpenAFS::Auth::Heimdal;
313
use OpenAFS::Dirpath;
314
use OpenAFS::ConfigUtils;
315
our @ISA = ("OpenAFS::Auth");
318
# Various checks during initialization.
322
unless ($self->{'realm'}) {
323
die "Missing realm parameter Auth::create().\n";
325
unless ($self->{'keytab'}) {
326
die "Missing keytab parameter Auth::create().\n";
328
unless ( -f $self->{'keytab'} ) {
329
die "keytab file not found: $self->{'keytab'}\n";
335
die "not implemented.";
339
# Get kerberos ticket and AFS token for the user.
343
my $principal = shift || 'admin';
344
run("kinit -k -t $self->{'keytab'} $principal\@$self->{'realm'} && afslog");
347
#------------------------------------------------------------------------------------
348
package OpenAFS::Auth::Kaserver;
350
use OpenAFS::Dirpath;
351
use OpenAFS::ConfigUtils;
352
our @ISA = ("OpenAFS::Auth");
356
# Various checks during initialization.
360
$self->check_program($kas);
361
$self->check_program($klog);
362
$self->check_program($tokens);
363
unless ($self->{'realm'}) {
364
die "Missing realm parameter Auth::create().\n";
370
run("$kas create afs -noauth");
371
run("$kas create admin -noauth");
372
run("$kas setfields admin -flags admin -noauth");
373
run("$bos addkey localhost -kvno 0 -noauth");
377
# Get kerberos ticket and AFS token for the user.
381
my $principal = shift || 'admin';
382
#run("echo \"Proceeding w/o authentication\"|klog -pipe ${principal}\@$self->{'realm'}");
383
run("klog $principal\@$self->{'realm'}");