1228060Sbapt/*	$NetBSD: account_usability.c,v 1.2 2021/08/14 16:14:55 christos Exp $	*/
2228060Sbapt
3228060Sbapt/* $OpenLDAP$ */
4228060Sbapt/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5228060Sbapt *
6228060Sbapt * Copyright 2004-2021 The OpenLDAP Foundation.
7228060Sbapt * Portions Copyright 2004 Hewlett-Packard Company.
8228060Sbapt * Portions Copyright 2004 Howard Chu, Symas Corp.
9228060Sbapt * All rights reserved.
10228060Sbapt *
11228060Sbapt * Redistribution and use in source and binary forms, with or without
12228060Sbapt * modification, are permitted only as authorized by the OpenLDAP
13228060Sbapt * Public License.
14228060Sbapt *
15228060Sbapt * A copy of this license is available in the file LICENSE in the
16228060Sbapt * top-level directory of the distribution or, alternatively, at
17228060Sbapt * <http://www.OpenLDAP.org/license.html>.
18228060Sbapt */
19228060Sbapt/* ACKNOWLEDGEMENTS:
20228060Sbapt * This work was developed by Howard Chu for inclusion in
21228060Sbapt * OpenLDAP Software, based on prior work by Neil Dunbar (HP).
22228060Sbapt * This work was sponsored by the Hewlett-Packard Company.
23228060Sbapt */
24228060Sbapt
25228060Sbapt#include <sys/cdefs.h>
26228060Sbapt__RCSID("$NetBSD: account_usability.c,v 1.2 2021/08/14 16:14:55 christos Exp $");
27228060Sbapt
28228060Sbapt#include "portable.h"
29228060Sbapt
30228060Sbapt#include "ldap-int.h"
31228060Sbapt
32228060Sbapt#ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY
33228060Sbapt
34228060Sbaptint
35228060Sbaptldap_create_accountusability_control( LDAP *ld,
36228060Sbapt                                    LDAPControl **ctrlp )
37228060Sbapt{
38228060Sbapt	assert( ld != NULL );
39228060Sbapt	assert( LDAP_VALID( ld ) );
40228060Sbapt	assert( ctrlp != NULL );
41228060Sbapt
42228060Sbapt	ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_ACCOUNT_USABILITY,
43228060Sbapt		0, NULL, 0, ctrlp );
44228060Sbapt
45228060Sbapt	return ld->ld_errno;
46228060Sbapt}
47228060Sbapt
48228060Sbaptint
49228060Sbaptldap_parse_accountusability_control(
50228060Sbapt	LDAP           *ld,
51228060Sbapt	LDAPControl    *ctrl,
52228060Sbapt	int            *availablep,
53228060Sbapt	LDAPAccountUsability *usabilityp )
54228060Sbapt{
55228060Sbapt	BerElement  *ber;
56228060Sbapt	int available = 0;
57228060Sbapt	ber_tag_t tag;
58228060Sbapt	ber_len_t berLen;
59228060Sbapt	char *last;
60228060Sbapt
61228060Sbapt	assert( ld != NULL );
62228060Sbapt	assert( LDAP_VALID( ld ) );
63228060Sbapt	assert( ctrl != NULL );
64228060Sbapt
65228060Sbapt	if ( !ctrl->ldctl_value.bv_val ) {
66228060Sbapt		ld->ld_errno = LDAP_DECODING_ERROR;
67228060Sbapt		return(ld->ld_errno);
68228060Sbapt	}
69228060Sbapt
70228060Sbapt	/* Create a BerElement from the berval returned in the control. */
71228060Sbapt	ber = ber_init(&ctrl->ldctl_value);
72228060Sbapt
73228060Sbapt	if (ber == NULL) {
74228060Sbapt		ld->ld_errno = LDAP_NO_MEMORY;
75228060Sbapt		return(ld->ld_errno);
76228060Sbapt	}
77228060Sbapt
78228060Sbapt	tag = ber_peek_tag( ber, &berLen );
79228060Sbapt
80228060Sbapt	if ( tag == LDAP_TAG_X_ACCOUNT_USABILITY_AVAILABLE ) {
81228060Sbapt		available = 1;
82228060Sbapt
83228060Sbapt		if ( usabilityp != NULL ) {
84228060Sbapt			if (ber_get_int( ber, &usabilityp->seconds_remaining ) == LBER_DEFAULT) goto exit;
85228060Sbapt		}
86228060Sbapt	} else if ( tag == LDAP_TAG_X_ACCOUNT_USABILITY_NOT_AVAILABLE ) {
87228060Sbapt		available = 0;
88228060Sbapt		LDAPAccountUsabilityMoreInfo more_info = { 0, 0, 0, -1, -1 };
89228060Sbapt
90228060Sbapt		ber_skip_tag( ber, &berLen );
91228060Sbapt		while ( (tag = ber_peek_tag( ber, &berLen )) != LBER_DEFAULT ) {
92228060Sbapt			switch (tag) {
93228060Sbapt			case LDAP_TAG_X_ACCOUNT_USABILITY_INACTIVE:
94228060Sbapt				if (ber_get_boolean( ber, &more_info.inactive ) == LBER_DEFAULT) goto exit;
95228060Sbapt				break;
96228060Sbapt			case LDAP_TAG_X_ACCOUNT_USABILITY_RESET:
97228060Sbapt				if (ber_get_boolean( ber, &more_info.reset ) == LBER_DEFAULT) goto exit;
98228060Sbapt				break;
99228060Sbapt			case LDAP_TAG_X_ACCOUNT_USABILITY_EXPIRED:
100228060Sbapt				if (ber_get_boolean( ber, &more_info.expired ) == LBER_DEFAULT) goto exit;
101228060Sbapt				break;
102228060Sbapt			case LDAP_TAG_X_ACCOUNT_USABILITY_REMAINING_GRACE:
103228060Sbapt				if (ber_get_int( ber, &more_info.remaining_grace ) == LBER_DEFAULT) goto exit;
104228060Sbapt				break;
105228060Sbapt			case LDAP_TAG_X_ACCOUNT_USABILITY_UNTIL_UNLOCK:
106228060Sbapt				if (ber_get_int( ber, &more_info.seconds_before_unlock ) == LBER_DEFAULT) goto exit;
107228060Sbapt				break;
108228060Sbapt			default:
109228060Sbapt				goto exit;
110228060Sbapt			}
111228060Sbapt		}
112228060Sbapt		if ( usabilityp != NULL ) {
113228060Sbapt			usabilityp->more_info = more_info;
114228060Sbapt		}
115228060Sbapt	} else {
116228060Sbapt		goto exit;
117228060Sbapt	}
118228060Sbapt	if ( availablep != NULL ) {
119228060Sbapt		*availablep = available;
120228060Sbapt	}
121228060Sbapt
122228060Sbapt	ber_free(ber, 1);
123228060Sbapt
124228060Sbapt	ld->ld_errno = LDAP_SUCCESS;
125228060Sbapt	return(ld->ld_errno);
126228060Sbapt
127228060Sbapt  exit:
128228060Sbapt	ber_free(ber, 1);
129228060Sbapt	ld->ld_errno = LDAP_DECODING_ERROR;
130228060Sbapt	return(ld->ld_errno);
131228060Sbapt}
132228060Sbapt
133228060Sbapt#endif /* LDAP_CONTROL_X_ACCOUNT_USABILITY */
134228060Sbapt