oracular (3) Wallet::Config.3pm.gz

Provided by: krb5-wallet-server_1.5-1.1_all bug

NAME

       Wallet::Config - Configuration handling for the wallet server

SYNOPSIS

           use Wallet::Config;
           my $driver = $Wallet::Config::DB_DRIVER;
           my $info;
           if (defined $Wallet::Config::DB_INFO) {
               $info = $Wallet::Config::DB_INFO;
           } else {
               $info = "database=$Wallet::Config::DB_NAME";
               $info .= ";host=$Wallet::Config::DB_HOST"
                   if $Wallet::Config::DB_HOST;
               $info .= ";port=$Wallet::Config::DB_PORT"
                   if $Wallet::Config::DB_PORT;
           }
           my $dsn = "dbi:$driver:$info";
           my $user = $Wallet::Config::DB_USER;
           my $password = $Wallet::Config::DB_PASSWORD;
           my $dbh = DBI->connect ($dsn, $user, $password);

DESCRIPTION

       Wallet::Config encapsulates all of the site-specific configuration for the wallet server.  It is
       implemented as a Perl class that declares and sets the defaults for various configuration variables and
       then, if it exists, loads the file specified by the WALLET_CONFIG environment variable or
       /etc/wallet/wallet.conf if that environment variable isn't set.  That file should contain any site-
       specific overrides to the defaults, and at least some parameters must be set.

       This file must be valid Perl.  To set a variable, use the syntax:

           $VARIABLE = <value>;

       where VARIABLE is the variable name (always in all-capital letters) and <value> is the value.  If setting
       a variable to a string and not a number, you should normally enclose <value> in ''.  For example, to set
       the variable DB_DRIVER to "MySQL", use:

           $DB_DRIVER = 'MySQL';

       Always remember the initial dollar sign ("$") and ending semicolon (";").  Those familiar with Perl
       syntax can of course use the full range of Perl expressions.

       This configuration file should end with the line:

           1;

       This ensures that Perl doesn't think there is an error when loading the file.

DATABASE CONFIGURATION

       DB_DDL_DIRECTORY
           Specifies the directory used to dump the database schema in formats for each possible database
           server.  This also includes diffs between schema versions, for upgrades.  The default value is
           /usr/local/share/wallet, which matches the default installation location.

       DB_DRIVER
           Sets the Perl database driver to use for the wallet database.  Common values would be "SQLite" or
           "MySQL".  Less common values would be "Oracle", "Sybase", or "ODBC".  The appropriate DBD::* Perl
           module for the chosen driver must be installed and will be dynamically loaded by the wallet.  For
           more information, see DBI.

           This variable must be set.

       DB_INFO
           Sets the remaining contents for the DBI DSN (everything after the driver).  Using this variable
           provides full control over the connect string passed to DBI.  When using SQLite, set this variable to
           the path to the SQLite database.  If this variable is set, DB_NAME, DB_HOST, and DB_PORT are ignored.
           For more information, see DBI and the documentation for the database driver you're using.

           Either DB_INFO or DB_NAME must be set.  If you don't need to pass any additional information to DBI,
           set DB_INFO to the empty string ('').

       DB_NAME
           If DB_INFO is not set, specifies the database name.  The third part of the DBI connect string will be
           set to "database=DB_NAME", possibly with a host and port appended if DB_HOST and DB_PORT are set.
           For more information, see DBI and the documentation for the database driver you're using.

           Either DB_INFO or DB_NAME must be set.

       DB_HOST
           If DB_INFO is not set, specifies the database host.  ";host=DB_HOST" will be appended to the DBI
           connect string.  For more information, see DBI and the documentation for the database driver you're
           using.

       DB_PORT
           If DB_PORT is not set, specifies the database port.  ";port=DB_PORT" will be appended to the DBI
           connect string.  If this variable is set, DB_HOST should also be set.  For more information, see DBI
           and the documentation for the database driver you're using.

       DB_USER
           Specifies the user for database authentication.  Some database backends, particularly SQLite, do not
           need this.

       DB_PASSWORD
           Specifies the password for database authentication.  Some database backends, particularly SQLite, do
           not need this.

