pw_policy_t
pw_policy_load(
void *key
, int how
)
int
pw_policy_test(
pw_policy_t policy
, char *pw
)
void
pw_policy_free(
pw_policy_t policy
)
),
pw_policy_test(
),
and
pw_policy_free(
)
functions are used as an interface to the system's password policy
as specified in
/etc/passwd.conf
.
pw_policy_load()
will load a password policy and return a pointer to a
pw_policy_t
containing it.
It is the caller's responsibility to free this pointer using
pw_policy_free(
).
Using
pw_getconf(3)
terminology,
pw_policy_load()
accepts a
key
to be used when searching
/etc/passwd.conf
for a password policy.
This key contains various options describing different policies.
Some built-in ones are described along with their syntax below.
To allow calling from various program contexts
and using various password policy retrieval schemes,
how
tells
pw_policy_load()
how to treat
key.
Possible values for how are:
PW_POLICY_BYSTRING
char
*
,
looking up the string it contains in
/etc/passwd.conf
.
PW_POLICY_BYPASSWD
struct
passwd
*
,
first looking up the username in
pw_name
,
and if no key can be found, it will try the login class in
pw_class
.
PW_POLICY_BYGROUP
struct
group
*
,
looking up the group name in
gr_name
.
If
key
is
NULL
,
or no specified key can be found, the default key,
``pw_policy'',
is used.
If even the default key can't be found,
the password is accepted as no policy is defined.
pw_policy_test()
can be used to check if the password in
pw
is compliant with the policy in
policy.
Options are used inside keys. An option uses a format of ``option = value''. For the built-in options, we use either ``N'' or ``N-M'' for the value.
The first, ``N'' format, specifies a single length. For example, the following option specifies that the password should have exactly 3 upper-case characters:
uppercase = 3
The second, ``N-M'' format, can be used to specify a range. Forcing a policy for number of digits between 1 and 4 would be:
digits = 1-4
The characters `0' and `*' can also be used to indicate ``not allowed'' and ``any number'', respectively. To illustrate, the following example states that the number of punctuation characters should be at least two:
punctuation = 2-*
No more than 7 digits:
digits = *-7
Any number of lower-case characters:
lowercase = *
Upper-case characters not allowed:
uppercase = 0
To specify that the password must be at least 8 characters long:
length = 8-*
Specifying a password must have at least 3 different character classes:
nclasses = 3-*
And that the user must change character class every 2 characters:
ntoggles = *-2
Note that when using the ``nclasses'' directive, the policy will be initialized to allow any number of characters from all classes. If desired, this should be overridden after the ``nclasses'' option.
)
returns a
pw_policy_t
on success, or
NULL
on failure, in which case the
errno
variable will be set to any of the following values indicating the
reason for the failure:
ENOENT
]
/etc/passwd.conf
is missing.
EINVAL
]
pw_policy_load()
can also set
errno
to a value returned by the called handlers and/or
malloc(3).
pw_policy_test()
returns 0 if the password follows the policy, or -1 if it doesn't,
errno
can be set to any of the following values:
EPERM
]
EINVAL
]
NULL
pointer was passed as the password.
In addition, errno can be set to any error code returned by the handlers.
/etc/passwd.conf
pw_policy_t policy;
Load the system global password policy into policy:
policy = pw_policy_load(NULL, 0);
if (policy == NULL)
errx(1, "Can't load password policy");
Load a policy for a user whose password database entry is in pw_entry into policy:
policy = pw_policy_load(pw_entry, PW_POLICY_BYPASSWD);
if (policy == NULL)
errx(1, "Can't load password policy for \"%s\"", pw_entry->pw_name);
Note that
pw_policy_load()
will first look for a password policy for the username in
pw_entry->pw_name,
if not found, it will try looking for a policy for the login class in
pw_entry->pw_class,
and if it can't find such either it will fallback to the default key,
``pw_policy''.
Load the password policy for a group whose group database entry is in grent, into policy:
policy = pw_policy_load(grent, PW_POLICY_BYGROUP);
if (policy == NULL)
errx(1, "Can't load password policy for \"%s\"", grent->gr_name);
Check if the_password follows the policy in policy:
if (pw_policy_test(policy, the_password) != 0)
warnx("Please refer to the password policy");
After finished using the password policy, free it:
pw_policy_free(policy);
An example for a common default password policy in
/etc/passwd.conf
:
pw_policy:
length = 8-* # At least 8 characters long,
lowercase = 1-* # combining lowercase,
uppercase = 1-* # uppercase,
digits = 1-* # and digits.
punctuation = * # Punctuation is optional.
A different policy that might be used:
nclasses = 3-* # At least 3 different character classes,
ntoggles = *-2 # not more than 2 same class in a row.
),
pw_policy_test(
),
and
pw_policy_free(
)
functions first appeared in
NetBSD4.0.