1 /*        $NetBSD: account_usability.c,v 1.2 2021/08/14 16:14:55 christos Exp $ */
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 2004-2021 The OpenLDAP Foundation.
7  * Portions Copyright 2004 Hewlett-Packard Company.
8  * Portions Copyright 2004 Howard Chu, Symas Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted only as authorized by the OpenLDAP
13  * Public License.
14  *
15  * A copy of this license is available in the file LICENSE in the
16  * top-level directory of the distribution or, alternatively, at
17  * <http://www.OpenLDAP.org/license.html>.
18  */
19 /* ACKNOWLEDGEMENTS:
20  * This work was developed by Howard Chu for inclusion in
21  * OpenLDAP Software, based on prior work by Neil Dunbar (HP).
22  * This work was sponsored by the Hewlett-Packard Company.
23  */
24 
25 #include <sys/cdefs.h>
26 __RCSID("$NetBSD: account_usability.c,v 1.2 2021/08/14 16:14:55 christos Exp $");
27 
28 #include "portable.h"
29 
30 #include "ldap-int.h"
31 
32 #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
33 
34 int
ldap_create_accountusability_control(LDAP * ld,LDAPControl ** ctrlp)35 ldap_create_accountusability_control( LDAP *ld,
36                                     LDAPControl **ctrlp )
37 {
38           assert( ld != NULL );
39           assert( LDAP_VALID( ld ) );
40           assert( ctrlp != NULL );
41 
42           ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_ACCOUNT_USABILITY,
43                     0, NULL, 0, ctrlp );
44 
45           return ld->ld_errno;
46 }
47 
48 int
ldap_parse_accountusability_control(LDAP * ld,LDAPControl * ctrl,int * availablep,LDAPAccountUsability * usabilityp)49 ldap_parse_accountusability_control(
50           LDAP           *ld,
51           LDAPControl    *ctrl,
52           int            *availablep,
53           LDAPAccountUsability *usabilityp )
54 {
55           BerElement  *ber;
56           int available = 0;
57           ber_tag_t tag;
58           ber_len_t berLen;
59           char *last;
60 
61           assert( ld != NULL );
62           assert( LDAP_VALID( ld ) );
63           assert( ctrl != NULL );
64 
65           if ( !ctrl->ldctl_value.bv_val ) {
66                     ld->ld_errno = LDAP_DECODING_ERROR;
67                     return(ld->ld_errno);
68           }
69 
70           /* Create a BerElement from the berval returned in the control. */
71           ber = ber_init(&ctrl->ldctl_value);
72 
73           if (ber == NULL) {
74                     ld->ld_errno = LDAP_NO_MEMORY;
75                     return(ld->ld_errno);
76           }
77 
78           tag = ber_peek_tag( ber, &berLen );
79 
80           if ( tag == LDAP_TAG_X_ACCOUNT_USABILITY_AVAILABLE ) {
81                     available = 1;
82 
83                     if ( usabilityp != NULL ) {
84                               if (ber_get_int( ber, &usabilityp->seconds_remaining ) == LBER_DEFAULT) goto exit;
85                     }
86           } else if ( tag == LDAP_TAG_X_ACCOUNT_USABILITY_NOT_AVAILABLE ) {
87                     available = 0;
88                     LDAPAccountUsabilityMoreInfo more_info = { 0, 0, 0, -1, -1 };
89 
90                     ber_skip_tag( ber, &berLen );
91                     while ( (tag = ber_peek_tag( ber, &berLen )) != LBER_DEFAULT ) {
92                               switch (tag) {
93                               case LDAP_TAG_X_ACCOUNT_USABILITY_INACTIVE:
94                                         if (ber_get_boolean( ber, &more_info.inactive ) == LBER_DEFAULT) goto exit;
95                                         break;
96                               case LDAP_TAG_X_ACCOUNT_USABILITY_RESET:
97                                         if (ber_get_boolean( ber, &more_info.reset ) == LBER_DEFAULT) goto exit;
98                                         break;
99                               case LDAP_TAG_X_ACCOUNT_USABILITY_EXPIRED:
100                                         if (ber_get_boolean( ber, &more_info.expired ) == LBER_DEFAULT) goto exit;
101                                         break;
102                               case LDAP_TAG_X_ACCOUNT_USABILITY_REMAINING_GRACE:
103                                         if (ber_get_int( ber, &more_info.remaining_grace ) == LBER_DEFAULT) goto exit;
104                                         break;
105                               case LDAP_TAG_X_ACCOUNT_USABILITY_UNTIL_UNLOCK:
106                                         if (ber_get_int( ber, &more_info.seconds_before_unlock ) == LBER_DEFAULT) goto exit;
107                                         break;
108                               default:
109                                         goto exit;
110                               }
111                     }
112                     if ( usabilityp != NULL ) {
113                               usabilityp->more_info = more_info;
114                     }
115           } else {
116                     goto exit;
117           }
118           if ( availablep != NULL ) {
119                     *availablep = available;
120           }
121 
122           ber_free(ber, 1);
123 
124           ld->ld_errno = LDAP_SUCCESS;
125           return(ld->ld_errno);
126 
127   exit:
128           ber_free(ber, 1);
129           ld->ld_errno = LDAP_DECODING_ERROR;
130           return(ld->ld_errno);
131 }
132 
133 #endif /* LDAP_CONTROL_X_ACCOUNT_USABILITY */
134