]> git.sur5r.net Git - openldap/blob - libraries/libldap/ppolicy.c
Hide code behind #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
[openldap] / libraries / libldap / ppolicy.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2004 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
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>.
14  */
15
16 #include "portable.h"
17
18 #include <stdio.h>
19 #include <ac/stdlib.h>
20 #include <ac/string.h>
21 #include <ac/time.h>
22
23 #include "ldap-int.h"
24
25 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
26
27 #define PPOLICY_WARNING 0xa0L
28 #define PPOLICY_ERROR 0xa1L
29
30 #define PPOLICY_EXPIRE 0xa0L
31 #define PPOLICY_GRACE  0xa1L
32
33 /*---
34    ldap_create_passwordpolicy_control
35    
36    Create and encode the Password Policy Request
37
38    ld        (IN)  An LDAP session handle, as obtained from a call to
39                                    ldap_init().
40    
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().
47                                           
48    
49    There is no control value for a password policy request
50  ---*/
51
52 int
53 ldap_create_passwordpolicy_control( LDAP *ld,
54                                     LDAPControl **ctrlp )
55 {
56         BerElement *ber;
57
58         assert( ld != NULL );
59         assert( LDAP_VALID( ld ) );
60         assert( ctrlp != NULL );
61
62         if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
63                 ld->ld_errno = LDAP_NO_MEMORY;
64                 return(LDAP_NO_MEMORY);
65         }
66
67         ld->ld_errno = ldap_create_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
68                 ber, 0, ctrlp);
69
70         ber_free(ber, 1);
71         return(ld->ld_errno);
72 }
73
74
75 /*---
76    ldap_parse_passwordpolicy_control
77    
78    Decode the passwordPolicyResponse control and return information.
79
80    ld           (IN)   An LDAP session handle.
81    
82    ctrls        (IN)   The address of an
83                                            LDAPControl structure, typically obtained 
84                                            by a call to ldap_find_control().
85
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.
90
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
93                                            will be allowed.
94
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.
97    
98    Ber encoding
99    
100    PasswordPolicyResponseValue ::= SEQUENCE {
101        warning [0] CHOICE {
102            timeBeforeExpiration [0] INTEGER (0 .. maxInt),
103            graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
104        error [1] ENUMERATED {
105            passwordExpired        (0),
106            accountLocked          (1),
107            changeAfterReset       (2),
108            passwordModNotAllowed  (3),
109            mustSupplyOldPassword  (4),
110            invalidPasswordSyntax  (5),
111            passwordTooShort       (6),
112            passwordTooYoung       (7),
113            passwordInHistory      (8) } OPTIONAL }
114            
115 ---*/
116
117 int
118 ldap_parse_passwordpolicy_control(
119         LDAP           *ld,
120         LDAPControl    *ctrl,
121         int            *expirep,
122         int            *gracep,
123         LDAPPasswordPolicyError *errorp )
124 {
125         BerElement  *ber;
126         int i, exp = -1, grace = -1;
127         ber_tag_t tag;
128         ber_len_t berLen;
129         char *last;
130         LDAPPasswordPolicyError err = PP_noError;
131         
132         assert( ld != NULL );
133         assert( LDAP_VALID( ld ) );
134         assert( ctrl );
135
136         /* Create a BerElement from the berval returned in the control. */
137         ber = ber_init(&ctrl->ldctl_value);
138
139         if (ber == NULL) {
140                 ld->ld_errno = LDAP_NO_MEMORY;
141                 return(ld->ld_errno);
142         }
143
144         tag = ber_peek_tag( ber, &berLen );
145         if (tag != LBER_SEQUENCE) goto exit;
146
147         for( tag = ber_first_element( ber, &berLen, &last );
148              tag != LBER_DEFAULT;
149              tag = ber_next_element( ber, &berLen, last ) ) {
150             switch (tag) {
151                 case PPOLICY_WARNING:
152                     ber_skip_tag(ber, &berLen );
153                     tag = ber_peek_tag( ber, &berLen );
154                     switch( tag ) {
155                         case PPOLICY_EXPIRE:
156                             if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
157                             break;
158                         case PPOLICY_GRACE:
159                             if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
160                             break;
161                         default:
162                             goto exit;
163
164                     }
165                     
166                     break;
167                 case PPOLICY_ERROR:
168                     if (ber_get_enum( ber, (int *)&err ) == LBER_DEFAULT) goto exit;
169                     break;
170                 default:
171                     goto exit;
172             }
173         }
174         
175         ber_free(ber, 1);
176
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;
181         
182         ld->ld_errno = LDAP_SUCCESS;
183         return(ld->ld_errno);
184
185   exit:
186         ber_free(ber, 1);
187         ld->ld_errno = LDAP_DECODING_ERROR;
188         return(ld->ld_errno);
189 }
190
191 const char *
192 ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
193 {
194         switch(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";
206         }
207 }
208
209 #endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */