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