operational.c revision 1.1
1/*	$NetBSD: operational.c,v 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 */
33int
34mdb_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
77done:;
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 */
90int
91mdb_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