1 16 package com.sun.slamd.example; 17 18 19 20 import java.io.*; 21 import java.security.*; 22 import java.util.*; 23 import netscape.ldap.*; 24 import netscape.ldap.controls.*; 25 import netscape.ldap.factory.*; 26 import com.sun.slamd.job.*; 27 import com.sun.slamd.parameter.*; 28 import com.sun.slamd.stat.*; 29 30 31 32 44 public class TemplateBasedAddAndDelRateJobClass 45 extends JobClass 46 { 47 50 public static final String SSL_KEY_STORE_PROPERTY = 51 "javax.net.ssl.keyStore"; 52 53 54 55 58 public static final String SSL_KEY_PASSWORD_PROPERTY = 59 "javax.net.ssl.keyStorePassword"; 60 61 62 63 66 public static final String SSL_TRUST_STORE_PROPERTY = 67 "javax.net.ssl.trustStore"; 68 69 70 71 74 public static final String SSL_TRUST_PASSWORD_PROPERTY = 75 "javax.net.ssl.trustStorePassword"; 76 77 78 79 83 public static final String STAT_TRACKER_ADD_TIME = "Add Time (ms)"; 84 85 86 87 91 public static final String STAT_TRACKER_ADD_COUNT = "Adds Performed"; 92 93 94 95 99 public static final String STAT_TRACKER_ADD_TOTAL = "Total Adds"; 100 101 102 103 107 public static final String STAT_TRACKER_ADD_RESULT_CODES = "Add Result Codes"; 108 109 110 111 115 public static final String STAT_TRACKER_DELETE_TIME = "Delete Time (ms)"; 116 117 118 119 123 public static final String STAT_TRACKER_DELETE_COUNT = "Deletes Performed"; 124 125 126 127 131 public static final String STAT_TRACKER_DELETE_TOTAL = "Total Deletes"; 132 133 134 135 139 public static final String STAT_TRACKER_DELETE_RESULT_CODES = 140 "Delete Result Codes"; 141 142 143 144 147 public static final char[] NUMERIC_CHARS = "0123456789".toCharArray(); 148 149 150 151 154 public static final char[] ALPHA_CHARS = 155 "abcdefghijklmnopqrstuvwxyz".toCharArray(); 156 157 158 159 162 public static final char[] ALPHANUMERIC_CHARS = 163 "abcdefghijklmnopqrstuvwxyz0123456789".toCharArray(); 164 165 166 167 170 public static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); 171 172 173 174 177 public static final char[] BASE64_CHARS = 178 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + 179 "0123456789+/").toCharArray(); 180 181 182 183 186 public static final String [] MONTH_NAMES = 187 { 188 "January", 189 "February", 190 "March", 191 "April", 192 "May", 193 "June", 194 "July", 195 "August", 196 "September", 197 "October", 198 "November", 199 "December" 200 }; 201 202 203 204 207 public static final String [] DEFAULT_TEMPLATE_LINES = new String [] 208 { 209 "objectClass: top", 210 "objectClass: person", 211 "objectClass: organizationalPerson", 212 "objectClass: inetOrgPerson", 213 "employeeNumber: <entrynumber>", 214 "uid: user.{employeeNumber}", 215 "givenName: User", 216 "sn: {employeeNumber}", 217 "cn: User {sn}", 218 "initials: {givenName:1}{sn:1}", 219 "mail: {uid}@example.com", 220 "userPassword: password", 221 "telephoneNumber: <random:telephone>", 222 "mobile: <random:telephone>", 223 "pager: <random:telephone>", 224 "homePhone: <random:telephone>" 225 }; 226 227 228 229 BooleanParameter blindTrustParameter = 231 new BooleanParameter("blind_trust", "Blindly Trust Any Certificate", 232 "Indicates whether the client should blindly trust " + 233 "any certificate presented by the server, or " + 234 "whether the key and trust stores should be used.", 235 true); 236 237 BooleanParameter cleanTombstonesParameter = 240 new BooleanParameter("clean_tombstones", "Clean Up Tombstones", 241 "Indicates whether the client should clean up "+ 242 "tombstones that may be in the database after " + 243 "the delete has completed. This should only be " + 244 "used for improving the reliability of the " + 245 "testing in a replicated environment and should " + 246 "never be used in a production server.", false); 247 248 BooleanParameter disconnectParameter = 250 new BooleanParameter("disconnect", "Always Disconnect", 251 "Indicates whether to close the connection after " + 252 "each add", false); 253 254 BooleanParameter useSSLParameter = 256 new BooleanParameter("usessl", "Use SSL", 257 "Indicates whether SSL should be used for all " + 258 "communication with the directory server", false); 259 260 IntegerParameter delayParameter = 263 new IntegerParameter("delay", "Time Between Requests (ms)", 264 "Specifies the length of time in milliseconds " + 265 "each thread should wait between add " + 266 "requests. Note that this delay will be " + 267 "between consecutive requests and not between " + 268 "the response of one operation and the request " + 269 "for the next. If an add takes longer than " + 270 "this length of time, then there will be no delay.", 271 true, 0, true, 0, false, 0); 272 273 IntegerParameter deleteDelayParameter = 276 new IntegerParameter("delete_delay", "Time Between Adds and Deletes (s)", 277 "Specifies the length of time in seconds that " + 278 "the job should sleep after all threads have " + 279 "completed the add operations before starting to " + 280 "process the deletes.", true, 0, true, 0, false, 0); 281 282 IntegerParameter portParameter = 284 new IntegerParameter("ldapport", "Directory Server Port", 285 "The port number for the LDAP directory server", 286 true, 389, true, 1, true, 65535); 287 288 IntegerParameter startValueParameter = 290 new IntegerParameter("start_value", "Initial Entry Value Number", 291 "The number to use as the value of the " + 292 "entryNumber tag for the first entry to create", 293 true, 1, false, 0, false, 0); 294 295 IntegerParameter endValueParameter = 297 new IntegerParameter("end_value", "Final Entry Value Number", 298 "The number to use as the value of the " + 299 "entryNumber tag for the last entry to create", 300 false, 0, false, 0, false, 0); 301 302 IntegerParameter timeLimitParameter = 304 new IntegerParameter("time_limit", "Add Time Limit", 305 "The maximum length of time in seconds that the " + 306 "thread should wait for an operation to be " + 307 "performed before cancelling it and trying " + 308 "another.", false, 0, true, 0, false, 0); 309 310 IntegerParameter tombstoneDelayParameter = 313 new IntegerParameter("tombstone_delay", 314 "Delay Before Cleaning Tombstones (s)", 315 "Specifies the length of time in seconds that the " + 316 "job should wait after completing the deletes " + 317 "before starting the tombstone cleanup.", true, 30, 318 true, 0, false, 0); 319 320 MultiLineTextParameter templateParameter = 322 new MultiLineTextParameter("template", "Entry Template", 323 "The template to use when creating the " + 324 "entries. Consult the job reference guide " + 325 "for a description of the tags that may be " + 326 "used in the template", 327 DEFAULT_TEMPLATE_LINES, true); 328 329 PlaceholderParameter placeholder = new PlaceholderParameter(); 331 332 StringParameter bindDNParameter = 334 new StringParameter("binddn", "Bind DN", 335 "The DN to use to bind to the server", false, ""); 336 337 StringParameter baseDNParameter = 339 new StringParameter("basedn", "Base DN ", 340 "The base below which to add the entries", 341 true, ""); 342 343 StringParameter hostParameter = 345 new StringParameter("ldaphost", "Directory Server Host", 346 "The DNS hostname or IP address of the LDAP " + 347 "directory server", true, ""); 348 349 StringParameter proxyAsDNParameter = 351 new StringParameter("proxy_as_dn", "Proxy As DN", 352 "The DN of the user whose credentials should be " + 353 "used to perform the adds through the use " + 354 "of the proxied authorization control.", false, ""); 355 356 StringParameter rdnAttrParameter = 358 new StringParameter("rdn_attr", "RDN Attribute", 359 "The RDN attribute to use when creating the " + 360 "entries.", true, "uid"); 361 362 StringParameter keyStoreParameter = 364 new StringParameter("sslkeystore", "SSL Key Store", 365 "The path to the JSSE key store to use for an " + 366 "SSL-based connection", false, ""); 367 368 StringParameter trustStoreParameter = 370 new StringParameter("ssltruststore", "SSL Trust Store", 371 "The path to the JSSE trust store to use for an " + 372 "SSL-based connection", false, ""); 373 374 PasswordParameter bindPWParameter = 376 new PasswordParameter("bindpw", "Bind Password", 377 "The password for the bind DN", false, ""); 378 379 PasswordParameter keyPWParameter = 381 new PasswordParameter("sslkeypw", "SSL Key Store Password", 382 "The password for the JSSE key store", false, ""); 383 384 PasswordParameter trustPWParameter = 386 new PasswordParameter("ssltrustpw", "SSL Trust Store Password", 387 "The password for the JSSE trust store", false, ""); 388 389 390 static boolean alwaysDisconnect; 392 static boolean blindTrust; 393 static boolean cleanTombstones; 394 static boolean useProxyAuth; 395 static boolean useSSL; 396 static int deleteDelay; 397 static int endValue; 398 static int ldapPort; 399 static int nextValue; 400 static int startValue; 401 static int timeLimit; 402 static int tombstoneDelay; 403 static long delay; 404 static String baseDN; 405 static String bindDN; 406 static String bindPassword; 407 static String ldapHost; 408 static String lowerRDNAttr; 409 static String proxyAsDN; 410 static String rdnAttr; 411 static String sslKeyStore; 412 static String sslKeyPassword; 413 static String sslTrustStore; 414 static String sslTrustPassword; 415 static String [] attrNames; 416 static String [] attrValues; 417 static String [] lowerNames; 418 static String [] separators; 419 static String [] templateLines; 420 421 422 LDAPConnection conn; 425 426 427 AccumulatingTracker totalAdds; 429 AccumulatingTracker totalDeletes; 430 CategoricalTracker addResultCodes; 431 CategoricalTracker deleteResultCodes; 432 IncrementalTracker addCount; 433 IncrementalTracker deleteCount; 434 TimeTracker addTime; 435 TimeTracker deleteTime; 436 437 438 static Random parentRandom = new Random(); 441 static String guidBase = null; 442 Random random; 443 char[] chars5000; 444 445 446 ArrayList entriesAdded; 449 450 451 static int numActiveAddThreads; 454 static Object addThreadMutex; 455 456 457 458 459 465 public TemplateBasedAddAndDelRateJobClass() 466 { 467 super(); 468 469 templateParameter.setVisibleRows(10); 470 templateParameter.setVisibleColumns(80); 471 chars5000 = new char[5000]; 472 random = new Random(parentRandom.nextLong()); 473 474 if (guidBase == null) 475 { 476 guidBase = generateRandomValue(HEX_CHARS, 12); 477 } 478 } 479 480 481 482 487 public String getJobName() 488 { 489 return "LDAP Template-Based Add and Delete Rate"; 490 } 491 492 493 494 499 public String getJobDescription() 500 { 501 return "This job can be used to perform repeated add operations against " + 502 "an LDAP directory server, followed by repeated delete " + 503 "operations. The entries created will be based on a user-defined " + 504 "template."; 505 } 506 507 508 509 515 public String getJobCategoryName() 516 { 517 return "LDAP"; 518 } 519 520 521 522 528 public int overrideNumClients() 529 { 530 return 1; 531 } 532 533 534 535 542 public ParameterList getParameterStubs() 543 { 544 Parameter[] parameters = new Parameter[] 545 { 546 placeholder, 547 hostParameter, 548 portParameter, 549 bindDNParameter, 550 bindPWParameter, 551 proxyAsDNParameter, 552 placeholder, 553 baseDNParameter, 554 rdnAttrParameter, 555 startValueParameter, 556 endValueParameter, 557 templateParameter, 558 placeholder, 559 deleteDelayParameter, 560 timeLimitParameter, 561 delayParameter, 562 placeholder, 563 useSSLParameter, 564 blindTrustParameter, 565 keyStoreParameter, 566 keyPWParameter, 567 trustStoreParameter, 568 trustPWParameter, 569 placeholder, 570 disconnectParameter, 571 cleanTombstonesParameter, 572 tombstoneDelayParameter 573 }; 574 575 return new ParameterList(parameters); 576 } 577 578 579 580 602 public StatTracker[] getStatTrackerStubs(String clientID, String threadID, 603 int collectionInterval) 604 { 605 return new StatTracker[] 606 { 607 new IncrementalTracker(clientID, threadID, STAT_TRACKER_ADD_COUNT, 608 collectionInterval), 609 new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME, 610 collectionInterval), 611 new CategoricalTracker(clientID, threadID, STAT_TRACKER_ADD_RESULT_CODES, 612 collectionInterval), 613 new IncrementalTracker(clientID, threadID, STAT_TRACKER_DELETE_COUNT, 614 collectionInterval), 615 new TimeTracker(clientID, threadID, STAT_TRACKER_DELETE_TIME, 616 collectionInterval), 617 new CategoricalTracker(clientID, threadID, 618 STAT_TRACKER_DELETE_RESULT_CODES, 619 collectionInterval) 620 }; 621 } 622 623 624 625 630 public StatTracker[] getStatTrackers() 631 { 632 return new StatTracker[] 633 { 634 addCount, 635 addTime, 636 addResultCodes, 637 totalAdds, 638 deleteCount, 639 deleteTime, 640 deleteResultCodes, 641 totalDeletes 642 }; 643 } 644 645 646 647 669 public void validateJobInfo(int numClients, int threadsPerClient, 670 int threadStartupDelay, Date startTime, 671 Date stopTime, int duration, 672 int collectionInterval, ParameterList parameters) 673 throws InvalidValueException 674 { 675 if (numClients != 1) 677 { 678 throw new InvalidValueException("A template-based add and delete job " + 679 "may only run on a single client."); 680 } 681 682 MultiLineTextParameter templateParam = 684 parameters.getMultiLineTextParameter(templateParameter.getName()); 685 if (templateParam == null) 686 { 687 throw new InvalidValueException("No value provided for required " + 688 "parameter " + 689 templateParameter.getDisplayName()); 690 } 691 692 templateLines = templateParam.getNonBlankLines(); 693 if (templateLines.length == 0) 694 { 695 throw new InvalidValueException("No value provided for required " + 696 "parameter " + 697 templateParameter.getDisplayName()); 698 } 699 700 StringParameter rdnAttrParam = 701 parameters.getStringParameter(rdnAttrParameter.getName()); 702 if (rdnAttrParam == null) 703 { 704 throw new InvalidValueException("No value provided for required " + 705 "parameter " + 706 rdnAttrParameter.getDisplayName()); 707 } 708 rdnAttr = rdnAttrParam.getStringValue(); 709 lowerRDNAttr = rdnAttr.toLowerCase(); 710 711 try 712 { 713 validateTemplate(); 714 } 715 catch (UnableToRunException utre) 716 { 717 throw new InvalidValueException(utre.getMessage(), utre); 718 } 719 } 720 721 722 723 731 public boolean providesParameterTest() 732 { 733 return true; 734 } 735 736 737 738 765 public boolean testJobParameters(ParameterList parameters, 766 ArrayList outputMessages) 767 { 768 StringParameter hostParam = 770 parameters.getStringParameter(hostParameter.getName()); 771 if ((hostParam == null) || (! hostParam.hasValue())) 772 { 773 outputMessages.add("ERROR: No directory server address was provided."); 774 return false; 775 } 776 String host = hostParam.getStringValue(); 777 778 779 IntegerParameter portParam = 780 parameters.getIntegerParameter(portParameter.getName()); 781 if ((portParam == null) || (! hostParam.hasValue())) 782 { 783 outputMessages.add("ERROR: No directory server port was provided."); 784 return false; 785 } 786 int port = portParam.getIntValue(); 787 788 789 boolean useSSL = false; 790 BooleanParameter useSSLParam = 791 parameters.getBooleanParameter(useSSLParameter.getName()); 792 if (useSSLParam != null) 793 { 794 useSSL = useSSLParam.getBooleanValue(); 795 } 796 797 798 boolean blindTrust = true; 799 BooleanParameter blindTrustParam = 800 parameters.getBooleanParameter(blindTrustParameter.getName()); 801 if (blindTrustParam != null) 802 { 803 blindTrust = blindTrustParam.getBooleanValue(); 804 } 805 806 807 String keyStore = null; 808 StringParameter keyStoreParam = 809 parameters.getStringParameter(keyStoreParameter.getName()); 810 if ((keyStoreParam != null) && keyStoreParam.hasValue()) 811 { 812 keyStore = keyStoreParam.getStringValue(); 813 File keyStoreFile = new File(keyStore); 814 if (useSSL && (! blindTrust) && (! keyStoreFile.exists())) 815 { 816 outputMessages.add("WARNING: Key store file \"" + keyStore + 817 "\" not found on SLAMD server system. This test " + 818 "will blindly trust any SSL certificate " + 819 "presented by the directory server."); 820 outputMessages.add(""); 821 blindTrust = true; 822 } 823 else 824 { 825 System.setProperty(SSL_KEY_STORE_PROPERTY, keyStore); 826 } 827 } 828 829 830 String keyStorePassword = ""; 831 StringParameter keyPassParam = 832 parameters.getStringParameter(keyPWParameter.getName()); 833 if ((keyPassParam != null) && keyPassParam.hasValue()) 834 { 835 keyStorePassword = keyPassParam.getStringValue(); 836 System.setProperty(SSL_KEY_PASSWORD_PROPERTY, keyStorePassword); 837 } 838 839 840 String trustStore = null; 841 StringParameter trustStoreParam = 842 parameters.getStringParameter(trustStoreParameter.getName()); 843 if ((trustStoreParam != null) && trustStoreParam.hasValue()) 844 { 845 trustStore = trustStoreParam.getStringValue(); 846 File trustStoreFile = new File(trustStore); 847 if (useSSL && (! blindTrust) && (! trustStoreFile.exists())) 848 { 849 outputMessages.add("WARNING: trust store file \"" + trustStore + 850 "\" not found on SLAMD server system. This test " + 851 "will blindly trust any SSL certificate " + 852 "presented by the directory server."); 853 outputMessages.add(""); 854 blindTrust = true; 855 } 856 else 857 { 858 System.setProperty(SSL_TRUST_STORE_PROPERTY, trustStore); 859 } 860 } 861 862 863 String trustStorePassword = ""; 864 StringParameter trustPassParam = 865 parameters.getStringParameter(trustPWParameter.getName()); 866 if ((trustPassParam != null) && trustPassParam.hasValue()) 867 { 868 trustStorePassword = trustPassParam.getStringValue(); 869 System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, trustStorePassword); 870 } 871 872 873 String bindDN = ""; 874 StringParameter bindDNParam = 875 parameters.getStringParameter(bindDNParameter.getName()); 876 if ((bindDNParam != null) && bindDNParam.hasValue()) 877 { 878 bindDN = bindDNParam.getStringValue(); 879 } 880 881 882 String bindPassword = ""; 883 PasswordParameter bindPWParam = 884 parameters.getPasswordParameter(bindPWParameter.getName()); 885 if ((bindPWParam != null) && bindPWParam.hasValue()) 886 { 887 bindPassword = bindPWParam.getStringValue(); 888 } 889 890 891 String proxyAsDN = null; 892 StringParameter proxyAsDNParam = 893 parameters.getStringParameter(proxyAsDNParameter.getName()); 894 if ((proxyAsDNParam != null) && proxyAsDNParam.hasValue()) 895 { 896 proxyAsDN = proxyAsDNParam.getStringValue(); 897 } 898 899 900 StringParameter baseDNParam = 901 parameters.getStringParameter(baseDNParameter.getName()); 902 if ((baseDNParam == null) || (! baseDNParam.hasValue())) 903 { 904 outputMessages.add("ERROR: No base DN was provided."); 905 return false; 906 } 907 String baseDN = baseDNParam.getStringValue(); 908 909 910 LDAPConnection conn; 913 if (useSSL) 914 { 915 if (blindTrust) 916 { 917 try 918 { 919 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 920 } 921 catch (Exception e) 922 { 923 outputMessages.add("ERROR: Unable to instantiate the blind trust " + 924 "socket factory for use in creating the SSL " + 925 "connection: " + stackTraceToString(e)); 926 return false; 927 } 928 } 929 else 930 { 931 conn = new LDAPConnection(new JSSESocketFactory(null)); 932 } 933 } 934 else 935 { 936 conn = new LDAPConnection(); 937 } 938 939 940 try 942 { 943 if (useSSL) 944 { 945 outputMessages.add("Attempting to establish an SSL-based connection " + 946 "to " + host + ":" + port + "...."); 947 } 948 else 949 { 950 outputMessages.add("Attempting to establish a connection to " + host + 951 ":" + port + "...."); 952 } 953 conn.connect(host, port); 954 outputMessages.add("Connected successfully."); 955 outputMessages.add(""); 956 } 957 catch (Exception e) 958 { 959 outputMessages.add("ERROR: Unable to connect to the directory " + 960 "server: " + stackTraceToString(e)); 961 return false; 962 } 963 964 965 try 967 { 968 outputMessages.add("Attempting to perform an LDAPv3 bind to the " + 969 "directory server with a DN of '" + bindDN + "'...."); 970 conn.bind(3, bindDN, bindPassword); 971 outputMessages.add("Bound successfully."); 972 outputMessages.add(""); 973 } 974 catch (Exception e) 975 { 976 try 977 { 978 conn.disconnect(); 979 } catch (Exception e2) {} 980 981 outputMessages.add("ERROR: Unable to bind to the directory server: " + 982 stackTraceToString(e)); 983 return false; 984 } 985 986 987 if (proxyAsDN != null) 989 { 990 try 991 { 992 outputMessages.add("Checking to make sure that the proxied user '" + 993 proxyAsDN + "' exists in the directory...."); 994 LDAPEntry proxyUserEntry = conn.read(proxyAsDN, new String [] { "1.1" }); 995 if (proxyUserEntry == null) 996 { 997 try 998 { 999 conn.disconnect(); 1000 } catch (Exception e2) {} 1001 1002 outputMessages.add("ERROR: Unable to retrieve the proxied user's " + 1003 "entry."); 1004 return false; 1005 } 1006 else 1007 { 1008 outputMessages.add("Successfully read the proxied user's entry."); 1009 outputMessages.add(""); 1010 } 1011 } 1012 catch (Exception e) 1013 { 1014 try 1015 { 1016 conn.disconnect(); 1017 } catch (Exception e2) {} 1018 1019 outputMessages.add("ERROR: Unable to retrieve the proxied user's " + 1020 "entry: " + stackTraceToString(e)); 1021 return false; 1022 } 1023 } 1024 1025 1026 try 1028 { 1029 outputMessages.add("Checking to make sure that the base DN entry '" + 1030 baseDN + "' exists in the directory...."); 1031 LDAPEntry baseDNEntry = conn.read(baseDN, new String [] { "1.1" }); 1032 if (baseDNEntry == null) 1033 { 1034 try 1035 { 1036 conn.disconnect(); 1037 } catch (Exception e2) {} 1038 1039 outputMessages.add("ERROR: Unable to retrieve the base DN entry."); 1040 return false; 1041 } 1042 else 1043 { 1044 outputMessages.add("Successfully read the base DN entry."); 1045 outputMessages.add(""); 1046 } 1047 } 1048 catch (Exception e) 1049 { 1050 try 1051 { 1052 conn.disconnect(); 1053 } catch (Exception e2) {} 1054 1055 outputMessages.add("ERROR: Unable to retrieve the base DN entry: " + 1056 stackTraceToString(e)); 1057 return false; 1058 } 1059 1060 1061 try 1064 { 1065 conn.disconnect(); 1066 } catch (Exception e) {} 1067 1068 outputMessages.add("All tests completed successfully."); 1069 return true; 1070 } 1071 1072 1073 1074 1084 public void initializeClient(String clientID, ParameterList parameters) 1085 throws UnableToRunException 1086 { 1087 ldapHost = null; 1089 hostParameter = parameters.getStringParameter(hostParameter.getName()); 1090 if (hostParameter != null) 1091 { 1092 ldapHost = hostParameter.getStringValue(); 1093 } 1094 1095 ldapPort = 389; 1097 portParameter = parameters.getIntegerParameter(portParameter.getName()); 1098 if (portParameter != null) 1099 { 1100 ldapPort = portParameter.getIntValue(); 1101 } 1102 1103 bindDN = ""; 1105 bindDNParameter = parameters.getStringParameter(bindDNParameter.getName()); 1106 if (bindDNParameter != null) 1107 { 1108 bindDN = bindDNParameter.getStringValue(); 1109 } 1110 1111 bindPassword = ""; 1113 bindPWParameter = 1114 parameters.getPasswordParameter(bindPWParameter.getName()); 1115 if (bindPWParameter != null) 1116 { 1117 bindPassword = bindPWParameter.getStringValue(); 1118 } 1119 1120 useProxyAuth = false; 1122 proxyAsDNParameter = 1123 parameters.getStringParameter(proxyAsDNParameter.getName()); 1124 if ((proxyAsDNParameter != null) && (proxyAsDNParameter.hasValue())) 1125 { 1126 useProxyAuth = true; 1127 proxyAsDN = proxyAsDNParameter.getStringValue(); 1128 } 1129 1130 baseDN = null; 1132 baseDNParameter = parameters.getStringParameter(baseDNParameter.getName()); 1133 if ((baseDNParameter != null) && (baseDNParameter.hasValue())) 1134 { 1135 baseDN = baseDNParameter.getStringValue(); 1136 } 1137 1138 rdnAttr = "uid"; 1140 rdnAttrParameter = 1141 parameters.getStringParameter(rdnAttrParameter.getName()); 1142 if ((rdnAttrParameter != null) && (rdnAttrParameter.hasValue())) 1143 { 1144 rdnAttr = rdnAttrParameter.getStringValue().toLowerCase(); 1145 } 1146 lowerRDNAttr = rdnAttr.toLowerCase(); 1147 1148 startValue = 0; 1150 startValueParameter = 1151 parameters.getIntegerParameter(startValueParameter.getName()); 1152 if ((startValueParameter != null) && (startValueParameter.hasValue())) 1153 { 1154 startValue = startValueParameter.getIntValue(); 1155 } 1156 nextValue = startValue; 1157 1158 endValue = Integer.MAX_VALUE; 1160 endValueParameter = 1161 parameters.getIntegerParameter(endValueParameter.getName()); 1162 if ((endValueParameter != null) && (endValueParameter.hasValue())) 1163 { 1164 endValue = endValueParameter.getIntValue(); 1165 if (endValue <= 0) 1166 { 1167 endValue = Integer.MAX_VALUE; 1168 } 1169 } 1170 1171 templateLines = DEFAULT_TEMPLATE_LINES; 1173 templateParameter = 1174 parameters.getMultiLineTextParameter(templateParameter.getName()); 1175 if ((templateParameter != null) && templateParameter.hasValue()) 1176 { 1177 templateLines = templateParameter.getNonBlankLines(); 1178 } 1179 validateTemplate(); 1180 1181 deleteDelay = 0; 1183 deleteDelayParameter = 1184 parameters.getIntegerParameter(deleteDelayParameter.getName()); 1185 if ((deleteDelayParameter != null) && deleteDelayParameter.hasValue()) 1186 { 1187 deleteDelay = deleteDelayParameter.getIntValue(); 1188 } 1189 1190 timeLimit = 0; 1192 timeLimitParameter = 1193 parameters.getIntegerParameter(timeLimitParameter.getName()); 1194 if (timeLimitParameter != null) 1195 { 1196 timeLimit = timeLimitParameter.getIntValue(); 1197 } 1198 1199 delay = 0; 1201 delayParameter = parameters.getIntegerParameter(delayParameter.getName()); 1202 if (delayParameter != null) 1203 { 1204 delay = delayParameter.getIntValue(); 1205 } 1206 1207 useSSL = false; 1209 useSSLParameter = parameters.getBooleanParameter(useSSLParameter.getName()); 1210 if (useSSLParameter != null) 1211 { 1212 useSSL = useSSLParameter.getBooleanValue(); 1213 } 1214 1215 if (useSSL) 1217 { 1218 blindTrustParameter = 1220 parameters.getBooleanParameter(blindTrustParameter.getName()); 1221 if (blindTrustParameter != null) 1222 { 1223 blindTrust = blindTrustParameter.getBooleanValue(); 1224 } 1225 1226 sslKeyStore = null; 1228 keyStoreParameter = 1229 parameters.getStringParameter(keyStoreParameter.getName()); 1230 if ((keyStoreParameter != null) && (keyStoreParameter.hasValue())) 1231 { 1232 sslKeyStore = keyStoreParameter.getStringValue(); 1233 System.setProperty(SSL_KEY_STORE_PROPERTY, sslKeyStore); 1234 } 1235 1236 sslKeyPassword = null; 1238 keyPWParameter = 1239 parameters.getPasswordParameter(keyPWParameter.getName()); 1240 if ((keyPWParameter != null) && (keyPWParameter.hasValue())) 1241 { 1242 sslKeyPassword = keyPWParameter.getStringValue(); 1243 System.setProperty(SSL_KEY_PASSWORD_PROPERTY, sslKeyPassword); 1244 } 1245 1246 sslTrustStore = null; 1248 trustStoreParameter = 1249 parameters.getStringParameter(trustStoreParameter.getName()); 1250 if ((trustStoreParameter != null) && (trustStoreParameter.hasValue())) 1251 { 1252 sslTrustStore = trustStoreParameter.getStringValue(); 1253 System.setProperty(SSL_TRUST_STORE_PROPERTY, sslTrustStore); 1254 } 1255 1256 sslTrustPassword = null; 1258 trustPWParameter = 1259 parameters.getPasswordParameter(trustPWParameter.getName()); 1260 if ((trustPWParameter != null) && (trustPWParameter.hasValue())) 1261 { 1262 sslTrustPassword = trustPWParameter.getStringValue(); 1263 System.setProperty(SSL_TRUST_PASSWORD_PROPERTY, sslTrustPassword); 1264 } 1265 } 1266 1267 alwaysDisconnect = false; 1269 disconnectParameter = 1270 parameters.getBooleanParameter(disconnectParameter.getName()); 1271 if (disconnectParameter != null) 1272 { 1273 alwaysDisconnect = disconnectParameter.getBooleanValue(); 1274 } 1275 1276 cleanTombstones = false; 1278 cleanTombstonesParameter = 1279 parameters.getBooleanParameter(cleanTombstonesParameter.getName()); 1280 if (cleanTombstonesParameter != null) 1281 { 1282 cleanTombstones = cleanTombstonesParameter.getBooleanValue(); 1283 } 1284 1285 tombstoneDelay = 0; 1287 tombstoneDelayParameter = 1288 parameters.getIntegerParameter(tombstoneDelayParameter.getName()); 1289 if ((tombstoneDelayParameter != null) && 1290 tombstoneDelayParameter.hasValue()) 1291 { 1292 tombstoneDelay = tombstoneDelayParameter.getIntValue(); 1293 } 1294 1295 addThreadMutex = new Object (); 1296 } 1297 1298 1299 1300 1316 public void initializeThread(String clientID, String threadID, 1317 int collectionInterval, ParameterList parameters) 1318 throws UnableToRunException 1319 { 1320 addCount = new IncrementalTracker(clientID, threadID, 1322 STAT_TRACKER_ADD_COUNT, 1323 collectionInterval); 1324 addTime = new TimeTracker(clientID, threadID, STAT_TRACKER_ADD_TIME, 1325 collectionInterval); 1326 addResultCodes = new CategoricalTracker(clientID, threadID, 1327 STAT_TRACKER_ADD_RESULT_CODES, 1328 collectionInterval); 1329 totalAdds = new AccumulatingTracker(clientID, threadID, 1330 STAT_TRACKER_ADD_TOTAL, 1331 collectionInterval); 1332 deleteCount = new IncrementalTracker(clientID, threadID, 1333 STAT_TRACKER_DELETE_COUNT, 1334 collectionInterval); 1335 deleteTime = new TimeTracker(clientID, threadID, STAT_TRACKER_DELETE_TIME, 1336 collectionInterval); 1337 deleteResultCodes = new CategoricalTracker(clientID, threadID, 1338 STAT_TRACKER_DELETE_RESULT_CODES, 1339 collectionInterval); 1340 totalDeletes = new AccumulatingTracker(clientID, threadID, 1341 STAT_TRACKER_DELETE_TOTAL, 1342 collectionInterval); 1343 1344 1345 RealTimeStatReporter statReporter = getStatReporter(); 1347 if (statReporter != null) 1348 { 1349 String jobID = getJobID(); 1350 addCount.enableRealTimeStats(statReporter, jobID); 1351 addTime.enableRealTimeStats(statReporter, jobID); 1352 totalAdds.enableRealTimeStats(statReporter, jobID); 1353 deleteCount.enableRealTimeStats(statReporter, jobID); 1354 deleteTime.enableRealTimeStats(statReporter, jobID); 1355 totalDeletes.enableRealTimeStats(statReporter, jobID); 1356 } 1357 1358 1359 if (useSSL) 1367 { 1368 try 1369 { 1370 if (blindTrust) 1371 { 1372 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 1373 } 1374 else 1375 { 1376 conn = new LDAPConnection(new JSSESocketFactory(null)); 1377 } 1378 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1379 conn.disconnect(); 1380 } 1381 catch (Exception e) {} 1382 } 1383 1384 1385 entriesAdded = new ArrayList(); 1388 } 1389 1390 1391 1392 1399 public void runJob() 1400 { 1401 boolean connected = false; 1404 1405 boolean allAdded = false; 1408 1409 long addStartTime = 0; 1412 1413 if (useSSL) 1415 { 1416 if (blindTrust) 1417 { 1418 try 1419 { 1420 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 1421 } 1422 catch (LDAPException le) 1423 { 1424 logMessage(le.getMessage()); 1425 indicateStoppedDueToError(); 1426 return; 1427 } 1428 } 1429 else 1430 { 1431 conn = new LDAPConnection(new JSSESocketFactory(null)); 1432 } 1433 } 1434 else 1435 { 1436 conn = new LDAPConnection(); 1437 } 1438 1439 1440 synchronized (addThreadMutex) 1442 { 1443 numActiveAddThreads++; 1444 } 1445 1446 1447 addCount.startTracker(); 1449 addTime.startTracker(); 1450 addResultCodes.startTracker(); 1451 totalAdds.startTracker(); 1452 1453 1454 while ((! shouldStop()) && (! allAdded)) 1456 { 1457 if (! connected) 1459 { 1460 try 1461 { 1462 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1463 connected = true; 1464 } 1465 catch (LDAPException le) 1466 { 1467 logMessage("ERROR -- Could not connect to " + ldapHost + ":" + 1468 ldapPort + " (" + le + ") -- aborting thread"); 1469 addResultCodes.increment(String.valueOf(le.getLDAPResultCode())); 1470 indicateStoppedDueToError(); 1471 break; 1472 } 1473 } 1474 1475 LDAPConstraints constraints = conn.getConstraints(); 1476 if (useProxyAuth) 1477 { 1478 LDAPProxiedAuthControl proxyAuthControl = 1479 new LDAPProxiedAuthControl(proxyAsDN, true); 1480 constraints.setServerControls(proxyAuthControl); 1481 } 1482 constraints.setTimeLimit(1000 * timeLimit); 1483 1484 1485 LDAPEntry entryToAdd = createEntry(); 1487 if (entryToAdd == null) 1488 { 1489 allAdded = true; 1490 } 1491 else 1492 { 1493 addTime.startTimer(); 1495 if (delay > 0) 1496 { 1497 addStartTime = System.currentTimeMillis(); 1498 } 1499 1500 int resultCode = LDAPException.SUCCESS; 1502 try 1503 { 1504 conn.add(entryToAdd, constraints); 1505 entriesAdded.add(entryToAdd.getDN()); 1506 } 1507 catch (LDAPException le) 1508 { 1509 resultCode = le.getLDAPResultCode(); 1510 } 1511 1512 1513 addCount.increment(); 1515 totalAdds.increment(); 1516 addTime.stopTimer(); 1517 addResultCodes.increment(String.valueOf(resultCode)); 1518 } 1519 1520 if (alwaysDisconnect) 1522 { 1523 try 1524 { 1525 conn.disconnect(); 1526 } catch (LDAPException le) {} 1527 connected = false; 1528 } 1529 1530 if ((delay > 0) && (! shouldStop())) 1532 { 1533 long now = System.currentTimeMillis(); 1534 long sleepTime = delay - (now - addStartTime); 1535 if (sleepTime > 0) 1536 { 1537 try 1538 { 1539 Thread.sleep(sleepTime); 1540 } catch (InterruptedException ie) {} 1541 } 1542 } 1543 } 1544 1545 1546 addCount.stopTracker(); 1548 addTime.stopTracker(); 1549 addResultCodes.stopTracker(); 1550 totalAdds.stopTracker(); 1551 1552 1553 if (shouldStop()) 1555 { 1556 try 1558 { 1559 conn.disconnect(); 1560 } catch (LDAPException le) {} 1561 1562 synchronized (addThreadMutex) 1564 { 1565 numActiveAddThreads--; 1566 } 1567 1568 return; 1569 } 1570 1571 1572 synchronized (addThreadMutex) 1575 { 1576 if (numActiveAddThreads > 1) 1577 { 1578 numActiveAddThreads--; 1579 } 1580 else 1581 { 1582 try 1583 { 1584 Thread.sleep(deleteDelay * 1000); 1585 } catch (InterruptedException ie) {} 1586 1587 numActiveAddThreads--; 1589 } 1590 } 1591 1592 1593 while ((numActiveAddThreads > 0) && (! shouldStop())) 1595 { 1596 try 1597 { 1598 Thread.sleep(10); 1599 } catch (InterruptedException ie) {} 1600 } 1601 1602 1603 if (shouldStop()) 1605 { 1606 try 1607 { 1608 conn.disconnect(); 1609 } catch (LDAPException le) {} 1610 1611 return; 1612 } 1613 1614 1615 deleteCount.startTracker(); 1617 deleteTime.startTracker(); 1618 deleteResultCodes.startTracker(); 1619 totalDeletes.startTracker(); 1620 1621 1622 Iterator iterator = entriesAdded.iterator(); 1624 while (iterator.hasNext() && (! shouldStop())) 1625 { 1626 if (! connected) 1628 { 1629 try 1630 { 1631 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1632 connected = true; 1633 } 1634 catch (LDAPException le) 1635 { 1636 logMessage("ERROR -- Could not connect to " + ldapHost + ":" + 1637 ldapPort + " (" + le + ") -- aborting thread"); 1638 addResultCodes.increment(String.valueOf(le.getLDAPResultCode())); 1639 indicateStoppedDueToError(); 1640 break; 1641 } 1642 } 1643 1644 LDAPConstraints constraints = conn.getConstraints(); 1645 if (useProxyAuth) 1646 { 1647 LDAPProxiedAuthControl proxyAuthControl = 1648 new LDAPProxiedAuthControl(proxyAsDN, true); 1649 constraints.setServerControls(proxyAuthControl); 1650 } 1651 constraints.setTimeLimit(1000 * timeLimit); 1652 1653 1654 if (delay > 0) 1656 { 1657 addStartTime = System.currentTimeMillis(); 1658 } 1659 1660 1661 int resultCode = LDAPException.SUCCESS; 1663 deleteTime.startTimer(); 1664 try 1665 { 1666 conn.delete((String ) iterator.next(), constraints); 1667 } 1668 catch (LDAPException le) 1669 { 1670 resultCode = le.getLDAPResultCode(); 1671 } 1672 deleteTime.stopTimer(); 1673 deleteCount.increment(); 1674 totalDeletes.increment(); 1675 deleteResultCodes.increment(String.valueOf(resultCode)); 1676 1677 if (alwaysDisconnect) 1679 { 1680 try 1681 { 1682 conn.disconnect(); 1683 } catch (LDAPException le) {} 1684 connected = false; 1685 } 1686 1687 if ((delay > 0) && (! shouldStop())) 1689 { 1690 long now = System.currentTimeMillis(); 1691 long sleepTime = delay - (now - addStartTime); 1692 if (sleepTime > 0) 1693 { 1694 try 1695 { 1696 Thread.sleep(sleepTime); 1697 } catch (InterruptedException ie) {} 1698 } 1699 } 1700 } 1701 1702 1703 try 1705 { 1706 conn.disconnect(); 1707 } catch (LDAPException le) {} 1708 1709 1710 deleteCount.stopTracker(); 1712 deleteTime.stopTracker(); 1713 deleteResultCodes.stopTracker(); 1714 totalDeletes.stopTracker(); 1715 } 1716 1717 1718 1719 1724 public void finalizeClient() 1725 { 1726 if (! cleanTombstones) 1727 { 1728 return; 1729 } 1730 1731 1732 if (tombstoneDelay > 0) 1734 { 1735 try 1736 { 1737 Thread.sleep(1000 * tombstoneDelay); 1738 } catch (InterruptedException ie) {} 1739 } 1740 1741 1742 if (useSSL) 1744 { 1745 if (blindTrust) 1746 { 1747 try 1748 { 1749 conn = new LDAPConnection(new JSSEBlindTrustSocketFactory()); 1750 } 1751 catch (LDAPException le) 1752 { 1753 logMessage("Unable to create LDAP connection to clean up " + 1754 "tombstones -- " + le.getMessage()); 1755 indicateCompletedWithErrors(); 1756 return; 1757 } 1758 } 1759 else 1760 { 1761 conn = new LDAPConnection(new JSSESocketFactory(null)); 1762 } 1763 } 1764 else 1765 { 1766 conn = new LDAPConnection(); 1767 } 1768 1769 try 1770 { 1771 conn.connect(3, ldapHost, ldapPort, bindDN, bindPassword); 1772 } 1773 catch (LDAPException le) 1774 { 1775 logMessage("Unable to connect to server to clean up tombstones -- " + 1776 le.getMessage()); 1777 indicateCompletedWithErrors(); 1778 return; 1779 } 1780 1781 1782 LDAPSearchResults results = null; 1784 try 1785 { 1786 results = conn.search(baseDN, LDAPConnection.SCOPE_SUB, 1787 "(&(objectClass=nsTombstone)(!(nsds50RUV=*)))", 1788 new String [] { "1.1" }, false); 1789 } 1790 catch (LDAPException le) 1791 { 1792 logMessage("Unable to search for tombstone entries -- " + 1793 le.getMessage()); 1794 indicateCompletedWithErrors(); 1795 1796 try 1797 { 1798 conn.disconnect(); 1799 } catch (Exception e) {} 1800 1801 return; 1802 } 1803 1804 1805 while (results.hasMoreElements()) 1807 { 1808 Object element = results.nextElement(); 1809 if (element instanceof LDAPEntry) 1810 { 1811 String entryDN = ((LDAPEntry) element).getDN(); 1812 try 1813 { 1814 conn.delete(entryDN); 1815 } catch (LDAPException le) {} 1816 } 1817 } 1818 1819 1820 try 1822 { 1823 conn.disconnect(); 1824 } catch (Exception e) {} 1825 } 1826 1827 1828 1829 1833 public void destroy() 1834 { 1835 if (conn != null) 1836 { 1837 try 1838 { 1839 conn.disconnect(); 1840 } catch (Exception e) {} 1841 1842 conn = null; 1843 } 1844 } 1845 1846 1847 1848 1855 public void validateTemplate() 1856 throws UnableToRunException 1857 { 1858 boolean rdnAttrFound = false; 1859 attrNames = new String [templateLines.length]; 1860 lowerNames = new String [templateLines.length]; 1861 separators = new String [templateLines.length]; 1862 attrValues = new String [templateLines.length]; 1863 1864 for (int i=0; i < templateLines.length; i++) 1865 { 1866 int colonPos = templateLines[i].indexOf(':'); 1867 if (colonPos < 0) 1868 { 1869 throw new UnableToRunException("No colon found in template line \"" + 1870 templateLines[i] + "\" to separate " + 1871 "the attribute name from the value."); 1872 } 1873 else if (colonPos == 0) 1874 { 1875 throw new UnableToRunException("No attribute name found in template " + 1876 "line \"" + templateLines[i] + "\"."); 1877 } 1878 else if (colonPos == (templateLines[i].length() - 1)) 1879 { 1880 throw new UnableToRunException("No attribute value found in template " + 1881 "line \"" + templateLines[i] + "\"."); 1882 } 1883 attrNames[i] = templateLines[i].substring(0, colonPos); 1884 lowerNames[i] = attrNames[i].toLowerCase(); 1885 if (lowerNames[i].equals(lowerRDNAttr)) 1886 { 1887 rdnAttrFound = true; 1888 } 1889 1890 char nextChar = templateLines[i].charAt(colonPos+1); 1891 if (nextChar == ' ') 1892 { 1893 separators[i] = ":"; 1894 attrValues[i] = templateLines[i].substring(colonPos+2).trim(); 1895 } 1896 else if (nextChar == ':') 1897 { 1898 if (colonPos == (templateLines[i].length() - 2)) 1899 { 1900 throw new UnableToRunException("No attribute value found in " + 1901 "template line \"" + templateLines[i] + 1902 "\"."); 1903 } 1904 else if (templateLines[i].charAt(colonPos+2) == ' ') 1905 { 1906 separators[i] = "::"; 1907 attrValues[i] = templateLines[i].substring(colonPos+3).trim(); 1908 } 1909 else 1910 { 1911 throw new UnableToRunException("Invalid character sequence found " + 1912 "in template line \"" + 1913 templateLines[i] + "\" -- illegal " + 1914 "character '" + 1915 templateLines[i].charAt(colonPos+2) + 1916 "' in column " + (colonPos+2)); 1917 } 1918 } 1919 else 1920 { 1921 throw new UnableToRunException("Invalid character sequence found " + 1922 "in template line \"" + 1923 templateLines[i] + "\" -- illegal " + 1924 "character '" + 1925 templateLines[i].charAt(colonPos+1) + 1926 "' in column " + (colonPos+1)); 1927 } 1928 } 1929 1930 if (! rdnAttrFound) 1931 { 1932 throw new UnableToRunException("No value provided for RDN attribute \"" + 1933 rdnAttr + "\" in template definition."); 1934 } 1935 } 1936 1937 1938 1939 1944 public LDAPEntry createEntry() 1945 { 1946 int entryValue = nextValue++; 1947 int entryNumCreated = entryValue - startValue + 1; 1948 if (nextValue > endValue) 1949 { 1950 return null; 1951 } 1952 1953 LDAPAttributeSet attributeSet = new LDAPAttributeSet(); 1954 String rdnValue = null; 1955 for (int i=0; i < attrNames.length; i++) 1956 { 1957 String value = processValue(attrValues[i], attributeSet, entryValue, 1958 entryNumCreated); 1959 if (value == null) 1960 { 1961 continue; 1962 } 1963 1964 if ((rdnValue == null) && (lowerNames[i].equals(lowerRDNAttr))) 1965 { 1966 rdnValue = value; 1967 } 1968 attributeSet.add(new LDAPAttribute(attrNames[i], value)); 1969 } 1970 1971 return new LDAPEntry(rdnAttr + "=" + rdnValue + "," + baseDN, 1972 attributeSet); 1973 } 1974 1975 1976 1977 1990 public String processValue(String value, LDAPAttributeSet attributeSet, 1991 int entryNumber, int entryInSequence) 1992 { 1993 boolean needReprocess = true; 1994 int pos; 1995 1996 if ((pos = value.indexOf("<presence:")) >= 0) 2000 { 2001 int closePos = value.indexOf(">", pos); 2002 if (closePos > pos) 2003 { 2004 String numStr = value.substring(pos+10, closePos); 2005 try 2006 { 2007 int percentage = Integer.parseInt(numStr); 2008 int randomValue = ((random.nextInt() & 0x7FFFFFFF) % 100) + 1; 2009 if (randomValue <= percentage) 2010 { 2011 value = value.substring(0, pos) + value.substring(closePos+1); 2015 } 2016 else 2017 { 2018 return null; 2021 } 2022 } 2023 catch (NumberFormatException nfe) 2024 { 2025 return null; 2026 } 2027 } 2028 } 2029 2030 if ((pos = value.indexOf("<ifpresent:")) >= 0) 2034 { 2035 int closePos = value.indexOf(">", pos); 2036 if (closePos > pos) 2037 { 2038 int colonPos = value.indexOf(":", pos+11); 2039 if ((colonPos > 0) && (colonPos < closePos)) 2040 { 2041 boolean matchFound = false; 2043 String attrName = value.substring(pos+11, colonPos); 2044 String matchValue = value.substring(colonPos+1, closePos); 2045 2046 String [] values = null; 2047 LDAPAttribute attr = attributeSet.getAttribute(attrName); 2048 if (attr != null) 2049 { 2050 values = attr.getStringValueArray(); 2051 } 2052 2053 for (int j=0; ((values != null) && (j < values.length)); j++) 2054 { 2055 if (matchValue.equalsIgnoreCase(values[j])) 2056 { 2057 value = value.substring(0, pos) + value.substring(closePos+1); 2058 matchFound = true; 2059 break; 2060 } 2061 } 2062 2063 if (! matchFound) 2064 { 2065 return null; 2066 } 2067 } 2068 else 2069 { 2070 String attrName = value.substring(pos+11, closePos); 2072 String [] values = null; 2073 LDAPAttribute attr = attributeSet.getAttribute(attrName); 2074 if (attr != null) 2075 { 2076 values = attr.getStringValueArray(); 2077 } 2078 if ((values == null) || (values.length == 0)) 2079 { 2080 return null; 2082 } 2083 else 2084 { 2085 value = value.substring(0, pos) + value.substring(closePos+1); 2086 } 2087 } 2088 } 2089 } 2090 2091 if ((pos = value.indexOf("<ifabsent:")) >= 0) 2095 { 2096 int closePos = value.indexOf(">", pos); 2097 if (closePos > pos) 2098 { 2099 int colonPos = value.indexOf(":", pos+10); 2100 if ((colonPos > 0) && (colonPos < closePos)) 2101 { 2102 boolean matchFound = false; 2104 String attrName = value.substring(pos+10, colonPos); 2105 String matchValue = value.substring(colonPos+1, closePos); 2106 2107 String [] values = null; 2108 LDAPAttribute attr = attributeSet.getAttribute(attrName); 2109 if (attr != null) 2110 { 2111 values = attr.getStringValueArray(); 2112 } 2113 2114 for (int j=0; ((values != null) && (j < values.length)); j++) 2115 { 2116 if (matchValue.equalsIgnoreCase(values[j])) 2117 { 2118 matchFound = true; 2119 break; 2120 } 2121 } 2122 2123 if (matchFound) 2124 { 2125 return null; 2126 } 2127 else 2128 { 2129 value = value.substring(0, pos) + value.substring(closePos+1); 2130 } 2131 } 2132 else 2133 { 2134 String attrName = value.substring(pos+10, closePos); 2136 String [] values = null; 2137 LDAPAttribute attr = attributeSet.getAttribute(attrName); 2138 if (attr != null) 2139 { 2140 values = attr.getStringValueArray(); 2141 } 2142 if ((values != null) && (values.length > 0)) 2143 { 2144 return null; 2146 } 2147 else 2148 { 2149 value = value.substring(0, pos) + value.substring(closePos+1); 2150 } 2151 } 2152 } 2153 } 2154 2155 while (needReprocess && (value.indexOf("<") >= 0)) 2156 { 2157 needReprocess = false; 2158 2159 2160 if ((pos = value.indexOf("<entrynumber>")) >= 0) 2163 { 2164 value = value.substring(0, pos) + entryNumber + 2165 value.substring(pos + 13); 2166 needReprocess = true; 2167 } 2168 if ((pos = value.indexOf("<entryNumber>")) >= 0) 2169 { 2170 value = value.substring(0, pos) + entryNumber + 2171 value.substring(pos + 13); 2172 needReprocess = true; 2173 } 2174 2175 if ((pos = value.indexOf("<random:chars:")) >= 0) 2179 { 2180 int colonPos = value.indexOf(":", pos+14); 2182 int closePos = value.indexOf(">", colonPos+1); 2183 String charSet = value.substring(pos+14, colonPos); 2184 2185 int count; 2188 int colonPos2 = value.indexOf(":", colonPos+1); 2189 if ((colonPos2 > 0) && (colonPos2 < closePos)) 2190 { 2191 int minValue = Integer.parseInt(value.substring(colonPos+1, 2192 colonPos2)); 2193 int maxValue = Integer.parseInt(value.substring(colonPos2+1, 2194 closePos)); 2195 int span = maxValue - minValue + 1; 2196 count = (random.nextInt() & 0x7FFFFFFF) % span + minValue; 2197 } 2198 else 2199 { 2200 count = Integer.parseInt(value.substring(colonPos+1, closePos)); 2201 } 2202 2203 String randVal = generateRandomValue(charSet.toCharArray(), count); 2204 value = value.substring(0, pos) + randVal + 2205 value.substring(closePos+1); 2206 needReprocess = true; 2207 } 2208 2209 if ((pos = value.indexOf("<random:alpha:")) >= 0) 2212 { 2213 int count; 2216 int closePos = value.indexOf(">", pos+14); 2217 int colonPos = value.indexOf(":", pos+14); 2218 if ((colonPos > 0) && (colonPos < closePos)) 2219 { 2220 int minValue = Integer.parseInt(value.substring(pos+14, colonPos)); 2221 int maxValue = Integer.parseInt(value.substring(colonPos+1, 2222 closePos)); 2223 int span = maxValue - minValue + 1; 2224 count = (random.nextInt() & 0x7FFFFFFF) % span + minValue; 2225 } 2226 else 2227 { 2228 count = Integer.parseInt(value.substring(pos+14, closePos)); 2229 } 2230 2231 String randVal = generateRandomValue(ALPHA_CHARS, count); 2233 value = value.substring(0, pos) + randVal + 2234 value.substring(closePos + 1); 2235 needReprocess = true; 2236 } 2237 2238 if ((pos = value.indexOf("<random:numeric:")) >= 0) 2242 { 2243 int closePos = value.indexOf('>', pos); 2244 2245 int extraColonPos = value.indexOf(':', pos+16); 2249 if ((extraColonPos > 0) && (extraColonPos < closePos)) 2250 { 2251 int extraColonPos2 = value.indexOf(':', extraColonPos+1); 2255 if ((extraColonPos2 > 0) && (extraColonPos2 < closePos)) 2256 { 2257 String lowerBoundStr = value.substring(pos+16, extraColonPos); 2258 String upperBoundStr = value.substring(extraColonPos+1, 2259 extraColonPos2); 2260 String lengthStr = value.substring(extraColonPos2+1, closePos); 2261 int lowerBound = Integer.parseInt(lowerBoundStr); 2262 int upperBound = Integer.parseInt(upperBoundStr); 2263 int length = Integer.parseInt(lengthStr); 2264 int span = (upperBound - lowerBound + 1); 2265 int randomValue = (random.nextInt() & 0x7FFFFFFF) % span + 2266 lowerBound; 2267 String valueStr = String.valueOf(randomValue); 2268 while (valueStr.length() < length) 2269 { 2270 valueStr = "0" + valueStr; 2271 } 2272 value = value.substring(0, pos) + valueStr + 2273 value.substring(closePos+1); 2274 } 2275 else 2276 { 2277 String lowerBoundStr = value.substring(pos+16, extraColonPos); 2278 String upperBoundStr = value.substring(extraColonPos+1, closePos); 2279 int lowerBound = Integer.parseInt(lowerBoundStr); 2280 int upperBound = Integer.parseInt(upperBoundStr); 2281 int span = (upperBound - lowerBound + 1); 2282 int randomValue = (random.nextInt() & 0x7FFFFFFF) % span + 2283 lowerBound; 2284 value = value.substring(0, pos) + randomValue + 2285 value.substring(closePos+1); 2286 } 2287 } 2288 else 2289 { 2290 int numPos = pos + 16; 2292 int count = Integer.parseInt(value.substring(numPos, closePos)); 2293 String randVal = generateRandomValue(NUMERIC_CHARS, count); 2294 value = value.substring(0, pos) + randVal + 2295 value.substring(closePos+1); 2296 } 2297 2298 needReprocess = true; 2299 } 2300 2301 if ((pos = value.indexOf("<random:alphanumeric:")) >= 0) 2304 { 2305 int count; 2308 int closePos = value.indexOf(">", pos+21); 2309 int colonPos = value.indexOf(":", pos+21); 2310 if ((colonPos > 0) && (colonPos < closePos)) 2311 { 2312 int minValue = Integer.parseInt(value.substring(pos+21, colonPos)); 2313 int maxValue = Integer.parseInt(value.substring(colonPos+1, 2314 closePos)); 2315 int span = maxValue - minValue + 1; 2316 count = (random.nextInt() & 0x7FFFFFFF) % span + minValue; 2317 } 2318 else 2319 { 2320 count = Integer.parseInt(value.substring(pos+21, closePos)); 2321 } 2322 2323 String randVal = generateRandomValue(ALPHANUMERIC_CHARS, count); 2325 value = value.substring(0, pos) + randVal + 2326 value.substring(closePos + 1); 2327 needReprocess = true; 2328 } 2329 2330 if ((pos = value.indexOf("<random:hex:")) >= 0) 2333 { 2334 int count; 2337 int closePos = value.indexOf(">", pos+12); 2338 int colonPos = value.indexOf(":", pos+12); 2339 if ((colonPos > 0) && (colonPos < closePos)) 2340 { 2341 int minValue = Integer.parseInt(value.substring(pos+12, colonPos)); 2342 int maxValue = Integer.parseInt(value.substring(colonPos+1, 2343 closePos)); 2344 int span = maxValue - minValue + 1; 2345 count = (random.nextInt() & 0x7FFFFFFF) % span + minValue; 2346 } 2347 else 2348 { 2349 count = Integer.parseInt(value.substring(pos+12, closePos)); 2350 } 2351 2352 String randVal = generateRandomValue(HEX_CHARS, count); 2354 value = value.substring(0, pos) + randVal + 2355 value.substring(closePos + 1); 2356 needReprocess = true; 2357 } 2358 2359 if ((pos = value.indexOf("<random:base64:")) >= 0) 2362 { 2363 int count; 2366 int closePos = value.indexOf(">", pos+15); 2367 int colonPos = value.indexOf(":", pos+15); 2368 if ((colonPos > 0) && (colonPos < closePos)) 2369 { 2370 int minValue = Integer.parseInt(value.substring(pos+15, colonPos)); 2371 int maxValue = Integer.parseInt(value.substring(colonPos+1, 2372 closePos)); 2373 int span = maxValue - minValue + 1; 2374 count = (random.nextInt() & 0x7FFFFFFF) % span + minValue; 2375 } 2376 else 2377 { 2378 count = Integer.parseInt(value.substring(pos+15, closePos)); 2379 } 2380 2381 String randVal = generateRandomValue(BASE64_CHARS, count); 2383 switch (count % 4) 2384 { 2385 case 1: randVal += "==="; 2386 break; 2387 case 2: randVal += "=="; 2388 break; 2389 case 3: randVal += "="; 2390 break; 2391 } 2392 value = value.substring(0, pos) + randVal + 2393 value.substring(closePos + 1); 2394 needReprocess = true; 2395 } 2396 2397 if ((pos = value.indexOf("<random:telephone>")) >= 0) 2400 { 2401 String randVal = generateRandomValue(NUMERIC_CHARS, 10); 2403 value = value.substring(0, pos) + randVal.substring(0, 3) + "-" + 2404 randVal.substring(3, 6) + "-" + randVal.substring(6) + 2405 value.substring(pos + 18); 2406 needReprocess = true; 2407 } 2408 2409 if ((pos = value.indexOf("<random:month")) >= 0) 2413 { 2414 int closePos = value.indexOf('>', pos+13); 2415 String monthStr = MONTH_NAMES[(random.nextInt() & 0x7FFFFFFF) % 12]; 2416 2417 int colonPos = value.indexOf(':', pos+13); 2419 if ((colonPos > 0) && (colonPos < closePos)) 2420 { 2421 String lengthStr = value.substring(colonPos+1, closePos); 2422 int length = Integer.parseInt(lengthStr); 2423 if (monthStr.length() > length) 2424 { 2425 monthStr = monthStr.substring(0, length); 2426 } 2427 } 2428 2429 value = value.substring(0, pos) + monthStr + 2430 value.substring(closePos+1); 2431 needReprocess = true; 2432 } 2433 2434 if ((pos = value.indexOf("<guid>")) >= 0) 2436 { 2437 value = value.substring(0, pos) + generateGUID() + 2439 value.substring(pos + 6); 2440 needReprocess = true; 2441 } 2442 2443 if ((pos = value.indexOf("<sequential")) >= 0) 2446 { 2447 int closePos = value.indexOf(">", pos); 2448 2449 int colonPos = value.indexOf(":", pos); 2451 int startingValue = 0; 2452 if ((colonPos > pos) && (colonPos < closePos)) 2453 { 2454 startingValue = Integer.parseInt(value.substring(colonPos+1, 2455 closePos)); 2456 } 2457 2458 value = value.substring(0, pos) + (startingValue + entryInSequence) + 2459 value.substring(closePos+1); 2460 needReprocess = true; 2461 } 2462 } 2463 2464 needReprocess = true; 2465 while (needReprocess && ((pos = value.indexOf("{")) >= 0)) 2466 { 2467 if ((pos > 0) && (value.charAt(pos-1) == '\\')) 2470 { 2471 boolean keepGoing = true; 2472 boolean nonEscaped = false; 2473 while (keepGoing) 2474 { 2475 value = value.substring(0, pos-1) + value.substring(pos); 2476 2477 pos = value.indexOf('{', pos); 2478 if (pos < 0) 2479 { 2480 keepGoing = false; 2481 } 2482 else if (value.charAt(pos-1) != '\\') 2483 { 2484 nonEscaped = true; 2485 } 2486 } 2487 2488 if (! nonEscaped) 2489 { 2490 break; 2491 } 2492 } 2493 2494 2495 int closePos = value.indexOf("}", pos); 2501 if (closePos > 0) 2502 { 2503 int colonPos = value.indexOf(":", pos); 2504 int substringChars = -1; 2505 String attrName = null; 2506 if ((colonPos > 0) && (colonPos < closePos)) 2507 { 2508 attrName = value.substring(pos+1, colonPos).toLowerCase(); 2509 String numStr = value.substring(colonPos+1, closePos); 2510 try 2511 { 2512 substringChars = Integer.parseInt(numStr); 2513 } 2514 catch (NumberFormatException nfe) 2515 { 2516 writeVerbose(nfe.toString()); 2517 return null; 2518 } 2519 } 2520 else 2521 { 2522 attrName = value.substring(pos+1, closePos).toLowerCase(); 2523 } 2524 2525 String attrValue = ""; 2526 LDAPAttribute attr = attributeSet.getAttribute(attrName); 2527 if (attr != null) 2528 { 2529 String [] values = attr.getStringValueArray(); 2530 if ((values != null) && (values.length > 0)) 2531 { 2532 attrValue = values[0]; 2533 } 2534 } 2535 if ((colonPos > 0) && (colonPos < closePos) && (substringChars > 0) && 2536 (attrValue.length() > substringChars)) 2537 { 2538 attrValue = attrValue.substring(0, substringChars); 2539 } 2540 2541 StringBuffer valueBuffer = new StringBuffer (1000); 2542 valueBuffer.append(value.substring(0, pos)).append(attrValue). 2543 append(value.substring(closePos+1)); 2544 value = valueBuffer.toString(); 2545 needReprocess = true; 2546 } 2547 } 2548 2549 if ((pos = value.indexOf("<base64:")) >= 0) 2550 { 2551 String charset; 2552 String valueToEncode; 2553 2554 int closePos = value.indexOf('>', pos+8); 2555 int colonPos = value.indexOf(':', pos+8); 2556 if ((closePos > 0) && (colonPos > 0) && (colonPos < closePos)) 2557 { 2558 charset = value.substring(pos+8, colonPos); 2559 valueToEncode = value.substring(colonPos+1, closePos); 2560 } 2561 else 2562 { 2563 charset = "UTF-8"; 2564 valueToEncode = value.substring(pos+8, closePos); 2565 } 2566 2567 try 2568 { 2569 String encodedStr = 2570 Base64Encoder.encode(valueToEncode.getBytes(charset)); 2571 value = value.substring(0, pos) + encodedStr + 2572 value.substring(closePos+1); 2573 } 2574 catch (UnsupportedEncodingException uee) 2575 { 2576 writeVerbose(uee.toString()); 2577 return null; 2578 } 2579 } 2580 2581 return value; 2582 } 2583 2584 2585 2586 2597 public String generateRandomValue(char[] charSet, int length) 2598 { 2599 if (length <= 5000) 2605 { 2606 for (int i=0; i < length; i++) 2607 { 2608 chars5000[i] = charSet[(random.nextInt() & 0x7FFFFFFF) % 2609 charSet.length]; 2610 } 2611 2612 return new String (chars5000, 0, length); 2613 } 2614 else 2615 { 2616 char[] retArray = new char[length]; 2617 2618 for (int i=0; i < length; i++) 2619 { 2620 retArray[i] = charSet[(random.nextInt() & 0x7FFFFFFF) % charSet.length]; 2621 } 2622 2623 return new String (retArray); 2624 } 2625 } 2626 2627 2628 2629 2636 public String generateGUID() 2637 { 2638 String timeStr = Long.toHexString(System.currentTimeMillis()); 2639 String tmpStr = timeStr + 2640 generateRandomValue(HEX_CHARS, 20-timeStr.length()); 2641 return tmpStr.substring(0, 8) + "-" + tmpStr.substring(8, 12) + "-" + 2642 tmpStr.substring(12,16) + "-" + tmpStr.substring(16) + "-" + 2643 guidBase; 2644 } 2645} 2646 2647 | Popular Tags |