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
34int
35ldap_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
48int
49ldap_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