diff options
Diffstat (limited to 'examples/stanford.conf')
-rw-r--r-- | examples/stanford.conf | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/examples/stanford.conf b/examples/stanford.conf new file mode 100644 index 0000000..fa03668 --- /dev/null +++ b/examples/stanford.conf @@ -0,0 +1,150 @@ +# /etc/wallet/wallet.conf -- Wallet system configuration. -*- perl -*- +# $Id$ +# +# 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. + +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_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'; + +$KEYTAB_AFS_ADMIN = 'service.wallet@IR.STANFORD.EDU'; +$KEYTAB_AFS_DESTROY = 1; +$KEYTAB_AFS_REALM = 'IR.STANFORD.EDU'; +$KEYTAB_AFS_SRVTAB = '/etc/wallet/srvtab'; + +$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 princial 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; |