7 use OpenAFS::ConfigUtils;
9 my $path = $OpenAFS::Dirpath::openafsdirpath;
12 # Create an auth type for the specified Kerberos implementation.
15 # type -- Kerberos implementation: mit, heimdal, kaserver
16 # keytab -- path and name of the keytab file for mit and heimdal
17 # cell -- cell name. if not specified, attempts to find the
18 # cell name in the ThisCell configuration file.
19 # realm -- realm name. if not specified, assume the realm name
20 # is the same as the cell name, in uppercase.
23 # my $auth = OpenAFS::Auth::create(
25 # 'keytab'=>'/path/to/file/krb5.keytab');
27 # $auth->authorize('admin');
33 'keytab' => "$path->{'afsconfdir'}/krb5.keytab",
37 # user specified values
41 # check for supported kerberos type.
42 my $type = $self->{'type'};
43 $self->{'type'} = _check_kerberos_type($type) or
44 die "Unsupported kerberos type: $type\n";
46 # create the sub-class for the kerberos type.
47 my $class = "OpenAFS::Auth::$self->{'type'}";
48 $self = bless($self, $class);
50 # attempt get default values.
51 unless ($self->{'cell'}) {
53 $self->{'cell'} = $self->_lookup_cell_name();
56 unless ($self->{'realm'}) {
57 if ($self->{'cell'}) {
58 my $cell = $self->{'cell'};
59 ($self->{'realm'} = $cell) =~ tr[a-z][A-Z];
62 unless ($self->{'keytab'}) {
63 $self->{'keytab'} = "$path->{'afsconfdir'}/krb5.keytab";
66 # kerberos type specific sanity checks.
67 $self->_sanity_check();
70 print "debug: Auth::create()\n";
71 foreach my $k (sort keys(%$self)) {
72 print "debug: $k => $self->{$k}\n";
79 # Check for supported kerberos type, and allow for case insensitivity.
81 sub _check_kerberos_type {
83 foreach my $supported ('MIT', 'Heimdal', 'Kaserver') {
84 if ($type =~ /^$supported$/i) {
92 # Returns the cell name from the ThisCell configuration file.
94 sub _lookup_cell_name {
97 open(CELL, "$path->{'afsconfdir'}/ThisCell")
98 or die "error: Cannot open $path->{'afsconfdir'}/ThisCell: $!\n";
106 # Placeholder for make_keyfile. Sub-classes should override.
114 # Make the krb.conf file if the realm name is different
115 # than the cell name. The syntax is something like,
118 # UMICH.EDU fear.ifs.umich.edu admin server
119 # UMICH.EDU surprise.ifs.umich.edu
120 # UMICH.EDU ruthless.ifs.umich.edu
122 sub make_krb_config {
124 my $cell = $self->{'cell'};
125 my $realm = $self->{'realm'};
127 if ($realm && $realm ne $cell) {
128 unless ( -d $path->{'afsconfdir'} ) {
129 die "error: OpenAFS configuration directory '$path->{'afsconfdir'}' is missing.\n";
131 unless ( -w $path->{'afsconfdir'} ) {
132 die "error: Write access to the configuration directory '$path->{'afsconfdir'}' is required.\n";
134 print "debug: Making $path->{'afsconfdir'}/krb.conf file for realm $realm\n" if $self->{'debug'};
135 open(KRB, "> $path->{'afsconfdir'}/krb.conf") or die "error: Failed to open $path->{'afsconfdir'}/krb.conf, $!\n";
136 print KRB "$realm\n";
142 # Enable/disable debug messages.
147 $self->{'debug'} = shift;
149 return $self->{'debug'};
153 #------------------------------------------------------------------------------------
154 # MIT Kerberos authorization commands.
156 package OpenAFS::Auth::MIT;
158 use OpenAFS::Dirpath;
159 use OpenAFS::ConfigUtils;
160 our @ISA = ("OpenAFS::Auth");
163 # Sanity checks before we get started.
167 unless (defined $path->{'afssrvbindir'}) {
168 die "error: \$path->{'afssrvbindir'} is not defined.\n";
170 unless (-f "$path->{'afssrvbindir'}/aklog") {
171 die "error: $path->{'afssrvbindir'}/aklog not found.\n";
173 unless (-x "$path->{'afssrvbindir'}/aklog") {
174 die "error: $path->{'afssrvbindir'}/aklog not executable.\n";
176 unless ($self->{'realm'}) {
177 die "error: Missing realm parameter Auth::create().\n";
179 unless ($self->{'keytab'}) {
180 die "error: Missing keytab parameter Auth::create().\n";
182 unless ( -f $self->{'keytab'} ) {
183 die "error: Kerberos keytab file not found: $self->{'keytab'}\n";
185 unless ( -f $self->{'keytab'} ) {
186 die "error: Keytab file not found: $self->{'keytab'}\n";
191 # Create the KeyFile from the Kerberos keytab file. The keytab file
192 # should be created using the Kerberos kadmin command (or with the kadmin.local command
193 # as root on the KDC). See the OpenAFS asetkey man page for details.
198 # asetkey annoyance. The current asetkey implementation requires the ThisCell and CellServDB files
199 # to be present but they really are not needed to create the KeyFile. This check is done here
200 # rather than in the _sanity_checks() because the ThisCell/CellServerDB are created later in
201 # the process of creating the new cell.
202 unless ( -f "$path->{'afsconfdir'}/ThisCell" ) {
203 die "error: OpenAFS configuration file is required, $path->{'afsconfdir'}/ThisCell\n";
205 unless ( -f "$path->{'afsconfdir'}/CellServDB" ) {
206 die "error: OpenAFS configuration file is required, $path->{'afsconfdir'}/CellServDB\n";
209 unless ( -f "$path->{'afssrvbindir'}/asetkey" ) {
210 die "error: $path->{'afssrvbindir'}/asetkey is missing.\nWas OpenAFS built with Kerberos support?\n";
212 unless ( -x "$path->{'afssrvbindir'}/asetkey" ) {
213 die "error: Do not have execute permissions on $path->{'afssrvbindir'}/asetkey\n";
215 unless ( -d $path->{'afsconfdir'} ) {
216 die "error: OpenAFS configuration directory '$path->{'afsconfdir'}' is missing.\n";
218 unless ( -w $path->{'afsconfdir'} ) {
219 die "error: Write access to the OpenAFS configuration directory '$path->{'afsconfdir'}' is required.\n";
223 # Run klist to get the kvno of the afs key. Search for afs/cellname@REALM
224 # then afs@REALM. klist must be in the path.
231 print "debug: reading $self->{'keytab'} to find afs kvno\n";
233 open(KLIST, "klist -k $self->{'keytab'} |") or die "make_keyfile: Failed to run klist.";
236 next if /^Keytab/; # skip headers
239 ($kvno, $principal) = split;
241 print "debug: kvno=$kvno principal=$principal\n";
243 $keys{$principal} = $kvno;
246 my $cell = $self->{'cell'};
247 my $realm = $self->{'realm'};
248 foreach my $principal ("afs/$cell\@$realm", "afs\@$realm") {
250 print "debug: searching for $principal\n";
252 if (defined $keys{$principal}) {
253 $afs_principal = $principal;
254 $afs_kvno = $keys{$afs_principal};
256 print "debug: found principal=$afs_principal kvno=$afs_kvno\n";
262 die "error: Could not find an afs key matching 'afs/$cell\@$realm' or ".
263 "'afs/$cell' in keytab $self->{'keytab'}\n";
266 # Run asetkey on the keytab to create the KeyFile. asetkey must be in the PATH.
267 run("$path->{'afssrvbindir'}/asetkey add $afs_kvno $self->{'keytab'} $afs_principal");
271 # Get kerberos ticket and AFS token for the user.
275 my $principal = shift || 'admin';
277 $opt_aklog .= " -d" if $self->debug;
279 run("kinit -k -t $self->{'keytab'} $principal");
280 run("$path->{'afssrvbindir'}/aklog $opt_aklog");
281 run("$path->{'afssrvbindir'}/tokens");
285 #------------------------------------------------------------------------------------
286 package OpenAFS::Auth::Heimdal;
288 use OpenAFS::Dirpath;
289 use OpenAFS::ConfigUtils;
290 our @ISA = ("OpenAFS::Auth");
293 # Various checks during initialization.
297 unless ($self->{'realm'}) {
298 die "Missing realm parameter Auth::create().\n";
300 unless ($self->{'keytab'}) {
301 die "Missing keytab parameter Auth::create().\n";
303 unless ( -f $self->{'keytab'} ) {
304 die "keytab file not found: $self->{'keytab'}\n";
309 # Get kerberos ticket and AFS token for the user.
313 my $principal = shift || 'admin';
314 run("kinit -k -t $self->{'keytab'} $principal\@$self->{'realm'} && afslog");
317 #------------------------------------------------------------------------------------
318 package OpenAFS::Auth::Kaserver;
320 use OpenAFS::Dirpath;
321 use OpenAFS::ConfigUtils;
322 our @ISA = ("OpenAFS::Auth");
325 # Various checks during initialization.
329 unless ($self->{'realm'}) {
330 die "Missing realm parameter Auth::create().\n";
335 # Get kerberos ticket and AFS token for the user.
339 my $principal = shift || 'admin';
340 run("echo \"Proceeding w/o authentication\"|klog -pipe ${principal}\@$self->{'realm'}");