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");