Changeset 740 for vendor/current/source3/lib/tldap.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/lib/tldap.c
r414 r740 19 19 20 20 #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 26 static int tldap_simple_recv(struct tevent_req *req); 21 27 22 28 bool tevent_req_is_ldap_error(struct tevent_req *req, int *perr) … … 419 425 } 420 426 421 state->iov.iov_base = blob.data;427 state->iov.iov_base = (void *)blob.data; 422 428 state->iov.iov_len = blob.length; 423 429 … … 506 512 507 513 /* 508 * We're the first one s, add the read_ldap request that waits for the514 * We're the first one, add the read_ldap request that waits for the 509 515 * answer from the server 510 516 */ … … 555 561 struct tevent_req *req; 556 562 struct tldap_msg_state *state; 557 struct tevent_context *ev;558 563 struct asn1_data *data; 559 564 uint8_t *inbuf; … … 614 619 state->data = talloc_move(state, &data); 615 620 616 ev = state->ev;617 618 621 talloc_set_destructor(req, NULL); 619 622 tldap_msg_unset_pending(req); … … 734 737 { 735 738 char *result = talloc_array(mem_ctx, char, blob.length+1); 739 740 if (result == NULL) { 741 return NULL; 742 } 743 736 744 memcpy(result, blob.data, blob.length); 737 745 result[blob.length] = '\0'; … … 741 749 static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, 742 750 struct asn1_data *data, 743 char ** result)751 char **presult) 744 752 { 745 753 DATA_BLOB string; 754 char *result; 746 755 if (!asn1_read_OctetString(data, mem_ctx, &string)) 747 756 return false; 748 *result = blob2string_talloc(mem_ctx, string); 757 758 result = blob2string_talloc(mem_ctx, string); 759 749 760 data_blob_free(&string); 761 762 if (result == NULL) { 763 return false; 764 } 765 *presult = result; 750 766 return true; 751 767 } … … 869 885 int tldap_sasl_bind_recv(struct tevent_req *req) 870 886 { 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); 877 888 } 878 889 … … 957 968 /*****************************************************************************/ 958 969 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 972 static bool tldap_is_alpha(char c) 973 { 974 return (((c >= 'a') && (c <= 'z')) || \ 975 ((c >= 'A') && (c <= 'Z'))); 976 } 977 978 static 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. 962 1003 */ 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 { 1004 static bool tldap_is_attrdesc(const char *s, int len, bool no_tagopts) 1005 { 1006 bool is_oid = false; 1007 bool dot = false; 970 1008 int i; 971 1009 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 */ 980 1042 return false; 981 1043 } 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. */ 1067 static 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 1090 static 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 1110 static 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 1149 static 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 1200 static bool tldap_push_filter_basic(struct tldap_context *ld, 1201 struct asn1_data *data, 1202 const char **_s); 1203 static bool tldap_push_filter_substring(struct tldap_context *ld, 1204 struct asn1_data *data, 1205 const char *val, 1206 const char **_s); 1207 static 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; 982 1243 } 983 1244 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) { 989 1261 return false; 990 1262 } 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 */ 991 1271 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 */ 1023 1283 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 1288 done: 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 1305 static 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 } 1032 1388 } else { 1033 ctx = 1; 1389 if (rule == e) { 1390 rule = NULL; 1391 } else { 1392 rule++; 1393 } 1034 1394 } 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 1083 1402 /* 1084 1403 MatchingRuleAssertion ::= SEQUENCE { 1085 1404 matchingRule [1] MatchingRuleID OPTIONAL, 1086 type 1405 type [2] AttributeDescription OPTIONAL, 1087 1406 matchValue [3] AssertionValue, 1088 1407 dnAttributes [4] BOOLEAN DEFAULT FALSE 1089 1408 } 1090 1409 */ 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 } 1093 1417 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); 1095 1419 asn1_pop_tag(data); 1096 1420 } 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 } 1098 1428 asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); 1099 asn1_write _LDAPString(data, tree->u.extended.attr);1429 asn1_write(data, type, type_len); 1100 1430 asn1_pop_tag(data); 1101 1431 } 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 1102 1443 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); 1104 1445 asn1_pop_tag(data); 1446 1105 1447 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); 1107 1449 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 1514 static 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); 1108 1594 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 */ 1612 static 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"); 1112 1623 return false; 1113 1624 } 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);1128 1625 return ret; 1129 1626 } … … 1166 1663 asn1_write_BOOLEAN(state->out, attrsonly); 1167 1664 1168 if (!tldap_push_filter( state->out, filter)) {1665 if (!tldap_push_filter(ld, state->out, filter)) { 1169 1666 goto encoding_error; 1170 1667 } … … 1345 1842 tevent_req_set_callback(req, tldap_search_cb, &state); 1346 1843 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 1347 1851 while (tevent_req_is_in_progress(req) 1348 1852 && (state.rc == TLDAP_SUCCESS)) { … … 1455 1959 } 1456 1960 1457 bool tldap_entry_attributes(struct tldap_message *msg, int *num_attributes, 1458 struct tldap_attribute **attributes) 1961 bool tldap_entry_attributes(struct tldap_message *msg, 1962 struct tldap_attribute **attributes, 1963 int *num_attributes) 1459 1964 { 1460 1965 if ((msg->dn == NULL) && (!tldap_parse_search_entry(msg))) { … … 1628 2133 1629 2134 int 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, 1631 2136 struct tldap_control *sctrls, int num_sctrls, 1632 2137 struct tldap_control *cctrls, int num_cctrls) … … 1668 2173 struct tldap_context *ld, 1669 2174 const char *dn, 1670 int num_mods, struct tldap_mod *mods,2175 struct tldap_mod *mods, int num_mods, 1671 2176 struct tldap_control *sctrls, 1672 2177 int num_sctrls, … … 1728 2233 1729 2234 int 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, 1731 2236 struct tldap_control *sctrls, int num_sctrls, 1732 2237 struct tldap_control *cctrls, int num_cctrls) … … 1743 2248 } 1744 2249 1745 req = tldap_modify_send(frame, ev, ld, dn, num_mods,mods,2250 req = tldap_modify_send(frame, ev, ld, dn, mods, num_mods, 1746 2251 sctrls, num_sctrls, cctrls, num_cctrls); 1747 2252 if (req == NULL) { … … 1878 2383 *sctrls = NULL; 1879 2384 *num_sctrls = 0; 2385 return; 1880 2386 } 1881 2387 *sctrls = msg->res_sctrls;
Note:
See TracChangeset
for help on using the changeset viewer.