diff options
| author | Russ Allbery <rra@stanford.edu> | 2008-04-24 03:01:48 +0000 | 
|---|---|---|
| committer | Russ Allbery <rra@stanford.edu> | 2008-04-24 03:01:48 +0000 | 
| commit | 4a93a31f926b4a94f82efb570845715080a56e02 (patch) | |
| tree | 1b45b1775e85bd03efba21a3c6221b89ffd7eee6 | |
| parent | 3ebbd3e716bfd4ac2b645a9701c51bb7c3afba0d (diff) | |
Include Stanford's wallet.conf as an example (examples/stanford.conf).
| -rw-r--r-- | NEWS | 2 | ||||
| -rw-r--r-- | examples/stanford.conf | 150 | 
2 files changed, 152 insertions, 0 deletions
| @@ -30,6 +30,8 @@ wallet 0.9 (unreleased)      Perl 5.8 is required to run the test suite, but IO::String is not. +    Include Stanford's wallet.conf as an example (examples/stanford.conf). +  wallet 0.8 (2008-02-13)      Fix the wallet client to use check instead of exists. 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; | 
