~ubuntu-branches/ubuntu/oneiric/openafs/oneiric-201305130334

« back to all changes in this revision

Viewing changes to src/tests/OpenAFS/Auth.pm

  • Committer: Bazaar Package Importer
  • Author(s): Russ Allbery
  • Date: 2008-09-22 19:07:02 UTC
  • mfrom: (12.1.14 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080922190702-59m13d7kn6gkw32d
Tags: 1.4.7.dfsg1-6
* Apply upstream patch to free /proc entries in the correct order.
  Thanks, Marc Dionne.  (Closes: #493914)
* Apply upstream deltas to support 2.6.27 kernels and to stop using
  COMMON_KERN_CFLAGS for all 2.6 kernels uniformly, which fixes
  problems on amd64 with newer kernels.  Thanks, Björn Torkelsson.
  (LP: #267504)
* Translation updates:
  - Swedish, thanks Martin Bagge.  (Closes: #493120)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# This is -*- perl -*-
 
2
 
 
3
package OpenAFS::Auth;
 
4
use strict;
 
5
use warnings;
 
6
use OpenAFS::Dirpath;
 
7
use OpenAFS::ConfigUtils;
 
8
 
 
9
my $path = $OpenAFS::Dirpath::openafsdirpath;
 
10
my $classes = {
 
11
  'mit'      => 'OpenAFS::Auth::MIT',
 
12
  #'heimdal' => 'OpenAFS::Auth::Heimdal',
 
13
  'kaserver' => 'OpenAFS::Auth::Kaserver',
 
14
};
 
15
 
 
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";
 
22
 
 
23
#
 
24
# Create an auth type for the specified Kerberos implementation.
 
25
#
 
26
# parameters:
 
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.
 
33
#
 
34
# example:
 
35
#  my $auth = OpenAFS::Auth::create(
 
36
#               'type'=>'mit', 
 
37
#               'keytab'=>'/path/to/file/krb5.keytab');
 
38
#
 
39
#  $auth->authorize('admin');
 
40
#
 
41
sub create {
 
42
  my $parms = {@_};
 
43
  my $type = 'mit';
 
44
 
 
45
  if (defined $parms->{'type'}) {
 
46
    $type = $parms->{'type'};
 
47
  }
 
48
  $type =~ tr/A-Z/a-z/;
 
49
  my $class = $classes->{$type};
 
50
  unless($class) {
 
51
    die "Unsupported kerberos type: $type\n";
 
52
  }
 
53
  return $class->new(@_);
 
54
}
 
55
 
 
56
#
 
57
# Create an auth instance.
 
58
#
 
59
sub new {
 
60
  my $class = shift;
 
61
  my $self = {
 
62
     # default values
 
63
     'type' => 'MIT',
 
64
     'cell' => '',
 
65
     'realm' => '', 
 
66
     'admin' => 'admin',
 
67
     'debug' => '0',
 
68
     # user specified values
 
69
     @_,
 
70
  };
 
71
 
 
72
  $self = bless($self, $class);
 
73
 
 
74
  # attempt get default values.
 
75
  unless ($self->{'cell'}) {
 
76
    eval {
 
77
      $self->{'cell'} = $self->_lookup_cell_name();
 
78
    }
 
79
  }
 
80
  unless ($self->{'realm'}) {
 
81
    if ($self->{'cell'}) {
 
82
      my $cell = $self->{'cell'};
 
83
      ($self->{'realm'} = $cell) =~ tr[a-z][A-Z];
 
84
    }
 
85
  }
 
86
  unless ($self->{'keytab'}) {
 
87
    $self->{'keytab'} = "$path->{'afsconfdir'}/krb5.keytab";
 
88
  }
 
89
 
 
90
  # kerberos type specific sanity checks.
 
91
  $self->_sanity_check();
 
92
 
 
93
  if ($self->debug) {
 
94
    print "debug: Auth::create()\n";
 
95
    foreach my $k (sort keys(%$self)) {
 
96
      print "debug:  $k => $self->{$k}\n";
 
97
    }
 
98
  }
 
99
  return $self;
 
100
}
 
101
 
 
102
#
 
103
# Returns the cell name from the ThisCell configuration file.
 
104
#
 
105
sub _lookup_cell_name {
 
106
  my $self = shift;
 
107
  my $cell;
 
108
  open(CELL, "$path->{'afsconfdir'}/ThisCell") 
 
109
    or die "error: Cannot open $path->{'afsconfdir'}/ThisCell: $!\n";
 
110
  $cell = <CELL>;
 
111
  chomp $cell;
 
112
  close CELL;
 
113
  return $cell;
 
114
}
 
115
 
 
116
#
 
117
# Placeholder for make_keyfile. Sub-classes should override.
 
118
#
 
119
sub make_keyfile {
 
120
  my $self = shift;
 
121
  return;
 
122
}
 
123
 
 
124
 
125
# Make the krb.conf file if the realm name is different
 
126
# than the cell name. The syntax is something like,
 
127
#
 
128
#   UMICH.EDU
 
129
#   UMICH.EDU fear.ifs.umich.edu admin server
 
130
#   UMICH.EDU surprise.ifs.umich.edu
 
131
#   UMICH.EDU ruthless.ifs.umich.edu
 
132
#
 
133
sub make_krb_config {
 
134
  my $self = shift;
 
135
  my $cell = $self->{'cell'};
 
136
  my $realm = $self->{'realm'};
 
137
 
 
138
  if ($realm && $realm ne $cell) {
 
139
    unless ( -d $path->{'afsconfdir'} ) {
 
140
      die "error: OpenAFS configuration directory '$path->{'afsconfdir'}' is missing.\n";
 
141
    }
 
142
    unless ( -w $path->{'afsconfdir'} ) {
 
143
      die "error: Write access to the configuration directory '$path->{'afsconfdir'}' is required.\n";
 
144
    }
 
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";
 
148
    close KRB;
 
149
  } 
 
150
}
 
151
 
 
152
#
 
153
# Enable/disable debug messages.
 
154
#
 
155
sub debug {
 
156
  my $self = shift;
 
157
  if (@_) {
 
158
    $self->{'debug'} = shift;
 
159
  }
 
160
  return $self->{'debug'};
 
161
}
 
162
 
 
163
#
 
164
# check_program($prog) - verify the program is installed.
 
165
#
 
166
sub check_program {
 
167
  my $self = shift;
 
168
  my $program = shift;
 
169
  unless ( -f $program ) {
 
170
     die "error: Missing program: $program\n";
 
171
  }
 
172
  unless ( -x $program ) {
 
173
     die "error: Not executable: $program\n";
 
174
  }
 
175
}
 
176
 
 
177
#------------------------------------------------------------------------------------
 
178
# MIT Kerberos authorization commands.
 
179
#
 
180
package OpenAFS::Auth::MIT;
 
181
use strict;
 
182
use OpenAFS::Dirpath;
 
183
use OpenAFS::ConfigUtils;
 
184
our @ISA = ("OpenAFS::Auth");
 
185
 
 
186
 
 
187
#
 
188
# Sanity checks before we get started.
 
189
#
 
190
sub _sanity_check {
 
191
  my $self = shift;
 
192
 
 
193
  $self->check_program($aklog);
 
194
  $self->check_program($tokens);
 
195
  $self->check_program($asetkey);
 
196
 
 
197
  unless ($self->{'realm'}) {
 
198
    die "error: Missing realm parameter Auth::create().\n";
 
199
  }
 
200
  unless ($self->{'keytab'}) {
 
201
    die "error: Missing keytab parameter Auth::create().\n";
 
202
  }
 
203
  unless ( -f $self->{'keytab'} ) {
 
204
    die "error: Kerberos keytab file not found: $self->{'keytab'}\n";
 
205
  }
 
206
 
 
207
  print "debug: Verifying the keytab and admin name, $self->{'admin'}.\n" if $self->debug;
 
208
  run("kinit -k -t $self->{'keytab'} $self->{'admin'}");
 
209
 
 
210
  print "debug: Getting the afs principal and kvno from the keytab.\n" if $self->debug;
 
211
  $self->_prepare_make_keyfile();
 
212
}
 
213
 
 
214
#
 
215
# Read the keytab to find the kvno of the afs principal.
 
216
#
 
217
sub _prepare_make_keyfile {
 
218
  my $self = shift;
 
219
 
 
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.
 
222
  my %keys = ();
 
223
  my $kvno;
 
224
  my $principal;
 
225
  my $afs_kvno;
 
226
  my $afs_principal;
 
227
  if ($self->debug) {
 
228
    print "debug: reading $self->{'keytab'} to find afs kvno\n";
 
229
  }
 
230
  open(KLIST, "klist -k $self->{'keytab'} |") or die "make_keyfile: Failed to run klist.";
 
231
  while (<KLIST>) {
 
232
    chomp;
 
233
    next if /^Keytab/;  # skip headers
 
234
    next if /^KVNO/;
 
235
    next if /^----/;
 
236
    ($kvno, $principal) = split;
 
237
    if ($self->debug) {
 
238
      print "debug:  kvno=$kvno principal=$principal\n";
 
239
    }
 
240
    $keys{$principal} = $kvno;
 
241
  }
 
242
  close KLIST;
 
243
  my $cell = $self->{'cell'};
 
244
  my $realm = $self->{'realm'};
 
245
  foreach my $principal ("afs/$cell\@$realm", "afs\@$realm") {
 
246
    if ($self->debug) {
 
247
      print "debug: searching for $principal\n";
 
248
    }
 
249
    if (defined $keys{$principal}) {
 
250
      $afs_principal = $principal;
 
251
      $afs_kvno = $keys{$afs_principal};
 
252
      if ($self->debug) {
 
253
         print "debug: found principal=$afs_principal kvno=$afs_kvno\n";
 
254
      }
 
255
      last;
 
256
    }
 
257
  }
 
258
  unless ($afs_kvno) {
 
259
    die "error: Could not find an afs key matching 'afs/$cell\@$realm' or ".
 
260
      "'afs/$cell' in keytab $self->{'keytab'}\n";
 
261
  }
 
262
  
 
263
  $self->{'afs_principal'} = $afs_principal;
 
264
  $self->{'afs_kvno'}      = $afs_kvno;
 
265
}
 
266
 
 
267
#
 
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.
 
271
#
 
272
sub make_keyfile {
 
273
  my $self = shift;
 
274
  
 
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";
 
281
  }
 
282
  unless ( -w $path->{'afsconfdir'} ) {
 
283
    die "error: Write access to the OpenAFS configuration directory '$path->{'afsconfdir'}' is required.\n";
 
284
  }
 
285
  unless ( -f "$path->{'afsconfdir'}/ThisCell" ) {
 
286
    die "error: OpenAFS configuration file is required, $path->{'afsconfdir'}/ThisCell\n";
 
287
  }
 
288
  unless ( -f "$path->{'afsconfdir'}/CellServDB" ) {
 
289
    die "error: OpenAFS configuration file is required, $path->{'afsconfdir'}/CellServDB\n";
 
290
  }
 
291
 
 
292
  run("$asetkey add $self->{'afs_kvno'} $self->{'keytab'} $self->{'afs_principal'}");
 
293
}
 
294
 
 
295
#
 
296
# Get kerberos ticket and AFS token for the user.
 
297
#
 
298
sub authorize {
 
299
  my $self = shift;
 
300
  my $principal = shift || $self->{'admin'};
 
301
  my $opt_aklog = "";
 
302
  $opt_aklog .= " -d" if $self->debug;
 
303
 
 
304
  run("kinit -k -t $self->{'keytab'} $principal");
 
305
  run("$aklog $opt_aklog");
 
306
  run("$tokens");
 
307
}
 
308
 
 
309
 
 
310
#------------------------------------------------------------------------------------
 
311
package OpenAFS::Auth::Heimdal;
 
312
use strict;
 
313
use OpenAFS::Dirpath;
 
314
use OpenAFS::ConfigUtils;
 
315
our @ISA = ("OpenAFS::Auth");
 
316
 
 
317
#
 
318
# Various checks during initialization.
 
319
#
 
320
sub _sanity_check {
 
321
  my $self = shift;
 
322
  unless ($self->{'realm'}) {
 
323
    die "Missing realm parameter Auth::create().\n";
 
324
  }
 
325
  unless ($self->{'keytab'}) {
 
326
    die "Missing keytab parameter Auth::create().\n";
 
327
  }
 
328
  unless ( -f $self->{'keytab'} ) {
 
329
    die "keytab file not found: $self->{'keytab'}\n";
 
330
  }
 
331
}
 
332
 
 
333
sub make_keyfile {
 
334
  my $self = shift;
 
335
  die "not implemented.";
 
336
}
 
337
 
 
338
#
 
339
# Get kerberos ticket and AFS token for the user.
 
340
#
 
341
sub authorize {
 
342
  my $self = shift;
 
343
  my $principal = shift || 'admin';  
 
344
  run("kinit -k -t $self->{'keytab'} $principal\@$self->{'realm'} && afslog");
 
345
}
 
346
 
 
347
#------------------------------------------------------------------------------------
 
348
package OpenAFS::Auth::Kaserver;
 
349
use strict;
 
350
use OpenAFS::Dirpath;
 
351
use OpenAFS::ConfigUtils;
 
352
our @ISA = ("OpenAFS::Auth");
 
353
 
 
354
 
 
355
#
 
356
# Various checks during initialization.
 
357
#
 
358
sub _sanity_check {
 
359
  my $self = shift;
 
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";
 
365
  }
 
366
}
 
367
 
 
368
sub make_keyfile {
 
369
  my $self = shift;
 
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");
 
374
}
 
375
 
 
376
#
 
377
# Get kerberos ticket and AFS token for the user.
 
378
#
 
379
sub authorize {
 
380
  my $self = shift;
 
381
  my $principal = shift || 'admin';
 
382
  #run("echo \"Proceeding w/o authentication\"|klog -pipe ${principal}\@$self->{'realm'}");
 
383
  run("klog $principal\@$self->{'realm'}");
 
384
}
 
385
 
 
386
1;