Subject: pw_policy(3) override functionality
To: None <tech-userlevel@netbsd.org>
From: Elad Efrat <elad@NetBSD.org>
List: tech-userlevel
Date: 09/21/2006 16:37:13
This is a multi-part message in MIME format.

--Boundary_(ID_A+OKAy/FP+qXsO5RYXZdVQ)
Content-type: text/plain; charset=ISO-8859-1
Content-transfer-encoding: 7BIT

Hi,

Attached is a diff to add "override after N tries" functionality to
pw_policy(3), as requested some time ago. All it does is load an integer
(0-255) from keyword "override" in the policy. Applications can use
pw_policy_getoverride() to get that value and use it.

However...

The current API we have for pw_policy(3) is more or less consistent;
we have routines to load, test, and free a password policy.

The attached code would work, but I'm thinking longer term we might want
something like this:

	int
	pw_policy_export(pw_policy_t policy, const char *key, void *v);

That can be easily extended in the future without breaking API if we
decide we want to export more values like "override [after N attempts]".

Questions are, does this sound okay, and should I be using proplib
internally for that or whatever I want? using proplib means that libutil
depends on it to build.

-e.

-- 
Elad Efrat


--Boundary_(ID_A+OKAy/FP+qXsO5RYXZdVQ)
Content-type: text/plain; name=pw_policy.diff
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=pw_policy.diff

--- /usr/netbsd/src/lib/libutil/pw_policy.c	2006-04-15 18:44:03.000000000 +0300
+++ pw_policy.c	2006-04-15 19:11:27.000000000 +0300
@@ -59,6 +59,7 @@ static int pw_policy_handle_len(HANDLER_
 static int pw_policy_handle_charclass(HANDLER_PROTO);
 static int pw_policy_handle_nclasses(HANDLER_PROTO);
 static int pw_policy_handle_ntoggles(HANDLER_PROTO);
+static int pw_policy_handle_override(HANDLER_PROTO);
 
 struct pw_policy {
 	int32_t minlen;
@@ -75,6 +76,7 @@ struct pw_policy {
 	int32_t maxtoggles;
 	int32_t minclasses;
 	int32_t maxclasses;
+	uint8_t override;
 };
 
 struct pw_policy_handler {
@@ -91,6 +93,7 @@ static struct pw_policy_handler handlers
 	{ "punctuation", pw_policy_handle_charclass, ispunct },
 	{ "nclasses", pw_policy_handle_nclasses, NULL },
 	{ "ntoggles", pw_policy_handle_ntoggles, NULL },
+	{ "override", pw_policy_handle_override, NULL },
 	{ NULL, NULL, NULL },
 };
 
@@ -333,6 +336,38 @@ pw_policy_handle_ntoggles(HANDLER_ARGS)
 	}
 }
 
+/*ARGSUSED*/
+static int
+pw_policy_handle_override(HANDLER_ARGS)
+{
+	char *endptr;
+	unsigned long ul;
+	extern int errno;
+
+	switch (flag) {
+	case LOAD_POLICY:
+		errno = 0;
+		ul = strtoul(arg, &endptr, 10);
+		if (*endptr != '\0')
+			return EINVAL;
+		if (errno == ERANGE && (ul == ULONG_MAX))
+			return ERANGE;
+		if (ul >= UINT8_MAX)
+			return ERANGE;
+
+		policy->override = (uint8_t)ul;
+
+		return 0;
+
+	case TEST_POLICY:
+		/* Nothing to do. */
+		return 0;
+	default:
+
+		return EINVAL;
+	}
+}
+
 pw_policy_t
 pw_policy_load(void *key, int how)
 {
@@ -419,6 +454,7 @@ pw_policy_load(void *key, int how)
 		return NULL;
 
 	memset(policy, 0xff, sizeof(struct pw_policy));
+	policy->override = 2;
 
 	hp = &handlers[0];
 	while (hp->name != NULL) {
@@ -471,3 +507,9 @@ pw_policy_free(pw_policy_t policy)
 
 	free(policy);
 }
+
+uint8_t
+pw_policy_getoverride(pw_policy_t policy)
+{
+	return (policy->override);
+}


--Boundary_(ID_A+OKAy/FP+qXsO5RYXZdVQ)--