DUO OBJECT CONFIGURATION

       These configuration variables only need to be set if you intend to use the "duo" object type (the
       Wallet::Object::Duo class).

       DUO_AGENT
           If this configuration variable is set, its value should be an object that is call-compatible with
           LWP::UserAgent.  This object will be used instead of LWP::UserAgent to make API calls to Duo.  This
           is primarily useful for testing, allowing replacement of the user agent with a mock implementation so
           that a test can run without needing a Duo account.

       DUO_KEY_FILE
           The path to a file in JSON format that contains the key and hostname data for the Duo Admin API
           integration used to manage integrations via wallet.  This file should be in the format expected by
           the "key_file" parameter to the Net::Duo::Admin constructor.  See Net::Duo::Admin for more
           information.

           DUO_KEY_FILE must be set to use Duo objects.

       DUO_TYPE
           The type of integration to create.  The default value is "unix" to create UNIX integrations, since
           this was the first integration created and users may rely on it to still be the default.

FILE OBJECT CONFIGURATION

       These configuration variables only need to be set if you intend to use the "file" object type (the
       Wallet::Object::File class).

       FILE_BUCKET
           The directory into which to store file objects.  File objects will be stored in subdirectories of
           this directory.  See Wallet::Object::File for the full details of the naming scheme.  This directory
           must be writable by the wallet server and the wallet server must be able to create subdirectories of
           it.

           FILE_BUCKET must be set to use file objects.

       FILE_MAX_SIZE
           The maximum size of data that can be stored in a file object in bytes.  If this configuration
           variable is set, an attempt to store data larger than this limit will be rejected.

PASSWORD OBJECT CONFIGURATION

       These configuration variables only need to be set if you intend to use the "password" object type (the
       Wallet::Object::Password class).  You will also need to set the FILE_MAX_SIZE value from the file object
       configuration, as that is inherited.

       PWD_FILE_BUCKET
           The directory into which to store password objects.  Password objects will be stored in
           subdirectories of this directory.  See Wallet::Object::Password for the full details of the naming
           scheme.  This directory must be writable by the wallet server and the wallet server must be able to
           create subdirectories of it.

           PWD_FILE_BUCKET must be set to use file objects.

       PWD_LENGTH_MIN
           The minimum length for any auto-generated password objects created when get is run before data is
           stored.

       PWD_LENGTH_MAX
           The maximum length for any auto-generated password objects created when get is run before data is
           stored.

       PWD_CHARACTERS
           A string that contains valid characters to be used in generating passwords.  Restricting the possible
           password characters can be used to remove ambiguous characters from generated passwords, e.g.
           removing the letter O from possible password character set ensures that there is no confusion with
           the number 0.  The default is to allow any printable character.

KEYTAB OBJECT CONFIGURATION

       These configuration variables only need to be set if you intend to use the "keytab" object type (the
       Wallet::Object::Keytab class).

       KEYTAB_FILE
           Specifies the keytab to use to authenticate to kadmind.  The principal whose key is stored in this
           keytab must have the ability to create, modify, inspect, and delete any principals that should be
           managed by the wallet.  (In MIT Kerberos kadm5.acl parlance, this is "admci" privileges.)

           KEYTAB_FILE must be set to use keytab objects with any backend other than Active Directory.

       KEYTAB_FLAGS
           These flags, if any, are passed to the "addprinc" command when creating a new principal in the
           Kerberos KDC.  To not pass any flags, set KEYTAB_FLAGS to the empty string.  The default value is
           "-clearpolicy", which clears any password strength policy from principals created by the wallet.
           (Since the wallet randomizes the keys, password strength checking is generally pointless and may
           interact poorly with the way "addprinc -randkey" works when third-party add-ons for password strength
           checking are used.)

           This option is ignored when using Active Directory.

       KEYTAB_HOST
           Specifies the host on which the kadmin or Active Directory service is running.  This setting
           overrides the "admin_server" setting in the [realms] section of krb5.conf and any DNS SRV records and
           allows the wallet to run on a system that doesn't have a Kerberos configuration for the wallet's
           realm.

       KEYTAB_KADMIN
           The path to the kadmin command-line client.  The default value is "kadmin", which will cause the
           wallet to search for kadmin on its default PATH.

           This option is ignored when using Active Directory.

       KEYTAB_KRBTYPE
           The Kerberos KDC implementation type, chosen from "AD", "Heimdal", or "MIT" (case-insensitive).
           KEYTAB_KRBTYPE must be set to use keytab objects.

       KEYTAB_PRINCIPAL
           The principal whose key is stored in KEYTAB_FILE.  The wallet will authenticate as this principal to
           the kadmin service.

           KEYTAB_PRINCIPAL must be set to use keytab objects unless Active Directory is the backend, at least
           until kadmin is smart enough to use the first principal found in the keytab it's using for
           authentication.

       KEYTAB_REALM
           Specifies the realm in which to create Kerberos principals.  The keytab object implementation can
           only work in a single realm for a given wallet installation and the keytab object names are stored
           without realm.  KEYTAB_REALM is added when talking to the KDC via kadmin.

           KEYTAB_REALM must be set to use keytab objects.  "ktadd" doesn't always default to the local realm
           and the Active Directory integration requires it.

       KEYTAB_TMP
           A directory into which the wallet can write keytabs temporarily while processing "get" commands from
           clients.  The keytabs are written into this directory with predictable names, so this should not be a
           system temporary directory such as /tmp or /var/tmp.  It's best to create a directory solely for this
           purpose that's owned by the user the wallet server will run as.

           KEYTAB_TMP must be set to use keytab objects.

       The following parameters are specific to generating keytabs from Active Directory (KEYTAB_KRBTYPE is set
       to "AD").

       AD_BASE_DN
           The base distinguished name of the Active Directory instance.  This is used when Wallet uses LDAP
           directly to examine objects in Active Directory.

       AD_CACHE
           Specifies the ticket cache to use when manipulating Active Directory objects.  The ticket cache must
           be for a principal able to bind to Active Directory and run msktutil.

       AD_COMPUTER_RDN
           The LDAP base DN for computer objects inside Active Directory.  All keytabs of the form
           host/<hostname> will be mapped to objects with a "samAccountName" of the <hostname> portion under
           this DN.

           AD_COMPUTER_RDN must be set if using Active Directory as the keytab backend.

       AD_DEBUG
           If set to true, asks for some additional debugging information, such as the msktutil command, to be
           logged to syslog.  These debugging messages will be logged to the "local3" facility.

       AD_MSKTUTIL
           The path to the msktutil command-line client.  The default value is "msktutil", which will cause the
           wallet to search for msktutil on its default PATH.

       AD_SERVICE_LENGTH
           The maximum length of a unique identifier, "samAccountName", for Active Directory keytab objects.  If
           the identifier exceeds this length then it will be truncated and an integer will be appended to the
           end of the identifier.  This parameter is here in hopes that at some point in the future Microsoft
           will remove the limitation.  The default value is 19.

       AD_SERVICE_LIMIT
           Used to limit the number of iterations used in attempting to find a unique account name for
           principals.  Defaults to 999.

       AD_SERVICE_PREFIX
           For service principals the AD_SERVICE_PREFIX will be combined with the principal identifier to form
           the account name, i.e. the CN, used to store the keytab entry in the Active Directory.  Active
           Directory limits these CN's to a maximum of 20 characters.  If the resulting CN is greater than 20
           characters the CN will be truncated and an integer will be appended to it.  The integer will be
           incremented until a unique CN is found.

           The AD_SERVICE_PREFIX is generally useful only prevent name collisions when the service keytabs are
           store in branch of the DIT that also contains other similar objects.

       AD_SERVER
           The hostname of the Active Directory Domain Controller.

       AD_USER_RDN
           The LDAP base DN for user objects inside Active Directory.  All keytabs of the form service/<user>
           will be mapped to objects with a "servicePrincipalName" matching the wallet object name under this
           DN.

           AD_USER_RDN must be set if using Active Directory as the keytab backend.

   Retrieving Existing Keytabs
       Heimdal provides the choice, over the network protocol, of either downloading the existing keys for a
       principal or generating new random keys.  Neither MIT Kerberos or Active Directory support retrieving an
       existing keytab; downloading a keytab over the kadmin protocol or using msktutil always rekeys the
       principal.

       For MIT Kerberos, the keytab object backend therefore optionally supports retrieving existing keys, and
       hence keytabs, for Kerberos principals by contacting the KDC via remctl and talking to keytab-backend.
       This is enabled by setting the "unchanging" flag on keytab objects.  To configure that support, set the
       following variables.

       For Active Directory Kerberos, the keytab object backend supports storing the keytabs on the wallet
       server.  This functionality is enabled by setting the configuration variable AD_KEYTAB_BUCKET.  (This had
       not been implemented yet.)

       This is not required for Heimdal; for Heimdal, setting the "unchanging" flag is all that's needed.

       KEYTAB_REMCTL_CACHE
           Specifies the ticket cache to use when retrieving existing keytabs from the KDC.  This is only used
           to implement support for the "unchanging" flag.  The ticket cache must be for a principal with access
           to run "keytab retrieve" via remctl on KEYTAB_REMCTL_HOST.

       KEYTAB_REMCTL_HOST
           The host to which to connect with remctl to retrieve existing keytabs.  This is only used to
           implement support for the "unchanging" flag.  This host must provide the "keytab retrieve" command
           and KEYTAB_REMCTL_CACHE must also be set to a ticket cache for a principal with access to run that
           command.

       KEYTAB_REMCTL_PRINCIPAL
           The service principal to which to authenticate when retrieving existing keytabs.  This is only used
           to implement support for the "unchanging" flag.  If this variable is not set, the default is formed
           by prepending "host/" to KEYTAB_REMCTL_HOST.  (Note that KEYTAB_REMCTL_HOST is not lowercased first.)

       KEYTAB_REMCTL_PORT
           The port on KEYTAB_REMCTL_HOST to which to connect with remctl to retrieve existing keytabs.  This is
           only used to implement support for the "unchanging" flag.  If this variable is not set, the default
           remctl port will be used.

       AD_KEYTAB_BUCKET
           The path to store a copy of keytabs created.  This is required for the support of unchanging keytabs
           with an Active Directory KDC.  (This has not been implemented yet.)

EXTERNAL ACL CONFIGURATION

       This configuration variable is only needed if you intend to use the "external" ACL type (the
       Wallet::ACL::External class).  This ACL type runs an external command to determine if access is granted.

       EXTERNAL_COMMAND
           Path to the command to run to determine whether access is granted.  The first argument to the command
           will be the principal requesting access.  The second and third arguments will be the type and name of
           the object that principal is requesting access to.  The final argument will be the identifier of the
           ACL.

           No other arguments are passed to the command, but the command will have access to all of the remctl
           environment variables seen by the wallet server (such as REMOTE_USER).  For a full list of
           environment variables, see "ENVIRONMENT" in remctld(8).

           The external command should exit with a non-zero status but no output to indicate a normal failure to
           satisfy the ACL.  Any output will be treated as an error.

LDAP ACL CONFIGURATION

       These configuration variables are only needed if you intend to use the "ldap-attr" ACL type (the
       Wallet::ACL::LDAP::Attribute class).  They specify the LDAP server and additional connection and data
       model information required for the wallet to check for the existence of attributes.

       LDAP_HOST
           The LDAP server name to use to verify LDAP ACLs.  This variable must be set to use LDAP ACLs.

       LDAP_BASE
           The base DN under which to search for the entry corresponding to a principal.  Currently, the wallet
           always does a full subtree search under this base DN.  This variable must be set to use LDAP ACLs.

       LDAP_FILTER_ATTR
           The attribute used to find the entry corresponding to a principal.  The LDAP entry containing this
           attribute with a value equal to the principal will be found and checked for the required attribute
           and value.  If this variable is not set, the default is "krb5PrincipalName".

       LDAP_CACHE
           Specifies the Kerberos ticket cache to use when connecting to the LDAP server.  GSS-API
           authentication is always used; there is currently no support for any other type of bind.  The ticket
           cache must be for a principal with access to verify the values of attributes that will be used with
           this ACL type.  This variable must be set to use LDAP ACLs.

       Finally, depending on the structure of the LDAP directory being queried, there may not be any attribute
       in the directory whose value exactly matches the Kerberos principal.  The attribute designated by
       LDAP_FILTER_ATTR may instead hold a transformation of the principal name (such as the principal with the
       local realm stripped off, or rewritten into an LDAP DN form).  If this is the case, define a Perl
       function named ldap_map_principal.  This function will be called whenever an LDAP attribute ACL is being
       verified.  It will take one argument, the principal, and is expected to return the value to search for in
       the LDAP directory server.

       For example, if the principal name without the local realm is stored in the "uid" attribute in the
       directory, set LDAP_FILTER_ATTR to "uid" and then define ldap_map_attribute as follows:

           sub ldap_map_principal {
               my ($principal) = @_;
               $principal =~ s/\@EXAMPLE\.COM$//;
               return $principal;
           }

       Note that this example only removes the local realm (here, EXAMPLE.COM).  Any principal from some other
       realm will be left fully qualified, and then presumably will not be found in the directory.

