Back to index

openldap  2.4.31
ppolicy.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2004-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 2004 Hewlett-Packard Company.
00006  * Portions Copyright 2004 Howard Chu, Symas Corp.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in the file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 /* ACKNOWLEDGEMENTS:
00018  * This work was developed by Howard Chu for inclusion in
00019  * OpenLDAP Software, based on prior work by Neil Dunbar (HP).
00020  * This work was sponsored by the Hewlett-Packard Company.
00021  */
00022 
00023 #include "portable.h"
00024 
00025 #include <stdio.h>
00026 #include <ac/stdlib.h>
00027 #include <ac/string.h>
00028 #include <ac/time.h>
00029 
00030 #include "ldap-int.h"
00031 
00032 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
00033 
00034 /* IMPLICIT TAGS, all context-specific */
00035 #define PPOLICY_WARNING 0xa0L      /* constructed + 0 */
00036 #define PPOLICY_ERROR 0x81L        /* primitive + 1 */
00037 
00038 #define PPOLICY_EXPIRE 0x80L       /* primitive + 0 */
00039 #define PPOLICY_GRACE  0x81L       /* primitive + 1 */
00040 
00041 /*---
00042    ldap_create_passwordpolicy_control
00043    
00044    Create and encode the Password Policy Request
00045 
00046    ld        (IN)  An LDAP session handle, as obtained from a call to
00047                                ldap_init().
00048    
00049    ctrlp     (OUT) A result parameter that will be assigned the address
00050                                of an LDAPControl structure that contains the 
00051                                passwordPolicyRequest control created by this function.
00052                                The memory occupied by the LDAPControl structure
00053                                SHOULD be freed when it is no longer in use by
00054                                calling ldap_control_free().
00055                                      
00056    
00057    There is no control value for a password policy request
00058  ---*/
00059 
00060 int
00061 ldap_create_passwordpolicy_control( LDAP *ld,
00062                                     LDAPControl **ctrlp )
00063 {
00064        assert( ld != NULL );
00065        assert( LDAP_VALID( ld ) );
00066        assert( ctrlp != NULL );
00067 
00068        ld->ld_errno = ldap_control_create( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
00069               0, NULL, 0, ctrlp );
00070 
00071        return ld->ld_errno;
00072 }
00073 
00074 
00075 /*---
00076    ldap_parse_passwordpolicy_control
00077    
00078    Decode the passwordPolicyResponse control and return information.
00079 
00080    ld           (IN)   An LDAP session handle.
00081    
00082    ctrl         (IN)   The address of an
00083                                       LDAPControl structure, either obtained 
00084                                       by running thorugh the list of response controls or
00085                                       by a call to ldap_control_find().
00086 
00087    exptimep     (OUT)  This result parameter is filled in with the number of seconds before
00088                                            the password will expire, if expiration is imminent
00089                                            (imminency defined by the password policy). If expiration
00090                                            is not imminent, the value is set to -1.
00091 
00092    gracep       (OUT)  This result parameter is filled in with the number of grace logins after
00093                                            the password has expired, before no further login attempts
00094                                            will be allowed.
00095 
00096    errorcodep   (OUT)  This result parameter is filled in with the error code of the password operation
00097                                            If no error was detected, this error is set to PP_noError.
00098    
00099    Ber encoding
00100    
00101    PasswordPolicyResponseValue ::= SEQUENCE {
00102        warning [0] CHOICE {
00103            timeBeforeExpiration [0] INTEGER (0 .. maxInt),
00104            graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
00105        error [1] ENUMERATED {
00106            passwordExpired        (0),
00107            accountLocked          (1),
00108            changeAfterReset       (2),
00109            passwordModNotAllowed  (3),
00110            mustSupplyOldPassword  (4),
00111            invalidPasswordSyntax  (5),
00112            passwordTooShort       (6),
00113            passwordTooYoung       (7),
00114            passwordInHistory      (8) } OPTIONAL }
00115            
00116 ---*/
00117 
00118 int
00119 ldap_parse_passwordpolicy_control(
00120        LDAP           *ld,
00121        LDAPControl    *ctrl,
00122        ber_int_t      *expirep,
00123        ber_int_t      *gracep,
00124        LDAPPasswordPolicyError *errorp )
00125 {
00126        BerElement  *ber;
00127        int exp = -1, grace = -1;
00128        ber_tag_t tag;
00129        ber_len_t berLen;
00130         char *last;
00131        int err = PP_noError;
00132         
00133        assert( ld != NULL );
00134        assert( LDAP_VALID( ld ) );
00135        assert( ctrl != NULL );
00136 
00137        /* Create a BerElement from the berval returned in the control. */
00138        ber = ber_init(&ctrl->ldctl_value);
00139 
00140        if (ber == NULL) {
00141               ld->ld_errno = LDAP_NO_MEMORY;
00142               return(ld->ld_errno);
00143        }
00144 
00145        tag = ber_peek_tag( ber, &berLen );
00146        if (tag != LBER_SEQUENCE) goto exit;
00147 
00148        for( tag = ber_first_element( ber, &berLen, &last );
00149               tag != LBER_DEFAULT;
00150               tag = ber_next_element( ber, &berLen, last ) )
00151        {
00152               switch (tag) {
00153               case PPOLICY_WARNING:
00154                      ber_skip_tag(ber, &berLen );
00155                      tag = ber_peek_tag( ber, &berLen );
00156                      switch( tag ) {
00157                      case PPOLICY_EXPIRE:
00158                             if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
00159                             break;
00160                      case PPOLICY_GRACE:
00161                             if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
00162                             break;
00163                      default:
00164                             goto exit;
00165                      }
00166                      break;
00167               case PPOLICY_ERROR:
00168                      if (ber_get_enum( ber, &err ) == LBER_DEFAULT) goto exit;
00169                      break;
00170               default:
00171                      goto exit;
00172               }
00173        }
00174 
00175        ber_free(ber, 1);
00176 
00177        /* Return data to the caller for items that were requested. */
00178        if (expirep) *expirep = exp;
00179        if (gracep) *gracep = grace;
00180        if (errorp) *errorp = err;
00181         
00182        ld->ld_errno = LDAP_SUCCESS;
00183        return(ld->ld_errno);
00184 
00185   exit:
00186        ber_free(ber, 1);
00187        ld->ld_errno = LDAP_DECODING_ERROR;
00188        return(ld->ld_errno);
00189 }
00190 
00191 const char *
00192 ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
00193 {
00194        switch(err) {
00195        case PP_passwordExpired: return "Password expired";
00196        case PP_accountLocked: return "Account locked";
00197        case PP_changeAfterReset: return "Password must be changed";
00198        case PP_passwordModNotAllowed: return "Policy prevents password modification";
00199        case PP_mustSupplyOldPassword: return "Policy requires old password in order to change password";
00200        case PP_insufficientPasswordQuality: return "Password fails quality checks";
00201        case PP_passwordTooShort: return "Password is too short for policy";
00202        case PP_passwordTooYoung: return "Password has been changed too recently";
00203        case PP_passwordInHistory: return "New password is in list of old passwords";
00204        case PP_noError: return "No error";
00205        default: return "Unknown error code";
00206        }
00207 }
00208 
00209 #endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */