summaryrefslogtreecommitdiff
path: root/lib/libutil
diff options
context:
space:
mode:
authorelad <elad@NetBSD.org>2006-02-18 16:32:45 +0000
committerelad <elad@NetBSD.org>2006-02-18 16:32:45 +0000
commitcf6eceb4e76e53d00db56ca74b254a1d14d7c323 (patch)
tree84cb8f381a699ac4b9c7920a81c0a67ebc60975d /lib/libutil
parent5eb3b9f4ff8c38b90c01fbbe00dcbdbfaa3adf25 (diff)
Don't expose struct pw_policy and use pw_policy_t, use malloc, man-page
fixups. As discussed on source-changes@. Okay yamt@, thorpej@.
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/pw_policy.385
-rw-r--r--lib/libutil/pw_policy.c62
2 files changed, 94 insertions, 53 deletions
diff --git a/lib/libutil/pw_policy.3 b/lib/libutil/pw_policy.3
index 691aa643c91..070060961ba 100644
--- a/lib/libutil/pw_policy.3
+++ b/lib/libutil/pw_policy.3
@@ -1,4 +1,4 @@
-.\" $NetBSD: pw_policy.3,v 1.2 2006/02/18 10:52:48 elad Exp $
+.\" $NetBSD: pw_policy.3,v 1.3 2006/02/18 16:32:45 elad Exp $
.\"
.\" Copyright 2005, 2006 Elad Efrat <elad@NetBSD.org>
.\"
@@ -34,22 +34,28 @@
.Lb libutil
.Sh SYNOPSIS
.In util.h
+.Ft pw_policy_t
+.Fn pw_policy_load "void *key" "int how"
.Ft int
-.Fn pw_policy_load "struct pw_policy *policy" "void *key" "int how"
-.Ft int
-.Fn pw_policy_test "struct pw_policy *policy" "char *pw"
+.Fn pw_policy_test "pw_policy_t policy" "char *pw"
+.Ft void
+.Fn pw_policy_free "pw_policy_t policy"
.Sh DESCRIPTION
The
-.Fn pw_policy_load
+.Fn pw_policy_load ,
+.Fn pw_policy_test ,
and
-.Fn pw_policy_test
+.Fn pw_policy_free
functions are used as an interface to the system's password policy
as specified in
.Pa /etc/passwd.conf .
.Pp
.Fn pw_policy_load
-will load a password policy into
-.Ar policy .
+will load a password policy and return a pointer to a
+.Ar pw_policy_t
+containing it.
+It is the caller's responsibility to free this pointer using
+.Fn pw_policy_free .
.Pp
Using
.Xr pw_getconf 3
@@ -207,20 +213,29 @@ ntoggles = *-2
.Ed
.Sh RETURN VALUES
.Fn pw_policy_load
-returns 0 upon success, or any of the below errors upon failure:
+returns a
+.Ar pw_policu_t
+on success, or NULL on failure, in which case the
+.Ar errno
+variable will be set to any of the following values indicating the
+reason for the failure:
.Bl -tag -width Er
.It Bq Er ENOENT
The
.Pa /etc/passwd.conf
is missing.
-.It Bq Er EFAULT
-NULL pointer passed for policy storage.
.It Bq Er EINVAL
Invalid value for the
.Ar how
parameter or an invalid value in the password policy specification.
.El
.Pp
+.Fn pw_policy_load
+can also set
+.Ar errno
+to a value returned by the called handlers and/or
+.Xr malloc 3 .
+.Pp
.Fn pw_policy_test
returns 0 if the password follows the policy, or any of the following
values:
@@ -232,8 +247,6 @@ NULL pointer was passed as the password.
.El
.Pp
In addition,
-.Fn pw_policy_load
-and
.Fn pw_policy_test
can also return any of the values returned by the called handlers.
.Sh FILES
@@ -242,16 +255,16 @@ can also return any of the values returned by the called handlers.
password configuration file.
.El
.Sh EXAMPLES
-Initialize a password policy structure:
+Declare a password policy storage:
.Bd -literal -offset indent
-struct pw_policy policy = PW_POLICY_INIT;
+pw_policy_t policy;
.Ed
.Pp
Load the system global password policy into
.Ar policy :
.Bd -literal -offset indent
-error = pw_policy_load(&policy, NULL, 0);
-if (error)
+policy = pw_policy_load(NULL, 0);
+if (policy == NULL)
errx(1, "Can't load password policy");
.Ed
.Pp
@@ -260,11 +273,9 @@ Load a policy for a user whose password database entry is in
into
.Ar policy :
.Bd -literal -offset indent
-error = pw_policy_load(&policy, pw_entry, PW_POLICY_BYPASSWD);
-if (error == EPERM) {
- warnx("Please refer to the password policy");
- return (EPERM);
-}
+policy = pw_policy_load(pw_entry, PW_POLICY_BYPASSWD);
+if (policy == NULL)
+ errx(1, "Can't load password policy for \e"%s\e"", pw_entry-\*[Gt]pw_name);
.Ed
.Pp
Note that
@@ -276,25 +287,15 @@ if not found, it will try looking for a policy for the login class in
and if it can't find such either it will fallback to the default key,
.Dq pw_policy .
.Pp
-To handle cases where there is no
-.Pa /etc/passwd.conf ,
-it might be desired to fallback to an internal policy:
-.Bd -literal -offset indent
-error = pw_policy_load(&policy, NULL, 0);
-if (error == ENOENT) {
- /* No /etc/passwd.conf. Just check minimum length. */
- policy.minlen = 8;
-}
-.Ed
-.Pp
Load the password policy for a group
whose group database entry is in
.Ar grent ,
into
.Ar policy :
-error = pw_policy_load(&policy, grent, PW_POLICY_BYGROUP);
-if (error)
- errx(1, "Can't load password policy for \"%s\"", grent-\*[Gt]gr_name);
+.Bd -literal -offset indent
+policy = pw_policy_load(grent, PW_POLICY_BYGROUP);
+if (policy == NULL)
+ errx(1, "Can't load password policy for \e"%s\e"", grent-\*[Gt]gr_name);
.Ed
.Pp
Check if
@@ -302,11 +303,16 @@ Check if
follows the policy in
.Ar policy :
.Bd -literal -offset indent
-error = pw_policy_test(&policy, the_password);
+error = pw_policy_test(policy, the_password);
if (error == EPERM)
warnx("Please refer to the password policy");
.Ed
.Pp
+After finished using the password policy, free it:
+.Bd -literal -offset indent
+pw_policy_free(policy);
+.Ed
+.Pp
An example for a common default password policy in
.Pa /etc/passwd.conf :
.Bd -literal -offset indent
@@ -328,9 +334,10 @@ A different policy that might be used:
.Xr passwd.conf 5
.Sh HISTORY
The
-.Fn pw_policy_load
+.Fn pw_policy_load ,
+.Fn pw_policy_test ,
and
-.Fn pw_policy_test
+.Fn pw_policy_free
functions first appeared in
.Nx 4.0 .
.Sh AUTHORS
diff --git a/lib/libutil/pw_policy.c b/lib/libutil/pw_policy.c
index 0aeb0646ad8..65533194db4 100644
--- a/lib/libutil/pw_policy.c
+++ b/lib/libutil/pw_policy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pw_policy.c,v 1.3 2006/02/18 10:52:48 elad Exp $ */
+/* $NetBSD: pw_policy.c,v 1.4 2006/02/18 16:32:45 elad Exp $ */
/*-
* Copyright 2005, 2006 Elad Efrat <elad@NetBSD.org>
@@ -48,8 +48,8 @@
(min > 0 && min > n) || \
(max > 0 && max < n)
-#define HANDLER_PROTO struct pw_policy *, int, char *, void *, void *
-#define HANDLER_ARGS struct pw_policy *policy, int flag, char *pw, void *arg, void *arg2
+#define HANDLER_PROTO pw_policy_t, int, char *, void *, void *
+#define HANDLER_ARGS pw_policy_t policy, int flag, char *pw, void *arg, void *arg2
static int pw_policy_parse_num(char *, int32_t *);
static int pw_policy_parse_range(char *, int32_t *, int32_t *);
@@ -59,6 +59,23 @@ static int pw_policy_handle_charclass(HANDLER_PROTO);
static int pw_policy_handle_nclasses(HANDLER_PROTO);
static int pw_policy_handle_ntoggles(HANDLER_PROTO);
+struct pw_policy {
+ int32_t minlen;
+ int32_t maxlen;
+ int32_t minupper;
+ int32_t maxupper;
+ int32_t minlower;
+ int32_t maxlower;
+ int32_t mindigits;
+ int32_t maxdigits;
+ int32_t minpunct;
+ int32_t maxpunct;
+ int32_t mintoggles;
+ int32_t maxtoggles;
+ int32_t minclasses;
+ int32_t maxclasses;
+};
+
struct pw_policy_handler {
const char *name;
int (*handler)(HANDLER_PROTO);
@@ -322,18 +339,19 @@ pw_policy_handle_ntoggles(HANDLER_ARGS)
return (0);
}
-int
-pw_policy_load(struct pw_policy *policy, void *key, int how)
+pw_policy_t
+pw_policy_load(void *key, int how)
{
+ pw_policy_t policy;
struct pw_policy_handler *hp;
char buf[BUFSIZ];
/* If there's no /etc/passwd.conf, don't touch the policy. */
- if (access(_PATH_PASSWD_CONF, R_OK) == -1)
- return (ENOENT);
+ if (access(_PATH_PASSWD_CONF, R_OK) == -1) {
+ errno = ENOENT;
- if (policy == NULL)
- return (EFAULT);
+ return (NULL);
+ }
/* No key provided. Use default. */
if (key == NULL) {
@@ -399,10 +417,18 @@ pw_policy_load(struct pw_policy *policy, void *key, int how)
* Fail the policy because we don't know how to parse the
* key we were passed.
*/
- return (EINVAL);
+ errno = EINVAL;
+
+ return (NULL);
}
load_policies:
+ policy = malloc(sizeof(struct pw_policy));
+ if (policy == NULL)
+ return (NULL);
+
+ memset(policy, 0, sizeof(struct pw_policy));
+
hp = &handlers[0];
while (hp->name != NULL) {
int error;
@@ -412,18 +438,20 @@ pw_policy_load(struct pw_policy *policy, void *key, int how)
if (*buf) {
error = hp->handler(policy, LOAD_POLICY, NULL, buf,
hp->arg2);
- if (error)
- return (error);
+ if (error) {
+ errno = error;
+ return (NULL);
+ }
}
hp++;
}
- return (0);
+ return (policy);
}
int
-pw_policy_test(struct pw_policy *policy, char *pw)
+pw_policy_test(pw_policy_t policy, char *pw)
{
struct pw_policy_handler *hp;
@@ -443,3 +471,9 @@ pw_policy_test(struct pw_policy *policy, char *pw)
return (0);
}
+
+void
+pw_policy_free(pw_policy_t policy)
+{
+ free(policy);
+}