xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-mdb/operational.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: operational.c,v 1.1.1.1 2014/05/28 09:58:50 tron 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-2014 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 "portable.h"
20 
21 #include <stdio.h>
22 
23 #include <ac/string.h>
24 #include <ac/socket.h>
25 
26 #include "slap.h"
27 #include "back-mdb.h"
28 
29 /*
30  * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
31  * if the entry has children or not.
32  */
33 int
34 mdb_hasSubordinates(
35 	Operation	*op,
36 	Entry		*e,
37 	int		*hasSubordinates )
38 {
39 	struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
40 	MDB_txn		*rtxn;
41 	mdb_op_info	opinfo = {{{0}}}, *moi = &opinfo;
42 	int		rc;
43 
44 	assert( e != NULL );
45 
46 	rc = mdb_opinfo_get(op, mdb, 1, &moi);
47 	switch(rc) {
48 	case 0:
49 		break;
50 	default:
51 		rc = LDAP_OTHER;
52 		goto done;
53 	}
54 
55 	rtxn = moi->moi_txn;
56 
57 	rc = mdb_dn2id_children( op, rtxn, e );
58 
59 	switch( rc ) {
60 	case 0:
61 		*hasSubordinates = LDAP_COMPARE_TRUE;
62 		break;
63 
64 	case MDB_NOTFOUND:
65 		*hasSubordinates = LDAP_COMPARE_FALSE;
66 		rc = LDAP_SUCCESS;
67 		break;
68 
69 	default:
70 		Debug(LDAP_DEBUG_ARGS,
71 			"<=- " LDAP_XSTRING(mdb_hasSubordinates)
72 			": has_children failed: %s (%d)\n",
73 			mdb_strerror(rc), rc, 0 );
74 		rc = LDAP_OTHER;
75 	}
76 
77 done:;
78 	if ( moi == &opinfo ) {
79 		mdb_txn_reset( moi->moi_txn );
80 		LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
81 	} else {
82 		moi->moi_ref--;
83 	}
84 	return rc;
85 }
86 
87 /*
88  * sets the supported operational attributes (if required)
89  */
90 int
91 mdb_operational(
92 	Operation	*op,
93 	SlapReply	*rs )
94 {
95 	Attribute	**ap;
96 
97 	assert( rs->sr_entry != NULL );
98 
99 	for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
100 		if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
101 			break;
102 		}
103 	}
104 
105 	if ( *ap == NULL &&
106 		attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL &&
107 		( SLAP_OPATTRS( rs->sr_attr_flags ) ||
108 			ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) )
109 	{
110 		int	hasSubordinates, rc;
111 
112 		rc = mdb_hasSubordinates( op, rs->sr_entry, &hasSubordinates );
113 		if ( rc == LDAP_SUCCESS ) {
114 			*ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
115 			assert( *ap != NULL );
116 
117 			ap = &(*ap)->a_next;
118 		}
119 	}
120 
121 	return LDAP_SUCCESS;
122 }
123 
124