1#!/usr/bin/perl
2
3use strict;
4use File::Basename;
5
6my $configured = "/var/db/.configureLocalKDC";
7my $checked = "/var/db/.checkLocalKDC";
8my $keytab = "/etc/krb5.keytab";
9
10my $progname = basename ($0);
11
12chdir '/' or die "chdir: $!\n";
13
14if ($< != 0) {
15    print 'Error: '. $progname ." needs to be run by root\n";
16    exit 1;
17}
18
19if ($#ARGV != -1) {
20    sleep 60;  # Sleep for a minute so as not to slow down booting.
21}
22
23umask 022;
24
25my $kadmin = '/usr/sbin/kadmin';
26my $ktutil = '/usr/sbin/ktutil';
27my $dscl = '/usr/bin/dscl';
28my $security = '/usr/bin/security';
29
30if (! -e $configured) {
31    messageout("notConfigured", "The LocalKDC is not configured.");
32}
33
34my $realm = `$dscl . -read /Config/KerberosKDC RealName | awk '{print \$2}'`;
35chomp ($realm);
36
37if ($realm eq "") {
38    messageout("noKerberosKDC", "There is no KerberosKDC RealName.");
39}
40
41my $realmhash;
42if ($realm =~ /^.*LKDC:SHA1\.([0-9A-F]{40}).*$/) {
43    $realmhash = $1;
44}
45else {
46    messageout("notLocalRealm", "This ($realm) is not a LocalKDC realm.");
47}
48
49my $kdccerthash = `security find-certificate -c com.apple.kerberos.kdc -Z | head -1 | awk '{print \$3}'`;
50chomp($kdccerthash);
51
52if ($kdccerthash eq "") {
53    messageout("noCert", "There is no KDC certificate.");
54}
55
56if ($kdccerthash ne $realmhash) {
57    messageout("nonMatchingCert", "The KDC certificate hash ($kdccerthash) does not match the realm ($realmhash).");
58}
59
60if (! -e $keytab) {
61    messageout("noKeytab", "There is no keytab.");
62}
63
64if (-z $keytab) {
65    messageout("emptyKeytab", "The keytab is empty.");
66}
67
68my @ktlist = `$ktutil list`;
69if ($#ktlist < 6) {
70    messageout("brokenKeytab", "The keytab appears to be broken.");
71}
72
73my $foundafp = 0;
74foreach my $ktentry (@ktlist) {
75    if ($ktentry =~ /^.*?aes.*?afpserver\/$realm\@$realm.*$/) {
76	$foundafp = 1;
77    }
78}
79if (!$foundafp) {
80    messageout("incompleteKeytab", "The keytab appers to be incomplete.");
81}
82
83my $kadmincheck = system("$kadmin -l check --ds-local $realm");
84if ($kadmincheck != 0) {
85    messageout("kadminCheck", "The kadmin check failed.");
86}
87
88my @princs = `$dscl . -search /Users PrimaryGroupID 20 | grep PrimaryGroupID | awk '{print \$1}'`;
89my @kerbkeys;
90my $usercount = 0;
91my $badkeycount = 0;
92foreach my $p (@princs) {
93    chomp($p);
94    @kerbkeys = `$dscl . -read /Users/$p dsAttrTypeNative:KerberosKeys 2> /dev/null`;
95    if ($#kerbkeys < 1) {
96	$badkeycount++;
97    }
98    $usercount++;
99}
100if ($badkeycount) {
101    messageout("missingKeys", "$badkeycount of $usercount users have no Kerberos Keys.");
102}
103
104messageout("success", "Success.");
105
106
107sub messageout {
108    my $signature = shift;
109    my $message = shift;
110    my $result = "failure";
111    if ($signature eq "success") {
112	$result = "success";
113    }
114    `syslog -s -k com.apple.message.domain com.apple.kerberos.checkLocalKDC com.apple.message.signature $signature com.apple.message.result $result Message \"$message\"`;
115    print $message."\n";
116    `touch $checked`;
117    exit;
118}
119