1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
|
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2004-2024 The OpenLDAP Foundation.
* Portions Copyright 2004 Hewlett-Packard Company.
* Portions Copyright 2004 Howard Chu, Symas Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
* This work was developed by Howard Chu for inclusion in
* OpenLDAP Software, based on prior work by Neil Dunbar (HP).
* This work was sponsored by the Hewlett-Packard Company.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/time.h>
#include "ldap-int.h"
#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
/* IMPLICIT TAGS, all context-specific */
#define PPOLICY_WARNING 0xa0L /* constructed + 0 */
#define PPOLICY_ERROR 0x81L /* primitive + 1 */
#define PPOLICY_EXPIRE 0x80L /* primitive + 0 */
#define PPOLICY_GRACE 0x81L /* primitive + 1 */
/*---
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 )
{
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( ctrlp != NULL );
ld->ld_errno = ldap_control_create( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
0, NULL, 0, ctrlp );
return ld->ld_errno;
}
/*---
ldap_parse_passwordpolicy_control
Decode the passwordPolicyResponse control and return information.
ld (IN) An LDAP session handle.
ctrl (IN) The address of an
LDAPControl structure, either obtained
by running through the list of response controls or
by a call to ldap_control_find().
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 *ctrl,
ber_int_t *expirep,
ber_int_t *gracep,
LDAPPasswordPolicyError *errorp )
{
BerElement *ber;
int exp = -1, grace = -1;
ber_tag_t tag;
ber_len_t berLen;
char *last;
int err = PP_noError;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( ctrl != NULL );
if ( !ctrl->ldctl_value.bv_val ) {
ld->ld_errno = LDAP_DECODING_ERROR;
return(ld->ld_errno);
}
/* Create a BerElement from the berval returned in the control. */
ber = ber_init(&ctrl->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, &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);
}
const char *
ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
{
switch(err) {
case PP_passwordExpired: return "Password expired";
case PP_accountLocked: return "Account locked";
case PP_changeAfterReset: return "Password must be changed";
case PP_passwordModNotAllowed: return "Policy prevents password modification";
case PP_mustSupplyOldPassword: return "Policy requires old password in order to change password";
case PP_insufficientPasswordQuality: return "Password fails quality checks";
case PP_passwordTooShort: return "Password is too short for policy";
case PP_passwordTooYoung: return "Password has been changed too recently";
case PP_passwordInHistory: return "New password is in list of old passwords";
case PP_passwordTooLong: return "Password is too long for policy";
case PP_noError: return "No error";
default: return "Unknown error code";
}
}
#endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */
#ifdef LDAP_CONTROL_X_PASSWORD_EXPIRING
int
ldap_parse_password_expiring_control(
LDAP *ld,
LDAPControl *ctrl,
long *secondsp )
{
long seconds = 0;
char buf[sizeof("-2147483648")];
char *next;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( ctrl != NULL );
if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ||
ctrl->ldctl_value.bv_len >= sizeof(buf) ) {
ld->ld_errno = LDAP_DECODING_ERROR;
return(ld->ld_errno);
}
memcpy( buf, ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len );
buf[ctrl->ldctl_value.bv_len] = '\0';
seconds = strtol( buf, &next, 10 );
if ( next == buf || next[0] != '\0' ) goto exit;
if ( secondsp != NULL ) {
*secondsp = seconds;
}
ld->ld_errno = LDAP_SUCCESS;
return(ld->ld_errno);
exit:
ld->ld_errno = LDAP_DECODING_ERROR;
return(ld->ld_errno);
}
#endif /* LDAP_CONTROL_X_PASSWORD_EXPIRING */
|