Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/lib/tldap.c

    r414 r745  
    1919
    2020#include "includes.h"
     21
     22
     23
     24
     25
     26
    2127
    2228bool tevent_req_is_ldap_error(struct tevent_req *req, int *perr)
     
    419425        }
    420426
    421         state->iov.iov_base = blob.data;
     427        state->iov.iov_base = blob.data;
    422428        state->iov.iov_len = blob.length;
    423429
     
    506512
    507513        /*
    508          * We're the first ones, add the read_ldap request that waits for the
     514         * We're the first one, add the read_ldap request that waits for the
    509515         * answer from the server
    510516         */
     
    555561        struct tevent_req *req;
    556562        struct tldap_msg_state *state;
    557         struct tevent_context *ev;
    558563        struct asn1_data *data;
    559564        uint8_t *inbuf;
     
    614619        state->data = talloc_move(state, &data);
    615620
    616         ev = state->ev;
    617 
    618621        talloc_set_destructor(req, NULL);
    619622        tldap_msg_unset_pending(req);
     
    734737{
    735738        char *result = talloc_array(mem_ctx, char, blob.length+1);
     739
     740
     741
     742
     743
    736744        memcpy(result, blob.data, blob.length);
    737745        result[blob.length] = '\0';
     
    741749static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
    742750                                         struct asn1_data *data,
    743                                          char **result)
     751                                         char **result)
    744752{
    745753        DATA_BLOB string;
     754
    746755        if (!asn1_read_OctetString(data, mem_ctx, &string))
    747756                return false;
    748         *result = blob2string_talloc(mem_ctx, string);
     757
     758        result = blob2string_talloc(mem_ctx, string);
     759
    749760        data_blob_free(&string);
     761
     762
     763
     764
     765
    750766        return true;
    751767}
     
    869885int tldap_sasl_bind_recv(struct tevent_req *req)
    870886{
    871         int err;
    872 
    873         if (tevent_req_is_ldap_error(req, &err)) {
    874                 return err;
    875         }
    876         return TLDAP_SUCCESS;
     887        return tldap_simple_recv(req);
    877888}
    878889
     
    957968/*****************************************************************************/
    958969
    959 /*
    960  * This piece has a dependency on ldb, the ldb_parse_tree() function is used.
    961  * In case we want to separate out tldap, we need to copy or rewrite it.
     970/* can't use isalpha() as only a strict set is valid for LDAP */
     971
     972static bool tldap_is_alpha(char c)
     973{
     974        return (((c >= 'a') && (c <= 'z')) || \
     975                ((c >= 'A') && (c <= 'Z')));
     976}
     977
     978static bool tldap_is_adh(char c)
     979{
     980        return tldap_is_alpha(c) || isdigit(c) || (c == '-');
     981}
     982
     983#define TLDAP_FILTER_AND  ASN1_CONTEXT(0)
     984#define TLDAP_FILTER_OR   ASN1_CONTEXT(1)
     985#define TLDAP_FILTER_NOT  ASN1_CONTEXT(2)
     986#define TLDAP_FILTER_EQ   ASN1_CONTEXT(3)
     987#define TLDAP_FILTER_SUB  ASN1_CONTEXT(4)
     988#define TLDAP_FILTER_LE   ASN1_CONTEXT(5)
     989#define TLDAP_FILTER_GE   ASN1_CONTEXT(6)
     990#define TLDAP_FILTER_PRES ASN1_CONTEXT_SIMPLE(7)
     991#define TLDAP_FILTER_APX  ASN1_CONTEXT(8)
     992#define TLDAP_FILTER_EXT  ASN1_CONTEXT(9)
     993
     994#define TLDAP_SUB_INI ASN1_CONTEXT_SIMPLE(0)
     995#define TLDAP_SUB_ANY ASN1_CONTEXT_SIMPLE(1)
     996#define TLDAP_SUB_FIN ASN1_CONTEXT_SIMPLE(2)
     997
     998
     999/* oid's should be numerical only in theory,
     1000 * but apparently some broken servers may have alphanum aliases instead.
     1001 * Do like openldap libraries and allow alphanum aliases for oids, but
     1002 * do not allow Tagging options in that case.
    9621003 */
    963 
    964 #include "lib/ldb/include/ldb.h"
    965 #include "lib/ldb/include/ldb_errors.h"
    966 
    967 static bool ldap_push_filter(struct asn1_data *data,
    968                              struct ldb_parse_tree *tree)
    969 {
     1004static bool tldap_is_attrdesc(const char *s, int len, bool no_tagopts)
     1005{
     1006        bool is_oid = false;
     1007        bool dot = false;
    9701008        int i;
    9711009
    972         switch (tree->operation) {
    973         case LDB_OP_AND:
    974         case LDB_OP_OR:
    975                 asn1_push_tag(data,
    976                               ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1));
    977                 for (i=0; i<tree->u.list.num_elements; i++) {
    978                         if (!ldap_push_filter(data,
    979                                               tree->u.list.elements[i])) {
     1010        /* first char has stricter rules */
     1011        if (isdigit(*s)) {
     1012                is_oid = true;
     1013        } else if (!tldap_is_alpha(*s)) {
     1014                /* bad first char */
     1015                return false;
     1016        }
     1017
     1018        for (i = 1; i < len; i++) {
     1019
     1020                if (is_oid) {
     1021                        if (isdigit(s[i])) {
     1022                                dot = false;
     1023                                continue;
     1024                        }
     1025                        if (s[i] == '.') {
     1026                                if (dot) {
     1027                                        /* malformed */
     1028                                        return false;
     1029                                }
     1030                                dot = true;
     1031                                continue;
     1032                        }
     1033                } else {
     1034                        if (tldap_is_adh(s[i])) {
     1035                                continue;
     1036                        }
     1037                }
     1038
     1039                if (s[i] == ';') {
     1040                        if (no_tagopts) {
     1041                                /* no tagging options */
    9801042                                return false;
    9811043                        }
     1044
     1045
     1046
     1047
     1048
     1049
     1050
     1051
     1052
     1053
     1054
     1055
     1056
     1057
     1058
     1059
     1060
     1061
     1062
     1063
     1064
     1065
     1066
     1067
     1068
     1069
     1070
     1071
     1072
     1073
     1074
     1075
     1076
     1077
     1078
     1079
     1080
     1081
     1082
     1083
     1084
     1085
     1086
     1087
     1088
     1089
     1090
     1091
     1092
     1093
     1094
     1095
     1096
     1097
     1098
     1099
     1100
     1101
     1102
     1103
     1104
     1105
     1106
     1107
     1108
     1109
     1110
     1111
     1112
     1113
     1114
     1115
     1116
     1117
     1118
     1119
     1120
     1121
     1122
     1123
     1124
     1125
     1126
     1127
     1128
     1129
     1130
     1131
     1132
     1133
     1134
     1135
     1136
     1137
     1138
     1139
     1140
     1141
     1142
     1143
     1144
     1145
     1146
     1147
     1148
     1149
     1150
     1151
     1152
     1153
     1154
     1155
     1156
     1157
     1158
     1159
     1160
     1161
     1162
     1163
     1164
     1165
     1166
     1167
     1168
     1169
     1170
     1171
     1172
     1173
     1174
     1175
     1176
     1177
     1178
     1179
     1180
     1181
     1182
     1183
     1184
     1185
     1186
     1187
     1188
     1189
     1190
     1191
     1192
     1193
     1194
     1195
     1196
     1197
     1198
     1199
     1200
     1201
     1202
     1203
     1204
     1205
     1206
     1207
     1208
     1209
     1210
     1211
     1212
     1213
     1214
     1215
     1216
     1217
     1218
     1219
     1220
     1221
     1222
     1223
     1224
     1225
     1226
     1227
     1228
     1229
     1230
     1231
     1232
     1233
     1234
     1235
     1236
     1237
     1238
     1239
     1240
     1241
     1242
    9821243                }
    9831244                asn1_pop_tag(data);
    984                 break;
    985 
    986         case LDB_OP_NOT:
    987                 asn1_push_tag(data, ASN1_CONTEXT(2));
    988                 if (!ldap_push_filter(data, tree->u.isnot.child)) {
     1245                goto done;
     1246
     1247        case '(':
     1248        case ')':
     1249                tldap_debug(ld, TLDAP_DEBUG_ERROR,
     1250                            "Invalid parenthesis '%c'\n", *s);
     1251                return false;
     1252
     1253        case '\0':
     1254                tldap_debug(ld, TLDAP_DEBUG_ERROR,
     1255                            "Invalid filter termination\n");
     1256                return false;
     1257
     1258        default:
     1259                ret = tldap_push_filter_basic(ld, data, &s);
     1260                if (!ret) {
    9891261                        return false;
    9901262                }
     1263
     1264
     1265
     1266
     1267
     1268
     1269
     1270
    9911271                asn1_pop_tag(data);
    992                 break;
    993 
    994         case LDB_OP_EQUALITY:
    995                 /* equality test */
    996                 asn1_push_tag(data, ASN1_CONTEXT(3));
    997                 asn1_write_OctetString(data, tree->u.equality.attr,
    998                                       strlen(tree->u.equality.attr));
    999                 asn1_write_OctetString(data, tree->u.equality.value.data,
    1000                                       tree->u.equality.value.length);
    1001                 asn1_pop_tag(data);
    1002                 break;
    1003 
    1004         case LDB_OP_SUBSTRING:
    1005                 /*
    1006                   SubstringFilter ::= SEQUENCE {
    1007                           type            AttributeDescription,
    1008                           -- at least one must be present
    1009                           substrings      SEQUENCE OF CHOICE {
    1010                                   initial [0] LDAPString,
    1011                                   any     [1] LDAPString,
    1012                                   final   [2] LDAPString } }
    1013                 */
    1014                 asn1_push_tag(data, ASN1_CONTEXT(4));
    1015                 asn1_write_OctetString(data, tree->u.substring.attr,
    1016                                        strlen(tree->u.substring.attr));
    1017                 asn1_push_tag(data, ASN1_SEQUENCE(0));
    1018                 i = 0;
    1019                 if (!tree->u.substring.start_with_wildcard) {
    1020                         asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
    1021                         asn1_write_DATA_BLOB_LDAPString(
    1022                                 data, tree->u.substring.chunks[i]);
     1272                goto done;
     1273        }
     1274
     1275        while (*s) {
     1276                ret = tldap_push_filter_int(ld, data, &s);
     1277                if (!ret) {
     1278                        return false;
     1279                }
     1280
     1281                if (*s == ')') {
     1282                        /* end of list, return */
    10231283                        asn1_pop_tag(data);
    1024                         i++;
    1025                 }
    1026                 while (tree->u.substring.chunks[i]) {
    1027                         int ctx;
    1028 
    1029                         if ((!tree->u.substring.chunks[i + 1]) &&
    1030                             (tree->u.substring.end_with_wildcard == 0)) {
    1031                                 ctx = 2;
     1284                        break;
     1285                }
     1286        }
     1287
     1288done:
     1289        if (*s != ')') {
     1290                tldap_debug(ld, TLDAP_DEBUG_ERROR,
     1291                            "Incomplete or malformed filter\n");
     1292                return false;
     1293        }
     1294        s++;
     1295
     1296        if (data->has_error) {
     1297                return false;
     1298        }
     1299
     1300        *_s = s;
     1301        return true;
     1302}
     1303
     1304
     1305static bool tldap_push_filter_basic(struct tldap_context *ld,
     1306                                    struct asn1_data *data,
     1307                                    const char **_s)
     1308{
     1309        TALLOC_CTX *tmpctx = talloc_tos();
     1310        const char *s = *_s;
     1311        const char *e;
     1312        const char *eq;
     1313        const char *val;
     1314        const char *type;
     1315        const char *dn;
     1316        const char *rule;
     1317        const char *star;
     1318        size_t type_len = 0;
     1319        char *uval;
     1320        size_t uval_len;
     1321        bool write_octect = true;
     1322        bool ret;
     1323
     1324        eq = strchr(s, '=');
     1325        if (!eq) {
     1326                tldap_debug(ld, TLDAP_DEBUG_ERROR,
     1327                            "Invalid filter, missing equal sign\n");
     1328                return false;
     1329        }
     1330
     1331        val = eq + 1;
     1332        e = eq - 1;
     1333
     1334        switch (*e) {
     1335        case '<':
     1336                asn1_push_tag(data, TLDAP_FILTER_LE);
     1337                break;
     1338
     1339        case '>':
     1340                asn1_push_tag(data, TLDAP_FILTER_GE);
     1341                break;
     1342
     1343        case '~':
     1344                asn1_push_tag(data, TLDAP_FILTER_APX);
     1345                break;
     1346
     1347        case ':':
     1348                asn1_push_tag(data, TLDAP_FILTER_EXT);
     1349                write_octect = false;
     1350
     1351                type = NULL;
     1352                dn = NULL;
     1353                rule = NULL;
     1354
     1355                if (*s == ':') { /* [:dn]:rule:= value */
     1356                        if (s == e) {
     1357                                /* malformed filter */
     1358                                return false;
     1359                        }
     1360                        dn = s;
     1361                } else { /* type[:dn][:rule]:= value */
     1362                        type = s;
     1363                        dn = strchr(s, ':');
     1364                        type_len = dn - type;
     1365                        if (dn == e) { /* type:= value */
     1366                                dn = NULL;
     1367                        }
     1368                }
     1369                if (dn) {
     1370                        dn++;
     1371
     1372                        rule = strchr(dn, ':');
     1373                        if ((rule == dn + 1) || rule + 1 == e) {
     1374                                /* malformed filter, contains "::" */
     1375                                return false;
     1376                        }
     1377
     1378                        if (StrnCaseCmp(dn, "dn:", 3) != 0) {
     1379                                if (rule == e) {
     1380                                        rule = dn;
     1381                                        dn = NULL;
     1382                                } else {
     1383                                        /* malformed filter. With two
     1384                                         * optionals, the first must be "dn"
     1385                                         */
     1386                                        return false;
     1387                                }
    10321388                        } else {
    1033                                 ctx = 1;
     1389                                if (rule == e) {
     1390                                        rule = NULL;
     1391                                } else {
     1392                                        rule++;
     1393                                }
    10341394                        }
    1035                         asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx));
    1036                         asn1_write_DATA_BLOB_LDAPString(
    1037                                 data, tree->u.substring.chunks[i]);
    1038                         asn1_pop_tag(data);
    1039                         i++;
    1040                 }
    1041                 asn1_pop_tag(data);
    1042                 asn1_pop_tag(data);
    1043                 break;
    1044 
    1045         case LDB_OP_GREATER:
    1046                 /* greaterOrEqual test */
    1047                 asn1_push_tag(data, ASN1_CONTEXT(5));
    1048                 asn1_write_OctetString(data, tree->u.comparison.attr,
    1049                                       strlen(tree->u.comparison.attr));
    1050                 asn1_write_OctetString(data, tree->u.comparison.value.data,
    1051                                       tree->u.comparison.value.length);
    1052                 asn1_pop_tag(data);
    1053                 break;
    1054 
    1055         case LDB_OP_LESS:
    1056                 /* lessOrEqual test */
    1057                 asn1_push_tag(data, ASN1_CONTEXT(6));
    1058                 asn1_write_OctetString(data, tree->u.comparison.attr,
    1059                                       strlen(tree->u.comparison.attr));
    1060                 asn1_write_OctetString(data, tree->u.comparison.value.data,
    1061                                       tree->u.comparison.value.length);
    1062                 asn1_pop_tag(data);
    1063                 break;
    1064 
    1065         case LDB_OP_PRESENT:
    1066                 /* present test */
    1067                 asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7));
    1068                 asn1_write_LDAPString(data, tree->u.present.attr);
    1069                 asn1_pop_tag(data);
    1070                 return !data->has_error;
    1071 
    1072         case LDB_OP_APPROX:
    1073                 /* approx test */
    1074                 asn1_push_tag(data, ASN1_CONTEXT(8));
    1075                 asn1_write_OctetString(data, tree->u.comparison.attr,
    1076                                       strlen(tree->u.comparison.attr));
    1077                 asn1_write_OctetString(data, tree->u.comparison.value.data,
    1078                                       tree->u.comparison.value.length);
    1079                 asn1_pop_tag(data);
    1080                 break;
    1081 
    1082         case LDB_OP_EXTENDED:
     1395                }
     1396
     1397                if (!type && !dn && !rule) {
     1398                        /* malformed filter, there must be at least one */
     1399                        return false;
     1400                }
     1401
    10831402                /*
    10841403                  MatchingRuleAssertion ::= SEQUENCE {
    10851404                  matchingRule    [1] MatchingRuleID OPTIONAL,
    1086                   type            [2] AttributeDescription OPTIONAL,
     1405                  type    [2] AttributeDescription OPTIONAL,
    10871406                  matchValue      [3] AssertionValue,
    10881407                  dnAttributes    [4] BOOLEAN DEFAULT FALSE
    10891408                  }
    10901409                */
    1091                 asn1_push_tag(data, ASN1_CONTEXT(9));
    1092                 if (tree->u.extended.rule_id) {
     1410
     1411                /* check and add rule */
     1412                if (rule) {
     1413                        ret = tldap_is_attrdesc(rule, e - rule, true);
     1414                        if (!ret) {
     1415                                return false;
     1416                        }
    10931417                        asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1));
    1094                         asn1_write_LDAPString(data, tree->u.extended.rule_id);
     1418                        asn1_write);
    10951419                        asn1_pop_tag(data);
    10961420                }
    1097                 if (tree->u.extended.attr) {
     1421
     1422                /* check and add type */
     1423                if (type) {
     1424                        ret = tldap_is_attrdesc(type, type_len, false);
     1425                        if (!ret) {
     1426                                return false;
     1427                        }
    10981428                        asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2));
    1099                         asn1_write_LDAPString(data, tree->u.extended.attr);
     1429                        asn1_write);
    11001430                        asn1_pop_tag(data);
    11011431                }
     1432
     1433
     1434
     1435
     1436
     1437
     1438
     1439
     1440
     1441
     1442
    11021443                asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3));
    1103                 asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value);
     1444                asn1_write);
    11041445                asn1_pop_tag(data);
     1446
    11051447                asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4));
    1106                 asn1_write_uint8(data, tree->u.extended.dnAttributes);
     1448                asn1_write_uint8(data, );
    11071449                asn1_pop_tag(data);
     1450
     1451
     1452
     1453
     1454
     1455
     1456
     1457
     1458
     1459
     1460
     1461
     1462
     1463
     1464
     1465
     1466
     1467
     1468
     1469
     1470
     1471
     1472
     1473
     1474
     1475
     1476
     1477
     1478
     1479
     1480
     1481
     1482
     1483
     1484
     1485
     1486
     1487
     1488
     1489
     1490
     1491
     1492
     1493
     1494
     1495
     1496
     1497
     1498
     1499
     1500
     1501
     1502
     1503
     1504
     1505
     1506
     1507
     1508
     1509
     1510
     1511
     1512
     1513
     1514
     1515
     1516
     1517
     1518
     1519
     1520
     1521
     1522
     1523
     1524
     1525
     1526
     1527
     1528
     1529
     1530
     1531
     1532
     1533
     1534
     1535
     1536
     1537
     1538
     1539
     1540
     1541
     1542
     1543
     1544
     1545
     1546
     1547
     1548
     1549
     1550
     1551
     1552
     1553
     1554
     1555
     1556
     1557
     1558
     1559
     1560
     1561
     1562
     1563
     1564
     1565
     1566
     1567
     1568
     1569
     1570
     1571
     1572
     1573
     1574
     1575
     1576
     1577
     1578
     1579
     1580
     1581
     1582
     1583
     1584
     1585
     1586
     1587
     1588
     1589
     1590
     1591
     1592
     1593
    11081594                asn1_pop_tag(data);
    1109                 break;
    1110 
    1111         default:
     1595
     1596                val = star + 1;
     1597
     1598        } while (*star == '*');
     1599
     1600        *_s = star;
     1601
     1602        /* end of sequence */
     1603        asn1_pop_tag(data);
     1604        return true;
     1605}
     1606
     1607/* NOTE: although openldap libraries allow for spaces in some places, mosly
     1608 * around parenthesis, we do not allow any spaces (except in values of
     1609 * course) as I couldn't fine any place in RFC 4512 or RFC 4515 where
     1610 * leading or trailing spaces where allowed.
     1611 */
     1612static bool tldap_push_filter(struct tldap_context *ld,
     1613                              struct asn1_data *data,
     1614                              const char *filter)
     1615{
     1616        const char *s = filter;
     1617        bool ret;
     1618
     1619        ret = tldap_push_filter_int(ld, data, &s);
     1620        if (ret && *s) {
     1621                tldap_debug(ld, TLDAP_DEBUG_ERROR,
     1622                            "Incomplete or malformed filter\n");
    11121623                return false;
    11131624        }
    1114         return !data->has_error;
    1115 }
    1116 
    1117 static bool tldap_push_filter(struct asn1_data *data, const char *filter)
    1118 {
    1119         struct ldb_parse_tree *tree;
    1120         bool ret;
    1121 
    1122         tree = ldb_parse_tree(talloc_tos(), filter);
    1123         if (tree == NULL) {
    1124                 return false;
    1125         }
    1126         ret = ldap_push_filter(data, tree);
    1127         TALLOC_FREE(tree);
    11281625        return ret;
    11291626}
     
    11661663        asn1_write_BOOLEAN(state->out, attrsonly);
    11671664
    1168         if (!tldap_push_filter(state->out, filter)) {
     1665        if (!tldap_push_filter(state->out, filter)) {
    11691666                goto encoding_error;
    11701667        }
     
    13451842        tevent_req_set_callback(req, tldap_search_cb, &state);
    13461843
     1844
     1845
     1846
     1847
     1848
     1849
     1850
    13471851        while (tevent_req_is_in_progress(req)
    13481852               && (state.rc == TLDAP_SUCCESS)) {
     
    14551959}
    14561960
    1457 bool tldap_entry_attributes(struct tldap_message *msg, int *num_attributes,
    1458                             struct tldap_attribute **attributes)
     1961bool tldap_entry_attributes(struct tldap_message *msg,
     1962                            struct tldap_attribute **attributes,
     1963                            int *num_attributes)
    14591964{
    14601965        if ((msg->dn == NULL) && (!tldap_parse_search_entry(msg))) {
     
    16282133
    16292134int tldap_add(struct tldap_context *ld, const char *dn,
    1630               int num_attributes, struct tldap_mod *attributes,
     2135              attributes,
    16312136              struct tldap_control *sctrls, int num_sctrls,
    16322137              struct tldap_control *cctrls, int num_cctrls)
     
    16682173                                     struct tldap_context *ld,
    16692174                                     const char *dn,
    1670                                      int num_mods, struct tldap_mod *mods,
     2175                                     mods,
    16712176                                     struct tldap_control *sctrls,
    16722177                                     int num_sctrls,
     
    17282233
    17292234int tldap_modify(struct tldap_context *ld, const char *dn,
    1730                  int num_mods, struct tldap_mod *mods,
     2235                 mods,
    17312236                 struct tldap_control *sctrls, int num_sctrls,
    17322237                 struct tldap_control *cctrls, int num_cctrls)
     
    17432248        }
    17442249
    1745         req = tldap_modify_send(frame, ev, ld, dn, num_mods, mods,
     2250        req = tldap_modify_send(frame, ev, ld, dn, mods,
    17462251                                sctrls, num_sctrls, cctrls, num_cctrls);
    17472252        if (req == NULL) {
     
    18782383                *sctrls = NULL;
    18792384                *num_sctrls = 0;
     2385
    18802386        }
    18812387        *sctrls = msg->res_sctrls;
Note: See TracChangeset for help on using the changeset viewer.