1#!/usr/bin/perl
2# 
3# Copyright (c) 2007, 2008, 2009 Apple Inc. All rights reserved.
4#
5# @APPLE_LICENSE_HEADER_START@
6#
7# This file contains Original Code and/or Modifications of Original Code
8# as defined in and that are subject to the Apple Public Source License
9# Version 2.0 (the 'License'). You may not use this file except in
10# compliance with the License. Please obtain a copy of the License at
11# http://www.opensource.apple.com/apsl/ and read it before using this
12# file.
13#
14# The Original Code and all software distributed under the License are
15# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19# Please see the License for the specific language governing rights and
20# limitations under the License.
21#
22# @APPLE_LICENSE_HEADER_END@
23#
24# This script generates a LocalKDC and provisions LKDC service principals.
25#
26# The script is destructive - it can be run multiple times though and
27# will geneate new KDC and service keys every time.
28#
29# Flow
30# =======
31#   1. Redirect output to /Library/Logs/LKDC-setup
32#   2. generate: create the LKDC certificates
33#   3. Create database
34#   4. If creating the database, make launchd not launch us again
35#
36
37use strict;
38use File::Basename;
39
40my $configured = "/var/db/.configureLocalKDC";
41
42my $progname = basename ($0);
43
44chdir '/' or die "chdir: $!\n";
45
46if ($< != 0) {
47	print 'Error: '. $progname ." needs to be run by root\n";
48	exit 1;
49}
50
51umask 022;
52
53close STDOUT;
54open STDOUT, ">>/Library/Logs/LKDC-setup.log" || die "Failed to open STDOUT";
55open STDERR, ">&STDOUT" || die "Failed to open STDERR";
56
57# print when we are running
58system("date");
59
60my $hod_admin = '/System/Library/PrivateFrameworks/Heimdal.framework/Helpers/hod-admin';
61my $system_keychain = '/Library/Keychains/System.keychain';
62
63my $restore = 0;
64
65my $argc = scalar @ARGV;
66my $i;
67for ($i = 0; $i < $argc; ++$i) {
68	if ($ARGV[$i] eq '--plist') {
69	} elsif ($ARGV[$i] eq '--source') {
70		$restore = 1;
71		die "Error: --source requires an argument\n" unless ++$i < $argc;
72	} elsif ($ARGV[$i] eq '--source-version') {
73	    die "Error: --source-version requires an argument\n" unless ++$i < $argc;
74	} elsif ($ARGV[$i] eq '--mode') {
75	    die "Error: --mode requires an argument\n" unless ++$i < $argc;
76	} else {
77		die "Error: unknown argument $ARGV[$i]\n";
78	}
79}
80
81if ($restore) {
82    unlink $configured;
83    print "lkdc restore trigger re-setup of LKDC on next boot\n";
84    exit 0;
85}
86
87my $res;
88
89# certtool requires a system keychain to be present.  Bootstrap one if it is missing.
90if (! -f $system_keychain) {
91	system '/usr/sbin/systemkeychain', '-C';
92}
93
94printf("creating system keychain entries\n");
95
96$res = system '/usr/bin/certtool', 'C', 'com.apple.systemdefault', 'u', 'P', 'v';
97if ($res != 0) {
98    unlink $configured;
99    die "cert tool failed for com.apple.systemdefault";
100}
101$res = system '/usr/bin/certtool', 'C', 'com.apple.kerberos.kdc', 'u', 'P', 'v', 'x=S';
102if ($res != 0) {
103    unlink $configured;
104    die "cert tool failed for com.apple.kerberos.kdc";
105}
106
107$res = system '/System/Library/PrivateFrameworks/KerberosHelper.framework/Helpers/lkdc_acl',
108     '-s', 'com.apple.kerberos.kdc', '-a',
109    '/System/Library/PrivateFrameworks/Heimdal.framework/Helpers/kdc';
110if ($res != 0) {
111    print "ldkc_acl failed with: $res\n";
112}
113
114$res = system $hod_admin, '.', 'setup-lkdc';
115if ($res != 0) {
116    print "hod-admin . setup-lkdc failed with: $res\n";
117}
118
119if ($res eq 0) {
120    print "Done LKDC setup\n";
121    system "touch", $configured;
122    system 'killall', '-9', 'kdc', 'digest-service';
123} else {
124    print "Failed LKDC setup\n";
125    unlink $configured;
126}
127