summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2013-01-04 22:30:47 +0100
committerArthur de Jong <arthur@arthurdejong.org>2013-03-03 11:40:04 +0100
commit37151df22e5cdf31c92b15157fe8a18e061ee2fb (patch)
tree4ad7a0f50c73625bb37d7f0d8af06a41bc3456bd /compat
parent1c2ab50ab32ca1ececeba7bd45429a3bee1a8d05 (diff)
provide a replacement implementation of ldap_parse_passwordpolicy_control() for systems that don't have it
Diffstat (limited to 'compat')
-rw-r--r--compat/Makefile.am3
-rw-r--r--compat/ldap_compat.h19
-rw-r--r--compat/ldap_parse_passwordpolicy_control.c103
3 files changed, 124 insertions, 1 deletions
diff --git a/compat/Makefile.am b/compat/Makefile.am
index 07b5d80..5c8ec76 100644
--- a/compat/Makefile.am
+++ b/compat/Makefile.am
@@ -1,6 +1,6 @@
# Makefile.am - use automake to generate Makefile.in
#
-# Copyright (C) 2008, 2009, 2010, 2011, 2012 Arthur de Jong
+# Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,7 @@ EXTRA_DIST = getopt_long.c getopt_long.h \
strndup.c strndup.h \
nss_compat.h socket.h \
ldap_compat.h pagectrl.c ldap_passwd_s.c ldap_initialize.c \
+ ldap_parse_passwordpolicy_control.c \
pam_compat.h pam_get_authtok.c pam_prompt.c
libcompat_a_SOURCES = getpeercred.c getpeercred.h
diff --git a/compat/ldap_compat.h b/compat/ldap_compat.h
index 00d8af4..cf460d1 100644
--- a/compat/ldap_compat.h
+++ b/compat/ldap_compat.h
@@ -57,6 +57,25 @@ int ldap_passwd_s(LDAP *ld, struct berval *user, struct berval *oldpw,
LDAPControl **sctrls, LDAPControl **cctrls);
#endif /* not HAVE_LDAP_PASSWD_S */
+#ifndef HAVE_LDAP_PARSE_PASSWORDPOLICY_CONTROL
+/* definition lifted from ldap.h */
+typedef enum passpolicyerror_enum {
+ PP_passwordExpired = 0,
+ PP_accountLocked = 1,
+ PP_changeAfterReset = 2,
+ PP_passwordModNotAllowed = 3,
+ PP_mustSupplyOldPassword = 4,
+ PP_insufficientPasswordQuality = 5,
+ PP_passwordTooShort = 6,
+ PP_passwordTooYoung = 7,
+ PP_passwordInHistory = 8,
+ PP_noError = 65535
+} LDAPPasswordPolicyError;
+int ldap_parse_passwordpolicy_control(LDAP *ld, LDAPControl *ctrl,
+ ber_int_t *expirep, ber_int_t *gracep,
+ LDAPPasswordPolicyError *errorp);
+#endif /* HAVE_LDAP_PARSE_PASSWORDPOLICY_CONTROL */
+
/* compatibility definition */
#ifndef LDAP_SASL_QUIET
#define LDAP_SASL_QUIET 2U
diff --git a/compat/ldap_parse_passwordpolicy_control.c b/compat/ldap_parse_passwordpolicy_control.c
new file mode 100644
index 0000000..88a0d6a
--- /dev/null
+++ b/compat/ldap_parse_passwordpolicy_control.c
@@ -0,0 +1,103 @@
+/*
+ ldap_parse_passwordpolicy_control.c - replacement function
+
+ Copyright (C) 2013 Arthur de Jong
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <lber.h>
+#include <ldap.h>
+#include <string.h>
+
+#include "compat/ldap_compat.h"
+#include "compat/attrs.h"
+
+#ifndef PPOLICY_WARNING
+#define PPOLICY_WARNING 160
+#endif
+#ifndef PPOLICY_ERROR
+#define PPOLICY_ERROR 129
+#endif
+#ifndef PPOLICY_EXPIRE
+#define PPOLICY_EXPIRE 128
+#endif
+#ifndef PPOLICY_GRACE
+#define PPOLICY_GRACE 129
+#endif
+
+/* based on Openldap and pam_ldap implementations */
+
+int ldap_parse_passwordpolicy_control(LDAP UNUSED(*ld), LDAPControl *ctrl,
+ ber_int_t *expirep, ber_int_t *gracep,
+ LDAPPasswordPolicyError *errorp)
+{
+ BerElement *ber;
+ ber_tag_t tag;
+ ber_len_t berLen;
+ char *last;
+ int err = PP_noError;
+ /* get a BerElement from the control */
+ ber = ber_init(&ctrl->ldctl_value);
+ if (ber == NULL)
+ return LDAP_LOCAL_ERROR;
+ /* go over tags */
+ for(tag = ber_first_element(ber, &berLen, &last); tag != LBER_DEFAULT; tag = ber_next_element(ber, &berLen, last))
+ {
+ switch (tag)
+ {
+ case PPOLICY_WARNING:
+ ber_skip_tag(ber, &berLen);
+ tag = ber_peek_tag(ber, &berLen);
+ switch (tag)
+ {
+ case PPOLICY_EXPIRE:
+ if (ber_get_int(ber, expirep) == LBER_DEFAULT)
+ {
+ ber_free(ber, 1);
+ return LDAP_DECODING_ERROR;
+ }
+ break;
+ case PPOLICY_GRACE:
+ if (ber_get_int(ber, gracep) == LBER_DEFAULT)
+ {
+ ber_free(ber, 1);
+ return LDAP_DECODING_ERROR;
+ }
+ break;
+ default:
+ ber_free(ber, 1);
+ return LDAP_DECODING_ERROR;
+ }
+ break;
+ case PPOLICY_ERROR:
+ if (ber_get_enum(ber, &err) == LBER_DEFAULT)
+ {
+ ber_free(ber, 1);
+ return LDAP_DECODING_ERROR;
+ }
+ break;
+ default:
+ ber_free(ber, 1);
+ return LDAP_DECODING_ERROR;
+ }
+ }
+ ber_free(ber, 1);
+ return LDAP_SUCCESS;
+}