NETDB ACL CONFIGURATION

       These configuration variables are only needed if you intend to use the "netdb" ACL type (the
       Wallet::ACL::NetDB class).  They specify the remctl connection information for retrieving user roles from
       NetDB and the local realm to remove from principals (since NetDB normally expects unscoped local
       usernames).

       NETDB_REALM
           The wallet uses fully-qualified principal names (including the realm), but NetDB normally expects
           local usernames without the realm.  If this variable is set, the given realm will be stripped from
           any principal names before passing them to NetDB.  Principals in other realms will be passed to NetDB
           without modification.

       NETDB_REMCTL_CACHE
           Specifies the ticket cache to use when querying the NetDB remctl interface for user roles.  The
           ticket cache must be for a principal with access to run "netdb node-roles" via remctl on
           KEYTAB_REMCTL_HOST.  This variable must be set to use NetDB ACLs.

       NETDB_REMCTL_HOST
           The host to which to connect with remctl to query NetDB for user roles.  This host must provide the
           "netdb node-roles" command and NETDB_REMCTL_CACHE must also be set to a ticket cache for a principal
           with access to run that command.  This variable must be set to use NetDB ACLs.

       NETDB_REMCTL_PRINCIPAL
           The service principal to which to authenticate when querying NetDB for user roles.  If this variable
           is not set, the default is formed by prepending "host/" to NETDB_REMCTL_HOST.  (Note that
           NETDB_REMCTL_HOST is not lowercased first.)

       NETDB_REMCTL_PORT
           The port on NETDB_REMCTL_HOST to which to connect with remctl to query NetDB for user roles.  If this
           variable is not set, the default remctl port will be used.

DEFAULT OWNERS

       By default, only users in the ADMIN ACL can create new objects in the wallet.  To allow other users to
       create new objects, define a Perl function named default_owner.  This function will be called whenever a
       non-ADMIN user tries to create a new object and will be passed the type and name of the object.  It
       should return undef if there is no default owner for that object.  If there is, it should return a list
       containing the name to use for the ACL and then zero or more anonymous arrays of two elements each giving
       the type and identifier for each ACL entry.

       For example, the following simple function says to use a default owner named "default" with one entry of
       type "krb5" and identifier "rra@example.com" for the object with type "keytab" and name
       "host/example.com":

           sub default_owner {
               my ($type, $name) = @_;
               if ($type eq 'keytab' and $name eq 'host/example.com') {
                   return ('default', [ 'krb5', 'rra@example.com' ]);
               } else {
                   return;
               }
           }

       Of course, normally this function is used for more complex mappings.  Here is a more complete example.
       For objects of type keytab corresponding to various types of per-machine principals, return a default
       owner that sets as owner anyone with a NetDB role for that system and the system's host principal.  This
       permits authorization management using NetDB while also allowing the system to bootstrap itself once the
       host principal has been downloaded and rekey itself using the old host principal.

           sub default_owner {
               my ($type, $name) = @_;
               my %allowed = map { $_ => 1 }
                   qw(HTTP cifs host imap ldap nfs pop sieve smtp);
               my $realm = 'example.com';
               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 = ([ 'netdb', $instance ],
                          [ 'krb5', "host/$instance\@$realm" ]);
               return ($acl_name, @acl);
           }

       The auto-created ACL used for the owner of the new object will, in the above example, be named
       "host/system" where system is the fully-qualified name of the system as derived from the keytab being
       requested.

       If the name of the ACL returned by the default_owner function matches an ACL that already exists in the
       wallet database, the existing ACL will be compared to the default ACL returned by the default_owner
       function.  If the existing ACL has the same entries as the one returned by default_owner, creation
       continues if the user is authorized by that ACL.  If they don't match, creation of the object is
       rejected, since the presence of an existing ACL may indicate that something different is being done with
       this object.

NAMING ENFORCEMENT

       By default, wallet permits administrators to create objects of any name (unless the object backend
       rejects the name).  However, naming standards for objects can be enforced, even for administrators, by
       defining a Perl function in the configuration file named verify_name.  If such a function exists, it will
       be called for any object creation and will be passed the type of object, the object name, and the
       identity of the person doing the creation.  If it returns undef or the empty string, object creation will
       be allowed.  If it returns anything else, object creation is rejected and the return value is used as the
       error message.

       This function is also called for naming audits done via Wallet::Report to find any existing objects that
       violate a (possibly updated) naming policy.  In this case, the third argument (the identity of the person
       creating the object) will be undef.  As a general rule, if the third argument is undef, the function
       should apply the most liberal accepted naming policy so that the audit returns only objects that violate
       all naming policies, but some sites may wish different results for their audit reports.

       Please note that this return status is backwards from what one would normally expect.  A false value is
       success; a true value is failure with an error message.

       For example, the following verify_name function would ensure that any keytab objects for particular
       principals have fully-qualified hostnames:

           sub verify_name {
               my ($type, $name, $user) = @_;
               my %host_based = map { $_ => 1 }
                   qw(HTTP cifs host imap ldap nfs pop sieve smtp);
               return unless $type eq 'keytab';
               return unless $name =~ m%/%;
               my ($service, $instance) = split ('/', $name, 2);
               return unless $host_based{$service};
               return "host name $instance must be fully qualified"
                   unless $instance =~ /\./;
               return;
           }

       Objects that aren't of type "keytab" or which aren't for a host-based key have no naming requirements
       enforced by this example.

OBJECT HOST-BASED NAMES

       The above demonstrates having a host-based naming convention, where we expect one part of an object name
       to be the name of the host that this object is for.  The most obvious examples are those keytab objects
       above, where we want certain keytab names to be in the form of <service>/<hostname>.  It's then also
       useful to provide a Perl function named is_for_host which then can be used to tell if a given object is a
       host-based keytab for a specific host.  This function is then called by the objects_hostname in
       Wallet::Report to give a list of all host-based objects for a given hostname.  It should return true if
       the given object is a host-based object for the hostname, otherwise false.

       An example that matches the same policy as the last verify_name example would be:

           sub is_for_host {
               my ($type, $name, $hostname) = @_;
               my %host_based = map { $_ => 1 }
                   qw(HTTP cifs host imap ldap nfs pop sieve smtp);
               return 0 unless $type eq 'keytab';
               return 0 unless $name =~ m%/%;
               my ($service, $instance) = split ('/', $name, 2);
               return 0 unless $host_based{$service};
               return 1 if $hostname eq $instance;
               return 0;
           }

ACL NAMING ENFORCEMENT

       Similar to object names, by default wallet permits administrators to create ACLs with any name.  However,
       naming standards for ACLs can be enforced by defining a Perl function in the configuration file named
       verify_acl_name.  If such a function exists, it will be called for any ACL creation or rename and will be
       passed given the new ACL name and the identity of the person doing the creation.  If it returns undef or
       the empty string, object creation will be allowed.  If it returns anything else, object creation is
       rejected and the return value is used as the error message.

       This function is also called for naming audits done via Wallet::Report to find any existing objects that
       violate a (possibly updated) naming policy.  In this case, the second argument (the identity of the
       person creating the ACL) will be undef.  As a general rule, if the second argument is undef, the function
       should apply the most liberal accepted naming policy so that the audit returns only ACLs that violate all
       naming policies, but some sites may wish different results for their audit reports.

       Please note that this return status is backwards from what one would normally expect.  A false value is
       success; a true value is failure with an error message.

       For example, the following verify_acl_name function would ensure that any ACLs created contain a slash
       and the part before the slash be one of "host", "group", "user", or "service".

           sub verify_acl_name {
               my ($name, $user) = @_;
               return 'ACL names must contain a slash' unless $name =~ m,/,;
               my ($first, $rest) = split ('/', $name, 2);
               my %types = map { $_ => 1 } qw(host group user service);
               unless ($types{$first}) {
                   return "unknown ACL type $first";
               }
               return;
           }

       Obvious improvements could be made, such as checking that the part after the slash for a "host/" ACL
       looked like a host name and the part after a slash for a "user/" ACL look like a user name.

FILE CHECKSUMS

       By default a file objects checksum some will be calculated using the perl function md5_hex of the
       Digest::MD5 module.  This behavior can be overriden by defining a perl function in the configuration file
       named file_checksum that returns a checksum for the file.

       For example, the following file_checksub function returns the MD5 hash as a base64 string.

           sub file_checksum {
               my ($path) = @_;
               open(my $fh, '<', $path) or die "ERROR: reading $filename";
               binmode($fh);
               my $cs = Digest::MD5->new->addfile($fh)->b64digest, "\n";
               close $fh;
               return $cs;
           }

ENVIRONMENT

       WALLET_CONFIG
           If this environment variable is set, it is taken to be the path to the wallet configuration file to
           load instead of /etc/wallet/wallet.conf.

SEE ALSO

       DBI(3), Wallet::Object::Keytab(3), Wallet::Server(3), wallet-backend(8)

       This module is part of the wallet system.  The current version is available from
       <https://www.eyrie.org/~eagle/software/wallet/>.

AUTHORS

       Russ Allbery <eagle@eyrie.org> Bill MacAllister <bill@ca-zephyr.org>