~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to contrib/slapd-modules/cloak/cloak.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug, Steve Langasek, Mathias Gug
  • Date: 2009-02-18 18:44:00 UTC
  • mfrom: (1.1.2 upstream) (0.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20090218184400-zw4mjse9eywt5566
Tags: 2.4.14-0ubuntu1
[ Steve Langasek ]
* New upstream version
  - Fixes a bug with the pcache overlay not returning cached entries
    (closes: #497697)
  - Update evolution-ntlm patch to apply to current Makefiles.
  - (tentatively) drop gnutls-ciphers, since this bug was reported to be
    fixed upstream in 2.4.8.  The fix applied in 2.4.8 didn't match the
    patch from the bug report, so this should be watched for regressions.
* Build against db4.7 instead of db4.2 at last!  Closes: #421946.
* Build with --disable-ndb, to avoid a misbuild when libmysqlclient is
  installed in the build environment.
* New patch, no-crlcheck-for-gnutls, to fix a build failure when using
  --with-tls=gnutls.

[ Mathias Gug ]
* Merge from debian unstable, remaining changes:
  - debian/apparmor-profile: add AppArmor profile
  - debian/slapd.postinst: Reload AA profile on configuration
  - updated debian/slapd.README.Debian for note on AppArmor
  - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6
  - debian/control: Conflicts with apparmor-profiles << 2.1+1075-0ubuntu4
    to make sure that if earlier version of apparmour-profiles gets
    installed it won't overwrite our profile.
  - Modify Maintainer value to match the DebianMaintainerField
    speficication.
  - follow ApparmorProfileMigration and force apparmor compalin mode on 
    some upgrades (LP: #203529)
  - debian/slapd.dirs: add etc/apparmor.d/force-complain
  - debian/slapd.preinst: create symlink for force-complain on pre-feisty
    upgrades, upgrades where apparmor-profiles profile is unchanged (ie
    non-enforcing) and upgrades where apparmor profile does not exist.
  - debian/slapd.postrm: remove symlink in force-complain/ on purge
  - debian/patches/fix-ucred-libc due to changes how newer glibc handle
    the ucred struct now.
  - debian/control:
    - Build-depend on libltdl7-dev rather then libltdl3-dev.
  - debian/patches/autogen.sh:
    - Call libtoolize with the --install option to install config.{guess,sub}
      files.
  - Don't use local statement in config script as it fails if /bin/sh
    points to bash (LP: #286063).
  - Disable the testsuite on hppa. Allows building of packages on this
    architecture again, once this package is in the archive.
    LP: #288908.
  - debian/slapd.postinst, debian/slapd.script-common: set correct ownership
    and permissions on /var/lib/ldap, /etc/ldap/slapd.d (group readable) and
    /var/run/slapd (world readable). (LP: #257667).
  - debian/patches/nssov-build, debian/rules: 
    Build and package the nss overlay.
    debian/schema/misc.ldif: add ldif file for the misc schema, which defines
    rfc822MailMember (required by the nss overlay).
  - debian/{control,rules}: enable PIE hardening
  - Use cn=config as the default configuration backend instead of 
    slapd.conf. Migrate slapd.conf  file to /etc/ldap/slapd.d/ on upgrade
    asking the end user to enter a new password to control the access to the
    cn=config tree.
* debian/patches/corrupt-contextCSN: The contextCSN can get corrupted at
  times. (ITS: #5947)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/cloak/cloak.c,v 1.2.2.1 2009/01/21 01:15:37 quanah Exp $ */
 
2
/* cloak.c - Overlay to hide some attribute except if explicitely requested */
 
3
/* 
 
4
 * Copyright 2008 Emmanuel Dreyfus
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted only as authorized by the OpenLDAP
 
9
 * Public License.
 
10
 *
 
11
 * A copy of this license is available in the file LICENSE in the
 
12
 * top-level directory of the distribution or, alternatively, at
 
13
 * <http://www.OpenLDAP.org/license.html>.
 
14
 */
 
15
#include "portable.h"
 
16
 
 
17
#ifdef SLAPD_OVER_CLOAK
 
18
 
 
19
#include <stdio.h>
 
20
 
 
21
#include <ac/string.h>
 
22
#include <ac/socket.h>
 
23
 
 
24
#include "lutil.h"
 
25
#include "slap.h"
 
26
#include "config.h"
 
27
 
 
28
enum { CLOAK_ATTR = 1 };
 
29
 
 
30
typedef struct cloak_info_t {
 
31
        ObjectClass             *ci_oc; 
 
32
        AttributeDescription    *ci_ad;
 
33
        struct cloak_info_t     *ci_next;
 
34
} cloak_info_t;
 
35
 
 
36
#define CLOAK_USAGE "\"cloak-attr <attr> [<class>]\": "
 
37
 
 
38
static int
 
39
cloak_cfgen( ConfigArgs *c )
 
40
{
 
41
        slap_overinst   *on = (slap_overinst *)c->bi;
 
42
        cloak_info_t    *ci = (cloak_info_t *)on->on_bi.bi_private;
 
43
 
 
44
        int             rc = 0, i;
 
45
 
 
46
        if ( c->op == SLAP_CONFIG_EMIT ) {
 
47
                switch( c->type ) {
 
48
                case CLOAK_ATTR:
 
49
                        for ( i = 0; ci; i++, ci = ci->ci_next ) {
 
50
                                struct berval   bv;
 
51
                                int len;
 
52
 
 
53
                                assert( ci->ci_ad != NULL );
 
54
 
 
55
                                if ( ci->ci_oc != NULL )
 
56
                                        len = snprintf( c->cr_msg, 
 
57
                                        sizeof( c->cr_msg ),
 
58
                                        SLAP_X_ORDERED_FMT "%s %s", i,
 
59
                                        ci->ci_ad->ad_cname.bv_val,
 
60
                                        ci->ci_oc->soc_cname.bv_val );
 
61
                                else
 
62
                                        len = snprintf( c->cr_msg, 
 
63
                                        sizeof( c->cr_msg ),
 
64
                                        SLAP_X_ORDERED_FMT "%s", i,
 
65
                                        ci->ci_ad->ad_cname.bv_val );
 
66
 
 
67
                                bv.bv_val = c->cr_msg;
 
68
                                bv.bv_len = len;
 
69
                                value_add_one( &c->rvalue_vals, &bv );
 
70
                        }
 
71
                        break;
 
72
 
 
73
                default:
 
74
                        rc = 1;
 
75
                        break;
 
76
                }
 
77
 
 
78
                return rc;
 
79
 
 
80
        } else if ( c->op == LDAP_MOD_DELETE ) {
 
81
                cloak_info_t    *ci_next;
 
82
 
 
83
                switch( c->type ) {
 
84
                case CLOAK_ATTR:
 
85
                        for ( ci_next = ci, i = 0; 
 
86
                              ci_next, c->valx < 0 || i < c->valx; 
 
87
                              ci = ci_next, i++ ){
 
88
 
 
89
                                ci_next = ci->ci_next;
 
90
 
 
91
                                ch_free ( ci->ci_ad );
 
92
                                if ( ci->ci_oc != NULL )
 
93
                                        ch_free ( ci->ci_oc );
 
94
 
 
95
                                ch_free( ci );
 
96
                        }
 
97
                        ci = (cloak_info_t *)on->on_bi.bi_private;
 
98
                        break;
 
99
 
 
100
                default:
 
101
                        rc = 1;
 
102
                        break;
 
103
                }
 
104
 
 
105
                return rc;
 
106
        }
 
107
 
 
108
        switch( c->type ) {
 
109
        case CLOAK_ATTR: {
 
110
                ObjectClass             *oc = NULL;
 
111
                AttributeDescription    *ad = NULL;
 
112
                const char              *text;
 
113
                cloak_info_t           **cip = NULL;
 
114
                cloak_info_t            *ci_next = NULL;
 
115
 
 
116
                if ( c->argc == 3 ) {
 
117
                        oc = oc_find( c->argv[ 2 ] );
 
118
                        if ( oc == NULL ) {
 
119
                                snprintf( c->cr_msg, 
 
120
                                          sizeof( c->cr_msg ), 
 
121
                                          CLOAK_USAGE
 
122
                                          "unable to find ObjectClass \"%s\"",
 
123
                                          c->argv[ 2 ] );
 
124
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
 
125
                                       c->log, c->cr_msg, 0 );
 
126
                                return 1;
 
127
                        }
 
128
                }
 
129
 
 
130
                rc = slap_str2ad( c->argv[ 1 ], &ad, &text );
 
131
                if ( rc != LDAP_SUCCESS ) {
 
132
                        snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE
 
133
                                "unable to find AttributeDescription \"%s\"",
 
134
                                c->argv[ 1 ] );
 
135
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
 
136
                                c->log, c->cr_msg, 0 );
 
137
                        return 1;
 
138
                }
 
139
 
 
140
                for ( i = 0, cip = (cloak_info_t **)&on->on_bi.bi_private;
 
141
                      c->valx < 0 || i < c->valx, *cip;
 
142
                      i++, cip = &(*cip)->ci_next ) {
 
143
                        if ( c->valx >= 0 && *cip == NULL ) {
 
144
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
145
                                        CLOAK_USAGE
 
146
                                        "invalid index {%d}\n",
 
147
                                        c->valx );
 
148
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
 
149
                                        c->log, c->cr_msg, 0 );
 
150
                                return 1;
 
151
                        }
 
152
                        ci_next = *cip;
 
153
                }
 
154
 
 
155
                *cip = (cloak_info_t *)ch_calloc( 1, sizeof( cloak_info_t ) );
 
156
                (*cip)->ci_oc = oc;
 
157
                (*cip)->ci_ad = ad;
 
158
                (*cip)->ci_next = ci_next;
 
159
 
 
160
                rc = 0;
 
161
                break;
 
162
        }
 
163
 
 
164
        default:
 
165
                rc = 1;
 
166
                break;
 
167
        }
 
168
 
 
169
        return rc;
 
170
}
 
171
 
 
172
static int
 
173
cloak_search_cb( Operation *op, SlapReply *rs )
 
174
{
 
175
        slap_callback   *sc;
 
176
        cloak_info_t    *ci;
 
177
        Entry           *e = NULL;
 
178
        Entry           *me = NULL;
 
179
 
 
180
        assert( op && op->o_callback && rs );
 
181
 
 
182
        if ( rs->sr_type != REP_SEARCH || !rs->sr_entry ) {
 
183
                slap_freeself_cb( op, rs );
 
184
                return ( SLAP_CB_CONTINUE );
 
185
        }
 
186
 
 
187
        sc = op->o_callback;
 
188
        e = rs->sr_entry;
 
189
 
 
190
        /* 
 
191
         * First perform a quick scan for an attribute to cloak
 
192
         */
 
193
        for ( ci = (cloak_info_t *)sc->sc_private; ci; ci = ci->ci_next ) {
 
194
                Attribute *a;
 
195
 
 
196
                if ( ci->ci_oc != NULL &&
 
197
                     !is_entry_objectclass_or_sub( e, ci->ci_oc ) )
 
198
                        continue;
 
199
 
 
200
                for ( a = e->e_attrs; a; a = a->a_next )
 
201
                        if ( a->a_desc == ci->ci_ad )
 
202
                                break;
 
203
 
 
204
                if ( a != NULL )
 
205
                        break;
 
206
        }
 
207
 
 
208
        /*
 
209
         * Nothing found to cloak
 
210
         */
 
211
        if ( ci == NULL )
 
212
                return ( SLAP_CB_CONTINUE );
 
213
 
 
214
        /*
 
215
         * We are now committed to cloak an attribute.
 
216
         */
 
217
        if ( rs->sr_flags & REP_ENTRY_MODIFIABLE )
 
218
                me = e;
 
219
        else
 
220
                me = entry_dup( e );
 
221
                
 
222
        for ( ci = (cloak_info_t *)sc->sc_private; ci; ci = ci->ci_next ) {
 
223
                Attribute *a;
 
224
                Attribute *pa;
 
225
 
 
226
                for ( pa = NULL, a = me->e_attrs;
 
227
                      a; 
 
228
                      pa = a, a = a->a_next ) {
 
229
 
 
230
                        if ( a->a_desc != ci->ci_ad )
 
231
                                continue;
 
232
 
 
233
                        Debug( LDAP_DEBUG_TRACE, "cloak_search_cb: cloak %s\n", 
 
234
                               a->a_desc->ad_cname.bv_val,
 
235
                               0, 0 );
 
236
 
 
237
                        if ( pa != NULL ) 
 
238
                                pa->a_next = a->a_next;
 
239
                        else
 
240
                                me->e_attrs = a->a_next;
 
241
 
 
242
                        attr_clean( a );
 
243
                }
 
244
 
 
245
        }
 
246
 
 
247
        if ( me != e ) {
 
248
                if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED )
 
249
                        entry_free( e );
 
250
 
 
251
                rs->sr_entry = me;
 
252
                rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
 
253
        }
 
254
 
 
255
        return ( SLAP_CB_CONTINUE );
 
256
}
 
257
 
 
258
static int
 
259
cloak_search( Operation *op, SlapReply *rs )
 
260
{
 
261
        slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
 
262
        cloak_info_t    *ci = (cloak_info_t *)on->on_bi.bi_private; 
 
263
        slap_callback   *sc;
 
264
 
 
265
        if ( op->ors_attrsonly ||
 
266
             op->ors_attrs ||
 
267
             get_manageDSAit( op ) )
 
268
                return SLAP_CB_CONTINUE;
 
269
 
 
270
        sc = op->o_tmpcalloc( 1, sizeof( *sc ), op->o_tmpmemctx );
 
271
        sc->sc_response = cloak_search_cb;
 
272
        sc->sc_cleanup = NULL;
 
273
        sc->sc_next = NULL;
 
274
        sc->sc_private = ci;
 
275
        op->o_callback = sc;
 
276
 
 
277
        return SLAP_CB_CONTINUE;
 
278
}
 
279
 
 
280
static slap_overinst cloak_ovl;
 
281
 
 
282
static ConfigTable cloakcfg[] = {
 
283
        { "cloak-attr", "attribute [class]",
 
284
                2, 3, 0, ARG_MAGIC|CLOAK_ATTR, cloak_cfgen,
 
285
                "( OLcfgCtAt:4.1 NAME 'olcCloakAttribute' "
 
286
                        "DESC 'Cloaked attribute: attribute [class]' "
 
287
                        "EQUALITY caseIgnoreMatch "
 
288
                        "SYNTAX OMsDirectoryString "
 
289
                        "X-ORDERED 'VALUES' )",
 
290
                        NULL, NULL },
 
291
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
 
292
};
 
293
 
 
294
static ConfigOCs cloakocs[] = {
 
295
        { "( OLcfgCtOc:4.1 "
 
296
          "NAME 'olcCloakConfig' "
 
297
          "DESC 'Attribute cloak configuration' "
 
298
          "SUP olcOverlayConfig "
 
299
          "MAY ( olcCloakAttribute ) )", 
 
300
          Cft_Overlay, cloakcfg },
 
301
        { NULL, 0, NULL }
 
302
};
 
303
 
 
304
#if SLAPD_OVER_CLOAK == SLAPD_MOD_DYNAMIC
 
305
static
 
306
#endif
 
307
int
 
308
cloak_initialize( void ) {
 
309
        int rc;
 
310
        cloak_ovl.on_bi.bi_type = "cloak";
 
311
        cloak_ovl.on_bi.bi_op_search = cloak_search;
 
312
        cloak_ovl.on_bi.bi_cf_ocs = cloakocs;
 
313
 
 
314
        rc = config_register_schema ( cloakcfg, cloakocs );
 
315
        if ( rc ) 
 
316
                return rc;
 
317
 
 
318
        return overlay_register( &cloak_ovl );
 
319
}
 
320
 
 
321
#if SLAPD_OVER_CLOAK == SLAPD_MOD_DYNAMIC
 
322
int init_module(int argc, char *argv[]) {
 
323
        return cloak_initialize();
 
324
}
 
325
#endif
 
326
 
 
327
#endif /* defined(SLAPD_OVER_CLOAK) */
 
328