]> git.sur5r.net Git - openldap/blob - libraries/libldap/ppolicy.c
Rename ppcontrol.c to ppolicy.c
[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 #define PPOLICY_WARNING 0xa0L
26 #define PPOLICY_ERROR 0xa1L
27
28 #define PPOLICY_EXPIRE 0xa0L
29 #define PPOLICY_GRACE  0xa1L
30
31 /*---
32    ldap_create_passwordpolicy_control
33    
34    Create and encode the Password Policy Request
35
36    ld        (IN)  An LDAP session handle, as obtained from a call to
37                                    ldap_init().
38    
39    ctrlp     (OUT) A result parameter that will be assigned the address
40                                    of an LDAPControl structure that contains the 
41                                    passwordPolicyRequest control created by this function.
42                                    The memory occupied by the LDAPControl structure
43                                    SHOULD be freed when it is no longer in use by
44                                    calling ldap_control_free().
45                                           
46    
47    There is no control value for a password policy request
48  ---*/
49
50 int
51 ldap_create_passwordpolicy_control( LDAP *ld,
52                                     LDAPControl **ctrlp )
53 {
54         BerElement *ber;
55
56         assert( ld != NULL );
57         assert( LDAP_VALID( ld ) );
58         assert( ctrlp != NULL );
59
60         if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
61                 ld->ld_errno = LDAP_NO_MEMORY;
62                 return(LDAP_NO_MEMORY);
63         }
64
65         ld->ld_errno = ldap_create_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
66                 ber, 0, ctrlp);
67
68         ber_free(ber, 1);
69         return(ld->ld_errno);
70 }
71
72
73 /*---
74    ldap_parse_passwordpolicy_control
75    
76    Decode the passwordPolicyResponse control and return information.
77
78    ld           (IN)   An LDAP session handle.
79    
80    ctrls        (IN)   The address of an
81                                            LDAPControl structure, typically obtained 
82                                            by a call to ldap_find_control().
83
84    exptimep     (OUT)  This result parameter is filled in with the number of seconds before
85                                            the password will expire, if expiration is imminent
86                                            (imminency defined by the password policy). If expiration
87                                            is not imminent, the value is set to -1.
88
89    gracep       (OUT)  This result parameter is filled in with the number of grace logins after
90                                            the password has expired, before no further login attempts
91                                            will be allowed.
92
93    errorcodep   (OUT)  This result parameter is filled in with the error code of the password operation
94                                            If no error was detected, this error is set to PP_noError.
95    
96    Ber encoding
97    
98    PasswordPolicyResponseValue ::= SEQUENCE {
99        warning [0] CHOICE {
100            timeBeforeExpiration [0] INTEGER (0 .. maxInt),
101            graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
102        error [1] ENUMERATED {
103            passwordExpired        (0),
104            accountLocked          (1),
105            changeAfterReset       (2),
106            passwordModNotAllowed  (3),
107            mustSupplyOldPassword  (4),
108            invalidPasswordSyntax  (5),
109            passwordTooShort       (6),
110            passwordTooYoung       (7),
111            passwordInHistory      (8) } OPTIONAL }
112            
113 ---*/
114
115 int
116 ldap_parse_passwordpolicy_control(
117         LDAP           *ld,
118         LDAPControl    *ctrl,
119         int            *expirep,
120         int            *gracep,
121         LDAPPasswordPolicyError *errorp )
122 {
123         BerElement  *ber;
124         int i, exp = -1, grace = -1;
125         ber_tag_t tag;
126         ber_len_t berLen;
127         char *last;
128         LDAPPasswordPolicyError err = PP_noError;
129         
130         assert( ld != NULL );
131         assert( LDAP_VALID( ld ) );
132         assert( ctrl );
133
134         /* Create a BerElement from the berval returned in the control. */
135         ber = ber_init(&ctrl->ldctl_value);
136
137         if (ber == NULL) {
138                 ld->ld_errno = LDAP_NO_MEMORY;
139                 return(ld->ld_errno);
140         }
141
142         tag = ber_peek_tag( ber, &berLen );
143         if (tag != LBER_SEQUENCE) goto exit;
144
145         for( tag = ber_first_element( ber, &berLen, &last );
146              tag != LBER_DEFAULT;
147              tag = ber_next_element( ber, &berLen, last ) ) {
148             switch (tag) {
149                 case PPOLICY_WARNING:
150                     ber_skip_tag(ber, &berLen );
151                     tag = ber_peek_tag( ber, &berLen );
152                     switch( tag ) {
153                         case PPOLICY_EXPIRE:
154                             if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
155                             break;
156                         case PPOLICY_GRACE:
157                             if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
158                             break;
159                         default:
160                             goto exit;
161
162                     }
163                     
164                     break;
165                 case PPOLICY_ERROR:
166                     if (ber_get_enum( ber, (int *)&err ) == LBER_DEFAULT) goto exit;
167                     break;
168                 default:
169                     goto exit;
170             }
171         }
172         
173         ber_free(ber, 1);
174
175         /* Return data to the caller for items that were requested. */
176         if (expirep) *expirep = exp;
177         if (gracep) *gracep = grace;
178         if (errorp) *errorp = err;
179         
180         ld->ld_errno = LDAP_SUCCESS;
181         return(ld->ld_errno);
182
183   exit:
184         ber_free(ber, 1);
185         ld->ld_errno = LDAP_DECODING_ERROR;
186         return(ld->ld_errno);
187 }
188
189 const char *
190 ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
191 {
192         switch(err) {
193                 case PP_passwordExpired: return "Password expired";
194                 case PP_accountLocked: return "Account locked";
195                 case PP_changeAfterReset: return "Password must be changed";
196                 case PP_passwordModNotAllowed: return "Policy prevents password modification";
197                 case PP_mustSupplyOldPassword: return "Policy requires old password in order to change password";
198                 case PP_insufficientPasswordQuality: return "Password fails quality checks";
199                 case PP_passwordTooShort: return "Password is too short for policy";
200                 case PP_passwordTooYoung: return "Password has been changed too recently";
201                 case PP_passwordInHistory: return "New password is in list of old passwords";
202                 case PP_noError: return "No error";
203                 default: return "Unknown error code";
204         }
205 }