2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2004 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
19 #include <ac/stdlib.h>
20 #include <ac/string.h>
25 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
27 #define PPOLICY_WARNING 0xa0L
28 #define PPOLICY_ERROR 0xa1L
30 #define PPOLICY_EXPIRE 0xa0L
31 #define PPOLICY_GRACE 0xa1L
34 ldap_create_passwordpolicy_control
36 Create and encode the Password Policy Request
38 ld (IN) An LDAP session handle, as obtained from a call to
41 ctrlp (OUT) A result parameter that will be assigned the address
42 of an LDAPControl structure that contains the
43 passwordPolicyRequest control created by this function.
44 The memory occupied by the LDAPControl structure
45 SHOULD be freed when it is no longer in use by
46 calling ldap_control_free().
49 There is no control value for a password policy request
53 ldap_create_passwordpolicy_control( LDAP *ld,
59 assert( LDAP_VALID( ld ) );
60 assert( ctrlp != NULL );
62 if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
63 ld->ld_errno = LDAP_NO_MEMORY;
64 return(LDAP_NO_MEMORY);
67 ld->ld_errno = ldap_create_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
76 ldap_parse_passwordpolicy_control
78 Decode the passwordPolicyResponse control and return information.
80 ld (IN) An LDAP session handle.
82 ctrls (IN) The address of an
83 LDAPControl structure, typically obtained
84 by a call to ldap_find_control().
86 exptimep (OUT) This result parameter is filled in with the number of seconds before
87 the password will expire, if expiration is imminent
88 (imminency defined by the password policy). If expiration
89 is not imminent, the value is set to -1.
91 gracep (OUT) This result parameter is filled in with the number of grace logins after
92 the password has expired, before no further login attempts
95 errorcodep (OUT) This result parameter is filled in with the error code of the password operation
96 If no error was detected, this error is set to PP_noError.
100 PasswordPolicyResponseValue ::= SEQUENCE {
102 timeBeforeExpiration [0] INTEGER (0 .. maxInt),
103 graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
104 error [1] ENUMERATED {
107 changeAfterReset (2),
108 passwordModNotAllowed (3),
109 mustSupplyOldPassword (4),
110 invalidPasswordSyntax (5),
111 passwordTooShort (6),
112 passwordTooYoung (7),
113 passwordInHistory (8) } OPTIONAL }
118 ldap_parse_passwordpolicy_control(
123 LDAPPasswordPolicyError *errorp )
126 int i, exp = -1, grace = -1;
130 LDAPPasswordPolicyError err = PP_noError;
132 assert( ld != NULL );
133 assert( LDAP_VALID( ld ) );
136 /* Create a BerElement from the berval returned in the control. */
137 ber = ber_init(&ctrl->ldctl_value);
140 ld->ld_errno = LDAP_NO_MEMORY;
141 return(ld->ld_errno);
144 tag = ber_peek_tag( ber, &berLen );
145 if (tag != LBER_SEQUENCE) goto exit;
147 for( tag = ber_first_element( ber, &berLen, &last );
149 tag = ber_next_element( ber, &berLen, last ) ) {
151 case PPOLICY_WARNING:
152 ber_skip_tag(ber, &berLen );
153 tag = ber_peek_tag( ber, &berLen );
156 if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
159 if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
168 if (ber_get_enum( ber, (int *)&err ) == LBER_DEFAULT) goto exit;
177 /* Return data to the caller for items that were requested. */
178 if (expirep) *expirep = exp;
179 if (gracep) *gracep = grace;
180 if (errorp) *errorp = err;
182 ld->ld_errno = LDAP_SUCCESS;
183 return(ld->ld_errno);
187 ld->ld_errno = LDAP_DECODING_ERROR;
188 return(ld->ld_errno);
192 ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
195 case PP_passwordExpired: return "Password expired";
196 case PP_accountLocked: return "Account locked";
197 case PP_changeAfterReset: return "Password must be changed";
198 case PP_passwordModNotAllowed: return "Policy prevents password modification";
199 case PP_mustSupplyOldPassword: return "Policy requires old password in order to change password";
200 case PP_insufficientPasswordQuality: return "Password fails quality checks";
201 case PP_passwordTooShort: return "Password is too short for policy";
202 case PP_passwordTooYoung: return "Password has been changed too recently";
203 case PP_passwordInHistory: return "New password is in list of old passwords";
204 case PP_noError: return "No error";
205 default: return "Unknown error code";
209 #endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */