xref: /netbsd-src/external/bsd/openldap/dist/contrib/slapd-modules/proxyOld/proxyOld.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: proxyOld.c,v 1.3 2021/08/14 16:14:53 christos Exp $	*/
2 
3 /* proxyOld.c - module for supporting obsolete (rev 05) proxyAuthz control */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2005-2021 The OpenLDAP Foundation.
8  * Portions Copyright 2005 by 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 
20 #include <portable.h>
21 
22 #include <slap.h>
23 
24 #include <lber.h>
25 /*
26 #include <lber_pvt.h>
27 #include <lutil.h>
28 */
29 
30 /* This code is based on draft-weltman-ldapv3-proxy-05. There are a lot
31  * of holes in that draft, it doesn't specify that the control is legal
32  * for Add operations, and it makes no mention of Extended operations.
33  * It also doesn't specify whether an empty LDAPDN is allowed in the
34  * control value.
35  *
36  * For usability purposes, we're copying the op / exop behavior from the
37  * newer -12 draft.
38  */
39 #define LDAP_CONTROL_PROXY_AUTHZ05	"2.16.840.1.113730.3.4.12"
40 
41 static char *proxyOld_extops[] = {
42 	LDAP_EXOP_MODIFY_PASSWD,
43 	LDAP_EXOP_X_WHO_AM_I,
44 	NULL
45 };
46 
47 static int
proxyOld_parse(Operation * op,SlapReply * rs,LDAPControl * ctrl)48 proxyOld_parse(
49 	Operation *op,
50 	SlapReply *rs,
51 	LDAPControl *ctrl )
52 {
53 	int rc;
54 	BerElement	*ber;
55 	ber_tag_t	tag;
56 	struct berval dn = BER_BVNULL;
57 	struct berval authzDN = BER_BVNULL;
58 
59 
60 	/* We hijack the flag for the new control. Clearly only one or the
61 	 * other can be used at any given time.
62 	 */
63 	if ( op->o_proxy_authz != SLAP_CONTROL_NONE ) {
64 		rs->sr_text = "proxy authorization control specified multiple times";
65 		return LDAP_PROTOCOL_ERROR;
66 	}
67 
68 	op->o_proxy_authz = ctrl->ldctl_iscritical
69 		? SLAP_CONTROL_CRITICAL
70 		: SLAP_CONTROL_NONCRITICAL;
71 
72 	/* Parse the control value
73 	 *  proxyAuthzControlValue ::= SEQUENCE {
74 	 *		proxyDN	LDAPDN
75 	 *	}
76 	 */
77 	ber = ber_init( &ctrl->ldctl_value );
78 	if ( ber == NULL ) {
79 		rs->sr_text = "ber_init failed";
80 		return LDAP_OTHER;
81 	}
82 
83 	tag = ber_scanf( ber, "{m}", &dn );
84 
85 	if ( tag == LBER_ERROR ) {
86 		rs->sr_text = "proxyOld control could not be decoded";
87 		rc = LDAP_OTHER;
88 		goto done;
89 	}
90 	if ( BER_BVISEMPTY( &dn )) {
91 		Debug( LDAP_DEBUG_TRACE,
92 			"proxyOld_parse: conn=%lu anonymous\n",
93 				op->o_connid );
94 		authzDN.bv_val = ch_strdup("");
95 	} else {
96 		Debug( LDAP_DEBUG_ARGS,
97 			"proxyOld_parse: conn %lu ctrl DN=\"%s\"\n",
98 				op->o_connid, dn.bv_val );
99 		rc = dnNormalize( 0, NULL, NULL, &dn, &authzDN, op->o_tmpmemctx );
100 		if ( rc != LDAP_SUCCESS ) {
101 			goto done;
102 		}
103 		rc = slap_sasl_authorized( op, &op->o_ndn, &authzDN );
104 		if ( rc ) {
105 			op->o_tmpfree( authzDN.bv_val, op->o_tmpmemctx );
106 			rs->sr_text = "not authorized to assume identity";
107 			/* new spec uses LDAP_PROXY_AUTHZ_FAILURE */
108 			rc = LDAP_INSUFFICIENT_ACCESS;
109 			goto done;
110 		}
111 	}
112 	free( op->o_ndn.bv_val );
113 	free( op->o_dn.bv_val );
114 	op->o_ndn = authzDN;
115 	ber_dupbv( &op->o_dn, &authzDN );
116 
117 	Debug( LDAP_DEBUG_STATS, "conn=%lu op=%lu PROXYOLD dn=\"%s\"\n",
118 		op->o_connid, op->o_opid,
119 		authzDN.bv_len ? authzDN.bv_val : "anonymous" );
120 	rc = LDAP_SUCCESS;
121 done:
122 	ber_free( ber, 1 );
123 	return rc;
124 }
125 
init_module(int argc,char * argv[])126 int init_module(int argc, char *argv[]) {
127 	return register_supported_control( LDAP_CONTROL_PROXY_AUTHZ05,
128 		SLAP_CTRL_GLOBAL|SLAP_CTRL_HIDE|SLAP_CTRL_ACCESS, proxyOld_extops,
129 		proxyOld_parse, NULL );
130 }
131