1 /* $NetBSD: rewrite-int.h,v 1.1.1.3 2010/12/12 15:22:13 adam Exp $ */ 2 3 /* OpenLDAP: pkg/ldap/libraries/librewrite/rewrite-int.h,v 1.20.2.6 2010/04/13 20:23:08 kurt Exp */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 2000-2010 The OpenLDAP Foundation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 /* ACKNOWLEDGEMENT: 18 * This work was initially developed by Pierangelo Masarati for 19 * inclusion in OpenLDAP Software. 20 */ 21 22 #ifndef REWRITE_INT_H 23 #define REWRITE_INT_H 24 25 /* 26 * These are required by every file of the library, so they're included here 27 */ 28 #include <ac/stdlib.h> 29 #include <ac/string.h> 30 #include <ac/syslog.h> 31 #include <ac/regex.h> 32 #include <ac/socket.h> 33 #include <ac/unistd.h> 34 #include <ac/ctype.h> 35 36 #include <lber.h> 37 #include <ldap.h> 38 #include "../libldap/ldap-int.h" 39 #include <lutil.h> 40 #include <avl.h> 41 42 #include <rewrite.h> 43 44 #define malloc(x) ber_memalloc(x) 45 #define calloc(x,y) ber_memcalloc(x,y) 46 #define realloc(x,y) ber_memrealloc(x,y) 47 #define free(x) ber_memfree(x) 48 #undef strdup 49 #define strdup(x) ber_strdup(x) 50 51 /* Uncomment to use ldap pvt threads */ 52 #define USE_REWRITE_LDAP_PVT_THREADS 53 #include <ldap_pvt_thread.h> 54 55 /* 56 * For details, see RATIONALE. 57 */ 58 59 #define REWRITE_MAX_MATCH 11 /* 0: overall string; 1-9: submatches */ 60 #define REWRITE_MAX_PASSES 100 61 62 /* 63 * Submatch escape char 64 */ 65 /* the '\' conflicts with slapd.conf parsing */ 66 /* #define REWRITE_SUBMATCH_ESCAPE '\\' */ 67 #define REWRITE_SUBMATCH_ESCAPE_ORIG '%' 68 #define REWRITE_SUBMATCH_ESCAPE '$' 69 #define IS_REWRITE_SUBMATCH_ESCAPE(c) \ 70 ((c) == REWRITE_SUBMATCH_ESCAPE || (c) == REWRITE_SUBMATCH_ESCAPE_ORIG) 71 72 /* 73 * REGEX flags 74 */ 75 76 #define REWRITE_FLAG_HONORCASE 'C' 77 #define REWRITE_FLAG_BASICREGEX 'R' 78 79 /* 80 * Action flags 81 */ 82 #define REWRITE_FLAG_EXECONCE ':' 83 #define REWRITE_FLAG_STOP '@' 84 #define REWRITE_FLAG_UNWILLING '#' 85 #define REWRITE_FLAG_GOTO 'G' /* requires an arg */ 86 #define REWRITE_FLAG_USER 'U' /* requires an arg */ 87 #define REWRITE_FLAG_MAX_PASSES 'M' /* requires an arg */ 88 #define REWRITE_FLAG_IGNORE_ERR 'I' 89 90 /* 91 * Map operators 92 */ 93 #define REWRITE_OPERATOR_SUBCONTEXT '>' 94 #define REWRITE_OPERATOR_COMMAND '|' 95 #define REWRITE_OPERATOR_VARIABLE_SET '&' 96 #define REWRITE_OPERATOR_VARIABLE_GET '*' 97 #define REWRITE_OPERATOR_PARAM_GET '$' 98 99 100 /*********** 101 * PRIVATE * 102 ***********/ 103 104 /* 105 * Action 106 */ 107 struct rewrite_action { 108 struct rewrite_action *la_next; 109 110 #define REWRITE_ACTION_STOP 0x0001 111 #define REWRITE_ACTION_UNWILLING 0x0002 112 #define REWRITE_ACTION_GOTO 0x0003 113 #define REWRITE_ACTION_IGNORE_ERR 0x0004 114 #define REWRITE_ACTION_USER 0x0005 115 int la_type; 116 void *la_args; 117 }; 118 119 /* 120 * Map 121 */ 122 struct rewrite_map { 123 124 /* 125 * Legacy stuff 126 */ 127 #define REWRITE_MAP_XFILEMAP 0x0001 /* Rough implementation! */ 128 #define REWRITE_MAP_XPWDMAP 0x0002 /* uid -> gecos */ 129 #define REWRITE_MAP_XLDAPMAP 0x0003 /* Not implemented yet! */ 130 131 /* 132 * Maps with args 133 */ 134 #define REWRITE_MAP_SUBCONTEXT 0x0101 135 136 #define REWRITE_MAP_SET_OP_VAR 0x0102 137 #define REWRITE_MAP_SETW_OP_VAR 0x0103 138 #define REWRITE_MAP_GET_OP_VAR 0x0104 139 #define REWRITE_MAP_SET_SESN_VAR 0x0105 140 #define REWRITE_MAP_SETW_SESN_VAR 0x0106 141 #define REWRITE_MAP_GET_SESN_VAR 0x0107 142 #define REWRITE_MAP_GET_PARAM 0x0108 143 #define REWRITE_MAP_BUILTIN 0x0109 144 int lm_type; 145 146 char *lm_name; 147 void *lm_data; 148 149 /* 150 * Old maps store private data in _lm_args; 151 * new maps store the substitution pattern in _lm_subst 152 */ 153 union { 154 void *_lm_args; 155 struct rewrite_subst *_lm_subst; 156 } lm_union; 157 #define lm_args lm_union._lm_args 158 #define lm_subst lm_union._lm_subst 159 160 #ifdef USE_REWRITE_LDAP_PVT_THREADS 161 ldap_pvt_thread_mutex_t lm_mutex; 162 #endif /* USE_REWRITE_LDAP_PVT_THREADS */ 163 }; 164 165 /* 166 * Builtin maps 167 */ 168 struct rewrite_builtin_map { 169 #define REWRITE_BUILTIN_MAP 0x0200 170 int lb_type; 171 char *lb_name; 172 void *lb_private; 173 const rewrite_mapper *lb_mapper; 174 175 #ifdef USE_REWRITE_LDAP_PVT_THREADS 176 ldap_pvt_thread_mutex_t lb_mutex; 177 #endif /* USE_REWRITE_LDAP_PVT_THREADS */ 178 }; 179 180 /* 181 * Submatch substitution 182 */ 183 struct rewrite_submatch { 184 #define REWRITE_SUBMATCH_ASIS 0x0000 185 #define REWRITE_SUBMATCH_XMAP 0x0001 186 #define REWRITE_SUBMATCH_MAP_W_ARG 0x0002 187 int ls_type; 188 struct rewrite_map *ls_map; 189 int ls_submatch; 190 /* 191 * The first one represents the index of the submatch in case 192 * the map has single submatch as argument; 193 * the latter represents the map argument scheme in case 194 * the map has substitution string argument form 195 */ 196 }; 197 198 /* 199 * Pattern substitution 200 */ 201 struct rewrite_subst { 202 size_t lt_subs_len; 203 struct berval *lt_subs; 204 205 int lt_num_submatch; 206 struct rewrite_submatch *lt_submatch; 207 }; 208 209 /* 210 * Rule 211 */ 212 struct rewrite_rule { 213 struct rewrite_rule *lr_next; 214 struct rewrite_rule *lr_prev; 215 216 char *lr_pattern; 217 char *lr_subststring; 218 char *lr_flagstring; 219 regex_t lr_regex; 220 221 /* 222 * I was thinking about some kind of per-rule mutex, but there's 223 * probably no need, because rules after compilation are only read; 224 * however, I need to check whether regexec is reentrant ... 225 */ 226 227 struct rewrite_subst *lr_subst; 228 229 #define REWRITE_REGEX_ICASE REG_ICASE 230 #define REWRITE_REGEX_EXTENDED REG_EXTENDED 231 int lr_flags; 232 233 #define REWRITE_RECURSE 0x0001 234 #define REWRITE_EXEC_ONCE 0x0002 235 int lr_mode; 236 int lr_max_passes; 237 238 struct rewrite_action *lr_action; 239 }; 240 241 /* 242 * Rewrite Context (set of rules) 243 */ 244 struct rewrite_context { 245 char *lc_name; 246 struct rewrite_context *lc_alias; 247 struct rewrite_rule *lc_rule; 248 }; 249 250 /* 251 * Session 252 */ 253 struct rewrite_session { 254 void *ls_cookie; 255 Avlnode *ls_vars; 256 #ifdef USE_REWRITE_LDAP_PVT_THREADS 257 ldap_pvt_thread_rdwr_t ls_vars_mutex; 258 ldap_pvt_thread_mutex_t ls_mutex; 259 #endif /* USE_REWRITE_LDAP_PVT_THREADS */ 260 int ls_count; 261 }; 262 263 /* 264 * Variable 265 */ 266 struct rewrite_var { 267 char *lv_name; 268 int lv_flags; 269 struct berval lv_value; 270 }; 271 272 /* 273 * Operation 274 */ 275 struct rewrite_op { 276 int lo_num_passes; 277 int lo_depth; 278 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */ 279 char *lo_string; 280 #endif 281 char *lo_result; 282 Avlnode *lo_vars; 283 const void *lo_cookie; 284 }; 285 286 287 /********** 288 * PUBLIC * 289 **********/ 290 291 /* 292 * Rewrite info 293 */ 294 struct rewrite_info { 295 Avlnode *li_context; 296 Avlnode *li_maps; 297 /* 298 * No global mutex because maps are read only at 299 * config time 300 */ 301 Avlnode *li_params; 302 Avlnode *li_cookies; 303 int li_num_cookies; 304 305 #ifdef USE_REWRITE_LDAP_PVT_THREADS 306 ldap_pvt_thread_rdwr_t li_params_mutex; 307 ldap_pvt_thread_rdwr_t li_cookies_mutex; 308 #endif /* USE_REWRITE_LDAP_PVT_THREADS */ 309 310 /* 311 * Default to `off'; 312 * use `rewriteEngine {on|off}' directive to alter 313 */ 314 int li_state; 315 316 /* 317 * Defaults to REWRITE_MAXPASSES; 318 * use `rewriteMaxPasses numPasses' directive to alter 319 */ 320 #define REWRITE_MAXPASSES 100 321 int li_max_passes; 322 int li_max_passes_per_rule; 323 324 /* 325 * Behavior in case a NULL or non-existent context is required 326 */ 327 int li_rewrite_mode; 328 }; 329 330 /*********** 331 * PRIVATE * 332 ***********/ 333 334 LDAP_REWRITE_V (struct rewrite_context*) rewrite_int_curr_context; 335 336 /* 337 * Maps 338 */ 339 340 /* 341 * Parses a map (also in legacy 'x' version) 342 */ 343 LDAP_REWRITE_F (struct rewrite_map *) 344 rewrite_map_parse( 345 struct rewrite_info *info, 346 const char *s, 347 const char **end 348 ); 349 350 LDAP_REWRITE_F (struct rewrite_map *) 351 rewrite_xmap_parse( 352 struct rewrite_info *info, 353 const char *s, 354 const char **end 355 ); 356 357 /* 358 * Resolves key in val by means of map (also in legacy 'x' version) 359 */ 360 LDAP_REWRITE_F (int) 361 rewrite_map_apply( 362 struct rewrite_info *info, 363 struct rewrite_op *op, 364 struct rewrite_map *map, 365 struct berval *key, 366 struct berval *val 367 ); 368 369 LDAP_REWRITE_F (int) 370 rewrite_xmap_apply( 371 struct rewrite_info *info, 372 struct rewrite_op *op, 373 struct rewrite_map *map, 374 struct berval *key, 375 struct berval *val 376 ); 377 378 LDAP_REWRITE_F (int) 379 rewrite_map_destroy( 380 struct rewrite_map **map 381 ); 382 383 LDAP_REWRITE_F (int) 384 rewrite_xmap_destroy( 385 struct rewrite_map **map 386 ); 387 388 LDAP_REWRITE_F (void) 389 rewrite_builtin_map_free( 390 void *map 391 ); 392 /* 393 * Submatch substitution 394 */ 395 396 /* 397 * Compiles a substitution pattern 398 */ 399 LDAP_REWRITE_F (struct rewrite_subst *) 400 rewrite_subst_compile( 401 struct rewrite_info *info, 402 const char *result 403 ); 404 405 /* 406 * Substitutes a portion of rewritten string according to substitution 407 * pattern using submatches 408 */ 409 LDAP_REWRITE_F (int) 410 rewrite_subst_apply( 411 struct rewrite_info *info, 412 struct rewrite_op *op, 413 struct rewrite_subst *subst, 414 const char *string, 415 const regmatch_t *match, 416 struct berval *val 417 ); 418 419 LDAP_REWRITE_F (int) 420 rewrite_subst_destroy( 421 struct rewrite_subst **subst 422 ); 423 424 425 /* 426 * Rules 427 */ 428 429 /* 430 * Compiles the rule and appends it at the running context 431 */ 432 LDAP_REWRITE_F (int) 433 rewrite_rule_compile( 434 struct rewrite_info *info, 435 struct rewrite_context *context, 436 const char *pattern, 437 const char *result, 438 const char *flagstring 439 ); 440 441 /* 442 * Rewrites string according to rule; may return: 443 * REWRITE_REGEXEC_OK: fine; if *result != NULL rule matched 444 * and rewrite succeeded. 445 * REWRITE_REGEXEC_STOP: fine, rule matched; stop processing 446 * following rules 447 * REWRITE_REGEXEC_UNWILL: rule matched; force 'unwilling to perform' 448 * REWRITE_REGEXEC_ERR: an error occurred 449 */ 450 LDAP_REWRITE_F (int) 451 rewrite_rule_apply( 452 struct rewrite_info *info, 453 struct rewrite_op *op, 454 struct rewrite_rule *rule, 455 const char *string, 456 char **result 457 ); 458 459 LDAP_REWRITE_F (int) 460 rewrite_rule_destroy( 461 struct rewrite_rule **rule 462 ); 463 464 /* 465 * Sessions 466 */ 467 468 /* 469 * Fetches a struct rewrite_session 470 */ 471 LDAP_REWRITE_F (struct rewrite_session *) 472 rewrite_session_find( 473 struct rewrite_info *info, 474 const void *cookie 475 ); 476 477 /* 478 * Defines and inits a variable with session scope 479 */ 480 LDAP_REWRITE_F (int) 481 rewrite_session_var_set_f( 482 struct rewrite_info *info, 483 const void *cookie, 484 const char *name, 485 const char *value, 486 int flags 487 ); 488 489 /* 490 * Gets a var with session scope 491 */ 492 LDAP_REWRITE_F (int) 493 rewrite_session_var_get( 494 struct rewrite_info *info, 495 const void *cookie, 496 const char *name, 497 struct berval *val 498 ); 499 500 /* 501 * Deletes a session 502 */ 503 LDAP_REWRITE_F (int) 504 rewrite_session_delete( 505 struct rewrite_info *info, 506 const void *cookie 507 ); 508 509 /* 510 * Destroys the cookie tree 511 */ 512 LDAP_REWRITE_F (int) 513 rewrite_session_destroy( 514 struct rewrite_info *info 515 ); 516 517 518 /* 519 * Vars 520 */ 521 522 /* 523 * Finds a var 524 */ 525 LDAP_REWRITE_F (struct rewrite_var *) 526 rewrite_var_find( 527 Avlnode *tree, 528 const char *name 529 ); 530 531 /* 532 * Replaces the value of a variable 533 */ 534 LDAP_REWRITE_F (int) 535 rewrite_var_replace( 536 struct rewrite_var *var, 537 const char *value, 538 int flags 539 ); 540 541 /* 542 * Inserts a newly created var 543 */ 544 LDAP_REWRITE_F (struct rewrite_var *) 545 rewrite_var_insert_f( 546 Avlnode **tree, 547 const char *name, 548 const char *value, 549 int flags 550 ); 551 552 #define rewrite_var_insert(tree, name, value) \ 553 rewrite_var_insert_f((tree), (name), (value), \ 554 REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE) 555 556 /* 557 * Sets/inserts a var 558 */ 559 LDAP_REWRITE_F (struct rewrite_var *) 560 rewrite_var_set_f( 561 Avlnode **tree, 562 const char *name, 563 const char *value, 564 int flags 565 ); 566 567 #define rewrite_var_set(tree, name, value, insert) \ 568 rewrite_var_set_f((tree), (name), (value), \ 569 REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0)) 570 571 /* 572 * Deletes a var tree 573 */ 574 LDAP_REWRITE_F (int) 575 rewrite_var_delete( 576 Avlnode *tree 577 ); 578 579 580 /* 581 * Contexts 582 */ 583 584 /* 585 * Finds the context named rewriteContext in the context tree 586 */ 587 LDAP_REWRITE_F (struct rewrite_context *) 588 rewrite_context_find( 589 struct rewrite_info *info, 590 const char *rewriteContext 591 ); 592 593 /* 594 * Creates a new context called rewriteContext and stores in into the tree 595 */ 596 LDAP_REWRITE_F (struct rewrite_context *) 597 rewrite_context_create( 598 struct rewrite_info *info, 599 const char *rewriteContext 600 ); 601 602 /* 603 * Rewrites string according to context; may return: 604 * OK: fine; if *result != NULL rule matched and rewrite succeeded. 605 * STOP: fine, rule matched; stop processing following rules 606 * UNWILL: rule matched; force 'unwilling to perform' 607 */ 608 LDAP_REWRITE_F (int) 609 rewrite_context_apply( 610 struct rewrite_info *info, 611 struct rewrite_op *op, 612 struct rewrite_context *context, 613 const char *string, 614 char **result 615 ); 616 617 LDAP_REWRITE_F (int) 618 rewrite_context_destroy( 619 struct rewrite_context **context 620 ); 621 622 LDAP_REWRITE_F (void) 623 rewrite_context_free( 624 void *tmp 625 ); 626 627 #endif /* REWRITE_INT_H */ 628 629