summaryrefslogtreecommitdiff
path: root/examples/stanford.conf
blob: becfc6e8fd2765c95c45c9737b03e76e28ceefa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# /etc/wallet/wallet.conf -- Wallet system configuration.  -*- perl -*-
#
# Configuration for the wallet system as used at Stanford University.
# Interesting features to note are loading the database password from an
# external file and full implementations of a naming policy check and default
# ACL rules.
#
# Written by Russ Allbery <rra@stanford.edu>
# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.

use Wallet::ACL;
use Wallet::Database;

$DB_DRIVER = 'mysql';
$DB_NAME   = 'wallet';
$DB_HOST   = 'localhost';
$DB_USER   = 'wallet';

# Read the MySQL password from a separate file so that we don't have to commit
# it to the Puppet repository.
open (PASS, '<', '/etc/wallet/mysql-password')
    or die "cannot open /etc/wallet/mysql-password: $!\n";
$DB_PASSWORD = <PASS>;
close PASS;
chomp $DB_PASSWORD;

$KEYTAB_KRBTYPE      = 'MIT';
$KEYTAB_FILE         = '/etc/wallet/keytab';
$KEYTAB_FLAGS        = '-clearpolicy';
$KEYTAB_HOST         = 'krb5-admin.stanford.edu';
$KEYTAB_PRINCIPAL    = 'service/wallet@stanford.edu';
$KEYTAB_REALM        = 'stanford.edu';
$KEYTAB_TMP          = '/var/lib/wallet';

$KEYTAB_REMCTL_CACHE = '/var/lib/wallet/krb5cc_wallet';
$KEYTAB_REMCTL_HOST  = 'kerberos1.stanford.edu';

$NETDB_REALM         = 'stanford.edu';
$NETDB_REMCTL_CACHE  = '/var/lib/wallet/krb5cc_wallet';
$NETDB_REMCTL_HOST   = 'netdb-node-roles-rc.stanford.edu';

# Work around a bug in Net::Remctl.
$NETDB_REMCTL_PRINCIPAL = 'host/netdb-node-roles-rc.stanford.edu';

# Retrieve an existing ACL and check whether it contains a netdb-root member.
# This is used to check if a default ACL is already present with a netdb-root
# member so that we can return a default owner that matches.  We only ever
# increase the ACL from netdb to netdb-root, never degrade it, so this doesn't
# pose a security problem.
#
# On any failure, just return an empty ACL to use the default.
sub acl_has_netdb_root {
    my ($name) = @_;
    my $dbh = eval { Wallet::Database->connect };
    return unless ($dbh and not $@);
    my $acl = eval { Wallet::ACL->new ($name, $dbh) };
    return unless ($acl and not $@);
    for my $line ($acl->list) {
        return 1 if $line->[0] eq 'netdb-root';
    }
    return;
}

# The default owner of a host should be the host keytab and the NetDB ACL for
# that host, with one twist.  If the creator of a new node is using a root
# instance, we want to require everyone managing that node be using root
# instances by default (this will do the right thing for Unix Systems hosts).
sub default_owner {
    my ($type, $name) = @_;
    my %allowed = map { $_ => 1 }
        qw(HTTP afpserver cifs ftp host ident imap ldap lpr nfs pop sieve smtp
           uniengd webauth xmpp);
    my $realm = 'stanford.edu';
    return unless $type eq 'keytab';
    return unless $name =~ m,/,;
    my ($service, $instance) = split ('/', $name, 2);
    return unless $allowed{$service};
    my $acl_name = "host/$instance";
    my @acl;
    if ($ENV{REMOTE_USER} =~ m,/root, or acl_has_netdb_root ($acl_name)) {
        @acl = ([ 'netdb-root', $instance ],
                [ 'krb5', "host/$instance\@$realm" ]);
    } else {
        @acl = ([ 'netdb', $instance ],
                [ 'krb5', "host/$instance\@$realm" ]);
    }
    return ($acl_name, @acl);
}

# Enforce a naming policy.  Host-based keytabs must have fully-qualified
# hostnames, limit the acceptable characters for service/* keytabs, and
# enforce our naming constraints on */cgi principals.
#
# Also use this function to require that Unix systems staff always do implicit
# object creation using a */root instance.
sub verify_name {
    my ($type, $name, $user) = @_;
    my %host = map { $_ => 1 }
        qw(HTTP afpserver cifs ftp host ident imap ldap lpr nfs pop sieve smtp
           uniengd webauth xmpp);
    my %staff;
    if (open (STAFF, '<', '/etc/remctl/acl/systems')) {
        local $_;
        while (<STAFF>) {
            s/^\s+//;
            s/\s+$//;
            next if m,/root\@,;
            $staff{$_} = 1;
        }
        close STAFF;
    }

    # Check for a staff member not using their root instance.
    if ($staff{$user}) {
        return 'use a */root instance for wallet object creation';
    }

    # Check keytab naming conventions.
    if ($type eq 'keytab') {
        if ($name !~ m,^[a-zA-Z0-9_-]+/[a-z0-9.-]+$,) {
            return "invalid principal name $name";
        }
        my ($principal, $instance)
            = ($name =~ m,^([a-zA-Z0-9_-]+)/([a-z0-9.-]+)$,);
        unless (defined ($principal) && defined ($instance)) {
            return "invalid principal name $name";
        }
        if ($host{$principal}) {
            if ($instance !~ /^[a-z0-9-]+\.[a-z0-9.-]+$/) {
                return "host name $instance is not fully qualified";
            }
        } elsif ($principal eq 'service') {
            if ($instance !~ /^[a-z0-9-]+$/) {
                return "invalid service principal name $name";
            }
        } elsif ($instance eq 'cgi') {
            if ($principal !~ /^[a-z][a-z0-9]{1,7}$/
                and $principal !~ /^(class|dept|group)-[a-z0-9_-]+$/) {
                return "invalid CGI principal name $name";
            }
        }
    }

    # Success.
    return;
}

1;