xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-mdb/operational.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: operational.c,v 1.3 2021/08/14 16:15:00 christos Exp $	*/
2 
3 /* operational.c - mdb backend operational attributes function */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2000-2021 The OpenLDAP Foundation.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 
19 #include <sys/cdefs.h>
20 __RCSID("$NetBSD: operational.c,v 1.3 2021/08/14 16:15:00 christos Exp $");
21 
22 #include "portable.h"
23 
24 #include <stdio.h>
25 
26 #include <ac/string.h>
27 #include <ac/socket.h>
28 
29 #include "slap.h"
30 #include "back-mdb.h"
31 
32 /*
33  * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
34  * if the entry has children or not.
35  */
36 int
mdb_hasSubordinates(Operation * op,Entry * e,int * hasSubordinates)37 mdb_hasSubordinates(
38 	Operation	*op,
39 	Entry		*e,
40 	int		*hasSubordinates )
41 {
42 	struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
43 	MDB_txn		*rtxn;
44 	mdb_op_info	opinfo = {{{0}}}, *moi = &opinfo;
45 	int		rc;
46 
47 	assert( e != NULL );
48 
49 	rc = mdb_opinfo_get(op, mdb, 1, &moi);
50 	switch(rc) {
51 	case 0:
52 		break;
53 	default:
54 		rc = LDAP_OTHER;
55 		goto done;
56 	}
57 
58 	rtxn = moi->moi_txn;
59 
60 	rc = mdb_dn2id_children( op, rtxn, e );
61 
62 	switch( rc ) {
63 	case 0:
64 		*hasSubordinates = LDAP_COMPARE_TRUE;
65 		break;
66 
67 	case MDB_NOTFOUND:
68 		*hasSubordinates = LDAP_COMPARE_FALSE;
69 		rc = LDAP_SUCCESS;
70 		break;
71 
72 	default:
73 		Debug(LDAP_DEBUG_ARGS,
74 			"<=- " LDAP_XSTRING(mdb_hasSubordinates)
75 			": has_children failed: %s (%d)\n",
76 			mdb_strerror(rc), rc );
77 		rc = LDAP_OTHER;
78 	}
79 
80 done:;
81 	if ( moi == &opinfo ) {
82 		mdb_txn_reset( moi->moi_txn );
83 		LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
84 	} else {
85 		moi->moi_ref--;
86 	}
87 	return rc;
88 }
89 
90 /*
91  * sets the supported operational attributes (if required)
92  */
93 int
mdb_operational(Operation * op,SlapReply * rs)94 mdb_operational(
95 	Operation	*op,
96 	SlapReply	*rs )
97 {
98 	Attribute	**ap;
99 
100 	assert( rs->sr_entry != NULL );
101 
102 	for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
103 		if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
104 			break;
105 		}
106 	}
107 
108 	if ( *ap == NULL &&
109 		attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL &&
110 		( SLAP_OPATTRS( rs->sr_attr_flags ) ||
111 			ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) )
112 	{
113 		int	hasSubordinates, rc;
114 
115 		rc = mdb_hasSubordinates( op, rs->sr_entry, &hasSubordinates );
116 		if ( rc == LDAP_SUCCESS ) {
117 			*ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
118 			assert( *ap != NULL );
119 
120 			ap = &(*ap)->a_next;
121 		}
122 	}
123 
124 	return LDAP_SUCCESS;
125 }
126 
127