]> git.sur5r.net Git - openldap/commitdiff
Added PasswordPolicy control
authorHoward Chu <hyc@openldap.org>
Fri, 12 Mar 2004 21:22:32 +0000 (21:22 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 12 Mar 2004 21:22:32 +0000 (21:22 +0000)
include/ldap.h
libraries/libldap/Makefile.in
libraries/libldap/ppcontrol.c [new file with mode: 0644]
libraries/libldap_r/Makefile.in

index 0efd99e7210d1d77c2b386020a4cb21f5d26877f..453931ac2a54848077b82aa133a56a4231622d9e 100644 (file)
@@ -238,6 +238,11 @@ typedef struct ldapcontrol {
 #define LDAP_CONTROL_DUPENT    LDAP_CONTROL_DUPENT_REQUEST
 #endif
 
+/* Control Requests and Response for password policies */
+
+#define LDAP_CONTROL_PASSWORDPOLICYREQUEST "1.3.6.1.4.1.42.2.27.8.5.1"
+#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE "1.3.6.1.4.1.42.2.27.8.5.1"
+
 /* controls for MSAD compatibility */
 #define LDAP_CONTROL_X_DOMAIN_SCOPE            "1.2.840.113556.1.4.1339"
 #define LDAP_CONTROL_X_PERMISSIVE_MODIFY       "1.2.840.113556.1.4.1413"
@@ -1764,6 +1769,35 @@ ldap_passwd_s LDAP_P((
        LDAPControl **sctrls,
        LDAPControl **cctrls ));
 
+/*
+ * LDAP Password Policy controls
+ *     in ppcontrol.c
+ */
+typedef enum passpolicyerror_enum {
+       PP_passwordExpired = 0,
+       PP_accountLocked = 1,
+       PP_changeAfterReset = 2,
+       PP_passwordModNotAllowed = 3,
+       PP_mustSupplyOldPassword = 4,
+       PP_invalidPasswordSyntax = 5,
+       PP_passwordTooShort = 6,
+       PP_passwordTooYoung = 7,
+       PP_passwordInHistory = 8,
+       PP_noError = 65535
+} LDAPPasswordPolicyError;
+
+LDAP_F( int )
+ldap_create_passwordpolicy_control LDAP_P((
+        LDAP *ld,
+        LDAPControl **ctrlp ));
+
+LDAP_F( int )
+ldap_parse_passwordpolicy_control LDAP_P((
+        LDAP *ld,
+        LDAPControl **ctrls,
+        int *expirep,
+        int *gracep,
+        LDAPPasswordPolicyError *errorp ));
 
 LDAP_END_DECL
 #endif /* _LDAP_H */
index 5cbe6507de71b78dc8f3cb30a5e695053b2c2de7..dddebdada48f9b62586049730ad903f42482609d 100644 (file)
@@ -25,7 +25,9 @@ SRCS  = bind.c open.c result.c error.c compare.c search.c \
        getdn.c getentry.c getattr.c getvalues.c addentry.c \
        request.c os-ip.c url.c sortctrl.c vlvctrl.c \
        init.c options.c print.c string.c util-int.c schema.c \
-       charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c
+       charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
+       pcontrol.c
+
 OBJS   = bind.lo open.lo result.lo error.lo compare.lo search.lo \
        controls.lo messages.lo references.lo extended.lo cyrus.lo \
        modify.lo add.lo modrdn.lo delete.lo abandon.lo \
@@ -34,7 +36,8 @@ OBJS  = bind.lo open.lo result.lo error.lo compare.lo search.lo \
        getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
        request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
        init.lo options.lo print.lo string.lo util-int.lo schema.lo \
-       charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo
+       charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
+       ppcontrol.lo
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
diff --git a/libraries/libldap/ppcontrol.c b/libraries/libldap/ppcontrol.c
new file mode 100644 (file)
index 0000000..0cb62a0
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
+/*---
+ * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ *---*/
+/* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
+ * can be found in the file "build/LICENSE-2.0.1" in this distribution
+ * of OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+#define PPOLICY_WARNING 0xa0L
+#define PPOLICY_ERROR 0xa1L
+
+#define PPOLICY_EXPIRE 0xa0L
+#define PPOLICY_GRACE  0xa1L
+
+/*---
+   ldap_create_passwordpolicy_control
+   
+   Create and encode the Password Policy Request
+
+   ld        (IN)  An LDAP session handle, as obtained from a call to
+                                  ldap_init().
+   
+   ctrlp     (OUT) A result parameter that will be assigned the address
+                                  of an LDAPControl structure that contains the 
+                                  passwordPolicyRequest control created by this function.
+                                  The memory occupied by the LDAPControl structure
+                                  SHOULD be freed when it is no longer in use by
+                                  calling ldap_control_free().
+                                         
+   
+   There is no control value for a password policy request
+ ---*/
+
+int
+ldap_create_passwordpolicy_control( LDAP *ld,
+                                    LDAPControl **ctrlp )
+{
+       BerElement *ber;
+
+       assert( ld != NULL );
+       assert( LDAP_VALID( ld ) );
+       assert( ctrlp != NULL );
+
+       if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return(LDAP_NO_MEMORY);
+       }
+
+       ld->ld_errno = ldap_create_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
+               ber, 0, ctrlp);
+
+       ber_free(ber, 1);
+       return(ld->ld_errno);
+
+exit:
+       ber_free(ber, 1);
+       ld->ld_errno = LDAP_ENCODING_ERROR;
+       return(ld->ld_errno);
+}
+
+
+/*---
+   ldap_parse_passwordpolicy_control
+   
+   Decode the passwordPolicyResponse control and return information.
+
+   ld           (IN)   An LDAP session handle.
+   
+   ctrls        (IN)   The address of a NULL-terminated array of 
+                                          LDAPControl structures, typically obtained 
+                                          by a call to ldap_parse_result().
+
+   exptimep     (OUT)  This result parameter is filled in with the number of seconds before
+                                           the password will expire, if expiration is imminent
+                                           (imminency defined by the password policy). If expiration
+                                           is not imminent, the value is set to -1.
+
+   gracep       (OUT)  This result parameter is filled in with the number of grace logins after
+                                           the password has expired, before no further login attempts
+                                           will be allowed.
+
+   errorcodep   (OUT)  This result parameter is filled in with the error code of the password operation
+                                           If no error was detected, this error is set to PP_noError.
+   
+   Ber encoding
+   
+   PasswordPolicyResponseValue ::= SEQUENCE {
+       warning [0] CHOICE {
+           timeBeforeExpiration [0] INTEGER (0 .. maxInt),
+           graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
+       error [1] ENUMERATED {
+           passwordExpired        (0),
+           accountLocked          (1),
+           changeAfterReset       (2),
+           passwordModNotAllowed  (3),
+           mustSupplyOldPassword  (4),
+           invalidPasswordSyntax  (5),
+           passwordTooShort       (6),
+           passwordTooYoung       (7),
+           passwordInHistory      (8) } OPTIONAL }
+           
+---*/
+
+int
+ldap_parse_passwordpolicy_control(
+       LDAP           *ld,
+       LDAPControl    **ctrls,
+        int            *expirep,
+        int            *gracep,
+        LDAPPasswordPolicyError *errorp )
+{
+       BerElement  *ber;
+       LDAPControl *pControl;
+       int i, exp = -1, grace = -1;
+       ber_tag_t tag;
+       ber_len_t berLen;
+        char *last;
+        LDAPPasswordPolicyError err = PP_noError;
+        
+       assert( ld != NULL );
+       assert( LDAP_VALID( ld ) );
+
+       if (ctrls == NULL) {
+               ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
+               return(ld->ld_errno);
+       }
+
+       /* Search the list of control responses for a VLV control. */
+       for (i=0; ctrls[i]; i++) {
+               pControl = ctrls[i];
+               if (!strcmp(LDAP_CONTROL_PASSWORDPOLICYRESPONSE, pControl->ldctl_oid))
+                       goto foundPPControl;
+       }
+
+       /* No sort control was found. */
+       ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
+       return(ld->ld_errno);
+
+foundPPControl:
+       /* Create a BerElement from the berval returned in the control. */
+       ber = ber_init(&pControl->ldctl_value);
+
+       if (ber == NULL) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return(ld->ld_errno);
+       }
+
+        tag = ber_peek_tag( ber, &berLen );
+        if (tag != LBER_SEQUENCE) goto exit;
+
+        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, &exp ) == LBER_DEFAULT) goto exit;
+                            break;
+                        case PPOLICY_GRACE:
+                            if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
+                            break;
+                        default:
+                            goto exit;
+
+                    }
+                    
+                    break;
+                case PPOLICY_ERROR:
+                    if (ber_get_enum( ber, (int *)&err ) == LBER_DEFAULT) goto exit;
+                    break;
+                default:
+                    goto exit;
+            }
+        }
+        
+       ber_free(ber, 1);
+
+       /* Return data to the caller for items that were requested. */
+        if (expirep) *expirep = exp;
+        if (gracep) *gracep = grace;
+        if (errorp) *errorp = err;
+        
+       ld->ld_errno = LDAP_SUCCESS;
+       return(ld->ld_errno);
+
+  exit:
+        ber_free(ber, 1);
+        ld->ld_errno = LDAP_DECODING_ERROR;
+        return(ld->ld_errno);
+}
index df4fbc18f5a5dea7b5ea4d99d6cf24bee6e30d45..688957da8a256032b638731ba58e0331ec98906c 100644 (file)
@@ -27,7 +27,8 @@ XXSRCS    = apitest.c test.c \
        getdn.c getentry.c getattr.c getvalues.c addentry.c \
        request.c os-ip.c url.c sortctrl.c vlvctrl.c \
        init.c options.c print.c string.c util-int.c schema.c \
-       charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c
+       charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
+       ppcontrol.c
 SRCS   = threads.c rdwr.c tpool.c rq.c \
        thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
        thr_pth.c thr_stub.c
@@ -42,7 +43,8 @@ OBJS  = threads.lo rdwr.lo tpool.lo  rq.lo \
        getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
        request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
        init.lo options.lo print.lo string.lo util-int.lo schema.lo \
-       charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo
+       charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
+       ppcontrol.lo
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries