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

« back to all changes in this revision

Viewing changes to servers/slapd/controls.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2009-02-18 18:44:00 UTC
  • mfrom: (0.1.1 upstream)
  • mto: (0.3.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: james.westby@ubuntu.com-20090218184400-xmj1e22xo7i50ar6
Tags: upstream-2.4.14
ImportĀ upstreamĀ versionĀ 2.4.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $OpenLDAP: pkg/ldap/servers/slapd/controls.c,v 1.174.2.10 2008/04/14 22:15:21 quanah Exp $ */
 
1
/* $OpenLDAP: pkg/ldap/servers/slapd/controls.c,v 1.174.2.18 2009/01/22 00:01:01 kurt Exp $ */
2
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3
3
 *
4
 
 * Copyright 1998-2008 The OpenLDAP Foundation.
 
4
 * Copyright 1998-2009 The OpenLDAP Foundation.
5
5
 * All rights reserved.
6
6
 *
7
7
 * Redistribution and use in source and binary forms, with or without
48
48
#ifdef SLAP_CONTROL_X_SESSION_TRACKING
49
49
static SLAP_CTRL_PARSE_FN parseSessionTracking;
50
50
#endif
 
51
#ifdef SLAP_CONTROL_X_WHATFAILED
 
52
static SLAP_CTRL_PARSE_FN parseWhatFailed;
 
53
#endif
51
54
 
52
55
#undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
53
56
 
120
123
static struct slap_control control_defs[] = {
121
124
        {  LDAP_CONTROL_ASSERT,
122
125
                (int)offsetof(struct slap_control_ids, sc_assert),
123
 
                SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME|
124
 
                        SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH,
 
126
                SLAP_CTRL_UPDATE|SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH,
125
127
                NULL, NULL,
126
128
                parseAssert, LDAP_SLIST_ENTRY_INITIALIZER(next) },
127
129
        { LDAP_CONTROL_PRE_READ,
217
219
                session_tracking_extops, NULL,
218
220
                parseSessionTracking, LDAP_SLIST_ENTRY_INITIALIZER(next) },
219
221
#endif
 
222
#ifdef SLAP_CONTROL_X_WHATFAILED
 
223
        { LDAP_CONTROL_X_WHATFAILED,
 
224
                (int)offsetof(struct slap_control_ids, sc_whatFailed),
 
225
                SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE,
 
226
                NULL, NULL,
 
227
                parseWhatFailed, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 
228
#endif
 
229
 
220
230
        { NULL, 0, 0, NULL, 0, NULL, LDAP_SLIST_ENTRY_INITIALIZER(next) }
221
231
};
222
232
 
536
546
        const char **text )
537
547
{
538
548
        struct slap_control *sc;
 
549
        int rc = LDAP_SUCCESS;
539
550
 
540
551
        sc = find_ctrl( control->ldctl_oid );
541
552
        if( sc != NULL ) {
591
602
 
592
603
                if (( sc->sc_mask & tagmask ) == tagmask ) {
593
604
                        /* available extension */
594
 
                        int     rc;
 
605
                        if ( sc->sc_parse ) {
 
606
                                rc = sc->sc_parse( op, rs, control );
 
607
                                assert( rc != LDAP_UNAVAILABLE_CRITICAL_EXTENSION );
595
608
 
596
 
                        if( !sc->sc_parse ) {
 
609
                        } else if ( control->ldctl_iscritical ) {
597
610
                                *text = "not yet implemented";
598
 
                                return LDAP_OTHER;
599
 
                        }
600
 
 
601
 
                        rc = sc->sc_parse( op, rs, control );
602
 
                        if ( rc ) {
603
 
                                assert( rc != LDAP_UNAVAILABLE_CRITICAL_EXTENSION );
604
 
                                return rc;
605
 
                        }
606
 
 
607
 
                } else if( control->ldctl_iscritical ) {
 
611
                                rc = LDAP_OTHER;
 
612
                        }
 
613
 
 
614
 
 
615
                } else if ( control->ldctl_iscritical ) {
608
616
                        /* unavailable CRITICAL control */
609
617
                        *text = "critical extension is unavailable";
610
 
                        return LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
 
618
                        rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
611
619
                }
612
 
        } else if( control->ldctl_iscritical ) {
 
620
 
 
621
        } else if ( control->ldctl_iscritical ) {
613
622
                /* unrecognized CRITICAL control */
614
623
                *text = "critical extension is not recognized";
615
 
                return LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
 
624
                rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
616
625
        }
617
626
 
618
 
        return LDAP_SUCCESS;
 
627
        return rc;
619
628
}
620
629
 
621
630
int get_ctrls(
629
638
        char *opaque;
630
639
        BerElement *ber = op->o_ber;
631
640
        struct berval bv;
 
641
#ifdef SLAP_CONTROL_X_WHATFAILED
 
642
        /* NOTE: right now, slapd checks the validity of each control
 
643
         * while parsing.  As a consequence, it can only detect one
 
644
         * cause of failure at a time.  This results in returning
 
645
         * exactly one OID with the whatFailed control, or no control
 
646
         * at all.
 
647
         */
 
648
        char *failed_oid = NULL;
 
649
#endif
632
650
 
633
651
        len = ber_pvt_ber_remaining(ber);
634
652
 
769
787
 
770
788
                rs->sr_err = slap_parse_ctrl( op, rs, c, &rs->sr_text );
771
789
                if ( rs->sr_err != LDAP_SUCCESS ) {
 
790
#ifdef SLAP_CONTROL_X_WHATFAILED
 
791
                        failed_oid = c->ldctl_oid;
 
792
#endif
772
793
                        goto return_results;
773
794
                }
774
795
        }
784
805
                        send_ldap_disconnect( op, rs );
785
806
                        rs->sr_err = SLAPD_DISCONNECT;
786
807
                } else {
 
808
#ifdef SLAP_CONTROL_X_WHATFAILED
 
809
                        /* might have not been parsed yet? */
 
810
                        if ( failed_oid != NULL ) {
 
811
                                if ( !get_whatFailed( op ) ) {
 
812
                                        /* look it up */
 
813
 
 
814
                                        /* step through each remaining element */
 
815
                                        for ( ; tag != LBER_ERROR; tag = ber_next_element( ber, &len, opaque ) )
 
816
                                        {
 
817
                                                LDAPControl c = { 0 };
 
818
 
 
819
                                                tag = ber_scanf( ber, "{m" /*}*/, &bv );
 
820
                                                c.ldctl_oid = bv.bv_val;
 
821
 
 
822
                                                if ( tag == LBER_ERROR ) {
 
823
                                                        slap_free_ctrls( op, op->o_ctrls );
 
824
                                                        op->o_ctrls = NULL;
 
825
                                                        break;
 
826
 
 
827
                                                } else if ( c.ldctl_oid == NULL ) {
 
828
                                                        slap_free_ctrls( op, op->o_ctrls );
 
829
                                                        op->o_ctrls = NULL;
 
830
                                                        break;
 
831
                                                }
 
832
 
 
833
                                                tag = ber_peek_tag( ber, &len );
 
834
                                                if ( tag == LBER_BOOLEAN ) {
 
835
                                                        ber_int_t crit;
 
836
                                                        tag = ber_scanf( ber, "b", &crit );
 
837
                                                        if( tag == LBER_ERROR ) {
 
838
                                                                slap_free_ctrls( op, op->o_ctrls );
 
839
                                                                op->o_ctrls = NULL;
 
840
                                                                break;
 
841
                                                        }
 
842
 
 
843
                                                        tag = ber_peek_tag( ber, &len );
 
844
                                                }
 
845
 
 
846
                                                if ( tag == LBER_OCTETSTRING ) {
 
847
                                                        tag = ber_scanf( ber, "m", &c.ldctl_value );
 
848
 
 
849
                                                        if( tag == LBER_ERROR ) {
 
850
                                                                slap_free_ctrls( op, op->o_ctrls );
 
851
                                                                op->o_ctrls = NULL;
 
852
                                                                break;
 
853
                                                        }
 
854
                                                }
 
855
 
 
856
                                                if ( strcmp( c.ldctl_oid, LDAP_CONTROL_X_WHATFAILED ) == 0 ) {
 
857
                                                        const char *text;
 
858
                                                        slap_parse_ctrl( op, rs, &c, &text );
 
859
                                                        break;
 
860
                                                }
 
861
                                        }
 
862
                                }
 
863
 
 
864
                                if ( get_whatFailed( op ) ) {
 
865
                                        char *oids[ 2 ];
 
866
                                        oids[ 0 ] = failed_oid;
 
867
                                        oids[ 1 ] = NULL;
 
868
                                        slap_ctrl_whatFailed_add( op, rs, oids );
 
869
                                }
 
870
                        }
 
871
#endif
 
872
 
787
873
                        send_ldap_result( op, rs );
788
874
                }
789
875
        }
875
961
                return LDAP_PROTOCOL_ERROR;
876
962
        }
877
963
 
878
 
        if ( !ctrl->ldctl_iscritical ) {
 
964
        if ( ( global_disallows & SLAP_DISALLOW_DONTUSECOPY_N_CRIT )
 
965
                && !ctrl->ldctl_iscritical )
 
966
        {
879
967
                rs->sr_text = "dontUseCopy criticality of FALSE not allowed";
880
968
                return LDAP_PROTOCOL_ERROR;
881
969
        }
882
970
 
883
 
        op->o_dontUseCopy = SLAP_CONTROL_CRITICAL;
 
971
        op->o_dontUseCopy = ctrl->ldctl_iscritical
 
972
                ? SLAP_CONTROL_CRITICAL
 
973
                : SLAP_CONTROL_NONCRITICAL;
 
974
 
884
975
        return LDAP_SUCCESS;
885
976
}
886
977
 
946
1037
                return LDAP_PROTOCOL_ERROR;
947
1038
        }
948
1039
 
 
1040
        if ( ( global_disallows & SLAP_DISALLOW_PROXY_AUTHZ_N_CRIT )
 
1041
                && !ctrl->ldctl_iscritical )
 
1042
        {
 
1043
                rs->sr_text = "proxied authorization criticality of FALSE not allowed";
 
1044
                return LDAP_PROTOCOL_ERROR;
 
1045
        }
 
1046
 
949
1047
        if ( !( global_allows & SLAP_ALLOW_PROXY_AUTHZ_ANON )
950
1048
                && BER_BVISEMPTY( &op->o_ndn ) )
951
1049
        {
1112
1210
    If the page size is greater than or equal to the sizeLimit value, the
1113
1211
    server should ignore the control as the request can be satisfied in a
1114
1212
    single page.
1115
 
         
 
1213
 
1116
1214
         * NOTE: this assumes that the op->ors_slimit be set
1117
1215
         * before the controls are parsed.     
1118
1216
         */
1119
 
                
 
1217
 
1120
1218
        if ( op->ors_slimit > 0 && size >= op->ors_slimit ) {
1121
1219
                op->o_pagedresults = SLAP_CONTROL_IGNORED;
1122
1220
 
1192
1290
                rs->sr_text = "assert control: internal error";
1193
1291
                return LDAP_OTHER;
1194
1292
        }
1195
 
        
 
1293
 
1196
1294
        rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion),
1197
1295
                &rs->sr_text);
1198
1296
        (void) ber_free( ber, 1 );
1205
1303
                        send_ldap_result( op, rs );
1206
1304
                }
1207
1305
                if( op->o_assertion != NULL ) {
1208
 
                        filter_free_x( op, op->o_assertion );
 
1306
                        filter_free_x( op, op->o_assertion, 1 );
1209
1307
                }
1210
1308
                return rs->sr_err;
1211
1309
        }
1226
1324
        return LDAP_SUCCESS;
1227
1325
}
1228
1326
 
1229
 
static int parsePreRead (
1230
 
        Operation *op,
1231
 
        SlapReply *rs,
1232
 
        LDAPControl *ctrl )
1233
 
{
1234
 
        ber_len_t siz, off, i;
1235
 
        AttributeName *an = NULL;
1236
 
        BerElement      *ber;
1237
 
 
1238
 
        if ( op->o_preread != SLAP_CONTROL_NONE ) {
1239
 
                rs->sr_text = "preread control specified multiple times";
1240
 
                return LDAP_PROTOCOL_ERROR;
1241
 
        }
1242
 
 
1243
 
        if ( BER_BVISNULL( &ctrl->ldctl_value )) {
1244
 
                rs->sr_text = "preread control value is absent";
1245
 
                return LDAP_PROTOCOL_ERROR;
1246
 
        }
1247
 
 
1248
 
        if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
1249
 
                rs->sr_text = "preread control value is empty";
1250
 
                return LDAP_PROTOCOL_ERROR;
1251
 
        }
1252
 
 
1253
 
#ifdef LDAP_X_TXN
1254
 
        if ( op->o_txnSpec ) { /* temporary limitation */
1255
 
                rs->sr_text = "cannot perform pre-read in transaction";
1256
 
                return LDAP_UNWILLING_TO_PERFORM;
1257
 
        }
1258
 
#endif
1259
 
 
1260
 
        ber = ber_init( &(ctrl->ldctl_value) );
1261
 
        if (ber == NULL) {
1262
 
                rs->sr_text = "preread control: internal error";
1263
 
                return LDAP_OTHER;
1264
 
        }
1265
 
 
1266
 
        rs->sr_err = LDAP_SUCCESS;
1267
 
 
1268
 
        siz = sizeof( AttributeName );
1269
 
        off = offsetof( AttributeName, an_name );
1270
 
        if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
1271
 
                rs->sr_text = "preread control: decoding error";
1272
 
                rs->sr_err = LDAP_PROTOCOL_ERROR;
1273
 
                goto done;
1274
 
        }
1275
 
 
1276
 
        for( i=0; i<siz; i++ ) {
1277
 
                const char      *dummy = NULL;
1278
 
 
1279
 
                an[i].an_desc = NULL;
1280
 
                an[i].an_oc = NULL;
1281
 
                an[i].an_oc_exclude = 0;
1282
 
                rs->sr_err = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
1283
 
                if ( rs->sr_err != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
1284
 
                        rs->sr_text = dummy
1285
 
                                ? dummy
1286
 
                                : "postread control: unknown attributeType";
1287
 
                        goto done;
1288
 
                }
1289
 
        }
1290
 
 
1291
 
        op->o_preread = ctrl->ldctl_iscritical
1292
 
                ? SLAP_CONTROL_CRITICAL
1293
 
                : SLAP_CONTROL_NONCRITICAL;
1294
 
 
1295
 
        op->o_preread_attrs = an;
1296
 
 
1297
 
done:
1298
 
        (void) ber_free( ber, 1 );
1299
 
        return rs->sr_err;
1300
 
}
1301
 
 
1302
 
static int parsePostRead (
1303
 
        Operation *op,
1304
 
        SlapReply *rs,
1305
 
        LDAPControl *ctrl )
1306
 
{
1307
 
        ber_len_t siz, off, i;
1308
 
        AttributeName *an = NULL;
1309
 
        BerElement      *ber;
1310
 
 
1311
 
        if ( op->o_postread != SLAP_CONTROL_NONE ) {
1312
 
                rs->sr_text = "postread control specified multiple times";
1313
 
                return LDAP_PROTOCOL_ERROR;
1314
 
        }
1315
 
 
1316
 
        if ( BER_BVISNULL( &ctrl->ldctl_value )) {
1317
 
                rs->sr_text = "postread control value is absent";
1318
 
                return LDAP_PROTOCOL_ERROR;
1319
 
        }
1320
 
 
1321
 
        if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
1322
 
                rs->sr_text = "postread control value is empty";
1323
 
                return LDAP_PROTOCOL_ERROR;
1324
 
        }
1325
 
 
1326
 
#ifdef LDAP_X_TXN
1327
 
        if ( op->o_txnSpec ) { /* temporary limitation */
1328
 
                rs->sr_text = "cannot perform post-read in transaction";
1329
 
                return LDAP_UNWILLING_TO_PERFORM;
1330
 
        }
1331
 
#endif
1332
 
 
1333
 
        ber = ber_init( &(ctrl->ldctl_value) );
1334
 
        if (ber == NULL) {
1335
 
                rs->sr_text = "postread control: internal error";
1336
 
                return LDAP_OTHER;
1337
 
        }
1338
 
 
1339
 
        rs->sr_err = LDAP_SUCCESS;
1340
 
        siz = sizeof( AttributeName );
1341
 
        off = offsetof( AttributeName, an_name );
1342
 
        if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
1343
 
                rs->sr_text = "postread control: decoding error";
 
1327
#define READMSG(post, msg) \
 
1328
        ( post ? "postread control: " msg : "preread control: " msg )
 
1329
 
 
1330
static int
 
1331
parseReadAttrs(
 
1332
        Operation *op,
 
1333
        SlapReply *rs,
 
1334
        LDAPControl *ctrl,
 
1335
        int post )
 
1336
{
 
1337
        ber_len_t       siz, off, i;
 
1338
        BerElement      *ber;
 
1339
        AttributeName   *an = NULL;
 
1340
 
 
1341
        if ( ( post && op->o_postread != SLAP_CONTROL_NONE ) ||
 
1342
                ( !post && op->o_preread != SLAP_CONTROL_NONE ) )
 
1343
        {
 
1344
                rs->sr_text = READMSG( post, "specified multiple times" );
 
1345
                return LDAP_PROTOCOL_ERROR;
 
1346
        }
 
1347
 
 
1348
        if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
 
1349
                rs->sr_text = READMSG( post, "value is absent" );
 
1350
                return LDAP_PROTOCOL_ERROR;
 
1351
        }
 
1352
 
 
1353
        if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
 
1354
                rs->sr_text = READMSG( post, "value is empty" );
 
1355
                return LDAP_PROTOCOL_ERROR;
 
1356
        }
 
1357
 
 
1358
#ifdef LDAP_X_TXN
 
1359
        if ( op->o_txnSpec ) { /* temporary limitation */
 
1360
                rs->sr_text = READMSG( post, "cannot perform in transaction" );
 
1361
                return LDAP_UNWILLING_TO_PERFORM;
 
1362
        }
 
1363
#endif
 
1364
 
 
1365
        ber = ber_init( &ctrl->ldctl_value );
 
1366
        if ( ber == NULL ) {
 
1367
                rs->sr_text = READMSG( post, "internal error" );
 
1368
                return LDAP_OTHER;
 
1369
        }
 
1370
 
 
1371
        rs->sr_err = LDAP_SUCCESS;
 
1372
        siz = sizeof( AttributeName );
 
1373
        off = offsetof( AttributeName, an_name );
 
1374
        if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
 
1375
                rs->sr_text = READMSG( post, "decoding error" );
1344
1376
                rs->sr_err = LDAP_PROTOCOL_ERROR;
1345
1377
                goto done;
1346
1378
        }
1353
1385
                an[i].an_oc = NULL;
1354
1386
                an[i].an_oc_exclude = 0;
1355
1387
                rc = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
1356
 
                if ( rc != LDAP_SUCCESS ) {
1357
 
                        int                     i;
 
1388
                if ( rc == LDAP_SUCCESS ) {
 
1389
                        an[i].an_name = an[i].an_desc->ad_cname;
 
1390
 
 
1391
                } else {
 
1392
                        int                     j;
1358
1393
                        static struct berval    special_attrs[] = {
1359
1394
                                BER_BVC( LDAP_NO_ATTRS ),
1360
1395
                                BER_BVC( LDAP_ALL_USER_ATTRIBUTES ),
1363
1398
                        };
1364
1399
 
1365
1400
                        /* deal with special attribute types */
1366
 
                        for ( i = 0; !BER_BVISNULL( &special_attrs[ i ] ); i++ ) {
1367
 
                                if ( bvmatch( &an[i].an_name, &special_attrs[ i ] ) ) {
 
1401
                        for ( j = 0; !BER_BVISNULL( &special_attrs[ j ] ); j++ ) {
 
1402
                                if ( bvmatch( &an[i].an_name, &special_attrs[ j ] ) ) {
 
1403
                                        an[i].an_name = special_attrs[ j ];
1368
1404
                                        break;
1369
1405
                                }
1370
1406
                        }
1371
1407
 
1372
 
                        if ( BER_BVISNULL( &special_attrs[ i ] ) && ctrl->ldctl_iscritical ) {
 
1408
                        if ( BER_BVISNULL( &special_attrs[ j ] ) && ctrl->ldctl_iscritical ) {
1373
1409
                                rs->sr_err = rc;
1374
 
                                rs->sr_text = dummy
1375
 
                                        ? dummy
1376
 
                                        : "postread control: unknown attributeType";
 
1410
                                rs->sr_text = dummy ? dummy
 
1411
                                        : READMSG( post, "unknown attributeType" );
1377
1412
                                goto done;
1378
1413
                        }
1379
1414
                }
1380
1415
        }
1381
1416
 
1382
 
        op->o_postread = ctrl->ldctl_iscritical
1383
 
                ? SLAP_CONTROL_CRITICAL
1384
 
                : SLAP_CONTROL_NONCRITICAL;
1385
 
 
1386
 
        op->o_postread_attrs = an;
 
1417
        if ( post ) {
 
1418
                op->o_postread_attrs = an;
 
1419
                op->o_postread = ctrl->ldctl_iscritical
 
1420
                        ? SLAP_CONTROL_CRITICAL
 
1421
                        : SLAP_CONTROL_NONCRITICAL;
 
1422
        } else {
 
1423
                op->o_preread_attrs = an;
 
1424
                op->o_preread = ctrl->ldctl_iscritical
 
1425
                        ? SLAP_CONTROL_CRITICAL
 
1426
                        : SLAP_CONTROL_NONCRITICAL;
 
1427
        }
1387
1428
 
1388
1429
done:
1389
1430
        (void) ber_free( ber, 1 );
1390
1431
        return rs->sr_err;
1391
1432
}
1392
1433
 
 
1434
static int parsePreRead (
 
1435
        Operation *op,
 
1436
        SlapReply *rs,
 
1437
        LDAPControl *ctrl )
 
1438
{
 
1439
        return parseReadAttrs( op, rs, ctrl, 0 );
 
1440
}
 
1441
 
 
1442
static int parsePostRead (
 
1443
        Operation *op,
 
1444
        SlapReply *rs,
 
1445
        LDAPControl *ctrl )
 
1446
{
 
1447
        return parseReadAttrs( op, rs, ctrl, 1 );
 
1448
}
 
1449
 
1393
1450
static int parseValuesReturnFilter (
1394
1451
        Operation *op,
1395
1452
        SlapReply *rs,
1418
1475
                rs->sr_text = "internal error";
1419
1476
                return LDAP_OTHER;
1420
1477
        }
1421
 
        
 
1478
 
1422
1479
        rs->sr_err = get_vrFilter( op, ber,
1423
1480
                (ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
1424
1481
 
1906
1963
        return slap_ctrl_session_tracking_add( op, rs, &ip, &name, &id, ctrl );
1907
1964
}
1908
1965
#endif
 
1966
 
 
1967
#ifdef SLAP_CONTROL_X_WHATFAILED
 
1968
static int parseWhatFailed(
 
1969
        Operation *op,
 
1970
        SlapReply *rs,
 
1971
        LDAPControl *ctrl )
 
1972
{
 
1973
        if ( op->o_whatFailed != SLAP_CONTROL_NONE ) {
 
1974
                rs->sr_text = "\"WHat Failed?\" control specified multiple times";
 
1975
                return LDAP_PROTOCOL_ERROR;
 
1976
        }
 
1977
 
 
1978
        if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
 
1979
                rs->sr_text = "\"What Failed?\" control value not absent";
 
1980
                return LDAP_PROTOCOL_ERROR;
 
1981
        }
 
1982
 
 
1983
        op->o_whatFailed = ctrl->ldctl_iscritical
 
1984
                ? SLAP_CONTROL_CRITICAL
 
1985
                : SLAP_CONTROL_NONCRITICAL;
 
1986
 
 
1987
        return LDAP_SUCCESS;
 
1988
}
 
1989
 
 
1990
int
 
1991
slap_ctrl_whatFailed_add(
 
1992
        Operation *op,
 
1993
        SlapReply *rs,
 
1994
        char **oids )
 
1995
{
 
1996
        BerElementBuffer berbuf;
 
1997
        BerElement *ber = (BerElement *) &berbuf;
 
1998
        LDAPControl **ctrls = NULL;
 
1999
        struct berval ctrlval;
 
2000
        int i, rc = LDAP_SUCCESS;
 
2001
 
 
2002
        ber_init2( ber, NULL, LBER_USE_DER );
 
2003
        ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
 
2004
        ber_printf( ber, "[" /*]*/ );
 
2005
        for ( i = 0; oids[ i ] != NULL; i++ ) {
 
2006
                ber_printf( ber, "s", oids[ i ] );
 
2007
        }
 
2008
        ber_printf( ber, /*[*/ "]" );
 
2009
 
 
2010
        if ( ber_flatten2( ber, &ctrlval, 0 ) == -1 ) {
 
2011
                rc = LDAP_OTHER;
 
2012
                goto done;
 
2013
        }
 
2014
 
 
2015
        i = 0;
 
2016
        if ( rs->sr_ctrls != NULL ) {
 
2017
                for ( ; rs->sr_ctrls[ i ] != NULL; i++ ) {
 
2018
                        if ( strcmp( rs->sr_ctrls[ i ]->ldctl_oid, LDAP_CONTROL_X_WHATFAILED ) != 0 ) {
 
2019
                                /* TODO: add */
 
2020
                                assert( 0 );
 
2021
                        }
 
2022
                }
 
2023
        }
 
2024
 
 
2025
        ctrls = op->o_tmprealloc( rs->sr_ctrls,
 
2026
                        sizeof(LDAPControl *)*( i + 2 )
 
2027
                        + sizeof(LDAPControl)
 
2028
                        + ctrlval.bv_len + 1,
 
2029
                        op->o_tmpmemctx );
 
2030
        if ( ctrls == NULL ) {
 
2031
                rc = LDAP_OTHER;
 
2032
                goto done;
 
2033
        }
 
2034
        ctrls[ i + 1 ] = NULL;
 
2035
        ctrls[ i ] = (LDAPControl *)&ctrls[ i + 2 ];
 
2036
        ctrls[ i ]->ldctl_oid = LDAP_CONTROL_X_WHATFAILED;
 
2037
        ctrls[ i ]->ldctl_iscritical = 0;
 
2038
        ctrls[ i ]->ldctl_value.bv_val = (char *)&ctrls[ i ][ 1 ];
 
2039
        AC_MEMCPY( ctrls[ i ]->ldctl_value.bv_val, ctrlval.bv_val, ctrlval.bv_len + 1 );
 
2040
        ctrls[ i ]->ldctl_value.bv_len = ctrlval.bv_len;
 
2041
 
 
2042
        ber_free_buf( ber );
 
2043
 
 
2044
        rs->sr_ctrls = ctrls;
 
2045
 
 
2046
done:;
 
2047
        return rc;
 
2048
}
 
2049
#endif