Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/lib/tldap.c

    r414 r740  
    1919
    2020#include "includes.h"
     21#include "tldap.h"
     22#include "../lib/util/asn1.h"
     23#include "../lib/tsocket/tsocket.h"
     24#include "../lib/util/tevent_unix.h"
     25
     26static int tldap_simple_recv(struct tevent_req *req);
    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 = (void *)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        if (result == NULL) {
     741                return NULL;
     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 **presult)
    744752{
    745753        DATA_BLOB string;
     754        char *result;
    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        if (result == NULL) {
     763                return false;
     764        }
     765        *presult = result;
    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                        if (dot) {
     1045                                /* malformed */
     1046                                return false;
     1047                        }
     1048                        if ((i + 1) == len) {
     1049                                /* malformed */
     1050                                return false;
     1051                        }
     1052
     1053                        is_oid = false;
     1054                        continue;
     1055                }
     1056        }
     1057
     1058        if (dot) {
     1059                /* malformed */
     1060                return false;
     1061        }
     1062
     1063        return true;
     1064}
     1065
     1066/* this function copies the value until the closing parenthesis is found. */
     1067static char *tldap_get_val(TALLOC_CTX *memctx,
     1068                           const char *value, const char **_s)
     1069{
     1070        const char *s = value;
     1071
     1072        /* find terminator */
     1073        while (*s) {
     1074                s = strchr(s, ')');
     1075                if (s && (*(s - 1) == '\\')) {
     1076                        continue;
     1077                }
     1078                break;
     1079        }
     1080        if (!s || !(*s == ')')) {
     1081                /* malformed filter */
     1082                return NULL;
     1083        }
     1084
     1085        *_s = s;
     1086
     1087        return talloc_strndup(memctx, value, s - value);
     1088}
     1089
     1090static int tldap_hex2char(const char *x)
     1091{
     1092        if (isxdigit(x[0]) && isxdigit(x[1])) {
     1093                const char h1 = x[0], h2 = x[1];
     1094                int c = 0;
     1095
     1096                if (h1 >= 'a') c = h1 - (int)'a' + 10;
     1097                else if (h1 >= 'A') c = h1 - (int)'A' + 10;
     1098                else if (h1 >= '0') c = h1 - (int)'0';
     1099                c = c << 4;
     1100                if (h2 >= 'a') c += h2 - (int)'a' + 10;
     1101                else if (h2 >= 'A') c += h2 - (int)'A' + 10;
     1102                else if (h2 >= '0') c += h2 - (int)'0';
     1103
     1104                return c;
     1105        }
     1106
     1107        return -1;
     1108}
     1109
     1110static bool tldap_find_first_star(const char *val, const char **star)
     1111{
     1112        const char *s;
     1113
     1114        for (s = val; *s; s++) {
     1115                switch (*s) {
     1116                case '\\':
     1117                        if (isxdigit(s[1]) && isxdigit(s[2])) {
     1118                                s += 2;
     1119                                break;
     1120                        }
     1121                        /* not hex based escape, check older syntax */
     1122                        switch (s[1]) {
     1123                        case '(':
     1124                        case ')':
     1125                        case '*':
     1126                        case '\\':
     1127                                s++;
     1128                                break;
     1129                        default:
     1130                                /* invalid escape sequence */
     1131                                return false;
     1132                        }
     1133                        break;
     1134                case ')':
     1135                        /* end of val, nothing found */
     1136                        *star = s;
     1137                        return true;
     1138
     1139                case '*':
     1140                        *star = s;
     1141                        return true;
     1142                }
     1143        }
     1144
     1145        /* string ended without closing parenthesis, filter is malformed */
     1146        return false;
     1147}
     1148
     1149static bool tldap_unescape_inplace(char *value, size_t *val_len)
     1150{
     1151        int c, i, p;
     1152
     1153        for (i = 0,p = 0; i < *val_len; i++) {
     1154
     1155                switch (value[i]) {
     1156                case '(':
     1157                case ')':
     1158                case '*':
     1159                        /* these must be escaped */
     1160                        return false;
     1161
     1162                case '\\':
     1163                        if (!value[i + 1]) {
     1164                                /* invalid EOL */
     1165                                return false;
     1166                        }
     1167                        i++;
     1168
     1169                        c = tldap_hex2char(&value[i]);
     1170                        if (c >= 0 && c < 256) {
     1171                                value[p] = c;
     1172                                i++;
     1173                                p++;
     1174                                break;
     1175                        }
     1176
     1177                        switch (value[i]) {
     1178                        case '(':
     1179                        case ')':
     1180                        case '*':
     1181                        case '\\':
     1182                                value[p] = value[i];
     1183                                p++;
     1184                        default:
     1185                                /* invalid */
     1186                                return false;
     1187                        }
     1188                        break;
     1189
     1190                default:
     1191                        value[p] = value[i];
     1192                        p++;
     1193                }
     1194        }
     1195        value[p] = '\0';
     1196        *val_len = p;
     1197        return true;
     1198}
     1199
     1200static bool tldap_push_filter_basic(struct tldap_context *ld,
     1201                                    struct asn1_data *data,
     1202                                    const char **_s);
     1203static bool tldap_push_filter_substring(struct tldap_context *ld,
     1204                                        struct asn1_data *data,
     1205                                        const char *val,
     1206                                        const char **_s);
     1207static bool tldap_push_filter_int(struct tldap_context *ld,
     1208                                  struct asn1_data *data,
     1209                                  const char **_s)
     1210{
     1211        const char *s = *_s;
     1212        bool ret;
     1213
     1214        if (*s != '(') {
     1215                tldap_debug(ld, TLDAP_DEBUG_ERROR,
     1216                            "Incomplete or malformed filter\n");
     1217                return false;
     1218        }
     1219        s++;
     1220
     1221        /* we are right after a parenthesis,
     1222         * find out what op we have at hand */
     1223        switch (*s) {
     1224        case '&':
     1225                tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: AND\n");
     1226                asn1_push_tag(data, TLDAP_FILTER_AND);
     1227                s++;
     1228                break;
     1229
     1230        case '|':
     1231                tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: OR\n");
     1232                asn1_push_tag(data, TLDAP_FILTER_OR);
     1233                s++;
     1234                break;
     1235
     1236        case '!':
     1237                tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: NOT\n");
     1238                asn1_push_tag(data, TLDAP_FILTER_NOT);
     1239                s++;
     1240                ret = tldap_push_filter_int(ld, data, &s);
     1241                if (!ret) {
     1242                        return false;
    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                goto done;
     1264        }
     1265
     1266        /* only and/or filters get here.
     1267         * go through the list of filters */
     1268
     1269        if (*s == ')') {
     1270                /* RFC 4526: empty and/or */
    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(data, rule, e - rule);
    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(data, type, type_len);
    11001430                        asn1_pop_tag(data);
    11011431                }
     1432
     1433                uval = tldap_get_val(tmpctx, val, _s);
     1434                if (!uval) {
     1435                        return false;
     1436                }
     1437                uval_len = *_s - val;
     1438                ret = tldap_unescape_inplace(uval, &uval_len);
     1439                if (!ret) {
     1440                        return false;
     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(data, uval, uval_len);
    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, dn?1:0);
    11071449                asn1_pop_tag(data);
     1450                break;
     1451
     1452        default:
     1453                e = eq;
     1454
     1455                ret = tldap_is_attrdesc(s, e - s, false);
     1456                if (!ret) {
     1457                        return false;
     1458                }
     1459
     1460                if (strncmp(val, "*)", 2) == 0) {
     1461                        /* presence */
     1462                        asn1_push_tag(data, TLDAP_FILTER_PRES);
     1463                        asn1_write(data, s, e - s);
     1464                        *_s = val + 1;
     1465                        write_octect = false;
     1466                        break;
     1467                }
     1468
     1469                ret = tldap_find_first_star(val, &star);
     1470                if (!ret) {
     1471                        return false;
     1472                }
     1473                if (*star == '*') {
     1474                        /* substring */
     1475                        asn1_push_tag(data, TLDAP_FILTER_SUB);
     1476                        asn1_write_OctetString(data, s, e - s);
     1477                        ret = tldap_push_filter_substring(ld, data, val, &s);
     1478                        if (!ret) {
     1479                                return false;
     1480                        }
     1481                        *_s = s;
     1482                        write_octect = false;
     1483                        break;
     1484                }
     1485
     1486                /* if nothing else, then it is just equality */
     1487                asn1_push_tag(data, TLDAP_FILTER_EQ);
     1488                write_octect = true;
     1489                break;
     1490        }
     1491
     1492        if (write_octect) {
     1493                uval = tldap_get_val(tmpctx, val, _s);
     1494                if (!uval) {
     1495                        return false;
     1496                }
     1497                uval_len = *_s - val;
     1498                ret = tldap_unescape_inplace(uval, &uval_len);
     1499                if (!ret) {
     1500                        return false;
     1501                }
     1502
     1503                asn1_write_OctetString(data, s, e - s);
     1504                asn1_write_OctetString(data, uval, uval_len);
     1505        }
     1506
     1507        if (data->has_error) {
     1508                return false;
     1509        }
     1510        asn1_pop_tag(data);
     1511        return true;
     1512}
     1513
     1514static bool tldap_push_filter_substring(struct tldap_context *ld,
     1515                                        struct asn1_data *data,
     1516                                        const char *val,
     1517                                        const char **_s)
     1518{
     1519        TALLOC_CTX *tmpctx = talloc_tos();
     1520        bool initial = true;
     1521        const char *star;
     1522        char *chunk;
     1523        size_t chunk_len;
     1524        bool ret;
     1525
     1526        /*
     1527          SubstringFilter ::= SEQUENCE {
     1528                  type      AttributeDescription,
     1529                  -- at least one must be present
     1530                  substrings      SEQUENCE OF CHOICE {
     1531                          initial [0] LDAPString,
     1532                          any     [1] LDAPString,
     1533                          final   [2] LDAPString } }
     1534        */
     1535        asn1_push_tag(data, ASN1_SEQUENCE(0));
     1536
     1537        do {
     1538                ret = tldap_find_first_star(val, &star);
     1539                if (!ret) {
     1540                        return false;
     1541                }
     1542                chunk_len = star - val;
     1543
     1544                switch (*star) {
     1545                case '*':
     1546                        if (!initial && chunk_len == 0) {
     1547                                /* found '**', which is illegal */
     1548                                return false;
     1549                        }
     1550                        break;
     1551                case ')':
     1552                        if (initial) {
     1553                                /* no stars ?? */
     1554                                return false;
     1555                        }
     1556                        /* we are done */
     1557                        break;
     1558                default:
     1559                        /* ?? */
     1560                        return false;
     1561                }
     1562
     1563                if (initial && chunk_len == 0) {
     1564                        val = star + 1;
     1565                        initial = false;
     1566                        continue;
     1567                }
     1568
     1569                chunk = talloc_strndup(tmpctx, val, chunk_len);
     1570                if (!chunk) {
     1571                        return false;
     1572                }
     1573                ret = tldap_unescape_inplace(chunk, &chunk_len);
     1574                if (!ret) {
     1575                        return false;
     1576                }
     1577                switch (*star) {
     1578                case '*':
     1579                        if (initial) {
     1580                                asn1_push_tag(data, TLDAP_SUB_INI);
     1581                                initial = false;
     1582                        } else {
     1583                                asn1_push_tag(data, TLDAP_SUB_ANY);
     1584                        }
     1585                        break;
     1586                case ')':
     1587                        asn1_push_tag(data, TLDAP_SUB_FIN);
     1588                        break;
     1589                default:
     1590                        /* ?? */
     1591                        return false;
     1592                }
     1593                asn1_write(data, chunk, chunk_len);
    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(ld, state->out, filter)) {
    11691666                goto encoding_error;
    11701667        }
     
    13451842        tevent_req_set_callback(req, tldap_search_cb, &state);
    13461843
     1844        if (!tevent_req_is_in_progress(req)) {
     1845                /* an error happend before sending */
     1846                if (tevent_req_is_ldap_error(req, &state.rc)) {
     1847                        goto fail;
     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              struct tldap_mod *attributes, int num_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                                     struct tldap_mod *mods, int num_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                 struct tldap_mod *mods, int num_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, num_mods,
    17462251                                sctrls, num_sctrls, cctrls, num_cctrls);
    17472252        if (req == NULL) {
     
    18782383                *sctrls = NULL;
    18792384                *num_sctrls = 0;
     2385                return;
    18802386        }
    18812387        *sctrls = msg->res_sctrls;
Note: See TracChangeset for help on using the changeset viewer.