summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WHATSNEW.txt33
-rw-r--r--source4/auth/credentials/credentials.h5
-rw-r--r--source4/auth/credentials/credentials_krb5.c8
-rw-r--r--source4/auth/credentials/credentials_krb5.h14
-rw-r--r--source4/auth/kerberos/kerberos_util.c8
-rw-r--r--source4/auth/sam.c4
-rw-r--r--source4/build/m4/public.m48
-rw-r--r--source4/cluster/ctdb/opendb_ctdb.c2
-rw-r--r--source4/dsdb/common/util.c31
-rw-r--r--source4/dsdb/samdb/cracknames.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/kludge_acl.c45
-rw-r--r--source4/dsdb/samdb/ldb_modules/normalise.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c20
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c3
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c4
-rw-r--r--source4/heimdal/kdc/digest.c26
-rw-r--r--source4/heimdal/kdc/kaserver.c2
-rw-r--r--source4/heimdal/kdc/kdc-private.h3
-rw-r--r--source4/heimdal/kdc/kdc_locl.h5
-rw-r--r--source4/heimdal/kdc/kerberos5.c43
-rw-r--r--source4/heimdal/kdc/krb5tgs.c24
-rw-r--r--source4/heimdal/kdc/log.c10
-rwxr-xr-xsource4/heimdal/kdc/pkinit.c34
-rw-r--r--source4/heimdal/kdc/windc.c5
-rw-r--r--source4/heimdal/kdc/windc_plugin.h2
-rw-r--r--source4/heimdal/kuser/kinit.c27
-rw-r--r--source4/heimdal/lib/asn1/asn1-common.h2
-rw-r--r--source4/heimdal/lib/asn1/canthandle.asn14
-rw-r--r--source4/heimdal/lib/asn1/der.c2
-rw-r--r--source4/heimdal/lib/asn1/digest.asn118
-rw-r--r--source4/heimdal/lib/asn1/gen.c2
-rw-r--r--source4/heimdal/lib/asn1/gen_encode.c2
-rw-r--r--source4/heimdal/lib/asn1/k5.asn16
-rw-r--r--source4/heimdal/lib/asn1/lex.c44
-rw-r--r--source4/heimdal/lib/asn1/parse.c184
-rw-r--r--source4/heimdal/lib/asn1/parse.h4
-rw-r--r--source4/heimdal/lib/asn1/pkinit.asn123
-rw-r--r--source4/heimdal/lib/asn1/rfc2459.asn12
-rw-r--r--source4/heimdal/lib/com_err/lex.c44
-rw-r--r--source4/heimdal/lib/com_err/parse.c28
-rw-r--r--source4/heimdal/lib/com_err/parse.h4
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h3
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_mech.h2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/acquire_cred.c74
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h3
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c54
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_cred_option.c39
-rw-r--r--source4/heimdal/lib/gssapi/mech/context.c18
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c6
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_krb5.c43
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_mech_switch.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c4
-rw-r--r--source4/heimdal/lib/gssapi/spnego/accept_sec_context.c27
-rw-r--r--source4/heimdal/lib/gssapi/spnego/compat.c3
-rw-r--r--source4/heimdal/lib/gssapi/spnego/context_stubs.c70
-rw-r--r--source4/heimdal/lib/gssapi/spnego/external.c4
-rw-r--r--source4/heimdal/lib/gssapi/spnego/init_sec_context.c11
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego-private.h9
-rw-r--r--source4/heimdal/lib/hcrypto/bn.c6
-rw-r--r--source4/heimdal/lib/hcrypto/bn.h4
-rw-r--r--source4/heimdal/lib/hcrypto/camellia-ntt.c1461
-rw-r--r--source4/heimdal/lib/hcrypto/camellia-ntt.h54
-rw-r--r--source4/heimdal/lib/hcrypto/camellia.c118
-rw-r--r--source4/heimdal/lib/hcrypto/camellia.h74
-rw-r--r--source4/heimdal/lib/hcrypto/dh-imath.c14
-rw-r--r--source4/heimdal/lib/hcrypto/dh.c215
-rw-r--r--source4/heimdal/lib/hcrypto/evp.c648
-rw-r--r--source4/heimdal/lib/hcrypto/evp.h8
-rw-r--r--source4/heimdal/lib/hcrypto/hmac.c35
-rwxr-xr-xsource4/heimdal/lib/hcrypto/imath/imath.c6
-rw-r--r--source4/heimdal/lib/hcrypto/rand.c15
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.c97
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.h4
-rw-r--r--source4/heimdal/lib/hdb/dbinfo.c266
-rw-r--r--source4/heimdal/lib/hdb/hdb-protos.h11
-rw-r--r--source4/heimdal/lib/hdb/hdb.h6
-rw-r--r--source4/heimdal/lib/hdb/hdb_locl.h5
-rw-r--r--source4/heimdal/lib/hdb/keys.c15
-rw-r--r--source4/heimdal/lib/hdb/mkey.c7
-rw-r--r--source4/heimdal/lib/hx509/ca.c334
-rw-r--r--source4/heimdal/lib/hx509/cert.c878
-rw-r--r--source4/heimdal/lib/hx509/cms.c173
-rw-r--r--source4/heimdal/lib/hx509/crypto.c194
-rw-r--r--source4/heimdal/lib/hx509/env.c52
-rw-r--r--source4/heimdal/lib/hx509/error.c81
-rw-r--r--source4/heimdal/lib/hx509/hx509-private.h52
-rw-r--r--source4/heimdal/lib/hx509/hx509-protos.h47
-rw-r--r--source4/heimdal/lib/hx509/hx509.h7
-rw-r--r--source4/heimdal/lib/hx509/hx509_err.et4
-rw-r--r--source4/heimdal/lib/hx509/hx_locl.h6
-rw-r--r--source4/heimdal/lib/hx509/keyset.c237
-rw-r--r--source4/heimdal/lib/hx509/ks_file.c38
-rw-r--r--source4/heimdal/lib/hx509/ks_keychain.c10
-rw-r--r--source4/heimdal/lib/hx509/ks_p11.c4
-rw-r--r--source4/heimdal/lib/hx509/lock.c8
-rw-r--r--source4/heimdal/lib/hx509/name.c367
-rw-r--r--source4/heimdal/lib/hx509/peer.c54
-rw-r--r--source4/heimdal/lib/hx509/print.c200
-rw-r--r--source4/heimdal/lib/hx509/revoke.c398
-rw-r--r--source4/heimdal/lib/krb5/acache.c270
-rw-r--r--source4/heimdal/lib/krb5/add_et_list.c12
-rw-r--r--source4/heimdal/lib/krb5/addr_families.c282
-rw-r--r--source4/heimdal/lib/krb5/asn1_glue.c6
-rw-r--r--source4/heimdal/lib/krb5/auth_context.c8
-rw-r--r--source4/heimdal/lib/krb5/cache.c330
-rw-r--r--source4/heimdal/lib/krb5/context.c334
-rw-r--r--source4/heimdal/lib/krb5/convert_creds.c31
-rw-r--r--source4/heimdal/lib/krb5/copy_host_realm.c13
-rw-r--r--source4/heimdal/lib/krb5/creds.c84
-rw-r--r--source4/heimdal/lib/krb5/crypto.c63
-rw-r--r--source4/heimdal/lib/krb5/data.c100
-rw-r--r--source4/heimdal/lib/krb5/eai_to_heim_errno.c26
-rw-r--r--source4/heimdal/lib/krb5/error_string.c33
-rw-r--r--source4/heimdal/lib/krb5/expand_hostname.c6
-rw-r--r--source4/heimdal/lib/krb5/fcache.c131
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c10
-rw-r--r--source4/heimdal/lib/krb5/get_for_creds.c94
-rw-r--r--source4/heimdal/lib/krb5/get_in_tkt.c2
-rw-r--r--source4/heimdal/lib/krb5/init_creds.c2
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c12
-rw-r--r--source4/heimdal/lib/krb5/kcm.c30
-rw-r--r--source4/heimdal/lib/krb5/keytab.c7
-rw-r--r--source4/heimdal/lib/krb5/keytab_file.c6
-rw-r--r--source4/heimdal/lib/krb5/keytab_keyfile.c6
-rw-r--r--source4/heimdal/lib/krb5/keytab_krb4.c28
-rw-r--r--source4/heimdal/lib/krb5/krb5-private.h11
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h50
-rw-r--r--source4/heimdal/lib/krb5/krb5.h21
-rw-r--r--source4/heimdal/lib/krb5/krb5_ccapi.h8
-rw-r--r--source4/heimdal/lib/krb5/krb5_locl.h14
-rw-r--r--source4/heimdal/lib/krb5/mcache.c57
-rw-r--r--source4/heimdal/lib/krb5/n-fold.c23
-rw-r--r--source4/heimdal/lib/krb5/pac.c92
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c90
-rw-r--r--source4/heimdal/lib/krb5/plugin.c23
-rw-r--r--source4/heimdal/lib/krb5/principal.c37
-rw-r--r--source4/heimdal/lib/krb5/rd_priv.c2
-rw-r--r--source4/heimdal/lib/krb5/rd_req.c44
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c4
-rw-r--r--source4/heimdal/lib/krb5/store.c10
-rw-r--r--source4/heimdal/lib/krb5/store_emem.c21
-rw-r--r--source4/heimdal/lib/krb5/transited.c19
-rw-r--r--source4/heimdal/lib/krb5/v4_glue.c4
-rw-r--r--source4/heimdal/lib/ntlm/heimntlm-protos.h11
-rw-r--r--source4/heimdal/lib/ntlm/heimntlm.h81
-rw-r--r--source4/heimdal/lib/ntlm/ntlm.c278
-rw-r--r--source4/heimdal/lib/vers/print_version.c4
-rw-r--r--source4/heimdal/lib/wind/bidi.c92
-rw-r--r--source4/heimdal/lib/wind/bidi_table.c410
-rw-r--r--source4/heimdal/lib/wind/bidi_table.h21
-rw-r--r--source4/heimdal/lib/wind/combining.c62
-rw-r--r--source4/heimdal/lib/wind/combining_table.c362
-rw-r--r--source4/heimdal/lib/wind/combining_table.h18
-rw-r--r--source4/heimdal/lib/wind/errorlist.c77
-rw-r--r--source4/heimdal/lib/wind/errorlist_table.c88
-rw-r--r--source4/heimdal/lib/wind/errorlist_table.h19
-rw-r--r--source4/heimdal/lib/wind/ldap.c91
-rw-r--r--source4/heimdal/lib/wind/map.c87
-rw-r--r--source4/heimdal/lib/wind/map_table.c2613
-rw-r--r--source4/heimdal/lib/wind/map_table.h22
-rw-r--r--source4/heimdal/lib/wind/normalize.c301
-rw-r--r--source4/heimdal/lib/wind/normalize_table.c22976
-rw-r--r--source4/heimdal/lib/wind/normalize_table.h34
-rw-r--r--source4/heimdal/lib/wind/stringprep.c141
-rw-r--r--source4/heimdal/lib/wind/utf8.c443
-rw-r--r--source4/heimdal/lib/wind/wind.h82
-rw-r--r--source4/heimdal/lib/wind/wind_err.et22
-rw-r--r--source4/heimdal/lib/wind/windlocl.h64
-rw-r--r--source4/heimdal_build/config.h2
-rw-r--r--source4/heimdal_build/config.mk43
-rw-r--r--source4/kdc/hdb-ldb.c2
-rw-r--r--source4/kdc/kdc.c6
-rw-r--r--source4/kdc/pac-glue.c66
-rw-r--r--source4/lib/events/events_signal.c2
-rw-r--r--source4/lib/ldb/Makefile.in2
-rw-r--r--source4/lib/ldb/common/ldb.c2
-rw-r--r--source4/lib/ldb/include/ldb_includes.h1
-rw-r--r--source4/lib/ldb/include/ldb_private.h2
-rw-r--r--source4/lib/ldb/ldb.i34
-rw-r--r--source4/lib/ldb/ldb_ldap/ldb_ldap.c6
-rw-r--r--source4/lib/ldb/ldb_wrap.c65
-rw-r--r--source4/lib/ldb/rules.mk2
-rw-r--r--source4/lib/ldb/tests/sample_module.c2
-rwxr-xr-xsource4/lib/ldb/tests/test-soloading.sh2
-rw-r--r--source4/lib/messaging/messaging.c2
-rw-r--r--source4/lib/registry/registry_wrap.c26
-rw-r--r--source4/lib/replace/README2
-rw-r--r--source4/lib/replace/configure.ac3
-rw-r--r--source4/lib/replace/getifaddrs.m411
-rw-r--r--source4/lib/replace/getpass.c8
-rw-r--r--source4/lib/replace/inet_aton.c33
-rw-r--r--source4/lib/replace/inet_aton.m41
-rw-r--r--source4/lib/replace/inet_ntoa.c39
-rw-r--r--source4/lib/replace/inet_ntoa.m419
-rw-r--r--source4/lib/replace/libreplace.m423
-rw-r--r--source4/lib/replace/replace.c37
-rw-r--r--source4/lib/replace/replace.h9
-rw-r--r--source4/lib/replace/samba.m43
-rw-r--r--source4/lib/replace/snprintf.c2
-rw-r--r--source4/lib/replace/socket.m415
-rw-r--r--source4/lib/replace/socketpair.c46
-rw-r--r--source4/lib/replace/socketpair.m41
-rw-r--r--source4/lib/replace/system/network.h14
-rw-r--r--source4/lib/replace/test/os2_delete.c9
-rw-r--r--source4/lib/socket/config.m444
-rw-r--r--source4/lib/socket/config.mk6
-rw-r--r--source4/lib/socket_wrapper/config.mk2
-rw-r--r--source4/lib/socket_wrapper/socket_wrapper.c79
-rw-r--r--source4/lib/util/config.mk4
-rw-r--r--source4/libcli/composite/composite.c1
-rw-r--r--source4/libcli/raw/interfaces.h13
-rw-r--r--source4/libcli/raw/rawfile.c26
-rw-r--r--source4/libcli/security/security.h8
-rw-r--r--source4/libcli/security/security_token.c27
-rw-r--r--source4/libcli/security/security_wrap.c8
-rw-r--r--source4/libcli/swig/libcli_nbt_wrap.c2
-rw-r--r--source4/libcli/util/errors.i4
-rw-r--r--source4/libnet/libnet_rpc.c5
-rw-r--r--source4/libnet/net_wrap.c60
-rw-r--r--source4/librpc/config.mk2
-rw-r--r--source4/librpc/idl/opendb.idl1
-rw-r--r--source4/nsswitch/config.m43
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c7
-rw-r--r--source4/ntvfs/common/config.mk2
-rw-r--r--source4/ntvfs/common/opendb.c4
-rw-r--r--source4/ntvfs/common/opendb.h2
-rw-r--r--source4/ntvfs/common/opendb_tdb.c50
-rw-r--r--source4/ntvfs/posix/pvfs_open.c125
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c12
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c6
-rw-r--r--source4/ntvfs/sysdep/config.m410
-rw-r--r--source4/ntvfs/sysdep/config.mk8
-rw-r--r--source4/ntvfs/sysdep/sys_lease.c142
-rw-r--r--source4/ntvfs/sysdep/sys_lease.h65
-rw-r--r--source4/ntvfs/sysdep/sys_lease_linux.c213
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm34
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c71
-rw-r--r--source4/rpc_server/lsa/lsa_lookup.c1
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c138
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.h2
-rw-r--r--source4/rpc_server/winreg/rpc_winreg.c233
-rwxr-xr-xsource4/script/valgrind_run4
-rw-r--r--source4/scripting/python/config.m42
-rw-r--r--source4/scripting/python/misc_wrap.c2
-rw-r--r--source4/scripting/python/samba/provision.py634
-rw-r--r--source4/scripting/python/uuidmodule.c5
-rw-r--r--source4/selftest/output/plain.pm4
-rwxr-xr-xsource4/selftest/selftest.pl2
-rw-r--r--source4/selftest/target/Samba4.pm15
-rwxr-xr-xsource4/setup/newuser141
-rwxr-xr-xsource4/setup/newuser.py61
-rwxr-xr-xsource4/setup/provision3
-rwxr-xr-xsource4/setup/provision-backend287
-rw-r--r--source4/setup/provision-backend.js188
-rwxr-xr-xsource4/setup/provision.js198
-rw-r--r--source4/setup/provision_basedn.ldif3
-rw-r--r--source4/setup/schema-map-openldap-2.31
-rw-r--r--source4/setup/schema_samba4.ldif38
-rw-r--r--source4/setup/slapd.conf8
-rwxr-xr-xsource4/setup/tests/blackbox_provision.sh2
-rw-r--r--source4/smb_server/smb/nttrans.c25
-rw-r--r--source4/static_deps.mk3
-rw-r--r--source4/torture/raw/openbench.c112
-rw-r--r--source4/torture/raw/oplock.c333
-rw-r--r--source4/torture/raw/rename.c6
-rw-r--r--source4/torture/raw/search.c10
-rw-r--r--source4/torture/raw/streams.c10
-rw-r--r--source4/torture/rpc/lsa.c2
-rw-r--r--source4/torture/rpc/samba3rpc.c53
-rw-r--r--source4/torture/rpc/samr.c87
-rw-r--r--source4/utils/ntlm_auth.c20
-rw-r--r--source4/winbind/config.mk2
-rw-r--r--source4/winbind/idmap.c722
-rw-r--r--source4/winbind/idmap.h20
-rw-r--r--source4/winbind/wb_gid2sid.c47
-rw-r--r--source4/winbind/wb_sid2gid.c48
-rw-r--r--source4/winbind/wb_sid2uid.c50
-rw-r--r--source4/winbind/wb_sids2xids.c82
-rw-r--r--source4/winbind/wb_uid2sid.c49
-rw-r--r--source4/winbind/wb_xids2sids.c82
-rwxr-xr-xtestprogs/ejs/ldap.js28
283 files changed, 40103 insertions, 3433 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 0ce24fb60f..52f3055572 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,4 +1,4 @@
-What's new in Samba 4 alpha2
+What's new in Samba 4 alpha3
============================
Samba 4 is the ambitious next version of the Samba suite that is being
@@ -10,14 +10,14 @@ Samba 4 is currently not yet in a state where it is usable in
production environments. Note the WARNINGS below, and the STATUS file,
which aims to document what should and should not work.
-Samba4 alpha2 follows on from our first alpha release, made in
+Samba4 alpha3 follows on from our first alpha release, made in
September, and the Technology Preview series we have offered for some
time now.
WARNINGS
========
-Samba4 alpha2 is not a final Samba release. That is more a reference
+Samba4 alpha3 is not a final Samba release. That is more a reference
to Samba4's lack of the features we expect you will need than a
statement of code quality, but clearly it hasn't seen a broad
deployment yet. If you were to upgrade Samba3 (or indeed Windows) to
@@ -64,29 +64,27 @@ working on modules to map between AD-like behaviours and this backend.
We are aiming for Samba 4 to be powerful frontend to large
directories.
-CHANGES SINCE Alpha 1
+CHANGES SINCE Alpha2
=====================
-In the time since Samba4 Alpha1 was released in September 2007, Samba has
+In the time since Samba4 Alpha2 was released in December 2007, Samba has
continued to evolve, but you may particularly notice these areas:
- MMC Support: The Active Directory Users and Computers console now
- handles group membership correctly.
+ Python Bindings: Bindings for Python are now in place, and used for
+ Samba's provision script, slowly displacing EJS as the embedded
+ scripting language
- member/memberOf: These and other linked attributes are now kept in
- sync
+ SWAT Disabled: Due to a lack of developer time and without a
+ long-term web developer to maintain it, the SWAT web UI has been
+ disabled.
- subtree renames: Renaming a subtree of LDAP objects is now possible,
- with all linked attributes being kept consistant.
+ Oplock support: Samba4's file server now supports oplocks
- Python Bindings: Bindings for a future move to Python as the
- internal scripting language have been created.
-
- Shared library use: In support of projects such as OpenChange,
- which depend on Samba4, more of Samba4 is built as shared libraries.
+ GNU Make: To try and simplfy our build system, we rely on GNU Make
+ to avoid autogenerating a massive single makefile.
These are just some of the highlights of the work done in the past few
-months. More details can be found in our SVN history.
+months. More details can be found in our GIT history.
CHANGES
@@ -109,6 +107,7 @@ KNOWN ISSUES
actually due to Kerberos objecting to a clock skew between client
and server.
+
RUNNING Samba4
==============
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index a3da5c6054..1b205c61ce 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -128,7 +128,10 @@ struct cli_credentials {
struct ldb_context;
struct loadparm_context;
-#include "auth/credentials/credentials_krb5.h"
+struct ccache_container;
+
+struct gssapi_creds_container;
+
#include "auth/credentials/credentials_proto.h"
#endif /* __CREDENTIALS_H__ */
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index 90b196e99e..52bf9f124f 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -400,10 +400,10 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
to the credentials system.
*/
-int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
- struct loadparm_context *lp_ctx,
- gss_cred_id_t gssapi_cred,
- enum credentials_obtained obtained)
+ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
+ struct loadparm_context *lp_ctx,
+ gss_cred_id_t gssapi_cred,
+ enum credentials_obtained obtained)
{
int ret;
OM_uint32 maj_stat, min_stat;
diff --git a/source4/auth/credentials/credentials_krb5.h b/source4/auth/credentials/credentials_krb5.h
index b963fbdca4..aaa7d7f0da 100644
--- a/source4/auth/credentials/credentials_krb5.h
+++ b/source4/auth/credentials/credentials_krb5.h
@@ -26,10 +26,20 @@
#include <gssapi/gssapi.h>
#include <krb5.h>
-struct ccache_container;
-
struct gssapi_creds_container {
gss_cred_id_t creds;
};
+/* Manually prototyped here to avoid needing gss headers in most callers */
+int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
+ struct loadparm_context *lp_ctx,
+ gss_cred_id_t gssapi_cred,
+ enum credentials_obtained obtained);
+
+/* Manually prototyped here to avoid needing krb5 headers in most callers */
+krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
+ struct cli_credentials *credentials,
+ struct smb_krb5_context *smb_krb5_context,
+ krb5_principal *princ);
+
#endif /* __CREDENTIALS_KRB5_H__ */
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index 70e2961d55..e905e3e704 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -101,10 +101,10 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
* the library routines. The returned princ is placed in the talloc
* system by means of a destructor (do *not* free). */
-krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
- struct cli_credentials *credentials,
- struct smb_krb5_context *smb_krb5_context,
- krb5_principal *princ)
+ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
+ struct cli_credentials *credentials,
+ struct smb_krb5_context *smb_krb5_context,
+ krb5_principal *princ)
{
krb5_error_code ret;
const char *princ_string;
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index 882196343c..b171fc57b9 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -157,7 +157,7 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
- acct_expiry = samdb_result_account_expires(msg, 0);
+ acct_expiry = samdb_result_account_expires(msg);
/* Check for when we must change this password, taking the
* userAccountControl flags into account */
@@ -351,7 +351,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
server_info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
server_info->last_logoff = samdb_result_nttime(msg, "lastLogoff", 0);
- server_info->acct_expiry = samdb_result_account_expires(msg, 0);
+ server_info->acct_expiry = samdb_result_account_expires(msg);
server_info->last_password_change = samdb_result_nttime(msg, "pwdLastSet", 0);
ncname = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4
index 604092c8d7..0058afe2b5 100644
--- a/source4/build/m4/public.m4
+++ b/source4/build/m4/public.m4
@@ -39,13 +39,13 @@ ENABLE = YES
"
])
-dnl SMB_LIBRARY(name,obj_files,required_subsystems,version,so_version,cflags,ldflags)
+dnl SMB_LIBRARY(name,obj_files,required_subsystems,cflags,ldflags)
AC_DEFUN([SMB_LIBRARY],
[
MAKE_SETTINGS="$MAKE_SETTINGS
$1_OBJ_FILES = $2
-$1_CFLAGS = $6
-$1_LDFLAGS = $7
+$1_CFLAGS = $4
+$1_LDFLAGS = $5
$1_ENABLE = YES
"
@@ -54,8 +54,6 @@ SMB_INFO_LIBRARIES="$SMB_INFO_LIBRARIES
# Start Library $1
@<:@LIBRARY::$1@:>@
PRIVATE_DEPENDENCIES = $3
-VERSION = $4
-SO_VERSION = $5
CFLAGS = \$($1_CFLAGS)
LDFLAGS = \$($1_LDFLAGS)
ENABLE = YES
diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c
index a7b8ddf760..402f3a2a1a 100644
--- a/source4/cluster/ctdb/opendb_ctdb.c
+++ b/source4/cluster/ctdb/opendb_ctdb.c
@@ -283,7 +283,7 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_ent
*/
static NTSTATUS odb_ctdb_open_file(struct odb_lock *lck,
void *file_handle, const char *path,
- bool allow_level_II_oplock,
+ int *fd, bool allow_level_II_oplock,
uint32_t oplock_level, uint32_t *oplock_granted)
{
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 88c8afd6cc..1220a5c855 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -445,13 +445,12 @@ NTTIME samdb_result_nttime(struct ldb_message *msg, const char *attr, NTTIME def
* Consolidate that logic here to allow clearer logic for account expiry in
* the rest of the code.
*/
-NTTIME samdb_result_account_expires(struct ldb_message *msg,
- NTTIME default_value)
+NTTIME samdb_result_account_expires(struct ldb_message *msg)
{
NTTIME ret = ldb_msg_find_attr_as_uint64(msg, "accountExpires",
- default_value);
+ 0);
- if (ret == (NTTIME)0)
+ if (ret == 0)
ret = 0x7FFFFFFFFFFFFFFFULL;
return ret;
@@ -1004,7 +1003,13 @@ struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
{
TALLOC_CTX *tmp_ctx;
- struct dom_sid *domain_sid;
+ const struct dom_sid *domain_sid;
+ const char *attrs[] = {
+ "objectSid",
+ NULL
+ };
+ struct ldb_result *res;
+ int ret;
/* see if we have a cached copy */
domain_sid = (struct dom_sid *)ldb_get_opaque(ldb, "cache.domain_sid");
@@ -1017,9 +1022,17 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
goto failed;
}
- /* find the domain_sid */
- domain_sid = samdb_search_dom_sid(ldb, tmp_ctx, ldb_get_default_basedn(ldb),
- "objectSid", "objectClass=domainDNS");
+ ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, attrs, "objectSid=*");
+
+ if (ret != LDB_SUCCESS) {
+ goto failed;
+ }
+
+ if (res->count != 1) {
+ goto failed;
+ }
+
+ domain_sid = samdb_result_dom_sid(tmp_ctx, res->msgs[0], "objectSid");
if (domain_sid == NULL) {
goto failed;
}
@@ -1464,7 +1477,7 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
ret = ldb_search(ldb, sdn, LDB_SCOPE_BASE,
- "(|(objectClass=domain)(objectClass=builtinDomain))", attrs, &res);
+ "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))", attrs, &res);
if (ret == LDB_SUCCESS) {
talloc_steal(local_ctx, res);
if (res->count == 1) {
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index 93da46d5bd..b9333e451b 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -329,7 +329,7 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
result_filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))",
ldb_binary_encode_string(mem_ctx, unparsed_name_short));
- domain_filter = talloc_asprintf(mem_ctx, "(dn=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));
+ domain_filter = talloc_asprintf(mem_ctx, "(distinguishedName=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));
if (!result_filter || !domain_filter) {
free(unparsed_name_short);
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
index e3e1f7ac88..e418031271 100644
--- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c
+++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -46,42 +46,15 @@
*
*/
-enum user_is {
- ANONYMOUS,
- USER,
- ADMINISTRATOR,
- SYSTEM
-};
-
struct kludge_private_data {
const char **password_attrs;
};
-static enum user_is what_is_user(struct ldb_module *module)
+static enum security_user_level what_is_user(struct ldb_module *module)
{
struct auth_session_info *session_info
= (struct auth_session_info *)ldb_get_opaque(module->ldb, "sessionInfo");
- if (!session_info) {
- return ANONYMOUS;
- }
-
- if (security_token_is_system(session_info->security_token)) {
- return SYSTEM;
- }
-
- if (security_token_is_anonymous(session_info->security_token)) {
- return ANONYMOUS;
- }
-
- if (security_token_has_builtin_administrators(session_info->security_token)) {
- return ADMINISTRATOR;
- }
-
- if (security_token_has_nt_authenticated_users(session_info->security_token)) {
- return USER;
- }
-
- return ANONYMOUS;
+ return security_session_user_level(session_info);
}
static const char *user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module)
@@ -104,7 +77,7 @@ struct kludge_acl_context {
void *up_context;
int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *);
- enum user_is user_type;
+ enum security_user_level user_type;
bool allowedAttributes;
bool allowedAttributesEffective;
bool allowedChildClasses;
@@ -272,8 +245,8 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
if (data && data->password_attrs) /* if we are not initialized just get through */
{
switch (ac->user_type) {
- case SYSTEM:
- case ADMINISTRATOR:
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
if (ac->allowedAttributesEffective) {
ret = kludge_acl_allowedAttributes(ldb, ares->message, "allowedAttributesEffective");
if (ret != LDB_SUCCESS) {
@@ -359,7 +332,7 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
so we don't allow a search for 'sambaPassword=penguin',
just as we would not allow that attribute to be returned */
switch (ac->user_type) {
- case SYSTEM:
+ case SECURITY_SYSTEM:
break;
default:
/* remove password attributes */
@@ -391,10 +364,10 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
/* ANY change type */
static int kludge_acl_change(struct ldb_module *module, struct ldb_request *req)
{
- enum user_is user_type = what_is_user(module);
+ enum security_user_level user_type = what_is_user(module);
switch (user_type) {
- case SYSTEM:
- case ADMINISTRATOR:
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
return ldb_next_request(module, req);
default:
ldb_asprintf_errstring(module->ldb,
diff --git a/source4/dsdb/samdb/ldb_modules/normalise.c b/source4/dsdb/samdb/ldb_modules/normalise.c
index a0eff43534..8de9e33002 100644
--- a/source4/dsdb/samdb/ldb_modules/normalise.c
+++ b/source4/dsdb/samdb/ldb_modules/normalise.c
@@ -117,7 +117,7 @@ static int normalise_search_callback(struct ldb_context *ldb, void *context, str
talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = fix_dn(ares->message->dn);
+ ret = fix_dn(dn);
if (ret != LDB_SUCCESS) {
talloc_free(mem_ctx);
return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index e63ad4de56..4d4ef585cb 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -257,12 +257,18 @@ static DATA_BLOB *get_sd(struct ldb_module *module, TALLOC_CTX *mem_ctx,
DATA_BLOB *linear_sd;
struct auth_session_info *session_info
= ldb_get_opaque(module->ldb, "sessionInfo");
- struct security_descriptor *sd
- = sddl_decode(mem_ctx,
- objectclass->defaultSecurityDescriptor,
- samdb_domain_sid(module->ldb));
+ struct security_descriptor *sd;
+ struct dom_sid *domain_sid = samdb_domain_sid(module->ldb);
- if (!session_info || !session_info->security_token) {
+ if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
+ return NULL;
+ }
+
+ sd = sddl_decode(mem_ctx,
+ objectclass->defaultSecurityDescriptor,
+ domain_sid);
+
+ if (!sd || !session_info || !session_info->security_token) {
return NULL;
}
@@ -538,7 +544,9 @@ static int objectclass_do_add(struct ldb_handle *h)
}
if (!ldb_msg_find_element(msg, "nTSecurityDescriptor")) {
DATA_BLOB *sd = get_sd(ac->module, mem_ctx, current->objectclass);
- ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
+ if (sd) {
+ ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
+ }
}
}
}
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index aa64700f2f..1d2bdd988e 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1220,7 +1220,8 @@ static int build_domain_data_request(struct ph_context *ac)
ac->dom_req->op.search.base = ldb_get_default_basedn(ac->module->ldb);
ac->dom_req->op.search.scope = LDB_SCOPE_SUBTREE;
- filter = talloc_asprintf(ac->dom_req, "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))",
+ filter = talloc_asprintf(ac->dom_req,
+ "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
ldap_encode_ndr_dom_sid(ac->dom_req, ac->domain_sid));
if (filter == NULL) {
ldb_debug(ac->module->ldb, LDB_DEBUG_ERROR, "Out of Memory!\n");
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 905cd4a995..5407db9956 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -293,7 +293,7 @@ int samldb_notice_sid(struct ldb_module *module,
/* find the domain DN */
ret = ldb_search_exp_fmt(module->ldb, mem_ctx, &dom_res,
NULL, LDB_SCOPE_SUBTREE, attrs,
- "(&(objectSid=%s)(objectclass=domain))",
+ "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
if (ret == LDB_SUCCESS) {
if (dom_res->count == 0) {
@@ -369,7 +369,7 @@ static int samldb_generate_samAccountName(struct ldb_module *module, TALLOC_CTX
/* Format: $000000-000000000000 */
do {
- *name = talloc_asprintf(mem_ctx, "$%.6X-%.6X%.6X", (unsigned int)random(), (unsigned int)random(), (unsigned int)random());
+ *name = talloc_asprintf(mem_ctx, "$%.6X-%.6X%.6X", (unsigned int)generate_random(), (unsigned int)generate_random(), (unsigned int)generate_random());
/* TODO: Figure out exactly what this is meant to conflict with */
ret = ldb_search_exp_fmt(module->ldb,
mem_ctx, &res, dom_dn, LDB_SCOPE_SUBTREE, attrs,
diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c
index 358ca5ad56..b845b0f9a8 100644
--- a/source4/heimdal/kdc/digest.c
+++ b/source4/heimdal/kdc/digest.c
@@ -34,7 +34,7 @@
#include "kdc_locl.h"
#include <hex.h>
-RCSID("$Id: digest.c 21606 2007-07-17 07:03:25Z lha $");
+RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $");
#define MS_CHAP_V2 0x20
#define CHAP_MD5 0x10
@@ -1003,7 +1003,8 @@ _kdc_do_digest(krb5_context context,
}
r.u.ntlmInitReply.flags |=
- NTLM_NEG_TARGET_DOMAIN |
+ NTLM_NEG_TARGET |
+ NTLM_TARGET_DOMAIN |
NTLM_ENC_128;
#define ALL \
@@ -1331,6 +1332,27 @@ _kdc_do_digest(krb5_context context,
version, ireq.u.ntlmRequest.username);
break;
}
+ case choice_DigestReqInner_supportedMechs:
+
+ kdc_log(context, config, 0, "digest supportedMechs from %s", from);
+
+ r.element = choice_DigestRepInner_supportedMechs;
+ memset(&r.u.supportedMechs, 0, sizeof(r.u.supportedMechs));
+
+ if (config->digests_allowed & NTLM_V1)
+ r.u.supportedMechs.ntlm_v1 = 1;
+ if (config->digests_allowed & NTLM_V1_SESSION)
+ r.u.supportedMechs.ntlm_v1_session = 1;
+ if (config->digests_allowed & NTLM_V2)
+ r.u.supportedMechs.ntlm_v2 = 1;
+ if (config->digests_allowed & DIGEST_MD5)
+ r.u.supportedMechs.digest_md5 = 1;
+ if (config->digests_allowed & CHAP_MD5)
+ r.u.supportedMechs.chap_md5 = 1;
+ if (config->digests_allowed & MS_CHAP_V2)
+ r.u.supportedMechs.ms_chap_v2 = 1;
+ break;
+
default: {
char *s;
krb5_set_error_string(context, "unknown operation to digest");
diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c
index 15624e8e76..27f497ea66 100644
--- a/source4/heimdal/kdc/kaserver.c
+++ b/source4/heimdal/kdc/kaserver.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: kaserver.c 21661 2007-07-22 01:57:17Z lha $");
+RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $");
#include <krb5-v4compat.h>
#include <rx.h>
diff --git a/source4/heimdal/kdc/kdc-private.h b/source4/heimdal/kdc/kdc-private.h
index 030be9ae58..4052e9b509 100644
--- a/source4/heimdal/kdc/kdc-private.h
+++ b/source4/heimdal/kdc/kdc-private.h
@@ -281,6 +281,7 @@ krb5_error_code
_kdc_windc_client_access (
krb5_context /*context*/,
struct hdb_entry_ex */*client*/,
- KDC_REQ */*req*/);
+ KDC_REQ */*req*/,
+ krb5_data */*e_data*/);
#endif /* __kdc_private_h__ */
diff --git a/source4/heimdal/kdc/kdc_locl.h b/source4/heimdal/kdc/kdc_locl.h
index fdbdf271de..fe0523665a 100644
--- a/source4/heimdal/kdc/kdc_locl.h
+++ b/source4/heimdal/kdc/kdc_locl.h
@@ -32,7 +32,7 @@
*/
/*
- * $Id: kdc_locl.h 20954 2007-06-07 03:30:15Z lha $
+ * $Id: kdc_locl.h 22247 2007-12-08 23:49:41Z lha $
*/
#ifndef __KDC_LOCL_H__
@@ -58,8 +58,7 @@ extern int detach_from_console;
extern const struct units _kdc_digestunits[];
-#define _PATH_KDC_CONF HDB_DB_DIR "/kdc.conf"
-#define DEFAULT_LOG_DEST "0-1/FILE:" HDB_DB_DIR "/kdc.log"
+#define KDC_LOG_FILE "kdc.log"
extern struct timeval _kdc_now;
#define kdc_time (_kdc_now.tv_sec)
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 40a9c9c972..f1dea6499d 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: kerberos5.c 21529 2007-07-13 12:37:14Z lha $");
+RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $");
#define MAX_TIME ((time_t)((1U << 31) - 1))
@@ -362,6 +362,13 @@ older_enctype(krb5_enctype enctype)
case ETYPE_DES3_CBC_SHA1:
case ETYPE_ARCFOUR_HMAC_MD5:
case ETYPE_ARCFOUR_HMAC_MD5_56:
+ /*
+ * The following three is "old" windows enctypes and is needed for
+ * windows 2000 hosts.
+ */
+ case ETYPE_ARCFOUR_MD4:
+ case ETYPE_ARCFOUR_HMAC_OLD:
+ case ETYPE_ARCFOUR_HMAC_OLD_EXP:
return 1;
default:
return 0;
@@ -411,8 +418,8 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
*ent->salttype = key->salt->type;
#else
/*
- * We shouldn't sent salttype since its incompatible with the
- * specification and its break windows clients. The afs
+ * We shouldn't sent salttype since it is incompatible with the
+ * specification and it breaks windows clients. The afs
* salting problem is solved by using KRB5-PADATA-AFS3-SALT
* implemented in Heimdal 0.7 and later.
*/
@@ -472,11 +479,13 @@ get_pa_etype_info(krb5_context context,
free_ETYPE_INFO(&pa);
return ret;
}
+ break;
}
}
skip1:;
}
for(i = 0; i < client->keys.len; i++) {
+ /* already added? */
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j])
goto skip2;
@@ -497,7 +506,7 @@ get_pa_etype_info(krb5_context context,
}
if(n < pa.len) {
- /* stripped out newer enctypes */
+ /* stripped out dups, newer enctypes, and not valid enctypes */
pa.len = n;
}
@@ -621,23 +630,29 @@ get_pa_etype_info2(krb5_context context,
if(client->keys.val[i].key.keytype == etypes[j]) {
if (krb5_enctype_valid(context, etypes[j]) != 0)
continue;
+ if (n >= pa.len)
+ krb5_abortx(context, "internal error: n >= p.len");
if((ret = make_etype_info2_entry(&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO2(&pa);
return ret;
}
+ break;
}
}
skip1:;
}
- /* send enctypes that the cliene doesn't know about too */
+ /* send enctypes that the client doesn't know about too */
for(i = 0; i < client->keys.len; i++) {
+ /* already added? */
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j])
goto skip2;
}
if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
continue;
+ if (n >= pa.len)
+ krb5_abortx(context, "internal error: n >= p.len");
if((ret = make_etype_info2_entry(&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO2(&pa);
@@ -646,16 +661,8 @@ get_pa_etype_info2(krb5_context context,
skip2:;
}
- if(n != pa.len) {
- char *name;
- ret = krb5_unparse_name(context, client->principal, &name);
- if (ret)
- name = rk_UNCONST("<unparse_name failed>");
- kdc_log(context, config, 0,
- "internal error in get_pa_etype_info2(%s): %d != %d",
- name, n, pa.len);
- if (ret == 0)
- free(name);
+ if(n < pa.len) {
+ /* stripped out dups, and not valid enctypes */
pa.len = n;
}
@@ -1043,7 +1050,7 @@ _kdc_as_rep(krb5_context context,
goto out;
}
- ret = _kdc_windc_client_access(context, client, req);
+ ret = _kdc_windc_client_access(context, client, req, &e_data);
if(ret)
goto out;
@@ -1554,6 +1561,10 @@ _kdc_as_rep(krb5_context context,
* otherwise just a dummy lr.
*/
ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val));
+ if (ek.last_req.val == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
ek.last_req.len = 0;
if (client->entry.pw_end
&& (config->kdc_warn_pwexpire == 0
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 4d6be60f68..32bdee9799 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: krb5tgs.c 21262 2007-06-21 15:18:37Z lha $");
+RCSID("$Id: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $");
/*
* return the realm of a krbtgt-ticket or NULL
@@ -822,7 +822,7 @@ tgs_make_reply(krb5_context context,
if(rspac->length) {
/*
* No not need to filter out the any PAC from the
- * auth_data since its signed by the KDC.
+ * auth_data since it's signed by the KDC.
*/
ret = _kdc_tkt_add_if_relevant_ad(context, &et,
KRB5_AUTHDATA_WIN2K_PAC,
@@ -1099,11 +1099,14 @@ tgs_parse_request(krb5_context context,
ret = hdb_enctype2key(context, &(*krbtgt)->entry,
ap_req.ticket.enc_part.etype, &tkey);
if(ret){
- char *str, *p;
+ char *str = NULL, *p = NULL;
+
krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
krb5_unparse_name(context, princ, &p);
- kdc_log(context, config, 0,
- "No server key with enctype %s found for %s", str, p);
+ kdc_log(context, config, 0,
+ "No server key with enctype %s found for %s",
+ str ? str : "<unknown enctype>",
+ p ? p : "<unparse_name failed>");
free(str);
free(p);
ret = KRB5KRB_AP_ERR_BADKEYVER;
@@ -1163,8 +1166,10 @@ tgs_parse_request(krb5_context context,
}
if (b->enc_authorization_data) {
+ unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
krb5_keyblock *subkey;
krb5_data ad;
+
ret = krb5_auth_con_getremotesubkey(context,
ac,
&subkey);
@@ -1175,6 +1180,7 @@ tgs_parse_request(krb5_context context,
goto out;
}
if(subkey == NULL){
+ usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
ret = krb5_auth_con_getkey(context, ac, &subkey);
if(ret) {
krb5_auth_con_free(context, ac);
@@ -1199,7 +1205,7 @@ tgs_parse_request(krb5_context context,
}
ret = krb5_decrypt_EncryptedData (context,
crypto,
- KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+ usage,
b->enc_authorization_data,
&ad);
krb5_crypto_destroy(context, crypto);
@@ -1373,6 +1379,7 @@ server_lookup:
ret = krb5_unparse_name(context, sp, &spn);
if (ret)
goto out;
+ auth_data = NULL; /* ms don't handle AD in referals */
goto server_lookup;
}
}
@@ -1390,6 +1397,7 @@ server_lookup:
if (ret)
goto out;
krb5_free_host_realm(context, realms);
+ auth_data = NULL; /* ms don't handle AD in referals */
goto server_lookup;
}
krb5_free_host_realm(context, realms);
@@ -1431,8 +1439,8 @@ server_lookup:
}
/*
- * Check that service is in the same realm as the krbtgt. If its
- * not the same, its someone that is using a uni-directional trust
+ * Check that service is in the same realm as the krbtgt. If it's
+ * not the same, it's someone that is using a uni-directional trust
* backward.
*/
diff --git a/source4/heimdal/kdc/log.c b/source4/heimdal/kdc/log.c
index 977b1c9476..8cf967fbfb 100644
--- a/source4/heimdal/kdc/log.c
+++ b/source4/heimdal/kdc/log.c
@@ -32,7 +32,7 @@
*/
#include "kdc_locl.h"
-RCSID("$Id: log.c 15532 2005-06-30 01:54:49Z lha $");
+RCSID("$Id: log.c 22254 2007-12-09 06:01:05Z lha $");
void
kdc_openlog(krb5_context context,
@@ -47,8 +47,12 @@ kdc_openlog(krb5_context context,
for(p = s; *p; p++)
krb5_addlog_dest(context, config->logf, *p);
krb5_config_free_strings(s);
- }else
- krb5_addlog_dest(context, config->logf, DEFAULT_LOG_DEST);
+ }else {
+ char *s;
+ asprintf(&s, "0-1/FILE:%s/%s", hdb_db_dir(context), KDC_LOG_FILE);
+ krb5_addlog_dest(context, config->logf, s);
+ free(s);
+ }
krb5_set_warn_dest(context, config->logf);
}
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index ead961022d..bf248af588 100755
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: pkinit.c 21290 2007-06-25 14:13:23Z lha $");
+RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $");
#ifdef PKINIT
@@ -1248,6 +1248,7 @@ out:
static int
match_rfc_san(krb5_context context,
krb5_kdc_configuration *config,
+ hx509_context hx509ctx,
hx509_cert client_cert,
krb5_const_principal match)
{
@@ -1256,7 +1257,8 @@ match_rfc_san(krb5_context context,
memset(&list, 0 , sizeof(list));
- ret = hx509_cert_find_subjectAltName_otherName(client_cert,
+ ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
+ client_cert,
oid_id_pkinit_san(),
&list);
if (ret)
@@ -1304,6 +1306,7 @@ out:
static int
match_ms_upn_san(krb5_context context,
krb5_kdc_configuration *config,
+ hx509_context hx509ctx,
hx509_cert client_cert,
krb5_const_principal match)
{
@@ -1315,7 +1318,8 @@ match_ms_upn_san(krb5_context context,
memset(&list, 0 , sizeof(list));
- ret = hx509_cert_find_subjectAltName_otherName(client_cert,
+ ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
+ client_cert,
oid_id_pkinit_ms_san(),
&list);
if (ret)
@@ -1376,7 +1380,7 @@ _kdc_pk_check_client(krb5_context context,
hx509_name name;
int i;
- ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
+ ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
client_params->cert,
&name);
if (ret)
@@ -1393,6 +1397,7 @@ _kdc_pk_check_client(krb5_context context,
if (config->pkinit_princ_in_cert) {
ret = match_rfc_san(context, config,
+ kdc_identity->hx509ctx,
client_params->cert,
client->entry.principal);
if (ret == 0) {
@@ -1401,6 +1406,7 @@ _kdc_pk_check_client(krb5_context context,
return 0;
}
ret = match_ms_upn_san(context, config,
+ kdc_identity->hx509ctx,
client_params->cert,
client->entry.principal);
if (ret == 0) {
@@ -1580,7 +1586,8 @@ _kdc_pk_initialize(krb5_context context,
char **pool,
char **revoke_list)
{
- const char *file;
+ const char *file;
+ char *fn = NULL;
krb5_error_code ret;
file = krb5_config_get_string(context, NULL,
@@ -1646,14 +1653,19 @@ _kdc_pk_initialize(krb5_context context,
NULL);
_krb5_pk_allow_proxy_certificate(kdc_identity, ret);
- file = krb5_config_get_string_default(context,
- NULL,
- HDB_DB_DIR "/pki-mapping",
- "kdc",
- "pkinit_mappings_file",
- NULL);
+ file = krb5_config_get_string(context,
+ NULL,
+ "kdc",
+ "pkinit_mappings_file",
+ NULL);
+ if (file == NULL) {
+ asprintf(&fn, "%s/pki-mapping", hdb_db_dir(context));
+ file = fn;
+ }
load_mappings(context, file);
+ if (fn)
+ free(fn);
return 0;
}
diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c
index 395ab73432..85e4d7f725 100644
--- a/source4/heimdal/kdc/windc.c
+++ b/source4/heimdal/kdc/windc.c
@@ -101,9 +101,10 @@ _kdc_pac_verify(krb5_context context,
krb5_error_code
_kdc_windc_client_access(krb5_context context,
struct hdb_entry_ex *client,
- KDC_REQ *req)
+ KDC_REQ *req,
+ krb5_data *e_data)
{
if (windcft == NULL)
return 0;
- return (windcft->client_access)(windcctx, context, client, req);
+ return (windcft->client_access)(windcctx, context, client, req, e_data);
}
diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h
index ec480cf950..3ae0c94681 100644
--- a/source4/heimdal/kdc/windc_plugin.h
+++ b/source4/heimdal/kdc/windc_plugin.h
@@ -64,7 +64,7 @@ typedef krb5_error_code
typedef krb5_error_code
(*krb5plugin_windc_client_access)(
- void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *);
+ void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *, krb5_data *);
#define KRB5_WINDC_PLUGING_MINOR 2
diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c
index 23fa7a5baf..2676309859 100644
--- a/source4/heimdal/kuser/kinit.c
+++ b/source4/heimdal/kuser/kinit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -32,7 +32,7 @@
*/
#include "kuser_locl.h"
-RCSID("$Id: kinit.c 21483 2007-07-10 16:40:46Z lha $");
+RCSID("$Id: kinit.c 22116 2007-12-03 21:22:58Z lha $");
#include "krb5-v4compat.h"
@@ -260,7 +260,7 @@ renew_validate(krb5_context context,
if (renew) {
/*
- * no need to check the error here, its only to be
+ * no need to check the error here, it's only to be
* friendly to the user
*/
krb5_get_credentials(context, KRB5_GC_CACHED, cache, &in, &out);
@@ -377,6 +377,7 @@ get_new_tickets(krb5_context context,
char *renewstr = NULL;
krb5_enctype *enctype = NULL;
struct ntlm_buf ntlmkey;
+ krb5_ccache tempccache;
memset(&ntlmkey, 0, sizeof(ntlmkey));
passwd[0] = '\0';
@@ -577,16 +578,25 @@ get_new_tickets(krb5_context context,
}
}
- ret = krb5_cc_initialize (context, ccache, cred.client);
+ ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache),
+ NULL, &tempccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_new_unique");
+
+ ret = krb5_cc_initialize (context, tempccache, cred.client);
if (ret)
krb5_err (context, 1, ret, "krb5_cc_initialize");
- ret = krb5_cc_store_cred (context, ccache, &cred);
+ ret = krb5_cc_store_cred (context, tempccache, &cred);
if (ret)
krb5_err (context, 1, ret, "krb5_cc_store_cred");
krb5_free_cred_contents (context, &cred);
+ ret = krb5_cc_move(context, tempccache, ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_move");
+
if (ntlm_domain && ntlmkey.data)
store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey);
@@ -757,8 +767,11 @@ main (int argc, char **argv)
krb4_cc_name = NULL;
}
}
- } else
- ret = krb5_cc_default (context, &ccache);
+ } else {
+ ret = krb5_cc_cache_match(context, principal, NULL, &ccache);
+ if (ret)
+ ret = krb5_cc_default (context, &ccache);
+ }
}
if (ret)
krb5_err (context, 1, ret, "resolving credentials cache");
diff --git a/source4/heimdal/lib/asn1/asn1-common.h b/source4/heimdal/lib/asn1/asn1-common.h
index 15c4a09cd0..5789e0f22d 100644
--- a/source4/heimdal/lib/asn1/asn1-common.h
+++ b/source4/heimdal/lib/asn1/asn1-common.h
@@ -1,4 +1,4 @@
-/* $Id: asn1-common.h 19539 2006-12-28 17:15:05Z lha $ */
+/* $Id: asn1-common.h 22429 2008-01-13 10:25:50Z lha $ */
#include <stddef.h>
#include <time.h>
diff --git a/source4/heimdal/lib/asn1/canthandle.asn1 b/source4/heimdal/lib/asn1/canthandle.asn1
index edb8375ee3..5ba3e3880c 100644
--- a/source4/heimdal/lib/asn1/canthandle.asn1
+++ b/source4/heimdal/lib/asn1/canthandle.asn1
@@ -1,4 +1,4 @@
--- $Id: canthandle.asn1 16593 2006-01-18 19:12:33Z lha $ --
+-- $Id: canthandle.asn1 22071 2007-11-14 20:04:50Z lha $ --
CANTHANDLE DEFINITIONS ::= BEGIN
@@ -19,7 +19,7 @@ Foo ::= SEQUENCE {
kaka3 [2] IMPLICIT Kaka3 OPTIONAL
}
--- Don't code kaka if its 1
+-- Don't code kaka if it's 1
-- Workaround is to use OPTIONAL and check for in the encoder stubs
Bar ::= SEQUENCE {
diff --git a/source4/heimdal/lib/asn1/der.c b/source4/heimdal/lib/asn1/der.c
index c7b911b8d6..120dc086af 100644
--- a/source4/heimdal/lib/asn1/der.c
+++ b/source4/heimdal/lib/asn1/der.c
@@ -38,7 +38,7 @@
#include <getarg.h>
#include <err.h>
-RCSID("$Id: der.c 15617 2005-07-12 06:27:42Z lha $");
+RCSID("$Id: der.c 22429 2008-01-13 10:25:50Z lha $");
static const char *class_names[] = {
diff --git a/source4/heimdal/lib/asn1/digest.asn1 b/source4/heimdal/lib/asn1/digest.asn1
index 17341863c6..eafe48ea5a 100644
--- a/source4/heimdal/lib/asn1/digest.asn1
+++ b/source4/heimdal/lib/asn1/digest.asn1
@@ -1,10 +1,19 @@
--- $Id: digest.asn1 20138 2007-02-02 21:08:24Z lha $
+-- $Id: digest.asn1 22152 2007-12-04 19:59:18Z lha $
DIGEST DEFINITIONS ::=
BEGIN
IMPORTS EncryptedData, Principal FROM krb5;
+DigestTypes ::= BIT STRING {
+ ntlm-v1(0),
+ ntlm-v1-session(1),
+ ntlm-v2(2),
+ digest-md5(3),
+ chap-md5(4),
+ ms-chap-v2(5)
+}
+
DigestInit ::= SEQUENCE {
type UTF8String, -- http, sasl, chap, cram-md5 --
channel [0] SEQUENCE {
@@ -95,7 +104,8 @@ DigestReqInner ::= CHOICE {
init [0] DigestInit,
digestRequest [1] DigestRequest,
ntlmInit [2] NTLMInit,
- ntlmRequest [3] NTLMRequest
+ ntlmRequest [3] NTLMRequest,
+ supportedMechs [4] NULL
}
DigestREQ ::= [APPLICATION 128] SEQUENCE {
@@ -108,7 +118,9 @@ DigestRepInner ::= CHOICE {
initReply [1] DigestInitReply,
response [2] DigestResponse,
ntlmInitReply [3] NTLMInitReply,
- ntlmResponse [4] NTLMResponse
+ ntlmResponse [4] NTLMResponse,
+ supportedMechs [5] DigestTypes,
+ ...
}
DigestREP ::= [APPLICATION 129] SEQUENCE {
diff --git a/source4/heimdal/lib/asn1/gen.c b/source4/heimdal/lib/asn1/gen.c
index 26890212ae..499f8eab36 100644
--- a/source4/heimdal/lib/asn1/gen.c
+++ b/source4/heimdal/lib/asn1/gen.c
@@ -33,7 +33,7 @@
#include "gen_locl.h"
-RCSID("$Id: gen.c 21364 2007-06-27 08:51:06Z lha $");
+RCSID("$Id: gen.c 22429 2008-01-13 10:25:50Z lha $");
FILE *headerfile, *codefile, *logfile;
diff --git a/source4/heimdal/lib/asn1/gen_encode.c b/source4/heimdal/lib/asn1/gen_encode.c
index 9544514212..08f1a9449f 100644
--- a/source4/heimdal/lib/asn1/gen_encode.c
+++ b/source4/heimdal/lib/asn1/gen_encode.c
@@ -33,7 +33,7 @@
#include "gen_locl.h"
-RCSID("$Id: gen_encode.c 21503 2007-07-12 11:57:19Z lha $");
+RCSID("$Id: gen_encode.c 22429 2008-01-13 10:25:50Z lha $");
static void
encode_primitive (const char *typename, const char *name)
diff --git a/source4/heimdal/lib/asn1/k5.asn1 b/source4/heimdal/lib/asn1/k5.asn1
index e3fe2b11e9..18f1e1541b 100644
--- a/source4/heimdal/lib/asn1/k5.asn1
+++ b/source4/heimdal/lib/asn1/k5.asn1
@@ -1,4 +1,4 @@
--- $Id: k5.asn1 21400 2007-07-02 19:57:31Z lha $
+-- $Id: k5.asn1 21965 2007-10-18 18:24:36Z lha $
KERBEROS5 DEFINITIONS ::=
BEGIN
@@ -137,6 +137,10 @@ ENCTYPE ::= INTEGER {
ETYPE_ARCFOUR_HMAC_MD5(23),
ETYPE_ARCFOUR_HMAC_MD5_56(24),
ETYPE_ENCTYPE_PK_CROSS(48),
+-- some "old" windows types
+ ETYPE_ARCFOUR_MD4(-128),
+ ETYPE_ARCFOUR_HMAC_OLD(-133),
+ ETYPE_ARCFOUR_HMAC_OLD_EXP(-135),
-- these are for Heimdal internal use
ETYPE_DES_CBC_NONE(-0x1000),
ETYPE_DES3_CBC_NONE(-0x1001),
diff --git a/source4/heimdal/lib/asn1/lex.c b/source4/heimdal/lib/asn1/lex.c
index 86c4359f1a..da4f729c3d 100644
--- a/source4/heimdal/lib/asn1/lex.c
+++ b/source4/heimdal/lib/asn1/lex.c
@@ -1,6 +1,5 @@
-#include "config.h"
-#line 3 "heimdal/lib/asn1/lex.c"
+#line 3 "lex.c"
#define YY_INT_ALIGNED short int
@@ -827,7 +826,7 @@ char *yytext;
* SUCH DAMAGE.
*/
-/* $Id: lex.l,v 1.31 2006/10/21 11:57:22 lha Exp $ */
+/* $Id: lex.l 18738 2006-10-21 11:57:22Z lha $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -852,7 +851,7 @@ static unsigned lineno = 1;
static void unterminated(const char *, unsigned);
/* This is for broken old lexes (solaris 10 and hpux) */
-#line 855 "heimdal/lib/asn1/lex.c"
+#line 855 "lex.c"
#define INITIAL 0
@@ -870,6 +869,35 @@ static void unterminated(const char *, unsigned);
static int yy_init_globals (void );
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
@@ -1007,7 +1035,7 @@ YY_DECL
#line 68 "lex.l"
-#line 1010 "heimdal/lib/asn1/lex.c"
+#line 1039 "lex.c"
if ( !(yy_init) )
{
@@ -1676,7 +1704,7 @@ YY_RULE_SETUP
#line 274 "lex.l"
ECHO;
YY_BREAK
-#line 1679 "heimdal/lib/asn1/lex.c"
+#line 1708 "lex.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1907,7 +1935,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), (size_t) num_to_read );
+ (yy_n_chars), num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
@@ -2408,7 +2436,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
+ * @param str a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
diff --git a/source4/heimdal/lib/asn1/parse.c b/source4/heimdal/lib/asn1/parse.c
index edcb313bd0..6a3e524e93 100644
--- a/source4/heimdal/lib/asn1/parse.c
+++ b/source4/heimdal/lib/asn1/parse.c
@@ -248,7 +248,7 @@
/* Copy the first part of user declarations. */
-#line 36 "heimdal/lib/asn1/parse.y"
+#line 36 "parse.y"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -280,7 +280,7 @@ struct string_list {
/* Enabling traces. */
#ifndef YYDEBUG
-# define YYDEBUG 0
+# define YYDEBUG 1
#endif
/* Enabling verbose error messages. */
@@ -298,7 +298,7 @@ struct string_list {
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 65 "heimdal/lib/asn1/parse.y"
+#line 65 "parse.y"
{
int constant;
struct value *value;
@@ -314,7 +314,7 @@ typedef union YYSTYPE
struct constraint_spec *constraint_spec;
}
/* Line 187 of yacc.c. */
-#line 318 "heimdal/lib/asn1/parse.y"
+#line 318 "parse.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -327,7 +327,7 @@ typedef union YYSTYPE
/* Line 216 of yacc.c. */
-#line 331 "heimdal/lib/asn1/parse.y"
+#line 331 "parse.c"
#ifdef short
# undef short
@@ -1762,29 +1762,29 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 235 "heimdal/lib/asn1/parse.y"
+#line 235 "parse.y"
{
checkundefined();
}
break;
case 4:
-#line 242 "heimdal/lib/asn1/parse.y"
+#line 242 "parse.y"
{ error_message("implicit tagging is not supported"); }
break;
case 5:
-#line 244 "heimdal/lib/asn1/parse.y"
+#line 244 "parse.y"
{ error_message("automatic tagging is not supported"); }
break;
case 7:
-#line 249 "heimdal/lib/asn1/parse.y"
+#line 249 "parse.y"
{ error_message("no extensibility options supported"); }
break;
case 17:
-#line 270 "heimdal/lib/asn1/parse.y"
+#line 270 "parse.y"
{
struct string_list *sl;
for(sl = (yyvsp[(1) - (4)].sl); sl != NULL; sl = sl->next) {
@@ -1796,7 +1796,7 @@ yyreduce:
break;
case 22:
-#line 289 "heimdal/lib/asn1/parse.y"
+#line 289 "parse.y"
{
(yyval.sl) = emalloc(sizeof(*(yyval.sl)));
(yyval.sl)->string = (yyvsp[(1) - (3)].name);
@@ -1805,7 +1805,7 @@ yyreduce:
break;
case 23:
-#line 295 "heimdal/lib/asn1/parse.y"
+#line 295 "parse.y"
{
(yyval.sl) = emalloc(sizeof(*(yyval.sl)));
(yyval.sl)->string = (yyvsp[(1) - (1)].name);
@@ -1814,7 +1814,7 @@ yyreduce:
break;
case 24:
-#line 303 "heimdal/lib/asn1/parse.y"
+#line 303 "parse.y"
{
Symbol *s = addsym ((yyvsp[(1) - (3)].name));
s->stype = Stype;
@@ -1825,7 +1825,7 @@ yyreduce:
break;
case 42:
-#line 334 "heimdal/lib/asn1/parse.y"
+#line 334 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_Boolean,
TE_EXPLICIT, new_type(TBoolean));
@@ -1833,7 +1833,7 @@ yyreduce:
break;
case 43:
-#line 341 "heimdal/lib/asn1/parse.y"
+#line 341 "parse.y"
{
if((yyvsp[(2) - (5)].value)->type != integervalue)
error_message("Non-integer used in first part of range");
@@ -1846,7 +1846,7 @@ yyreduce:
break;
case 44:
-#line 351 "heimdal/lib/asn1/parse.y"
+#line 351 "parse.y"
{
if((yyvsp[(2) - (5)].value)->type != integervalue)
error_message("Non-integer in first part of range");
@@ -1857,7 +1857,7 @@ yyreduce:
break;
case 45:
-#line 359 "heimdal/lib/asn1/parse.y"
+#line 359 "parse.y"
{
if((yyvsp[(4) - (5)].value)->type != integervalue)
error_message("Non-integer in second part of range");
@@ -1868,7 +1868,7 @@ yyreduce:
break;
case 46:
-#line 367 "heimdal/lib/asn1/parse.y"
+#line 367 "parse.y"
{
if((yyvsp[(2) - (3)].value)->type != integervalue)
error_message("Non-integer used in limit");
@@ -1879,7 +1879,7 @@ yyreduce:
break;
case 47:
-#line 378 "heimdal/lib/asn1/parse.y"
+#line 378 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer,
TE_EXPLICIT, new_type(TInteger));
@@ -1887,7 +1887,7 @@ yyreduce:
break;
case 48:
-#line 383 "heimdal/lib/asn1/parse.y"
+#line 383 "parse.y"
{
(yyval.type) = new_type(TInteger);
(yyval.type)->range = (yyvsp[(2) - (2)].range);
@@ -1896,7 +1896,7 @@ yyreduce:
break;
case 49:
-#line 389 "heimdal/lib/asn1/parse.y"
+#line 389 "parse.y"
{
(yyval.type) = new_type(TInteger);
(yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -1905,7 +1905,7 @@ yyreduce:
break;
case 50:
-#line 397 "heimdal/lib/asn1/parse.y"
+#line 397 "parse.y"
{
(yyval.members) = emalloc(sizeof(*(yyval.members)));
ASN1_TAILQ_INIT((yyval.members));
@@ -1914,7 +1914,7 @@ yyreduce:
break;
case 51:
-#line 403 "heimdal/lib/asn1/parse.y"
+#line 403 "parse.y"
{
ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members);
(yyval.members) = (yyvsp[(1) - (3)].members);
@@ -1922,12 +1922,12 @@ yyreduce:
break;
case 52:
-#line 408 "heimdal/lib/asn1/parse.y"
+#line 408 "parse.y"
{ (yyval.members) = (yyvsp[(1) - (3)].members); }
break;
case 53:
-#line 412 "heimdal/lib/asn1/parse.y"
+#line 412 "parse.y"
{
(yyval.member) = emalloc(sizeof(*(yyval.member)));
(yyval.member)->name = (yyvsp[(1) - (4)].name);
@@ -1941,7 +1941,7 @@ yyreduce:
break;
case 54:
-#line 425 "heimdal/lib/asn1/parse.y"
+#line 425 "parse.y"
{
(yyval.type) = new_type(TInteger);
(yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -1950,7 +1950,7 @@ yyreduce:
break;
case 56:
-#line 436 "heimdal/lib/asn1/parse.y"
+#line 436 "parse.y"
{
(yyval.type) = new_type(TBitString);
(yyval.type)->members = emalloc(sizeof(*(yyval.type)->members));
@@ -1960,7 +1960,7 @@ yyreduce:
break;
case 57:
-#line 443 "heimdal/lib/asn1/parse.y"
+#line 443 "parse.y"
{
(yyval.type) = new_type(TBitString);
(yyval.type)->members = (yyvsp[(4) - (5)].members);
@@ -1969,7 +1969,7 @@ yyreduce:
break;
case 58:
-#line 451 "heimdal/lib/asn1/parse.y"
+#line 451 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_OID,
TE_EXPLICIT, new_type(TOID));
@@ -1977,7 +1977,7 @@ yyreduce:
break;
case 59:
-#line 457 "heimdal/lib/asn1/parse.y"
+#line 457 "parse.y"
{
Type *t = new_type(TOctetString);
t->range = (yyvsp[(3) - (3)].range);
@@ -1987,7 +1987,7 @@ yyreduce:
break;
case 60:
-#line 466 "heimdal/lib/asn1/parse.y"
+#line 466 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_Null,
TE_EXPLICIT, new_type(TNull));
@@ -1995,17 +1995,17 @@ yyreduce:
break;
case 61:
-#line 473 "heimdal/lib/asn1/parse.y"
+#line 473 "parse.y"
{ (yyval.range) = NULL; }
break;
case 62:
-#line 475 "heimdal/lib/asn1/parse.y"
+#line 475 "parse.y"
{ (yyval.range) = (yyvsp[(2) - (2)].range); }
break;
case 63:
-#line 480 "heimdal/lib/asn1/parse.y"
+#line 480 "parse.y"
{
(yyval.type) = new_type(TSequence);
(yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -2014,7 +2014,7 @@ yyreduce:
break;
case 64:
-#line 486 "heimdal/lib/asn1/parse.y"
+#line 486 "parse.y"
{
(yyval.type) = new_type(TSequence);
(yyval.type)->members = NULL;
@@ -2023,7 +2023,7 @@ yyreduce:
break;
case 65:
-#line 494 "heimdal/lib/asn1/parse.y"
+#line 494 "parse.y"
{
(yyval.type) = new_type(TSequenceOf);
(yyval.type)->range = (yyvsp[(2) - (4)].range);
@@ -2033,7 +2033,7 @@ yyreduce:
break;
case 66:
-#line 503 "heimdal/lib/asn1/parse.y"
+#line 503 "parse.y"
{
(yyval.type) = new_type(TSet);
(yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -2042,7 +2042,7 @@ yyreduce:
break;
case 67:
-#line 509 "heimdal/lib/asn1/parse.y"
+#line 509 "parse.y"
{
(yyval.type) = new_type(TSet);
(yyval.type)->members = NULL;
@@ -2051,7 +2051,7 @@ yyreduce:
break;
case 68:
-#line 517 "heimdal/lib/asn1/parse.y"
+#line 517 "parse.y"
{
(yyval.type) = new_type(TSetOf);
(yyval.type)->subtype = (yyvsp[(3) - (3)].type);
@@ -2060,7 +2060,7 @@ yyreduce:
break;
case 69:
-#line 525 "heimdal/lib/asn1/parse.y"
+#line 525 "parse.y"
{
(yyval.type) = new_type(TChoice);
(yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -2068,7 +2068,7 @@ yyreduce:
break;
case 72:
-#line 536 "heimdal/lib/asn1/parse.y"
+#line 536 "parse.y"
{
Symbol *s = addsym((yyvsp[(1) - (1)].name));
(yyval.type) = new_type(TType);
@@ -2080,7 +2080,7 @@ yyreduce:
break;
case 73:
-#line 547 "heimdal/lib/asn1/parse.y"
+#line 547 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
TE_EXPLICIT, new_type(TGeneralizedTime));
@@ -2088,7 +2088,7 @@ yyreduce:
break;
case 74:
-#line 552 "heimdal/lib/asn1/parse.y"
+#line 552 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_UTCTime,
TE_EXPLICIT, new_type(TUTCTime));
@@ -2096,7 +2096,7 @@ yyreduce:
break;
case 75:
-#line 559 "heimdal/lib/asn1/parse.y"
+#line 559 "parse.y"
{
/* if (Constraint.type == contentConstrant) {
assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
@@ -2112,14 +2112,14 @@ yyreduce:
break;
case 76:
-#line 575 "heimdal/lib/asn1/parse.y"
+#line 575 "parse.y"
{
(yyval.constraint_spec) = (yyvsp[(2) - (3)].constraint_spec);
}
break;
case 80:
-#line 588 "heimdal/lib/asn1/parse.y"
+#line 588 "parse.y"
{
(yyval.constraint_spec) = new_constraint_spec(CT_CONTENTS);
(yyval.constraint_spec)->u.content.type = (yyvsp[(2) - (2)].type);
@@ -2128,7 +2128,7 @@ yyreduce:
break;
case 81:
-#line 594 "heimdal/lib/asn1/parse.y"
+#line 594 "parse.y"
{
if ((yyvsp[(3) - (3)].value)->type != objectidentifiervalue)
error_message("Non-OID used in ENCODED BY constraint");
@@ -2139,7 +2139,7 @@ yyreduce:
break;
case 82:
-#line 602 "heimdal/lib/asn1/parse.y"
+#line 602 "parse.y"
{
if ((yyvsp[(5) - (5)].value)->type != objectidentifiervalue)
error_message("Non-OID used in ENCODED BY constraint");
@@ -2150,14 +2150,14 @@ yyreduce:
break;
case 83:
-#line 612 "heimdal/lib/asn1/parse.y"
+#line 612 "parse.y"
{
(yyval.constraint_spec) = new_constraint_spec(CT_USER);
}
break;
case 84:
-#line 618 "heimdal/lib/asn1/parse.y"
+#line 618 "parse.y"
{
(yyval.type) = new_type(TTag);
(yyval.type)->tag = (yyvsp[(1) - (3)].tag);
@@ -2171,7 +2171,7 @@ yyreduce:
break;
case 85:
-#line 631 "heimdal/lib/asn1/parse.y"
+#line 631 "parse.y"
{
(yyval.tag).tagclass = (yyvsp[(2) - (4)].constant);
(yyval.tag).tagvalue = (yyvsp[(3) - (4)].constant);
@@ -2180,56 +2180,56 @@ yyreduce:
break;
case 86:
-#line 639 "heimdal/lib/asn1/parse.y"
+#line 639 "parse.y"
{
(yyval.constant) = ASN1_C_CONTEXT;
}
break;
case 87:
-#line 643 "heimdal/lib/asn1/parse.y"
+#line 643 "parse.y"
{
(yyval.constant) = ASN1_C_UNIV;
}
break;
case 88:
-#line 647 "heimdal/lib/asn1/parse.y"
+#line 647 "parse.y"
{
(yyval.constant) = ASN1_C_APPL;
}
break;
case 89:
-#line 651 "heimdal/lib/asn1/parse.y"
+#line 651 "parse.y"
{
(yyval.constant) = ASN1_C_PRIVATE;
}
break;
case 90:
-#line 657 "heimdal/lib/asn1/parse.y"
+#line 657 "parse.y"
{
(yyval.constant) = TE_EXPLICIT;
}
break;
case 91:
-#line 661 "heimdal/lib/asn1/parse.y"
+#line 661 "parse.y"
{
(yyval.constant) = TE_EXPLICIT;
}
break;
case 92:
-#line 665 "heimdal/lib/asn1/parse.y"
+#line 665 "parse.y"
{
(yyval.constant) = TE_IMPLICIT;
}
break;
case 93:
-#line 672 "heimdal/lib/asn1/parse.y"
+#line 672 "parse.y"
{
Symbol *s;
s = addsym ((yyvsp[(1) - (4)].name));
@@ -2241,7 +2241,7 @@ yyreduce:
break;
case 95:
-#line 686 "heimdal/lib/asn1/parse.y"
+#line 686 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralString,
TE_EXPLICIT, new_type(TGeneralString));
@@ -2249,7 +2249,7 @@ yyreduce:
break;
case 96:
-#line 691 "heimdal/lib/asn1/parse.y"
+#line 691 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_UTF8String,
TE_EXPLICIT, new_type(TUTF8String));
@@ -2257,7 +2257,7 @@ yyreduce:
break;
case 97:
-#line 696 "heimdal/lib/asn1/parse.y"
+#line 696 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_PrintableString,
TE_EXPLICIT, new_type(TPrintableString));
@@ -2265,7 +2265,7 @@ yyreduce:
break;
case 98:
-#line 701 "heimdal/lib/asn1/parse.y"
+#line 701 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_VisibleString,
TE_EXPLICIT, new_type(TVisibleString));
@@ -2273,7 +2273,7 @@ yyreduce:
break;
case 99:
-#line 706 "heimdal/lib/asn1/parse.y"
+#line 706 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_IA5String,
TE_EXPLICIT, new_type(TIA5String));
@@ -2281,7 +2281,7 @@ yyreduce:
break;
case 100:
-#line 711 "heimdal/lib/asn1/parse.y"
+#line 711 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_BMPString,
TE_EXPLICIT, new_type(TBMPString));
@@ -2289,7 +2289,7 @@ yyreduce:
break;
case 101:
-#line 716 "heimdal/lib/asn1/parse.y"
+#line 716 "parse.y"
{
(yyval.type) = new_tag(ASN1_C_UNIV, UT_UniversalString,
TE_EXPLICIT, new_type(TUniversalString));
@@ -2297,7 +2297,7 @@ yyreduce:
break;
case 102:
-#line 724 "heimdal/lib/asn1/parse.y"
+#line 724 "parse.y"
{
(yyval.members) = emalloc(sizeof(*(yyval.members)));
ASN1_TAILQ_INIT((yyval.members));
@@ -2306,7 +2306,7 @@ yyreduce:
break;
case 103:
-#line 730 "heimdal/lib/asn1/parse.y"
+#line 730 "parse.y"
{
ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members);
(yyval.members) = (yyvsp[(1) - (3)].members);
@@ -2314,7 +2314,7 @@ yyreduce:
break;
case 104:
-#line 735 "heimdal/lib/asn1/parse.y"
+#line 735 "parse.y"
{
struct member *m = ecalloc(1, sizeof(*m));
m->name = estrdup("...");
@@ -2326,7 +2326,7 @@ yyreduce:
break;
case 105:
-#line 746 "heimdal/lib/asn1/parse.y"
+#line 746 "parse.y"
{
(yyval.member) = emalloc(sizeof(*(yyval.member)));
(yyval.member)->name = (yyvsp[(1) - (2)].name);
@@ -2338,7 +2338,7 @@ yyreduce:
break;
case 106:
-#line 757 "heimdal/lib/asn1/parse.y"
+#line 757 "parse.y"
{
(yyval.member) = (yyvsp[(1) - (1)].member);
(yyval.member)->optional = 0;
@@ -2347,7 +2347,7 @@ yyreduce:
break;
case 107:
-#line 763 "heimdal/lib/asn1/parse.y"
+#line 763 "parse.y"
{
(yyval.member) = (yyvsp[(1) - (2)].member);
(yyval.member)->optional = 1;
@@ -2356,7 +2356,7 @@ yyreduce:
break;
case 108:
-#line 769 "heimdal/lib/asn1/parse.y"
+#line 769 "parse.y"
{
(yyval.member) = (yyvsp[(1) - (3)].member);
(yyval.member)->optional = 0;
@@ -2365,7 +2365,7 @@ yyreduce:
break;
case 109:
-#line 777 "heimdal/lib/asn1/parse.y"
+#line 777 "parse.y"
{
(yyval.members) = emalloc(sizeof(*(yyval.members)));
ASN1_TAILQ_INIT((yyval.members));
@@ -2374,7 +2374,7 @@ yyreduce:
break;
case 110:
-#line 783 "heimdal/lib/asn1/parse.y"
+#line 783 "parse.y"
{
ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members);
(yyval.members) = (yyvsp[(1) - (3)].members);
@@ -2382,7 +2382,7 @@ yyreduce:
break;
case 111:
-#line 790 "heimdal/lib/asn1/parse.y"
+#line 790 "parse.y"
{
(yyval.member) = emalloc(sizeof(*(yyval.member)));
(yyval.member)->name = (yyvsp[(1) - (4)].name);
@@ -2396,26 +2396,26 @@ yyreduce:
break;
case 113:
-#line 803 "heimdal/lib/asn1/parse.y"
+#line 803 "parse.y"
{ (yyval.objid) = NULL; }
break;
case 114:
-#line 807 "heimdal/lib/asn1/parse.y"
+#line 807 "parse.y"
{
(yyval.objid) = (yyvsp[(2) - (3)].objid);
}
break;
case 115:
-#line 813 "heimdal/lib/asn1/parse.y"
+#line 813 "parse.y"
{
(yyval.objid) = NULL;
}
break;
case 116:
-#line 817 "heimdal/lib/asn1/parse.y"
+#line 817 "parse.y"
{
if ((yyvsp[(2) - (2)].objid)) {
(yyval.objid) = (yyvsp[(2) - (2)].objid);
@@ -2427,14 +2427,14 @@ yyreduce:
break;
case 117:
-#line 828 "heimdal/lib/asn1/parse.y"
+#line 828 "parse.y"
{
(yyval.objid) = new_objid((yyvsp[(1) - (4)].name), (yyvsp[(3) - (4)].constant));
}
break;
case 118:
-#line 832 "heimdal/lib/asn1/parse.y"
+#line 832 "parse.y"
{
Symbol *s = addsym((yyvsp[(1) - (1)].name));
if(s->stype != SValue ||
@@ -2448,14 +2448,14 @@ yyreduce:
break;
case 119:
-#line 843 "heimdal/lib/asn1/parse.y"
+#line 843 "parse.y"
{
(yyval.objid) = new_objid(NULL, (yyvsp[(1) - (1)].constant));
}
break;
case 129:
-#line 866 "heimdal/lib/asn1/parse.y"
+#line 866 "parse.y"
{
Symbol *s = addsym((yyvsp[(1) - (1)].name));
if(s->stype != SValue)
@@ -2467,7 +2467,7 @@ yyreduce:
break;
case 130:
-#line 877 "heimdal/lib/asn1/parse.y"
+#line 877 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = stringvalue;
@@ -2476,7 +2476,7 @@ yyreduce:
break;
case 131:
-#line 885 "heimdal/lib/asn1/parse.y"
+#line 885 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = booleanvalue;
@@ -2485,7 +2485,7 @@ yyreduce:
break;
case 132:
-#line 891 "heimdal/lib/asn1/parse.y"
+#line 891 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = booleanvalue;
@@ -2494,7 +2494,7 @@ yyreduce:
break;
case 133:
-#line 899 "heimdal/lib/asn1/parse.y"
+#line 899 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = integervalue;
@@ -2503,13 +2503,13 @@ yyreduce:
break;
case 135:
-#line 910 "heimdal/lib/asn1/parse.y"
+#line 910 "parse.y"
{
}
break;
case 136:
-#line 915 "heimdal/lib/asn1/parse.y"
+#line 915 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = objectidentifiervalue;
@@ -2519,7 +2519,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
-#line 2523 "heimdal/lib/asn1/parse.y"
+#line 2523 "parse.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2733,7 +2733,7 @@ yyreturn:
}
-#line 922 "heimdal/lib/asn1/parse.y"
+#line 922 "parse.y"
void
diff --git a/source4/heimdal/lib/asn1/parse.h b/source4/heimdal/lib/asn1/parse.h
index bea506ca7b..5e73094f9e 100644
--- a/source4/heimdal/lib/asn1/parse.h
+++ b/source4/heimdal/lib/asn1/parse.h
@@ -222,7 +222,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 65 "heimdal/lib/asn1/parse.y"
+#line 65 "parse.y"
{
int constant;
struct value *value;
@@ -238,7 +238,7 @@ typedef union YYSTYPE
struct constraint_spec *constraint_spec;
}
/* Line 1489 of yacc.c. */
-#line 242 "heimdal/lib/asn1/parse.y"
+#line 242 "parse.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
diff --git a/source4/heimdal/lib/asn1/pkinit.asn1 b/source4/heimdal/lib/asn1/pkinit.asn1
index 1bfc11ad74..989b26581b 100644
--- a/source4/heimdal/lib/asn1/pkinit.asn1
+++ b/source4/heimdal/lib/asn1/pkinit.asn1
@@ -2,7 +2,7 @@
PKINIT DEFINITIONS ::= BEGIN
-IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
+IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum, Ticket FROM krb5
IssuerAndSerialNumber, ContentInfo FROM cms
SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
heim_any FROM heim;
@@ -40,6 +40,11 @@ td-dh-parameters INTEGER ::= 109
DHNonce ::= OCTET STRING
+KDFAlgorithmId ::= SEQUENCE {
+ kdf-id [0] OBJECT IDENTIFIER,
+ ...
+}
+
TrustedCA ::= SEQUENCE {
caName [0] IMPLICIT OCTET STRING,
certificateSerialNumber [1] INTEGER OPTIONAL,
@@ -76,6 +81,8 @@ AuthPack ::= SEQUENCE {
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
clientDHNonce [3] DHNonce OPTIONAL,
+ ...,
+ supportedKDFs [4] SEQUENCE OF KDFAlgorithmId OPTIONAL,
...
}
@@ -89,10 +96,12 @@ KRB5PrincipalName ::= SEQUENCE {
AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier
-
DHRepInfo ::= SEQUENCE {
dhSignedData [0] IMPLICIT OCTET STRING,
- serverDHNonce [1] DHNonce OPTIONAL
+ serverDHNonce [1] DHNonce OPTIONAL,
+ ...,
+ kdf [2] KDFAlgorithmId OPTIONAL,
+ ...
}
PA-PK-AS-REP ::= CHOICE {
@@ -162,4 +171,12 @@ ReplyKeyPack-Win2k ::= SEQUENCE {
...
}
+PkinitSuppPubInfo ::= SEQUENCE {
+ enctype [0] INTEGER (-2147483648..2147483647),
+ as-REQ [1] OCTET STRING,
+ pk-as-rep [2] OCTET STRING,
+ ticket [3] Ticket,
+ ...
+}
+
END
diff --git a/source4/heimdal/lib/asn1/rfc2459.asn1 b/source4/heimdal/lib/asn1/rfc2459.asn1
index 0ec3b695eb..8e24f0740b 100644
--- a/source4/heimdal/lib/asn1/rfc2459.asn1
+++ b/source4/heimdal/lib/asn1/rfc2459.asn1
@@ -21,6 +21,8 @@ id-pkcs1-sha256WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 11 }
id-pkcs1-sha384WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 12 }
id-pkcs1-sha512WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 13 }
+id-heim-rsa-pkcs1-x509 OBJECT IDENTIFIER ::= { 1 2 752 43 16 1 }
+
id-pkcs-2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) pkcs(1) 2 }
id-pkcs2-md2 OBJECT IDENTIFIER ::= { id-pkcs-2 2 }
diff --git a/source4/heimdal/lib/com_err/lex.c b/source4/heimdal/lib/com_err/lex.c
index 7a85b302a1..3c6ea3beb7 100644
--- a/source4/heimdal/lib/com_err/lex.c
+++ b/source4/heimdal/lib/com_err/lex.c
@@ -1,6 +1,5 @@
-#include "config.h"
-#line 3 "heimdal/lib/com_err/lex.c"
+#line 3 "lex.c"
#define YY_INT_ALIGNED short int
@@ -524,7 +523,7 @@ char *yytext;
#include "parse.h"
#include "lex.h"
-RCSID("$Id: lex.l,v 1.8 2005/05/16 08:52:54 lha Exp $");
+RCSID("$Id: lex.l 15143 2005-05-16 08:52:54Z lha $");
static unsigned lineno = 1;
static int getstring(void);
@@ -533,7 +532,7 @@ static int getstring(void);
#undef ECHO
-#line 536 "heimdal/lib/com_err/lex.c"
+#line 536 "lex.c"
#define INITIAL 0
@@ -551,6 +550,35 @@ static int getstring(void);
static int yy_init_globals (void );
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
@@ -688,7 +716,7 @@ YY_DECL
#line 59 "lex.l"
-#line 691 "heimdal/lib/com_err/lex.c"
+#line 720 "lex.c"
if ( !(yy_init) )
{
@@ -852,7 +880,7 @@ YY_RULE_SETUP
#line 75 "lex.l"
ECHO;
YY_BREAK
-#line 855 "heimdal/lib/com_err/lex.c"
+#line 884 "lex.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1083,7 +1111,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), (size_t) num_to_read );
+ (yy_n_chars), num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
@@ -1584,7 +1612,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
+ * @param str a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
diff --git a/source4/heimdal/lib/com_err/parse.c b/source4/heimdal/lib/com_err/parse.c
index 95fe18f16e..4bacb721ca 100644
--- a/source4/heimdal/lib/com_err/parse.c
+++ b/source4/heimdal/lib/com_err/parse.c
@@ -90,7 +90,7 @@
/* Copy the first part of user declarations. */
-#line 1 "heimdal/lib/com_err/parse.y"
+#line 1 "parse.y"
/*
* Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
@@ -163,13 +163,13 @@ extern char *yytext;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 53 "heimdal/lib/com_err/parse.y"
+#line 53 "parse.y"
{
char *string;
int number;
}
/* Line 187 of yacc.c. */
-#line 173 "heimdal/lib/com_err/parse.y"
+#line 173 "parse.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -182,7 +182,7 @@ typedef union YYSTYPE
/* Line 216 of yacc.c. */
-#line 186 "heimdal/lib/com_err/parse.y"
+#line 186 "parse.c"
#ifdef short
# undef short
@@ -1381,14 +1381,14 @@ yyreduce:
switch (yyn)
{
case 6:
-#line 73 "heimdal/lib/com_err/parse.y"
+#line 73 "parse.y"
{
id_str = (yyvsp[(2) - (2)].string);
}
break;
case 7:
-#line 79 "heimdal/lib/com_err/parse.y"
+#line 79 "parse.y"
{
base_id = name2number((yyvsp[(2) - (2)].string));
strlcpy(name, (yyvsp[(2) - (2)].string), sizeof(name));
@@ -1397,7 +1397,7 @@ yyreduce:
break;
case 8:
-#line 85 "heimdal/lib/com_err/parse.y"
+#line 85 "parse.y"
{
base_id = name2number((yyvsp[(2) - (3)].string));
strlcpy(name, (yyvsp[(3) - (3)].string), sizeof(name));
@@ -1407,14 +1407,14 @@ yyreduce:
break;
case 11:
-#line 98 "heimdal/lib/com_err/parse.y"
+#line 98 "parse.y"
{
number = (yyvsp[(2) - (2)].number);
}
break;
case 12:
-#line 102 "heimdal/lib/com_err/parse.y"
+#line 102 "parse.y"
{
free(prefix);
asprintf (&prefix, "%s_", (yyvsp[(2) - (2)].string));
@@ -1425,7 +1425,7 @@ yyreduce:
break;
case 13:
-#line 110 "heimdal/lib/com_err/parse.y"
+#line 110 "parse.y"
{
prefix = realloc(prefix, 1);
if (prefix == NULL)
@@ -1435,7 +1435,7 @@ yyreduce:
break;
case 14:
-#line 117 "heimdal/lib/com_err/parse.y"
+#line 117 "parse.y"
{
struct error_code *ec = malloc(sizeof(*ec));
@@ -1458,7 +1458,7 @@ yyreduce:
break;
case 15:
-#line 137 "heimdal/lib/com_err/parse.y"
+#line 137 "parse.y"
{
YYACCEPT;
}
@@ -1466,7 +1466,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
-#line 1470 "heimdal/lib/com_err/parse.y"
+#line 1470 "parse.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1680,7 +1680,7 @@ yyreturn:
}
-#line 142 "heimdal/lib/com_err/parse.y"
+#line 142 "parse.y"
static long
diff --git a/source4/heimdal/lib/com_err/parse.h b/source4/heimdal/lib/com_err/parse.h
index 9aabca9023..4c9681ff34 100644
--- a/source4/heimdal/lib/com_err/parse.h
+++ b/source4/heimdal/lib/com_err/parse.h
@@ -64,13 +64,13 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 53 "heimdal/lib/com_err/parse.y"
+#line 53 "parse.y"
{
char *string;
int number;
}
/* Line 1489 of yacc.c. */
-#line 74 "heimdal/lib/com_err/parse.y"
+#line 74 "parse.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
index cca529fe26..2223f4f22f 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: gssapi_krb5.h 20385 2007-04-18 08:51:32Z lha $ */
+/* $Id: gssapi_krb5.h 22655 2008-02-26 12:40:35Z lha $ */
#ifndef GSSAPI_KRB5_H_
#define GSSAPI_KRB5_H_
@@ -80,6 +80,7 @@ extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
/* Extensions creds */
extern gss_OID GSS_KRB5_IMPORT_CRED_X;
extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X;
+extern gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X;
/*
* kerberos mechanism specific functions
diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h
index 403990ad47..b360de13fc 100644
--- a/source4/heimdal/lib/gssapi/gssapi_mech.h
+++ b/source4/heimdal/lib/gssapi/gssapi_mech.h
@@ -356,4 +356,6 @@ gssapi_mech_interface __gss_spnego_initialize(void);
gssapi_mech_interface __gss_krb5_initialize(void);
gssapi_mech_interface __gss_ntlm_initialize(void);
+void gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32);
+
#endif /* GSSAPI_MECH_H */
diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
index d5c70636bc..051446c19b 100644
--- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
@@ -33,7 +33,7 @@
#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: acquire_cred.c 21221 2007-06-20 08:42:10Z lha $");
+RCSID("$Id: acquire_cred.c 22596 2008-02-18 18:05:55Z lha $");
OM_uint32
__gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
@@ -128,9 +128,12 @@ static OM_uint32 acquire_initiator_cred
ret = GSS_S_FAILURE;
memset(&cred, 0, sizeof(cred));
- /* If we have a preferred principal, lets try to find it in all
- * caches, otherwise, fall back to default cache. Ignore
- * errors. */
+ /*
+ * If we have a preferred principal, lets try to find it in all
+ * caches, otherwise, fall back to default cache, ignore all
+ * errors while searching.
+ */
+
if (handle->principal)
kret = krb5_cc_cache_match (context,
handle->principal,
@@ -142,32 +145,30 @@ static OM_uint32 acquire_initiator_cred
if (kret)
goto end;
}
- kret = krb5_cc_get_principal(context, ccache,
- &def_princ);
+ kret = krb5_cc_get_principal(context, ccache, &def_princ);
if (kret != 0) {
/* we'll try to use a keytab below */
- krb5_cc_destroy(context, ccache);
- ccache = NULL;
+ krb5_cc_close(context, ccache);
+ def_princ = NULL;
kret = 0;
} else if (handle->principal == NULL) {
- kret = krb5_copy_principal(context, def_princ,
- &handle->principal);
+ kret = krb5_copy_principal(context, def_princ, &handle->principal);
if (kret)
goto end;
} else if (handle->principal != NULL &&
- krb5_principal_compare(context, handle->principal,
- def_princ) == FALSE) {
- /* Before failing, lets check the keytab */
+ krb5_principal_compare(context, handle->principal,
+ def_princ) == FALSE) {
krb5_free_principal(context, def_princ);
def_princ = NULL;
+ krb5_cc_close(context, ccache);
+ ccache = NULL;
}
if (def_princ == NULL) {
/* We have no existing credentials cache,
* so attempt to get a TGT using a keytab.
*/
if (handle->principal == NULL) {
- kret = krb5_get_default_principal(context,
- &handle->principal);
+ kret = krb5_get_default_principal(context, &handle->principal);
if (kret)
goto end;
}
@@ -182,16 +183,19 @@ static OM_uint32 acquire_initiator_cred
krb5_get_init_creds_opt_free(context, opt);
if (kret)
goto end;
- kret = krb5_cc_gen_new(context, &krb5_mcc_ops,
- &ccache);
+ kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
if (kret)
goto end;
kret = krb5_cc_initialize(context, ccache, cred.client);
- if (kret)
+ if (kret) {
+ krb5_cc_destroy(context, ccache);
goto end;
+ }
kret = krb5_cc_store_cred(context, ccache, &cred);
- if (kret)
+ if (kret) {
+ krb5_cc_destroy(context, ccache);
goto end;
+ }
handle->lifetime = cred.times.endtime;
handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
} else {
@@ -201,8 +205,10 @@ static OM_uint32 acquire_initiator_cred
ccache,
handle->principal,
&handle->lifetime);
- if (ret != GSS_S_COMPLETE)
+ if (ret != GSS_S_COMPLETE) {
+ krb5_cc_close(context, ccache);
goto end;
+ }
kret = 0;
}
@@ -216,13 +222,8 @@ end:
krb5_free_principal(context, def_princ);
if (keytab != NULL)
krb5_kt_close(context, keytab);
- if (ret != GSS_S_COMPLETE) {
- if (ccache != NULL)
- krb5_cc_close(context, ccache);
- if (kret != 0) {
- *minor_status = kret;
- }
- }
+ if (ret != GSS_S_COMPLETE && kret != 0)
+ *minor_status = kret;
return (ret);
}
@@ -257,8 +258,23 @@ static OM_uint32 acquire_acceptor_cred
goto end;
krb5_kt_free_entry(context, &entry);
ret = GSS_S_COMPLETE;
- }
-
+ } else {
+ /*
+ * Check if there is at least one entry in the keytab before
+ * declaring it as an useful keytab.
+ */
+ krb5_keytab_entry tmp;
+ krb5_kt_cursor c;
+
+ kret = krb5_kt_start_seq_get (context, handle->keytab, &c);
+ if (kret)
+ goto end;
+ if (krb5_kt_next_entry(context, handle->keytab, &tmp, &c) == 0) {
+ krb5_kt_free_entry(context, &tmp);
+ ret = GSS_S_COMPLETE; /* ok found one entry */
+ }
+ krb5_kt_end_seq_get (context, handle->keytab, &c);
+ }
end:
if (ret != GSS_S_COMPLETE) {
if (handle->keytab != NULL)
diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index d4c1bc4db2..03fe61dc57 100644
--- a/source4/heimdal/lib/gssapi/krb5/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -34,7 +34,7 @@
#include "krb5/gsskrb5_locl.h"
#include <gssapi_mech.h>
-RCSID("$Id: external.c 20386 2007-04-18 08:52:08Z lha $");
+RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $");
/*
* The implementation must reserve static storage for a
@@ -374,8 +374,6 @@ gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc;
* Context for krb5 calls.
*/
-krb5_context context;
-
/*
*
*/
diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h
index c2239f1346..64a0dd36b1 100644
--- a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h
+++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h
@@ -413,7 +413,7 @@ _gsskrb5_init (krb5_context */*context*/);
OM_uint32
_gsskrb5_init_sec_context (
OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*initiator_cred_handle*/,
+ const gss_cred_id_t /*cred_handle*/,
gss_ctx_id_t * /*context_handle*/,
const gss_name_t /*target_name*/,
const gss_OID /*mech_type*/,
diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
index 6ffb607035..3e8c1b8fa6 100644
--- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
+++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: gsskrb5_locl.h 20324 2007-04-12 16:46:01Z lha $ */
+/* $Id: gsskrb5_locl.h 22655 2008-02-26 12:40:35Z lha $ */
#ifndef GSSKRB5_LOCL_H
#define GSSKRB5_LOCL_H
@@ -86,6 +86,7 @@ typedef struct {
krb5_principal principal;
int cred_flags;
#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
+#define GSS_CF_NO_CI_FLAGS 2
struct krb5_keytab_data *keytab;
OM_uint32 lifetime;
gss_cred_usage_t usage;
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index 4d1ae0daa9..d4482a54b2 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: init_sec_context.c 20326 2007-04-12 16:49:57Z lha $");
+RCSID("$Id: init_sec_context.c 22671 2008-03-09 23:57:54Z lha $");
/*
* copy the addresses from `input_chan_bindings' (if any) to
@@ -326,7 +326,7 @@ do_delegation (krb5_context context,
static OM_uint32
init_auth
(OM_uint32 * minor_status,
- gsskrb5_cred initiator_cred_handle,
+ gsskrb5_cred cred,
gsskrb5_ctx ctx,
krb5_context context,
krb5_const_principal name,
@@ -344,7 +344,7 @@ init_auth
OM_uint32 ret = GSS_S_FAILURE;
krb5_error_code kret;
krb5_flags ap_options;
- krb5_creds *cred = NULL;
+ krb5_creds *kcred = NULL;
krb5_data outbuf;
krb5_ccache ccache = NULL;
uint32_t flags;
@@ -362,7 +362,7 @@ init_auth
if (actual_mech_type)
*actual_mech_type = GSS_KRB5_MECHANISM;
- if (initiator_cred_handle == NULL) {
+ if (cred == NULL) {
kret = krb5_cc_default (context, &ccache);
if (kret) {
*minor_status = kret;
@@ -370,7 +370,7 @@ init_auth
goto failure;
}
} else
- ccache = initiator_cred_handle->ccache;
+ ccache = cred->ccache;
kret = krb5_cc_get_principal (context, ccache, &ctx->source);
if (kret) {
@@ -400,8 +400,8 @@ init_auth
{
krb5_enctype *enctypes = NULL;
- if (initiator_cred_handle && initiator_cred_handle->enctypes)
- enctypes = initiator_cred_handle->enctypes;
+ if (cred && cred->enctypes)
+ enctypes = cred->enctypes;
krb5_set_default_in_tkt_etypes(context, enctypes);
}
@@ -412,11 +412,11 @@ init_auth
ctx->target,
time_req,
time_rec,
- &cred);
+ &kcred);
if (ret)
goto failure;
- ctx->lifetime = cred->times.endtime;
+ ctx->lifetime = kcred->times.endtime;
ret = _gsskrb5_lifetime_left(minor_status,
context,
@@ -434,11 +434,11 @@ init_auth
krb5_auth_con_setkey(context,
ctx->auth_context,
- &cred->session);
+ &kcred->session);
kret = krb5_auth_con_generatelocalsubkey(context,
ctx->auth_context,
- &cred->session);
+ &kcred->session);
if(kret) {
*minor_status = kret;
ret = GSS_S_FAILURE;
@@ -449,10 +449,10 @@ init_auth
* If the credential doesn't have ok-as-delegate, check what local
* policy say about ok-as-delegate, default is FALSE that makes
* code ignore the KDC setting and follow what the application
- * requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the
+ * requested. If it is TRUE, strip of the GSS_C_DELEG_FLAG if the
* KDC doesn't set ok-as-delegate.
*/
- if (!cred->flags.b.ok_as_delegate) {
+ if (!kcred->flags.b.ok_as_delegate) {
krb5_boolean delegate;
krb5_appdefault_boolean(context,
@@ -467,7 +467,7 @@ init_auth
if (req_flags & GSS_C_DELEG_FLAG)
do_delegation (context,
ctx->auth_context,
- ccache, cred, name, &fwd_data, &flags);
+ ccache, kcred, name, &fwd_data, &flags);
if (req_flags & GSS_C_MUTUAL_FLAG) {
flags |= GSS_C_MUTUAL_FLAG;
@@ -490,8 +490,10 @@ init_auth
if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
flags |= GSS_C_EXTENDED_ERROR_FLAG;
- flags |= GSS_C_CONF_FLAG;
- flags |= GSS_C_INTEG_FLAG;
+ if (cred == NULL || !(cred->cred_flags & GSS_CF_NO_CI_FLAGS)) {
+ flags |= GSS_C_CONF_FLAG;
+ flags |= GSS_C_INTEG_FLAG;
+ }
flags |= GSS_C_TRANS_FLAG;
if (ret_flags)
@@ -513,7 +515,7 @@ init_auth
kret = krb5_build_authenticator (context,
ctx->auth_context,
enctype,
- cred,
+ kcred,
&cksum,
NULL,
&authenticator,
@@ -527,7 +529,7 @@ init_auth
kret = krb5_build_ap_req (context,
enctype,
- cred,
+ kcred,
ap_options,
authenticator,
&outbuf);
@@ -544,9 +546,9 @@ init_auth
goto failure;
krb5_data_free (&outbuf);
- krb5_free_creds(context, cred);
+ krb5_free_creds(context, kcred);
free_Checksum(&cksum);
- if (initiator_cred_handle == NULL)
+ if (cred == NULL)
krb5_cc_close(context, ccache);
if (flags & GSS_C_MUTUAL_FLAG) {
@@ -556,9 +558,9 @@ init_auth
return gsskrb5_initiator_ready(minor_status, ctx, context);
failure:
- if(cred)
- krb5_free_creds(context, cred);
- if (ccache && initiator_cred_handle == NULL)
+ if(kcred)
+ krb5_free_creds(context, kcred);
+ if (ccache && cred == NULL)
krb5_cc_close(context, ccache);
return ret;
@@ -682,7 +684,7 @@ repl_mutual
OM_uint32 _gsskrb5_init_sec_context
(OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
+ const gss_cred_id_t cred_handle,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
@@ -697,7 +699,7 @@ OM_uint32 _gsskrb5_init_sec_context
)
{
krb5_context context;
- gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
+ gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
krb5_const_principal name = (krb5_const_principal)target_name;
gsskrb5_ctx ctx;
OM_uint32 ret;
diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
index d0ca1c4d95..242dfa87b4 100644
--- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
+++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
@@ -32,13 +32,22 @@
#include "krb5/gsskrb5_locl.h"
-RCSID("$Id: set_cred_option.c 20325 2007-04-12 16:49:17Z lha $");
+RCSID("$Id: set_cred_option.c 22655 2008-02-26 12:40:35Z lha $");
+/* 1.2.752.43.13.17 */
+static gss_OID_desc gss_krb5_ccache_name_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
+
+gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &gss_krb5_ccache_name_x_oid_desc;
+
+/* 1.2.752.43.13.18 */
static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
-{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
+
+
static OM_uint32
import_cred(OM_uint32 *minor_status,
krb5_context context,
@@ -201,6 +210,27 @@ out:
return major_stat;
}
+static OM_uint32
+no_ci_flags(OM_uint32 *minor_status,
+ krb5_context context,
+ gss_cred_id_t *cred_handle,
+ const gss_buffer_t value)
+{
+ gsskrb5_cred cred;
+
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ cred = (gsskrb5_cred)*cred_handle;
+ cred->cred_flags |= GSS_CF_NO_CI_FLAGS;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+}
+
OM_uint32
_gsskrb5_set_cred_option
@@ -224,6 +254,11 @@ _gsskrb5_set_cred_option
if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X))
return allowed_enctypes(minor_status, context, cred_handle, value);
+ if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) {
+ return no_ci_flags(minor_status, context, cred_handle, value);
+ }
+
+
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
diff --git a/source4/heimdal/lib/gssapi/mech/context.c b/source4/heimdal/lib/gssapi/mech/context.c
index e4517bee44..926630c42d 100644
--- a/source4/heimdal/lib/gssapi/mech/context.c
+++ b/source4/heimdal/lib/gssapi/mech/context.c
@@ -1,7 +1,7 @@
#include "mech/mech_locl.h"
#include "heim_threads.h"
-RCSID("$Id: context.c 21248 2007-06-21 00:45:13Z lha $");
+RCSID("$Id: context.c 22600 2008-02-21 12:46:24Z lha $");
struct mg_thread_ctx {
gss_OID mech;
@@ -107,6 +107,13 @@ _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)
OM_uint32 message_content;
struct mg_thread_ctx *mg;
+ /*
+ * Mechs without gss_display_status() does
+ * gss_mg_collect_error() by themself.
+ */
+ if (m->gm_display_status == NULL)
+ return ;
+
mg = _gss_mechglue_thread();
if (mg == NULL)
return;
@@ -139,3 +146,12 @@ _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)
mg->min_error.length = 0;
}
}
+
+void
+gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min)
+{
+ gssapi_mech_interface m = __gss_get_mechanism(mech);
+ if (m == NULL)
+ return;
+ _gss_mg_error(m, maj, min);
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
index d1e243d8b8..a6b1ded5ca 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -27,7 +27,7 @@
*/
#include "mech_locl.h"
-RCSID("$Id: gss_accept_sec_context.c 21237 2007-06-20 11:21:09Z lha $");
+RCSID("$Id: gss_accept_sec_context.c 22071 2007-11-14 20:04:50Z lha $");
static OM_uint32
parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
@@ -38,7 +38,7 @@ parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
/*
* Token must start with [APPLICATION 0] SEQUENCE.
- * But if it doesn't assume its DCE-STYLE Kerberos!
+ * But if it doesn't assume it is DCE-STYLE Kerberos!
*/
if (len == 0)
return (GSS_S_DEFECTIVE_TOKEN);
@@ -102,7 +102,7 @@ choose_mech(const gss_buffer_t input, gss_OID mech_oid)
OM_uint32 status;
/*
- * First try to parse the gssapi token header and see if its a
+ * First try to parse the gssapi token header and see if it's a
* correct header, use that in the first hand.
*/
diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
index 9e77f42982..03081cb70f 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
@@ -27,7 +27,7 @@
*/
#include "mech_locl.h"
-RCSID("$Id: gss_krb5.c 21123 2007-06-18 20:05:26Z lha $");
+RCSID("$Id: gss_krb5.c 21889 2007-08-09 07:43:24Z lha $");
#include <krb5.h>
#include <roken.h>
@@ -253,7 +253,6 @@ free_key(gss_krb5_lucid_key_t *key)
memset(key, 0, sizeof(*key));
}
-
OM_uint32
gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
@@ -824,3 +823,43 @@ gsskrb5_set_default_realm(const char *realm)
return (GSS_S_COMPLETE);
}
+
+OM_uint32
+gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ OM_uint32 *tkt_flags)
+{
+
+ OM_uint32 major_status;
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ major_status =
+ gss_inquire_sec_context_by_oid (minor_status,
+ context_handle,
+ GSS_KRB5_GET_TKT_FLAGS_X,
+ &data_set);
+ if (major_status)
+ return major_status;
+
+ if (data_set == GSS_C_NO_BUFFER_SET ||
+ data_set->count != 1 ||
+ data_set->elements[0].length < 4) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ const u_char *p = data_set->elements[0].value;
+ *tkt_flags = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+ }
+
+ gss_release_buffer_set(minor_status, &data_set);
+ return GSS_S_COMPLETE;
+}
+
diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
index f1a18afb13..fe65ad1ae1 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
#include <heim_threads.h>
-RCSID("$Id: gss_mech_switch.c 21700 2007-07-26 19:08:34Z lha $");
+RCSID("$Id: gss_mech_switch.c 21698 2007-07-26 19:07:11Z lha $");
#ifndef _PATH_GSS_MECH
#define _PATH_GSS_MECH "/etc/gss/mech"
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
index 4372e62294..388cfdbf4c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
@@ -27,7 +27,7 @@
*/
#include "mech_locl.h"
-RCSID("$Id: gss_release_oid_set.c 19963 2007-01-17 16:01:22Z lha $");
+RCSID("$Id: gss_release_oid_set.c 22144 2007-12-04 17:31:55Z lha $");
OM_uint32
gss_release_oid_set(OM_uint32 *minor_status,
@@ -35,7 +35,7 @@ gss_release_oid_set(OM_uint32 *minor_status,
{
*minor_status = 0;
- if (*set) {
+ if (set && *set) {
if ((*set)->elements)
free((*set)->elements);
free(*set);
diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
index 1afe26f1e3..df25b0f4bf 100644
--- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
@@ -33,7 +33,7 @@
#include "spnego/spnego_locl.h"
-RCSID("$Id: accept_sec_context.c 21461 2007-07-10 14:01:13Z lha $");
+RCSID("$Id: accept_sec_context.c 22600 2008-02-21 12:46:24Z lha $");
static OM_uint32
send_reject (OM_uint32 *minor_status,
@@ -540,7 +540,7 @@ acceptor_start
gss_cred_id_t *delegated_cred_handle
)
{
- OM_uint32 ret, junk, minor;
+ OM_uint32 ret, junk;
NegotiationToken nt;
size_t nt_len;
NegTokenInit *ni;
@@ -609,7 +609,7 @@ acceptor_start
/*
* First we try the opportunistic token if we have support for it,
* don't try to verify we have credential for the token,
- * gss_accept_sec_context will (hopefully) tell us that.
+ * gss_accept_sec_context() will (hopefully) tell us that.
* If that failes,
*/
@@ -633,12 +633,12 @@ acceptor_start
mech_cred = GSS_C_NO_CREDENTIAL;
if (ctx->mech_src_name != GSS_C_NO_NAME)
- gss_release_name(&minor, &ctx->mech_src_name);
+ gss_release_name(&junk, &ctx->mech_src_name);
if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL)
- _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id);
+ _gss_spnego_release_cred(&junk, &ctx->delegated_cred_id);
- ret = gss_accept_sec_context(&minor,
+ ret = gss_accept_sec_context(minor_status,
&ctx->negotiated_ctx_id,
mech_cred,
mech_input_token,
@@ -656,7 +656,7 @@ acceptor_start
ctx->open = 1;
if (mech_delegated_cred && delegated_cred_handle)
- ret = _gss_spnego_alloc_cred(minor_status,
+ ret = _gss_spnego_alloc_cred(&junk,
mech_delegated_cred,
delegated_cred_handle);
else
@@ -674,6 +674,8 @@ acceptor_start
goto out;
first_ok = 1;
+ } else {
+ gss_mg_collect_error(preferred_mech_type, ret, *minor_status);
}
}
@@ -681,7 +683,9 @@ acceptor_start
* If opportunistic token failed, lets try the other mechs.
*/
- if (!first_ok) {
+ if (!first_ok && ni->mechToken != NULL) {
+
+ preferred_mech_type = GSS_C_NO_OID;
/* Call glue layer to find first mech we support */
for (i = 1; i < ni->mechTypes.len; ++i) {
@@ -695,7 +699,7 @@ acceptor_start
if (preferred_mech_type == GSS_C_NO_OID) {
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
free_NegotiationToken(&nt);
- return GSS_S_BAD_MECH;
+ return ret;
}
ctx->preferred_mech_type = preferred_mech_type;
@@ -717,7 +721,7 @@ acceptor_start
out:
if (mech_output_token.value != NULL)
- gss_release_buffer(&minor, &mech_output_token);
+ gss_release_buffer(&junk, &mech_output_token);
if (mech_buf.value != NULL) {
free(mech_buf.value);
mech_buf.value = NULL;
@@ -754,7 +758,7 @@ out:
return ret;
}
- _gss_spnego_internal_delete_sec_context(&minor, context_handle,
+ _gss_spnego_internal_delete_sec_context(&junk, context_handle,
GSS_C_NO_BUFFER);
return ret;
@@ -877,6 +881,7 @@ acceptor_continue
}
if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
free_NegotiationToken(&nt);
+ gss_mg_collect_error(ctx->negotiated_mech_type, ret, minor);
send_reject (minor_status, output_token);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
return ret;
diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c
index bc7da9410e..287f4f760e 100644
--- a/source4/heimdal/lib/gssapi/spnego/compat.c
+++ b/source4/heimdal/lib/gssapi/spnego/compat.c
@@ -32,7 +32,7 @@
#include "spnego/spnego_locl.h"
-RCSID("$Id: compat.c 19415 2006-12-18 17:52:26Z lha $");
+RCSID("$Id: compat.c 21866 2007-08-08 11:31:29Z lha $");
/*
* Apparently Microsoft got the OID wrong, and used
@@ -129,6 +129,7 @@ OM_uint32 _gss_spnego_internal_delete_sec_context
gss_release_oid(&minor, &ctx->preferred_mech_type);
ctx->negotiated_mech_type = GSS_C_NO_OID;
+ gss_release_name(&minor, &ctx->target_name);
gss_release_name(&minor, &ctx->mech_src_name);
if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) {
diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
index 3535c7bb35..0169017ee5 100644
--- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c
+++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
@@ -32,7 +32,7 @@
#include "spnego/spnego_locl.h"
-RCSID("$Id: context_stubs.c 21035 2007-06-09 15:32:47Z lha $");
+RCSID("$Id: context_stubs.c 22604 2008-02-21 21:12:48Z lha $");
static OM_uint32
spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
@@ -263,18 +263,6 @@ OM_uint32 _gss_spnego_unwrap
qop_state);
}
-OM_uint32 _gss_spnego_display_status
- (OM_uint32 * minor_status,
- OM_uint32 status_value,
- int status_type,
- const gss_OID mech_type,
- OM_uint32 * message_context,
- gss_buffer_t status_string
- )
-{
- return GSS_S_FAILURE;
-}
-
OM_uint32 _gss_spnego_compare_name
(OM_uint32 *minor_status,
const gss_name_t name1,
@@ -406,28 +394,58 @@ OM_uint32 _gss_spnego_inquire_context (
)
{
gssspnego_ctx ctx;
+ OM_uint32 maj_stat, junk;
+ gss_name_t src_mn, targ_mn;
*minor_status = 0;
- if (context_handle == GSS_C_NO_CONTEXT) {
+ if (context_handle == GSS_C_NO_CONTEXT)
return GSS_S_NO_CONTEXT;
- }
ctx = (gssspnego_ctx)context_handle;
- if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
return GSS_S_NO_CONTEXT;
- }
- return gss_inquire_context(minor_status,
- ctx->negotiated_ctx_id,
- src_name,
- targ_name,
- lifetime_rec,
- mech_type,
- ctx_flags,
- locally_initiated,
- open_context);
+ maj_stat = gss_inquire_context(minor_status,
+ ctx->negotiated_ctx_id,
+ &src_mn,
+ &targ_mn,
+ lifetime_rec,
+ mech_type,
+ ctx_flags,
+ locally_initiated,
+ open_context);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ if (src_name) {
+ spnego_name name = calloc(1, sizeof(*name));
+ if (name == NULL)
+ goto enomem;
+ name->mech = src_mn;
+ *src_name = (gss_name_t)name;
+ } else
+ gss_release_name(&junk, &src_mn);
+
+ if (targ_name) {
+ spnego_name name = calloc(1, sizeof(*name));
+ if (name == NULL) {
+ gss_release_name(minor_status, src_name);
+ goto enomem;
+ }
+ name->mech = targ_mn;
+ *targ_name = (gss_name_t)name;
+ } else
+ gss_release_name(&junk, &targ_mn);
+
+ return GSS_S_COMPLETE;
+
+enomem:
+ gss_release_name(&junk, &targ_mn);
+ gss_release_name(&junk, &src_mn);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
}
OM_uint32 _gss_spnego_wrap_size_limit (
diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c
index fbc231f3ae..6c9a03a3b0 100644
--- a/source4/heimdal/lib/gssapi/spnego/external.c
+++ b/source4/heimdal/lib/gssapi/spnego/external.c
@@ -33,7 +33,7 @@
#include "spnego/spnego_locl.h"
#include <gssapi_mech.h>
-RCSID("$Id: external.c 18336 2006-10-07 22:27:13Z lha $");
+RCSID("$Id: external.c 22600 2008-02-21 12:46:24Z lha $");
/*
* RFC2478, SPNEGO:
@@ -57,7 +57,7 @@ static gssapi_mech_interface_desc spnego_mech = {
_gss_spnego_verify_mic,
_gss_spnego_wrap,
_gss_spnego_unwrap,
- _gss_spnego_display_status,
+ NULL,
NULL,
_gss_spnego_compare_name,
_gss_spnego_display_name,
diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
index 7c74981e66..bee4895898 100644
--- a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
@@ -33,7 +33,7 @@
#include "spnego/spnego_locl.h"
-RCSID("$Id: init_sec_context.c 19411 2006-12-18 15:42:03Z lha $");
+RCSID("$Id: init_sec_context.c 22600 2008-02-21 12:46:24Z lha $");
/*
* Is target_name an sane target for `mech´.
@@ -59,8 +59,10 @@ initiator_approved(gss_name_t target_name, gss_OID mech)
&out,
NULL,
NULL);
- if (GSS_ERROR(maj_stat))
+ if (GSS_ERROR(maj_stat)) {
+ gss_mg_collect_error(mech, maj_stat, min_stat);
return GSS_S_BAD_MECH;
+ }
gss_release_buffer(&min_stat, &out);
gss_delete_sec_context(&min_stat, &ctx, NULL);
@@ -268,6 +270,7 @@ spnego_initial
if (GSS_ERROR(sub)) {
free_NegTokenInit(&ni);
*minor_status = minor;
+ gss_mg_collect_error(ctx->preferred_mech_type, sub, minor);
_gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
return sub;
}
@@ -480,7 +483,8 @@ spnego_reply
return GSS_S_BAD_MECH;
}
- if (resp.responseToken != NULL ||
+ /* if a token (of non zero length), or no context, pass to underlaying mech */
+ if ((resp.responseToken != NULL && resp.responseToken->length) ||
ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
gss_buffer_desc mech_input_token;
@@ -515,6 +519,7 @@ spnego_reply
if (GSS_ERROR(ret)) {
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
free_NegTokenResp(&resp);
+ gss_mg_collect_error(&mech, ret, minor);
*minor_status = minor;
return ret;
}
diff --git a/source4/heimdal/lib/gssapi/spnego/spnego-private.h b/source4/heimdal/lib/gssapi/spnego/spnego-private.h
index d80db0018a..69f4d8423d 100644
--- a/source4/heimdal/lib/gssapi/spnego/spnego-private.h
+++ b/source4/heimdal/lib/gssapi/spnego/spnego-private.h
@@ -91,15 +91,6 @@ _gss_spnego_display_name (
gss_OID * output_name_type );
OM_uint32
-_gss_spnego_display_status (
- OM_uint32 * /*minor_status*/,
- OM_uint32 /*status_value*/,
- int /*status_type*/,
- const gss_OID /*mech_type*/,
- OM_uint32 * /*message_context*/,
- gss_buffer_t status_string );
-
-OM_uint32
_gss_spnego_duplicate_name (
OM_uint32 * /*minor_status*/,
const gss_name_t /*src_name*/,
diff --git a/source4/heimdal/lib/hcrypto/bn.c b/source4/heimdal/lib/hcrypto/bn.c
index 698da2fe0b..6076478bbb 100644
--- a/source4/heimdal/lib/hcrypto/bn.c
+++ b/source4/heimdal/lib/hcrypto/bn.c
@@ -35,7 +35,7 @@
#include <config.h>
#endif
-RCSID("$Id: bn.c 18449 2006-10-14 09:21:09Z lha $");
+RCSID("$Id: bn.c 22261 2007-12-09 06:24:18Z lha $");
#include <stdio.h>
#include <stdlib.h>
@@ -232,9 +232,9 @@ BN_set_negative(BIGNUM *bn, int flag)
}
int
-BN_is_negative(BIGNUM *bn)
+BN_is_negative(const BIGNUM *bn)
{
- return ((heim_integer *)bn)->negative ? 1 : 0;
+ return ((const heim_integer *)bn)->negative ? 1 : 0;
}
static const unsigned char is_set[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
diff --git a/source4/heimdal/lib/hcrypto/bn.h b/source4/heimdal/lib/hcrypto/bn.h
index 82c9991c2c..92cacec2a6 100644
--- a/source4/heimdal/lib/hcrypto/bn.h
+++ b/source4/heimdal/lib/hcrypto/bn.h
@@ -32,7 +32,7 @@
*/
/*
- * $Id: bn.h 16536 2006-01-13 08:27:50Z lha $
+ * $Id: bn.h 22260 2007-12-09 06:23:47Z lha $
*/
#ifndef _HEIM_BN_H
@@ -97,7 +97,7 @@ int BN_num_bytes(const BIGNUM *);
int BN_cmp(const BIGNUM *, const BIGNUM *);
void BN_set_negative(BIGNUM *, int);
-int BN_is_negative(BIGNUM *);
+int BN_is_negative(const BIGNUM *);
int BN_is_bit_set(const BIGNUM *, int);
int BN_set_bit(BIGNUM *, int);
diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.c b/source4/heimdal/lib/hcrypto/camellia-ntt.c
new file mode 100644
index 0000000000..c32c406baa
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/camellia-ntt.c
@@ -0,0 +1,1461 @@
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "camellia.h"
+
+/* u32 must be 32bit word */
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ * macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt) \
+ (((u32)(pt)[0] << 24) \
+ ^ ((u32)(pt)[1] << 16) \
+ ^ ((u32)(pt)[2] << 8) \
+ ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st) { \
+ (ct)[0] = (u8)((st) >> 24); \
+ (ct)[1] = (u8)((st) >> 16); \
+ (ct)[2] = (u8)((st) >> 8); \
+ (ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ ll = (ll << bits) + (lr >> (32 - bits)); \
+ lr = (lr << bits) + (rl >> (32 - bits)); \
+ rl = (rl << bits) + (rr >> (32 - bits)); \
+ rr = (rr << bits) + (w0 >> (32 - bits)); \
+ } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ w1 = lr; \
+ ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+ lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+ rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+ rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+ } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ il = xl ^ kl; \
+ ir = xr ^ kr; \
+ t0 = il >> 16; \
+ t1 = ir >> 16; \
+ yl = CAMELLIA_SP1110(ir & 0xff) \
+ ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
+ ^ CAMELLIA_SP3033(t1 & 0xff) \
+ ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
+ yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
+ ^ CAMELLIA_SP0222(t0 & 0xff) \
+ ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(il & 0xff); \
+ yl ^= yr; \
+ yr = CAMELLIA_RR8(yr); \
+ yr ^= yl; \
+ } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+ do { \
+ t0 = kll; \
+ t0 &= ll; \
+ lr ^= CAMELLIA_RL1(t0); \
+ t1 = klr; \
+ t1 |= lr; \
+ ll ^= t1; \
+ \
+ t2 = krr; \
+ t2 |= rr; \
+ rl ^= t2; \
+ t3 = krl; \
+ t3 &= rl; \
+ rr ^= CAMELLIA_RL1(t3); \
+ } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ ir = CAMELLIA_SP1110(xr & 0xff) \
+ ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \
+ ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \
+ ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \
+ il = CAMELLIA_SP1110((xl >> 24) & 0xff) \
+ ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \
+ ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(xl & 0xff); \
+ il ^= kl; \
+ ir ^= kr; \
+ ir ^= il; \
+ il = CAMELLIA_RR8(il); \
+ il ^= ir; \
+ yl ^= ir; \
+ yr ^= il; \
+ } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+ 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+ 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+ 0xe4e4e400,0x85858500,0x57575700,0x35353500,
+ 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+ 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+ 0x45454500,0x19191900,0xa5a5a500,0x21212100,
+ 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+ 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+ 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+ 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+ 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+ 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+ 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+ 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+ 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+ 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+ 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+ 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+ 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+ 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+ 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+ 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+ 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+ 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+ 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+ 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+ 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+ 0x53535300,0x18181800,0xf2f2f200,0x22222200,
+ 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+ 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+ 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+ 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+ 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+ 0xa1a1a100,0x89898900,0x62626200,0x97979700,
+ 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+ 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+ 0x10101000,0xc4c4c400,0x00000000,0x48484800,
+ 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+ 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+ 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+ 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+ 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+ 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+ 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+ 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+ 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+ 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+ 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+ 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+ 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+ 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+ 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+ 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+ 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+ 0xd4d4d400,0x25252500,0xababab00,0x42424200,
+ 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+ 0x72727200,0x07070700,0xb9b9b900,0x55555500,
+ 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+ 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+ 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+ 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+ 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+ 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+ 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+ 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+ 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+ 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+ 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+ 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+ 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+ 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+ 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+ 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+ 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+ 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+ 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+ 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+ 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+ 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+ 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+ 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+ 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+ 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+ 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+ 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+ 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+ 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+ 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+ 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+ 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+ 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+ 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+ 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+ 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+ 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+ 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+ 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+ 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+ 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+ 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+ 0x00202020,0x00898989,0x00000000,0x00909090,
+ 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+ 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+ 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+ 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+ 0x009b9b9b,0x00949494,0x00212121,0x00666666,
+ 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+ 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+ 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+ 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+ 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+ 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+ 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+ 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+ 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+ 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+ 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+ 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+ 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+ 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+ 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+ 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+ 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+ 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+ 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+ 0x00777777,0x00939393,0x00868686,0x00838383,
+ 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+ 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+ 0x38003838,0x41004141,0x16001616,0x76007676,
+ 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+ 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+ 0x75007575,0x06000606,0x57005757,0xa000a0a0,
+ 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+ 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+ 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+ 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+ 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+ 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+ 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+ 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+ 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+ 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+ 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+ 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+ 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+ 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+ 0x3a003a3a,0x09000909,0x95009595,0x10001010,
+ 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+ 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+ 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+ 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+ 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+ 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+ 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+ 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+ 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+ 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+ 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+ 0x12001212,0x04000404,0x74007474,0x54005454,
+ 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+ 0x55005555,0x68006868,0x50005050,0xbe00bebe,
+ 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+ 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+ 0x70007070,0xff00ffff,0x32003232,0x69006969,
+ 0x08000808,0x62006262,0x00000000,0x24002424,
+ 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+ 0x45004545,0x81008181,0x73007373,0x6d006d6d,
+ 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+ 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+ 0xe600e6e6,0x25002525,0x48004848,0x99009999,
+ 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+ 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+ 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+ 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+ 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+ 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+ 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+ 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+ 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+ 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+ 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+ 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+ 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+ 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+ 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+ 0x7c007c7c,0x77007777,0x56005656,0x05000505,
+ 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+ 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+ 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+ 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+ 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+ 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+ 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+ 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+ 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+ 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+ 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+ 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+ 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+ 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+ 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+ 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+ 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+ 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+ 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+ 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+ 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+ 0x24240024,0xe8e800e8,0x60600060,0x69690069,
+ 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+ 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+ 0x10100010,0x00000000,0xa3a300a3,0x75750075,
+ 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+ 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+ 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+ 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+ 0x81810081,0x6f6f006f,0x13130013,0x63630063,
+ 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+ 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+ 0x78780078,0x06060006,0xe7e700e7,0x71710071,
+ 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+ 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+ 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+ 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+ 0x15150015,0xadad00ad,0x77770077,0x80800080,
+ 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+ 0x85850085,0x35350035,0x0c0c000c,0x41410041,
+ 0xefef00ef,0x93930093,0x19190019,0x21210021,
+ 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+ 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+ 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+ 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+ 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+ 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+ 0x12120012,0x20200020,0xb1b100b1,0x99990099,
+ 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+ 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+ 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+ 0x0f0f000f,0x16160016,0x18180018,0x22220022,
+ 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+ 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+ 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+ 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+ 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+ 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+ 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+ 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+ 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+ 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+ 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+ 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+ 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+ 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+ 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+ 0x49490049,0x68680068,0x38380038,0xa4a400a4,
+ 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+ 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+void camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+ u32 kll, klr, krl, krr;
+ u32 il, ir, t0, t1, w0, w1;
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[26];
+ u32 subR[26];
+
+ /**
+ * k == kll || klr || krl || krr (|| is concatination)
+ */
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ /**
+ * generate KL dependent subkeys
+ */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(4) = kll; subr(4) = klr;
+ subl(5) = krl; subr(5) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(10) = kll; subr(10) = klr;
+ subl(11) = krl; subr(11) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(18) = kll; subr(18) = klr;
+ subl(19) = krl; subr(19) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+
+ /* generate KA */
+ kll = subl(0); klr = subr(0);
+ krl = subl(1); krr = subr(1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KA dependent subkeys */
+ subl(2) = kll; subr(2) = klr;
+ subl(3) = krl; subr(3) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(8) = kll; subr(8) = klr;
+ subl(9) = krl; subr(9) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(12) = kll; subr(12) = klr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(20) = kll; subr(20) = klr;
+ subl(21) = krl; subr(21) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(24) = kll; subr(24) = klr;
+ subl(25) = krl; subr(25) = krr;
+
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(25); kw4r = subr(25);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ CamelliaSubkeyL(23) = subl(22);
+ CamelliaSubkeyR(23) = subr(22);
+ CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+ CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+ /* apply the inverse of the last half of P-function */
+ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+ dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+ dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+ dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+ dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+ dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+ dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+ dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+ dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+ dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+ dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+ dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+ dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+ dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+ dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+ dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+ dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+ dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+ return;
+}
+
+void camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+ u32 kll,klr,krl,krr; /* left half of key */
+ u32 krll,krlr,krrl,krrr; /* right half of key */
+ u32 il, ir, t0, t1, w0, w1; /* temporary variables */
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[34];
+ u32 subR[34];
+
+ /**
+ * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+ * (|| is concatination)
+ */
+
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ krll = GETU32(key + 16);
+ krlr = GETU32(key + 20);
+ krrl = GETU32(key + 24);
+ krrr = GETU32(key + 28);
+
+ /* generate KL dependent subkeys */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+ subl(12) = kll; subr(12) = klr;
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(30) = kll; subr(30) = klr;
+ subl(31) = krl; subr(31) = krr;
+
+ /* generate KR dependent subkeys */
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(4) = krll; subr(4) = krlr;
+ subl(5) = krrl; subr(5) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(8) = krll; subr(8) = krlr;
+ subl(9) = krrl; subr(9) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(18) = krll; subr(18) = krlr;
+ subl(19) = krrl; subr(19) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+ subl(26) = krll; subr(26) = krlr;
+ subl(27) = krrl; subr(27) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+ /* generate KA */
+ kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+ krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ kll ^= krll; klr ^= krlr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KB */
+ krll ^= kll; krlr ^= klr;
+ krrl ^= krl; krrr ^= krr;
+ CAMELLIA_F(krll, krlr,
+ CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+ w0, w1, il, ir, t0, t1);
+ krrl ^= w0; krrr ^= w1;
+ CAMELLIA_F(krrl, krrr,
+ CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+ w0, w1, il, ir, t0, t1);
+ krll ^= w0; krlr ^= w1;
+
+ /* generate KA dependent subkeys */
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ subl(24) = klr; subr(24) = krl;
+ subl(25) = krr; subr(25) = kll;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+ subl(28) = kll; subr(28) = klr;
+ subl(29) = krl; subr(29) = krr;
+
+ /* generate KB dependent subkeys */
+ subl(2) = krll; subr(2) = krlr;
+ subl(3) = krrl; subr(3) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(10) = krll; subr(10) = krlr;
+ subl(11) = krrl; subr(11) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(20) = krll; subr(20) = krlr;
+ subl(21) = krrl; subr(21) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+ subl(32) = krll; subr(32) = krlr;
+ subl(33) = krrl; subr(33) = krrr;
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(25);
+ dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(27) ^= subl(1); subr(27) ^= subr(1);
+ subl(29) ^= subl(1); subr(29) ^= subr(1);
+ subl(31) ^= subl(1); subr(31) ^= subr(1);
+ subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(33); kw4r = subr(33);
+ subl(30) ^= kw4l; subr(30) ^= kw4r;
+ subl(28) ^= kw4l; subr(28) ^= kw4r;
+ subl(26) ^= kw4l; subr(26) ^= kw4r;
+ kw4l ^= kw4r & ~subr(24);
+ dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ tl = subl(26) ^ (subr(26) & ~subr(24));
+ dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(23) = subl(22) ^ tl;
+ CamelliaSubkeyR(23) = subr(22) ^ tr;
+ CamelliaSubkeyL(24) = subl(24);
+ CamelliaSubkeyR(24) = subr(24);
+ CamelliaSubkeyL(25) = subl(25);
+ CamelliaSubkeyR(25) = subr(25);
+ tl = subl(23) ^ (subr(23) & ~subr(25));
+ dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(26) = tl ^ subl(27);
+ CamelliaSubkeyR(26) = tr ^ subr(27);
+ CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+ CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+ CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+ CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+ CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+ CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+ CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+ CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+ CamelliaSubkeyL(31) = subl(30);
+ CamelliaSubkeyR(31) = subr(30);
+ CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+ CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+ /* apply the inverse of the last half of P-function */
+ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+ dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+ dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+ dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+ dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+ dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+ dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+ dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+ dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+ dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+ dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+ dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+ dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+ dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+ dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+ dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+ dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+ dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+ dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+ dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+ dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+ dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+ dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+ dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+
+ return;
+}
+
+void camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+ unsigned char kk[32];
+ u32 krll, krlr, krrl,krrr;
+
+ memcpy(kk, key, 24);
+ memcpy((unsigned char *)&krll, key+16,4);
+ memcpy((unsigned char *)&krlr, key+20,4);
+ krrl = ~krll;
+ krrr = ~krlr;
+ memcpy(kk+24, (unsigned char *)&krrl, 4);
+ memcpy(kk+28, (unsigned char *)&krrr, 4);
+ camellia_setup256(kk, subkey);
+ return;
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+ u32 il, ir, t0, t1;
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+ /* main iteration */
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(24);
+ io[3] ^= CamelliaSubkeyR(24);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(24);
+ io[1] ^= CamelliaSubkeyR(24);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(32);
+ io[3] ^= CamelliaSubkeyR(32);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(32);
+ io[1] ^= CamelliaSubkeyR(32);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable)
+{
+ switch(keyBitLength) {
+ case 128:
+ camellia_setup128(rawKey, keyTable);
+ break;
+ case 192:
+ camellia_setup192(rawKey, keyTable);
+ break;
+ case 256:
+ camellia_setup256(rawKey, keyTable);
+ break;
+ default:
+ break;
+ }
+}
+
+
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *ciphertext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(plaintext);
+ tmp[1] = GETU32(plaintext + 4);
+ tmp[2] = GETU32(plaintext + 8);
+ tmp[3] = GETU32(plaintext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_encrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_encrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+
+ PUTU32(ciphertext, tmp[0]);
+ PUTU32(ciphertext + 4, tmp[1]);
+ PUTU32(ciphertext + 8, tmp[2]);
+ PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *ciphertext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(ciphertext);
+ tmp[1] = GETU32(ciphertext + 4);
+ tmp[2] = GETU32(ciphertext + 8);
+ tmp[3] = GETU32(ciphertext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_decrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_decrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+ PUTU32(plaintext, tmp[0]);
+ PUTU32(plaintext + 4, tmp[1]);
+ PUTU32(plaintext + 8, tmp[2]);
+ PUTU32(plaintext + 12, tmp[3]);
+}
diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.h b/source4/heimdal/lib/hcrypto/camellia-ntt.h
new file mode 100644
index 0000000000..740ed8bfd9
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/camellia-ntt.h
@@ -0,0 +1,54 @@
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable);
+
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *cipherText,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
diff --git a/source4/heimdal/lib/hcrypto/camellia.c b/source4/heimdal/lib/hcrypto/camellia.c
new file mode 100644
index 0000000000..2047b75ead
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/camellia.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+RCSID("$Id: aes.c 20466 2007-04-20 08:29:05Z lha $");
+#endif
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+
+#include <string.h>
+
+#include "camellia-ntt.h"
+#include "camellia.h"
+
+int
+CAMELLIA_set_key(const unsigned char *userkey,
+ const int bits, CAMELLIA_KEY *key)
+{
+ key->bits = bits;
+ Camellia_Ekeygen(bits, userkey, key->key);
+ return 1;
+}
+
+void
+CAMELLIA_encrypt(const unsigned char *in, unsigned char *out,
+ const CAMELLIA_KEY *key)
+{
+ Camellia_EncryptBlock(key->bits, in, key->key, out);
+
+}
+
+void
+CAMELLIA_decrypt(const unsigned char *in, unsigned char *out,
+ const CAMELLIA_KEY *key)
+{
+ Camellia_DecryptBlock(key->bits, in, key->key, out);
+}
+
+void
+CAMELLIA_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ unsigned long size, const CAMELLIA_KEY *key,
+ unsigned char *iv, int mode_encrypt)
+{
+ unsigned char tmp[CAMELLIA_BLOCK_SIZE];
+ int i;
+
+ if (mode_encrypt) {
+ while (size >= CAMELLIA_BLOCK_SIZE) {
+ for (i = 0; i < CAMELLIA_BLOCK_SIZE; i++)
+ tmp[i] = in[i] ^ iv[i];
+ CAMELLIA_encrypt(tmp, out, key);
+ memcpy(iv, out, CAMELLIA_BLOCK_SIZE);
+ size -= CAMELLIA_BLOCK_SIZE;
+ in += CAMELLIA_BLOCK_SIZE;
+ out += CAMELLIA_BLOCK_SIZE;
+ }
+ if (size) {
+ for (i = 0; i < size; i++)
+ tmp[i] = in[i] ^ iv[i];
+ for (i = size; i < CAMELLIA_BLOCK_SIZE; i++)
+ tmp[i] = iv[i];
+ CAMELLIA_encrypt(tmp, out, key);
+ memcpy(iv, out, CAMELLIA_BLOCK_SIZE);
+ }
+ } else {
+ while (size >= CAMELLIA_BLOCK_SIZE) {
+ memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+ CAMELLIA_decrypt(tmp, out, key);
+ for (i = 0; i < CAMELLIA_BLOCK_SIZE; i++)
+ out[i] ^= iv[i];
+ memcpy(iv, tmp, CAMELLIA_BLOCK_SIZE);
+ size -= CAMELLIA_BLOCK_SIZE;
+ in += CAMELLIA_BLOCK_SIZE;
+ out += CAMELLIA_BLOCK_SIZE;
+ }
+ if (size) {
+ memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+ CAMELLIA_decrypt(tmp, out, key);
+ for (i = 0; i < size; i++)
+ out[i] ^= iv[i];
+ memcpy(iv, tmp, CAMELLIA_BLOCK_SIZE);
+ }
+ }
+}
diff --git a/source4/heimdal/lib/hcrypto/camellia.h b/source4/heimdal/lib/hcrypto/camellia.h
new file mode 100644
index 0000000000..3b21934b66
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/camellia.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_CAMELLIA_H
+#define HEIM_CAMELLIA_H 1
+
+#include <krb5-types.h>
+#include "camellia-ntt.h"
+
+/* symbol renaming */
+#define CAMELLIA_set_key hc_CAMELLIA_set_encrypt_key
+#define CAMELLIA_encrypt hc_CAMELLIA_encrypt
+#define CAMELLIA_decrypt hc_CAMELLIA_decrypt
+#define CAMELLIA_cbc_encrypt hc_CAMELLIA_cbc_encrypt
+
+/*
+ *
+ */
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_MAXNR 14
+
+#define CAMELLIA_ENCRYPT 1
+#define CAMELLIA_DECRYPT 0
+
+typedef struct camellia_key {
+ unsigned int bits;
+ KEY_TABLE_TYPE key;
+} CAMELLIA_KEY;
+
+int CAMELLIA_set_key(const unsigned char *, const int, CAMELLIA_KEY *);
+
+void CAMELLIA_encrypt(const unsigned char *, unsigned char *,
+ const CAMELLIA_KEY *);
+void CAMELLIA_decrypt(const unsigned char *, unsigned char *,
+ const CAMELLIA_KEY *);
+
+void CAMELLIA_cbc_encrypt(const unsigned char *, unsigned char *,
+ const unsigned long, const CAMELLIA_KEY *,
+ unsigned char *, int);
+
+#endif /* HEIM_CAMELLIA_H */
diff --git a/source4/heimdal/lib/hcrypto/dh-imath.c b/source4/heimdal/lib/hcrypto/dh-imath.c
index 17592bbdf6..494d436d13 100644
--- a/source4/heimdal/lib/hcrypto/dh-imath.c
+++ b/source4/heimdal/lib/hcrypto/dh-imath.c
@@ -43,7 +43,7 @@
#include "imath/imath.h"
-RCSID("$Id: dh-imath.c 18645 2006-10-20 06:56:57Z lha $");
+RCSID("$Id: dh-imath.c 22368 2007-12-28 15:27:52Z lha $");
static void
BN2mpz(mpz_t *s, const BIGNUM *bn)
@@ -224,7 +224,7 @@ dh_finish(DH *dh)
*
*/
-const DH_METHOD hc_dh_imath_method = {
+const DH_METHOD _hc_dh_imath_method = {
"hcrypto imath DH",
dh_generate_key,
dh_compute_key,
@@ -236,8 +236,16 @@ const DH_METHOD hc_dh_imath_method = {
dh_generate_params
};
+/**
+ * DH implementation using libimath.
+ *
+ * @return the DH_METHOD for the DH implementation using libimath.
+ *
+ * @ingroup hcrypto_dh
+ */
+
const DH_METHOD *
DH_imath_method(void)
{
- return &hc_dh_imath_method;
+ return &_hc_dh_imath_method;
}
diff --git a/source4/heimdal/lib/hcrypto/dh.c b/source4/heimdal/lib/hcrypto/dh.c
index b558eb901c..9f1af0b3b1 100644
--- a/source4/heimdal/lib/hcrypto/dh.c
+++ b/source4/heimdal/lib/hcrypto/dh.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -35,7 +35,7 @@
#include <config.h>
#endif
-RCSID("$Id: dh.c 18618 2006-10-19 17:31:51Z lha $");
+RCSID("$Id: dh.c 22397 2008-01-01 20:20:31Z lha $");
#include <stdio.h>
#include <stdlib.h>
@@ -43,8 +43,23 @@ RCSID("$Id: dh.c 18618 2006-10-19 17:31:51Z lha $");
#include <roken.h>
-/*
+/**
+ * @page page_dh DH - Diffie-Hellman key exchange
+ *
+ * Diffie-Hellman key exchange is a protocol that allows two parties
+ * to establish a shared secret key.
+ *
+ * Include and example how to use DH_new() and friends here.
*
+ * See the library functions here: @ref hcrypto_dh
+ */
+
+/**
+ * Create a new DH object using DH_new_method(NULL), see DH_new_method().
+ *
+ * @return a newly allocated DH object.
+ *
+ * @ingroup hcrypto_dh
*/
DH *
@@ -53,6 +68,17 @@ DH_new(void)
return DH_new_method(NULL);
}
+/**
+ * Create a new DH object from the given engine, if the NULL is used,
+ * the default engine is used. Free the DH object with DH_free().
+ *
+ * @param engine The engine to use to allocate the DH object.
+ *
+ * @return a newly allocated DH object.
+ *
+ * @ingroup hcrypto_dh
+ */
+
DH *
DH_new_method(ENGINE *engine)
{
@@ -88,6 +114,15 @@ DH_new_method(ENGINE *engine)
return dh;
}
+/**
+ * Free a DH object and release related resources, like ENGINE, that
+ * the object was using.
+ *
+ * @param dh object to be freed.
+ *
+ * @ingroup hcrypto_dh
+ */
+
void
DH_free(DH *dh)
{
@@ -116,18 +151,52 @@ DH_free(DH *dh)
free(dh);
}
+/**
+ * Add a reference to the DH object. The object should be free with
+ * DH_free() to drop the reference.
+ *
+ * @param dh the object to increase the reference count too.
+ *
+ * @return the updated reference count, can't safely be used except
+ * for debug printing.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_up_ref(DH *dh)
{
return ++dh->references;
}
+/**
+ * The maximum output size of the DH_compute_key() function.
+ *
+ * @param dh The DH object to get the size from.
+ *
+ * @return the maximum size in bytes of the out data.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_size(const DH *dh)
{
return BN_num_bytes(dh->p);
}
+/**
+ * Set the data index idx in the DH object to data.
+ *
+ * @param dh DH object.
+ * @param idx index to set the data for.
+ * @param data data to store for the index idx.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_set_ex_data(DH *dh, int idx, void *data)
{
@@ -135,12 +204,36 @@ DH_set_ex_data(DH *dh, int idx, void *data)
return 1;
}
+/**
+ * Get the data for index idx in the DH object.
+ *
+ * @param dh DH object.
+ * @param idx index to get the data for.
+ *
+ * @return the object store in index idx
+ *
+ * @ingroup hcrypto_dh
+ */
+
void *
DH_get_ex_data(DH *dh, int idx)
{
return dh->ex_data.sk;
}
+/**
+ * Generate DH parameters for the DH object give parameters.
+ *
+ * @param dh The DH object to generate parameters for.
+ * @param prime_len length of the prime
+ * @param generator generator, g
+ * @param cb Callback parameters to show progress, can be NULL.
+ *
+ * @return the maximum size in bytes of the out data.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb)
{
@@ -149,12 +242,17 @@ DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb)
return 0;
}
-/*
- * Check that
+/**
+ * Check that the public key is sane.
*
- * pub_key > 1 and pub_key < p - 1
+ * @param dh the local peer DH parameters.
+ * @param pub_key the remote peer public key parameters.
+ * @param codes return that the failures of the pub_key are.
*
- * to avoid small subgroups attack.
+ * @return 1 on success, 0 on failure and *codes is set the the
+ * combined fail check for the public key
+ *
+ * @ingroup hcrypto_dh
*/
int
@@ -165,6 +263,19 @@ DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes)
*codes = 0;
+ /**
+ * Checks that the function performs are:
+ * - pub_key is not negative
+ */
+
+ if (BN_is_negative(pub_key))
+ goto out;
+
+ /**
+ * - pub_key > 1 and pub_key < p - 1,
+ * to avoid small subgroups attack.
+ */
+
bn = BN_new();
if (bn == NULL)
goto out;
@@ -184,6 +295,28 @@ DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes)
if (BN_cmp(sum, dh->p) >= 0)
*codes |= DH_CHECK_PUBKEY_TOO_LARGE;
+ /**
+ * - if g == 2, pub_key have more then one bit set,
+ * if bits set is 1, log_2(pub_key) is trival
+ */
+
+ if (!BN_set_word(bn, 2))
+ goto out;
+
+ if (BN_cmp(bn, pub_key) == 0) {
+ unsigned i, n = BN_num_bits(pub_key);
+ unsigned bits = 0;
+
+ for (i = 0; i <= n; i++)
+ if (BN_is_bit_set(pub_key, i))
+ bits++;
+
+ if (bits > 1) {
+ *codes |= DH_CHECK_PUBKEY_TOO_SMALL;
+ goto out;
+ }
+ }
+
ret = 1;
out:
if (bn)
@@ -194,24 +327,64 @@ out:
return ret;
}
+/**
+ * Generate a new DH private-public key pair. The dh parameter must be
+ * allocted first with DH_new(). dh->p and dp->g must be set.
+ *
+ * @param dh dh parameter.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_generate_key(DH *dh)
{
return dh->meth->generate_key(dh);
}
+/**
+ * Complute the shared secret key.
+ *
+ * @param shared_key the resulting shared key, need to be at least
+ * DH_size() large.
+ * @param peer_pub_key the peer's public key.
+ * @param dh the dh key pair.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_compute_key(unsigned char *shared_key,
const BIGNUM *peer_pub_key, DH *dh)
{
int codes;
+ /**
+ * Checks that the pubkey passed in is valid using
+ * DH_check_pubkey().
+ */
+
if (!DH_check_pubkey(dh, peer_pub_key, &codes) || codes != 0)
return -1;
return dh->meth->compute_key(shared_key, peer_pub_key, dh);
}
+/**
+ * Set a new method for the DH keypair.
+ *
+ * @param dh dh parameter.
+ * @param method the new method for the DH parameter.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
int
DH_set_method(DH *dh, const DH_METHOD *method)
{
@@ -271,8 +444,16 @@ static const DH_METHOD dh_null_method = {
dh_null_generate_params
};
-extern const DH_METHOD hc_dh_imath_method;
-static const DH_METHOD *dh_default_method = &hc_dh_imath_method;
+extern const DH_METHOD _hc_dh_imath_method;
+static const DH_METHOD *dh_default_method = &_hc_dh_imath_method;
+
+/**
+ * Return the dummy DH implementation.
+ *
+ * @return pointer to a DH_METHOD.
+ *
+ * @ingroup hcrypto_dh
+ */
const DH_METHOD *
DH_null_method(void)
@@ -280,12 +461,28 @@ DH_null_method(void)
return &dh_null_method;
}
+/**
+ * Set the default DH implementation.
+ *
+ * @param meth pointer to a DH_METHOD.
+ *
+ * @ingroup hcrypto_dh
+ */
+
void
DH_set_default_method(const DH_METHOD *meth)
{
dh_default_method = meth;
}
+/**
+ * Return the default DH implementation.
+ *
+ * @return pointer to a DH_METHOD.
+ *
+ * @ingroup hcrypto_dh
+ */
+
const DH_METHOD *
DH_get_default_method(void)
{
diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c
index 19b0ac85e7..788000b054 100644
--- a/source4/heimdal/lib/hcrypto/evp.c
+++ b/source4/heimdal/lib/hcrypto/evp.c
@@ -1,7 +1,42 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+RCSID("$Id: evp.c 22379 2007-12-29 11:13:26Z lha $");
+
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
@@ -13,6 +48,7 @@
#include <krb5-types.h>
#include <aes.h>
+#include "camellia.h"
#include <des.h>
#include <sha.h>
#include <rc2.h>
@@ -21,6 +57,13 @@
#include <md4.h>
#include <md5.h>
+/**
+ * @page page_evp EVP - generic crypto interface
+ *
+ * See the library functions here: @ref hcrypto_evp
+ */
+
+
typedef int (*evp_md_init)(EVP_MD_CTX *);
typedef int (*evp_md_update)(EVP_MD_CTX *,const void *, size_t);
typedef int (*evp_md_final)(void *, EVP_MD_CTX *);
@@ -36,8 +79,14 @@ struct hc_evp_md {
evp_md_cleanup cleanup;
};
-/*
+/**
+ * Return the output size of the message digest function.
+ *
+ * @param md the evp message
*
+ * @return size output size of the message digest function.
+ *
+ * @ingroup hcrypto_evp
*/
size_t
@@ -46,24 +95,60 @@ EVP_MD_size(const EVP_MD *md)
return md->hash_size;
}
+/**
+ * Return the blocksize of the message digest function.
+ *
+ * @param md the evp message
+ *
+ * @return size size of the message digest block size
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_MD_block_size(const EVP_MD *md)
{
return md->block_size;
}
+/**
+ * Allocate a messsage digest context object. Free with
+ * EVP_MD_CTX_destroy().
+ *
+ * @return a newly allocated message digest context object.
+ *
+ * @ingroup hcrypto_evp
+ */
+
EVP_MD_CTX *
EVP_MD_CTX_create(void)
{
return calloc(1, sizeof(EVP_MD_CTX));
}
+/**
+ * Initiate a messsage digest context object. Deallocate with
+ * EVP_MD_CTX_cleanup(). Please use EVP_MD_CTX_create() instead.
+ *
+ * @param ctx variable to initiate.
+ *
+ * @ingroup hcrypto_evp
+ */
+
void
EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
memset(ctx, 0, sizeof(*ctx));
}
+/**
+ * Free a messsage digest context object.
+ *
+ * @param ctx context to free.
+ *
+ * @ingroup hcrypto_evp
+ */
+
void
EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
{
@@ -71,6 +156,16 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
free(ctx);
}
+/**
+ * Free the resources used by the EVP_MD context.
+ *
+ * @param ctx the context to free the resources from.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
{
@@ -79,9 +174,19 @@ EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
ctx->md = NULL;
ctx->engine = NULL;
free(ctx->ptr);
+ memset(ctx, 0, sizeof(*ctx));
return 1;
}
+/**
+ * Get the EVP_MD use for a specified context.
+ *
+ * @param ctx the EVP_MD context to get the EVP_MD for.
+ *
+ * @return the EVP_MD used for the context.
+ *
+ * @ingroup hcrypto_evp
+ */
const EVP_MD *
EVP_MD_CTX_md(EVP_MD_CTX *ctx)
@@ -89,18 +194,50 @@ EVP_MD_CTX_md(EVP_MD_CTX *ctx)
return ctx->md;
}
+/**
+ * Return the output size of the message digest function.
+ *
+ * @param ctx the evp message digest context
+ *
+ * @return size output size of the message digest function.
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_MD_CTX_size(EVP_MD_CTX *ctx)
{
return EVP_MD_size(ctx->md);
}
+/**
+ * Return the blocksize of the message digest function.
+ *
+ * @param ctx the evp message digest context
+ *
+ * @return size size of the message digest block size
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_MD_CTX_block_size(EVP_MD_CTX *ctx)
{
return EVP_MD_block_size(ctx->md);
}
+/**
+ * Init a EVP_MD_CTX for use a specific message digest and engine.
+ *
+ * @param ctx the message digest context to init.
+ * @param md the message digest to use.
+ * @param engine the engine to use, NULL to use the default engine.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
{
@@ -117,6 +254,18 @@ EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
return 1;
}
+/**
+ * Update the digest with some data.
+ *
+ * @param ctx the context to update
+ * @param data the data to update the context with
+ * @param size length of data
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size)
{
@@ -124,6 +273,19 @@ EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size)
return 1;
}
+/**
+ * Complete the message digest.
+ *
+ * @param ctx the context to complete.
+ * @param hash the output of the message digest function. At least
+ * EVP_MD_size().
+ * @param size the output size of hash.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size)
{
@@ -133,6 +295,23 @@ EVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size)
return 1;
}
+/**
+ * Do the whole EVP_MD_CTX_create(), EVP_DigestInit_ex(),
+ * EVP_DigestUpdate(), EVP_DigestFinal_ex(), EVP_MD_CTX_destroy()
+ * dance in one call.
+ *
+ * @param data the data to update the context with
+ * @param dsize length of data
+ * @param hash output data of at least EVP_MD_size() length.
+ * @param hsize output length of hash.
+ * @param md message digest to use
+ * @param engine engine to use, NULL for default engine.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
const EVP_MD *md, ENGINE *engine)
@@ -144,20 +323,26 @@ EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
if (ctx == NULL)
return 0;
ret = EVP_DigestInit_ex(ctx, md, engine);
- if (ret != 1)
+ if (ret != 1) {
+ EVP_MD_CTX_destroy(ctx);
return ret;
+ }
ret = EVP_DigestUpdate(ctx, data, dsize);
- if (ret != 1)
+ if (ret != 1) {
+ EVP_MD_CTX_destroy(ctx);
return ret;
+ }
ret = EVP_DigestFinal_ex(ctx, hash, hsize);
- if (ret != 1)
- return ret;
EVP_MD_CTX_destroy(ctx);
- return 1;
+ return ret;
}
-/*
+/**
+ * The message digest SHA256
+ *
+ * @return the message digest type.
*
+ * @ingroup hcrypto_evp
*/
const EVP_MD *
@@ -185,18 +370,42 @@ static const struct hc_evp_md sha1 = {
NULL
};
+/**
+ * The message digest SHA1
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_sha1(void)
{
return &sha1;
}
+/**
+ * The message digest SHA1
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_sha(void)
{
return &sha1;
}
+/**
+ * The message digest MD5
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_md5(void)
{
@@ -212,6 +421,14 @@ EVP_md5(void)
return &md5;
}
+/**
+ * The message digest MD4
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_md4(void)
{
@@ -227,6 +444,14 @@ EVP_md4(void)
return &md4;
}
+/**
+ * The message digest MD2
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_md2(void)
{
@@ -255,10 +480,18 @@ null_Update (void *m, const void * data, size_t size)
{
}
static void
-null_Final(void *res, struct md5 *m)
+null_Final(void *res, void *m)
{
}
+/**
+ * The null message digest
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_md_null(void)
{
@@ -282,8 +515,14 @@ int EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *);
int EVP_VerifyFinal(EVP_MD_CTX *, const void *, size_t, EVP_PKEY *);
#endif
-/*
+/**
+ * Return the block size of the cipher.
+ *
+ * @param c cipher to get the block size from.
*
+ * @return the block size of the cipher.
+ *
+ * @ingroup hcrypto_evp
*/
size_t
@@ -292,24 +531,63 @@ EVP_CIPHER_block_size(const EVP_CIPHER *c)
return c->block_size;
}
+/**
+ * Return the key size of the cipher.
+ *
+ * @param c cipher to get the key size from.
+ *
+ * @return the key size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_CIPHER_key_length(const EVP_CIPHER *c)
{
return c->key_len;
}
+/**
+ * Return the IV size of the cipher.
+ *
+ * @param c cipher to get the IV size from.
+ *
+ * @return the IV size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_CIPHER_iv_length(const EVP_CIPHER *c)
{
return c->iv_len;
}
+/**
+ * Initiate a EVP_CIPHER_CTX context. Clean up with
+ * EVP_CIPHER_CTX_cleanup().
+ *
+ * @param c the cipher initiate.
+ *
+ * @ingroup hcrypto_evp
+ */
+
void
EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c)
{
memset(c, 0, sizeof(*c));
}
+/**
+ * Clean up the EVP_CIPHER_CTX context.
+ *
+ * @param c the cipher to clean up.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{
@@ -336,54 +614,149 @@ EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad)
}
#endif
+/**
+ * Return the EVP_CIPHER for a EVP_CIPHER_CTX context.
+ *
+ * @param ctx the context to get the cipher type from.
+ *
+ * @return the EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx)
{
return ctx->cipher;
}
+/**
+ * Return the block size of the cipher context.
+ *
+ * @param ctx cipher context to get the block size from.
+ *
+ * @return the block size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
{
return EVP_CIPHER_block_size(ctx->cipher);
}
+/**
+ * Return the key size of the cipher context.
+ *
+ * @param ctx cipher context to get the key size from.
+ *
+ * @return the key size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
{
return EVP_CIPHER_key_length(ctx->cipher);
}
+/**
+ * Return the IV size of the cipher context.
+ *
+ * @param ctx cipher context to get the IV size from.
+ *
+ * @return the IV size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
size_t
EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
{
return EVP_CIPHER_iv_length(ctx->cipher);
}
+/**
+ * Get the flags for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the flags from
+ *
+ * @return the flags for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
unsigned long
EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
{
return ctx->cipher->flags;
}
+/**
+ * Get the mode for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the mode from
+ *
+ * @return the mode for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx)
{
return EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_MODE;
}
+/**
+ * Get the app data for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the app data from
+ *
+ * @return the app data for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
void *
EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *ctx)
{
return ctx->app_data;
}
+/**
+ * Set the app data for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to set the app data for
+ * @param data the app data to set for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
void
EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
{
ctx->app_data = data;
}
+/**
+ * Initiate the EVP_CIPHER_CTX context to encrypt or decrypt data.
+ * Clean up with EVP_CIPHER_CTX_cleanup().
+ *
+ * @param ctx context to initiate
+ * @param c cipher to use.
+ * @param engine crypto engine to use, NULL to select default.
+ * @param key the crypto key to use, NULL will use the previous value.
+ * @param iv the IV to use, NULL will use the previous value.
+ * @param encp non zero will encrypt, -1 use the previous value.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
const void *key, const void *iv, int encp)
@@ -426,6 +799,17 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
return 1;
}
+/**
+ * Encypher/decypher data
+ *
+ * @param ctx the cipher context.
+ * @param out out data from the operation.
+ * @param in in data to the operation.
+ * @param size length of data.
+ *
+ * @return 1 on success.
+ */
+
int
EVP_Cipher(EVP_CIPHER_CTX *ctx, void *out, const void *in,size_t size)
{
@@ -461,6 +845,14 @@ enc_null_cleanup(EVP_CIPHER_CTX *ctx)
return 1;
}
+/**
+ * The NULL cipher type, does no encryption/decryption.
+ *
+ * @return the null EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_enc_null(void)
{
@@ -524,6 +916,13 @@ rc2_cleanup(EVP_CIPHER_CTX *ctx)
return 1;
}
+/**
+ * The RC2 cipher type
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
const EVP_CIPHER *
EVP_rc2_cbc(void)
@@ -546,6 +945,14 @@ EVP_rc2_cbc(void)
return &rc2_cbc;
}
+/**
+ * The RC2-40 cipher type
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_rc2_40_cbc(void)
{
@@ -567,6 +974,14 @@ EVP_rc2_40_cbc(void)
return &rc2_40_cbc;
}
+/**
+ * The RC2-64 cipher type
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_rc2_64_cbc(void)
{
@@ -588,8 +1003,12 @@ EVP_rc2_64_cbc(void)
return &rc2_64_cbc;
}
-/*
+/**
+ * The RC4 cipher type
*
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
*/
const EVP_CIPHER *
@@ -600,6 +1019,14 @@ EVP_rc4(void)
return NULL;
}
+/**
+ * The RC4-40 cipher type
+ *
+ * @return the RC4-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_rc4_40(void)
{
@@ -651,6 +1078,14 @@ des_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx)
return 1;
}
+/**
+ * The tripple DES cipher type
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_des_ede3_cbc(void)
{
@@ -708,6 +1143,14 @@ aes_cleanup(EVP_CIPHER_CTX *ctx)
return 1;
}
+/**
+ * The AES-128 cipher type
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_aes_128_cbc(void)
{
@@ -729,6 +1172,14 @@ EVP_aes_128_cbc(void)
return &aes_128_cbc;
}
+/**
+ * The AES-192 cipher type
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_aes_192_cbc(void)
{
@@ -750,6 +1201,13 @@ EVP_aes_192_cbc(void)
return &aes_192_cbc;
}
+/**
+ * The AES-256 cipher type
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
const EVP_CIPHER *
EVP_aes_256_cbc(void)
@@ -772,6 +1230,123 @@ EVP_aes_256_cbc(void)
return &aes_256_cbc;
}
+static int
+camellia_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ CAMELLIA_KEY *k = ctx->cipher_data;
+ k->bits = ctx->cipher->key_len * 8;
+ CAMELLIA_set_key(key, ctx->cipher->key_len * 8, k);
+ return 1;
+}
+
+static int
+camellia_do_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in,
+ unsigned int size)
+{
+ CAMELLIA_KEY *k = ctx->cipher_data;
+ CAMELLIA_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+ return 1;
+}
+
+static int
+camellia_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ memset(ctx->cipher_data, 0, sizeof(CAMELLIA_KEY));
+ return 1;
+}
+
+/**
+ * The Camellia-128 cipher type
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_128_cbc(void)
+{
+ static const EVP_CIPHER cipher = {
+ 0,
+ 16,
+ 16,
+ 16,
+ EVP_CIPH_CBC_MODE,
+ camellia_init,
+ camellia_do_cipher,
+ camellia_cleanup,
+ sizeof(CAMELLIA_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &cipher;
+}
+
+/**
+ * The Camellia-198 cipher type
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_192_cbc(void)
+{
+ static const EVP_CIPHER cipher = {
+ 0,
+ 16,
+ 24,
+ 16,
+ EVP_CIPH_CBC_MODE,
+ camellia_init,
+ camellia_do_cipher,
+ camellia_cleanup,
+ sizeof(CAMELLIA_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &cipher;
+}
+
+/**
+ * The Camellia-256 cipher type
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_256_cbc(void)
+{
+ static const EVP_CIPHER cipher = {
+ 0,
+ 16,
+ 32,
+ 16,
+ EVP_CIPH_CBC_MODE,
+ camellia_init,
+ camellia_do_cipher,
+ camellia_cleanup,
+ sizeof(CAMELLIA_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &cipher;
+}
+
/*
*
*/
@@ -783,9 +1358,21 @@ static const struct cipher_name {
{ "des-ede3-cbc", EVP_des_ede3_cbc },
{ "aes-128-cbc", EVP_aes_128_cbc },
{ "aes-192-cbc", EVP_aes_192_cbc },
- { "aes-256-cbc", EVP_aes_256_cbc }
+ { "aes-256-cbc", EVP_aes_256_cbc },
+ { "camellia-128-cbc", EVP_camellia_128_cbc },
+ { "camellia-192-cbc", EVP_camellia_192_cbc },
+ { "camellia-256-cbc", EVP_camellia_256_cbc }
};
+/**
+ * Get the cipher type using their name.
+ *
+ * @param name the name of the cipher.
+ *
+ * @return the selected EVP_CIPHER pointer or NULL if not found.
+ *
+ * @ingroup hcrypto_evp
+ */
const EVP_CIPHER *
EVP_get_cipherbyname(const char *name)
@@ -807,6 +1394,26 @@ EVP_get_cipherbyname(const char *name)
#define min(a,b) (((a)>(b))?(b):(a))
#endif
+/**
+ * Provides a legancy string to key function, used in PEM files.
+ *
+ * New protocols should use new string to key functions like NIST
+ * SP56-800A or PKCS#5 v2.0 (see PKCS5_PBKDF2_HMAC_SHA1()).
+ *
+ * @param type type of cipher to use
+ * @param md message digest to use
+ * @param salt salt salt string, should be an binary 8 byte buffer.
+ * @param data the password/input key string.
+ * @param datalen length of data parameter.
+ * @param count iteration counter.
+ * @param keydata output keydata, needs to of the size EVP_CIPHER_key_length().
+ * @param ivdata output ivdata, needs to of the size EVP_CIPHER_block_size().
+ *
+ * @return the size of derived key.
+ *
+ * @ingroup hcrypto_evp
+ */
+
int
EVP_BytesToKey(const EVP_CIPHER *type,
const EVP_MD *md,
@@ -886,8 +1493,10 @@ EVP_BytesToKey(const EVP_CIPHER *type,
return EVP_CIPHER_key_length(type);
}
-/*
+/**
+ * Add all algorithms to the crypto core.
*
+ * @ingroup hcrypto_core
*/
void
@@ -896,12 +1505,25 @@ OpenSSL_add_all_algorithms(void)
return;
}
+/**
+ * Add all algorithms to the crypto core using configuration file.
+ *
+ * @ingroup hcrypto_core
+ */
+
void
OpenSSL_add_all_algorithms_conf(void)
{
return;
}
+/**
+ * Add all algorithms to the crypto core, but don't use the
+ * configuration file.
+ *
+ * @ingroup hcrypto_core
+ */
+
void
OpenSSL_add_all_algorithms_noconf(void)
{
diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h
index a3fbc4c9ca..4910ca01b8 100644
--- a/source4/heimdal/lib/hcrypto/evp.h
+++ b/source4/heimdal/lib/hcrypto/evp.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: evp.h 18312 2006-10-07 17:21:48Z lha $ */
+/* $Id: evp.h 21687 2007-07-24 16:29:05Z lha $ */
#ifndef HEIM_EVP_H
#define HEIM_EVP_H 1
@@ -83,6 +83,9 @@
#define EVP_rc2_cbc hc_EVP_rc2_cbc
#define EVP_rc4 hc_EVP_rc4
#define EVP_rc4_40 hc_EVP_rc4_40
+#define EVP_camellia_128_cbc hc_EVP_camellia_128_cbc
+#define EVP_camellia_192_cbc hc_EVP_camellia_192_cbc
+#define EVP_camellia_256_cbc hc_EVP_camellia_256_cbc
#define EVP_sha hc_EVP_sha
#define EVP_sha1 hc_EVP_sha1
#define EVP_sha256 hc_EVP_sha256
@@ -180,6 +183,9 @@ const EVP_CIPHER * EVP_rc2_64_cbc(void);
const EVP_CIPHER * EVP_rc2_cbc(void);
const EVP_CIPHER * EVP_rc4(void);
const EVP_CIPHER * EVP_rc4_40(void);
+const EVP_CIPHER * EVP_camellia_128_cbc(void);
+const EVP_CIPHER * EVP_camellia_192_cbc(void);
+const EVP_CIPHER * EVP_camellia_256_cbc(void);
/*
*
diff --git a/source4/heimdal/lib/hcrypto/hmac.c b/source4/heimdal/lib/hcrypto/hmac.c
index 6c59758b11..d0433edef6 100644
--- a/source4/heimdal/lib/hcrypto/hmac.c
+++ b/source4/heimdal/lib/hcrypto/hmac.c
@@ -1,6 +1,35 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <sys/types.h>
#include <stdio.h>
diff --git a/source4/heimdal/lib/hcrypto/imath/imath.c b/source4/heimdal/lib/hcrypto/imath/imath.c
index 376425788b..4487029f78 100755
--- a/source4/heimdal/lib/hcrypto/imath/imath.c
+++ b/source4/heimdal/lib/hcrypto/imath/imath.c
@@ -2,7 +2,7 @@
Name: imath.c
Purpose: Arbitrary precision integer arithmetic routines.
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
- Info: $Id: imath.c 20854 2007-06-03 18:04:10Z lha $
+ Info: $Id: imath.c 22648 2008-02-25 07:37:57Z lha $
Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
@@ -1769,7 +1769,7 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e
return MP_RANGE;
/* Skip leading whitespace */
- while(isspace((int)*str))
+ while(isspace((unsigned char)*str))
++str;
/* Handle leading sign tag (+/-, positive default) */
@@ -3135,7 +3135,7 @@ static int s_ch2val(char c, int r)
if(isdigit((unsigned char) c))
out = c - '0';
else if(r > 10 && isalpha((unsigned char) c))
- out = toupper(c) - 'A' + 10;
+ out = toupper((unsigned char)c) - 'A' + 10;
else
return -1;
diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c
index 248fdde620..79dd39eb76 100644
--- a/source4/heimdal/lib/hcrypto/rand.c
+++ b/source4/heimdal/lib/hcrypto/rand.c
@@ -35,7 +35,7 @@
#include <config.h>
#endif
-RCSID("$Id: rand.c 21198 2007-06-20 05:10:41Z lha $");
+RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $");
#include <stdio.h>
#include <stdlib.h>
@@ -189,13 +189,12 @@ RAND_file_name(char *filename, size_t size)
pathp = 1;
}
}
- if (e == NULL) {
- struct passwd *pw = getpwuid(getuid());
- if (pw) {
- e = pw->pw_dir;
- pathp = 1;
- }
- }
+ /*
+ * Here we really want to call getpwuid(getuid()) but this will
+ * cause recursive lookups if the nss library uses
+ * gssapi/krb5/hcrypto to authenticate to the ldap servers.
+ */
+
if (e == NULL)
return NULL;
diff --git a/source4/heimdal/lib/hcrypto/rsa.c b/source4/heimdal/lib/hcrypto/rsa.c
index a7b4371e4d..270857d175 100644
--- a/source4/heimdal/lib/hcrypto/rsa.c
+++ b/source4/heimdal/lib/hcrypto/rsa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -35,7 +35,7 @@
#include <config.h>
#endif
-RCSID("$Id: rsa.c 20466 2007-04-20 08:29:05Z lha $");
+RCSID("$Id: rsa.c 22422 2008-01-13 09:43:59Z lha $");
#include <stdio.h>
#include <stdlib.h>
@@ -46,12 +46,41 @@ RCSID("$Id: rsa.c 20466 2007-04-20 08:29:05Z lha $");
#include <roken.h>
+/**
+ * @page page_rsa RSA - public-key cryptography
+ *
+ * RSA is named by its inventors (Ron Rivest, Adi Shamir, and Leonard
+ * Adleman) (published in 1977), patented expired in 21 September 2000.
+ *
+ * See the library functions here: @ref hcrypto_rsa
+ */
+
+/**
+ * Same as RSA_new_method() using NULL as engine.
+ *
+ * @return a newly allocated RSA object. Free with RSA_free().
+ *
+ * @ingroup hcrypto_rsa
+ */
+
RSA *
RSA_new(void)
{
return RSA_new_method(NULL);
}
+/**
+ * Allocate a new RSA object using the engine, if NULL is specified as
+ * the engine, use the default RSA engine as returned by
+ * ENGINE_get_default_RSA().
+ *
+ * @param engine Specific what ENGINE RSA provider should be used.
+ *
+ * @return a newly allocated RSA object. Free with RSA_free().
+ *
+ * @ingroup hcrypto_rsa
+ */
+
RSA *
RSA_new_method(ENGINE *engine)
{
@@ -87,6 +116,12 @@ RSA_new_method(ENGINE *engine)
return rsa;
}
+/**
+ * Free an allocation RSA object.
+ *
+ * @param rsa the RSA object to free.
+ * @ingroup hcrypto_rsa
+ */
void
RSA_free(RSA *rsa)
@@ -117,18 +152,51 @@ RSA_free(RSA *rsa)
free(rsa);
}
+/**
+ * Add an extra reference to the RSA object. The object should be free
+ * with RSA_free() to drop the reference.
+ *
+ * @param rsa the object to add reference counting too.
+ *
+ * @return the current reference count, can't safely be used except
+ * for debug printing.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
int
RSA_up_ref(RSA *rsa)
{
return ++rsa->references;
}
+/**
+ * Return the RSA_METHOD used for this RSA object.
+ *
+ * @param rsa the object to get the method from.
+ *
+ * @return the method used for this RSA object.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
const RSA_METHOD *
RSA_get_method(const RSA *rsa)
{
return rsa->meth;
}
+/**
+ * Set a new method for the RSA keypair.
+ *
+ * @param rsa rsa parameter.
+ * @param method the new method for the RSA parameter.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
int
RSA_set_method(RSA *rsa, const RSA_METHOD *method)
{
@@ -144,6 +212,17 @@ RSA_set_method(RSA *rsa, const RSA_METHOD *method)
return 1;
}
+/**
+ * Set the application data for the RSA object.
+ *
+ * @param rsa the rsa object to set the parameter for
+ * @param arg the data object to store
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
int
RSA_set_app_data(RSA *rsa, void *arg)
{
@@ -151,6 +230,16 @@ RSA_set_app_data(RSA *rsa, void *arg)
return 1;
}
+/**
+ * Get the application data for the RSA object.
+ *
+ * @param rsa the rsa object to get the parameter for
+ *
+ * @return the data object
+ *
+ * @ingroup hcrypto_rsa
+ */
+
void *
RSA_get_app_data(RSA *rsa)
{
@@ -296,7 +385,11 @@ RSA_null_method(void)
}
extern const RSA_METHOD hc_rsa_imath_method;
+#ifdef HAVE_GMP
+static const RSA_METHOD *default_rsa_method = &hc_rsa_gmp_method;
+#else
static const RSA_METHOD *default_rsa_method = &hc_rsa_imath_method;
+#endif
const RSA_METHOD *
RSA_get_default_method(void)
diff --git a/source4/heimdal/lib/hcrypto/rsa.h b/source4/heimdal/lib/hcrypto/rsa.h
index 575774dbde..0f54ca0a4d 100644
--- a/source4/heimdal/lib/hcrypto/rsa.h
+++ b/source4/heimdal/lib/hcrypto/rsa.h
@@ -32,7 +32,7 @@
*/
/*
- * $Id: rsa.h 19734 2007-01-05 20:26:23Z lha $
+ * $Id: rsa.h 22269 2007-12-11 10:59:22Z lha $
*/
#ifndef _HEIM_RSA_H
@@ -41,6 +41,7 @@
/* symbol renaming */
#define RSA_null_method hc_RSA_null_method
#define RSA_imath_method hc_RSA_imath_method
+#define RSA_gmp_method hc_RSA_gmp_method
#define RSA_new hc_RSA_new
#define RSA_new_method hc_RSA_new_method
#define RSA_free hc_RSA_free
@@ -133,6 +134,7 @@ struct RSA {
const RSA_METHOD *RSA_null_method(void);
const RSA_METHOD *RSA_imath_method(void);
+const RSA_METHOD *RSA_gmp_method(void);
/*
*
diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c
new file mode 100644
index 0000000000..d43e31b39a
--- /dev/null
+++ b/source4/heimdal/lib/hdb/dbinfo.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hdb_locl.h"
+
+RCSID("$Id: dbinfo.c 22306 2007-12-14 12:22:38Z lha $");
+
+struct hdb_dbinfo {
+ char *label;
+ char *realm;
+ char *dbname;
+ char *mkey_file;
+ char *acl_file;
+ char *log_file;
+ const krb5_config_binding *binding;
+ struct hdb_dbinfo *next;
+};
+
+static int
+get_dbinfo(krb5_context context,
+ const krb5_config_binding *db_binding,
+ const char *label,
+ struct hdb_dbinfo **db)
+{
+ struct hdb_dbinfo *di;
+ const char *p;
+
+ *db = NULL;
+
+ p = krb5_config_get_string(context, db_binding, "dbname", NULL);
+ if(p == NULL)
+ return 0;
+
+ di = calloc(1, sizeof(*di));
+ if (di == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ di->label = strdup(label);
+ di->dbname = strdup(p);
+
+ p = krb5_config_get_string(context, db_binding, "realm", NULL);
+ if(p)
+ di->realm = strdup(p);
+ p = krb5_config_get_string(context, db_binding, "mkey_file", NULL);
+ if(p)
+ di->mkey_file = strdup(p);
+ p = krb5_config_get_string(context, db_binding, "acl_file", NULL);
+ if(p)
+ di->acl_file = strdup(p);
+ p = krb5_config_get_string(context, db_binding, "log_file", NULL);
+ if(p)
+ di->log_file = strdup(p);
+
+ di->binding = db_binding;
+
+ *db = di;
+ return 0;
+}
+
+
+int
+hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
+{
+ const krb5_config_binding *db_binding;
+ struct hdb_dbinfo *di, **dt, *databases;
+ const char *default_dbname = HDB_DEFAULT_DB;
+ const char *default_mkey = HDB_DB_DIR "/m-key";
+ const char *default_acl = HDB_DB_DIR "/kadmind.acl";
+ const char *p;
+ int ret;
+
+ *dbp = NULL;
+ dt = NULL;
+ databases = NULL;
+
+ db_binding = krb5_config_get(context, NULL, krb5_config_list,
+ "kdc",
+ "database",
+ NULL);
+ if (db_binding) {
+
+ ret = get_dbinfo(context, db_binding, "default", &di);
+ if (ret == 0 && di) {
+ databases = di;
+ dt = &di->next;
+ }
+
+ for ( ; db_binding != NULL; db_binding = db_binding->next) {
+
+ if (db_binding->type != krb5_config_list)
+ continue;
+
+ ret = get_dbinfo(context, db_binding->u.list,
+ db_binding->name, &di);
+ if (ret)
+ krb5_err(context, 1, ret, "failed getting realm");
+
+ if (di == NULL)
+ continue;
+
+ if (dt)
+ *dt = di;
+ else
+ databases = di;
+ dt = &di->next;
+
+ }
+ }
+
+ if(databases == NULL) {
+ /* if there are none specified, create one and use defaults */
+ di = calloc(1, sizeof(*di));
+ databases = di;
+ di->label = strdup("default");
+ }
+
+ for(di = databases; di; di = di->next) {
+ if(di->dbname == NULL) {
+ di->dbname = strdup(default_dbname);
+ if (di->mkey_file == NULL)
+ di->mkey_file = strdup(default_mkey);
+ }
+ if(di->mkey_file == NULL) {
+ p = strrchr(di->dbname, '.');
+ if(p == NULL || strchr(p, '/') != NULL)
+ /* final pathname component does not contain a . */
+ asprintf(&di->mkey_file, "%s.mkey", di->dbname);
+ else
+ /* the filename is something.else, replace .else with
+ .mkey */
+ asprintf(&di->mkey_file, "%.*s.mkey",
+ (int)(p - di->dbname), di->dbname);
+ }
+ if(di->acl_file == NULL)
+ di->acl_file = strdup(default_acl);
+ }
+ *dbp = databases;
+ return 0;
+}
+
+
+struct hdb_dbinfo *
+hdb_dbinfo_get_next(struct hdb_dbinfo *dbp, struct hdb_dbinfo *dbprevp)
+{
+ if (dbprevp == NULL)
+ return dbp;
+ else
+ return dbprevp->next;
+}
+
+const char *
+hdb_dbinfo_get_label(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->label;
+}
+
+const char *
+hdb_dbinfo_get_realm(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->realm;
+}
+
+const char *
+hdb_dbinfo_get_dbname(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->dbname;
+}
+
+const char *
+hdb_dbinfo_get_mkey_file(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->mkey_file;
+}
+
+const char *
+hdb_dbinfo_get_acl_file(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->acl_file;
+}
+
+const char *
+hdb_dbinfo_get_log_file(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->log_file;
+}
+
+const krb5_config_binding *
+hdb_dbinfo_get_binding(krb5_context context, struct hdb_dbinfo *dbp)
+{
+ return dbp->binding;
+}
+
+void
+hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
+{
+ struct hdb_dbinfo *di, *ndi;
+
+ for(di = *dbp; di != NULL; di = ndi) {
+ ndi = di->next;
+ free (di->realm);
+ free (di->dbname);
+ if (di->mkey_file)
+ free (di->mkey_file);
+ free(di);
+ }
+ *dbp = NULL;
+}
+
+/**
+ * Return the directory where the hdb database resides.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return string pointing to directory.
+ */
+
+const char *
+hdb_db_dir(krb5_context context)
+{
+ return HDB_DB_DIR;
+}
+
+/**
+ * Return the default hdb database resides.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return string pointing to directory.
+ */
+
+const char *
+hdb_default_db(krb5_context context)
+{
+ return HDB_DEFAULT_DB;
+}
diff --git a/source4/heimdal/lib/hdb/hdb-protos.h b/source4/heimdal/lib/hdb/hdb-protos.h
index 6d679fd48f..4c3d3eb1ab 100644
--- a/source4/heimdal/lib/hdb/hdb-protos.h
+++ b/source4/heimdal/lib/hdb/hdb-protos.h
@@ -43,6 +43,9 @@ hdb_db_create (
const char */*filename*/);
const char *
+hdb_db_dir (krb5_context /*context*/);
+
+const char *
hdb_dbinfo_get_acl_file (
krb5_context /*context*/,
struct hdb_dbinfo */*dbp*/);
@@ -63,6 +66,11 @@ hdb_dbinfo_get_label (
struct hdb_dbinfo */*dbp*/);
const char *
+hdb_dbinfo_get_log_file (
+ krb5_context /*context*/,
+ struct hdb_dbinfo */*dbp*/);
+
+const char *
hdb_dbinfo_get_mkey_file (
krb5_context /*context*/,
struct hdb_dbinfo */*dbp*/);
@@ -77,6 +85,9 @@ hdb_dbinfo_get_realm (
krb5_context /*context*/,
struct hdb_dbinfo */*dbp*/);
+const char *
+hdb_default_db (krb5_context /*context*/);
+
krb5_error_code
hdb_enctype2key (
krb5_context /*context*/,
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index 830589388f..742b92405d 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: hdb.h 20535 2007-04-23 07:49:16Z lha $ */
+/* $Id: hdb.h 22198 2007-12-07 13:09:25Z lha $ */
#ifndef __HDB_H__
#define __HDB_H__
@@ -135,10 +135,6 @@ struct hdb_so_method {
krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
};
-#define HDB_DB_DIR "/var/heimdal"
-#define HDB_DEFAULT_DB HDB_DB_DIR "/heimdal"
-#define HDB_DB_FORMAT_ENTRY "hdb/db-format"
-
typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*,
hdb_entry_ex*, void*);
extern krb5_kt_ops hdb_kt_ops;
diff --git a/source4/heimdal/lib/hdb/hdb_locl.h b/source4/heimdal/lib/hdb/hdb_locl.h
index ad16075b24..8f9d6fc4c2 100644
--- a/source4/heimdal/lib/hdb/hdb_locl.h
+++ b/source4/heimdal/lib/hdb/hdb_locl.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: hdb_locl.h 12820 2003-09-10 21:54:58Z lha $ */
+/* $Id: hdb_locl.h 22209 2007-12-07 19:03:41Z lha $ */
#ifndef __HDB_LOCL_H__
#define __HDB_LOCL_H__
@@ -64,6 +64,9 @@
#include <hdb.h>
#include <hdb-private.h>
+#define HDB_DEFAULT_DB HDB_DB_DIR "/heimdal"
+#define HDB_DB_FORMAT_ENTRY "hdb/db-format"
+
krb5_error_code
hdb_ldb_create (
krb5_context /*context*/,
diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c
index 9b87050120..60a58677fe 100644
--- a/source4/heimdal/lib/hdb/keys.c
+++ b/source4/heimdal/lib/hdb/keys.c
@@ -33,7 +33,7 @@
#include "hdb_locl.h"
-RCSID("$Id: keys.c 18819 2006-10-22 09:40:12Z lha $");
+RCSID("$Id: keys.c 22071 2007-11-14 20:04:50Z lha $");
/*
* free all the memory used by (len, keys)
@@ -105,7 +105,7 @@ parse_key_set(krb5_context context, const char *key,
salt->saltvalue.length = 0;
for(i = 0; i < num_buf; i++) {
- if(enctypes == NULL) {
+ if(enctypes == NULL && num_buf > 1) {
/* this might be a etype specifier */
/* XXX there should be a string_to_etypes handling
special cases like `des' and `all' */
@@ -124,7 +124,9 @@ parse_key_set(krb5_context context, const char *key,
} else
return ret;
}
- } else if(salt->salttype == 0) {
+ continue;
+ }
+ if(salt->salttype == 0) {
/* interpret string as a salt specifier, if no etype
is set, this sets default values */
/* XXX should perhaps use string_to_salttype, but that
@@ -142,7 +144,10 @@ parse_key_set(krb5_context context, const char *key,
}
salt->salttype = KRB5_AFS3_SALT;
}
- } else {
+ continue;
+ }
+
+ {
/* if there is a final string, use it as the string to
salt with, this is mostly useful with null salt for
v4 compat, and a cell name for afs compat */
@@ -239,7 +244,7 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
/*
* Generate the `key_set' from the [kadmin]default_keys statement. If
* `no_salt' is set, salt is not important (and will not be set) since
- * its random keys that is going to be created.
+ * it's random keys that is going to be created.
*/
krb5_error_code
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
index 02d87b6cf3..05cf71c593 100644
--- a/source4/heimdal/lib/hdb/mkey.c
+++ b/source4/heimdal/lib/hdb/mkey.c
@@ -36,7 +36,7 @@
#define O_BINARY 0
#endif
-RCSID("$Id: mkey.c 17445 2006-05-05 10:37:46Z lha $");
+RCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $");
struct hdb_master_key_data {
krb5_keytab_entry keytab;
@@ -129,6 +129,11 @@ read_master_keytab(krb5_context context, const char *filename,
*mkey = NULL;
while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) {
p = calloc(1, sizeof(*p));
+ if(p == NULL) {
+ krb5_kt_end_seq_get(context, id, &cursor);
+ ret = ENOMEM;
+ goto out;
+ }
p->keytab = entry;
ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto);
p->next = *mkey;
diff --git a/source4/heimdal/lib/hx509/ca.c b/source4/heimdal/lib/hx509/ca.c
index bf8fe1be1a..40260700b3 100644
--- a/source4/heimdal/lib/hx509/ca.c
+++ b/source4/heimdal/lib/hx509/ca.c
@@ -33,7 +33,13 @@
#include "hx_locl.h"
#include <pkinit_asn1.h>
-RCSID("$Id: ca.c 21379 2007-06-28 07:38:17Z lha $");
+RCSID("$Id: ca.c 22456 2008-01-15 20:22:53Z lha $");
+
+/**
+ * @page page_ca Hx509 CA functions
+ *
+ * See the library functions here: @ref hx509_ca
+ */
struct hx509_ca_tbs {
hx509_name subject;
@@ -55,6 +61,19 @@ struct hx509_ca_tbs {
CRLDistributionPoints crldp;
};
+/**
+ * Allocate an to-be-signed certificate object that will be converted
+ * into an certificate.
+ *
+ * @param context A hx509 context.
+ * @param tbs returned to-be-signed certicate object, free with
+ * hx509_ca_tbs_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
{
@@ -74,6 +93,14 @@ hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
return 0;
}
+/**
+ * Free an To Be Signed object.
+ *
+ * @param tbs object to free.
+ *
+ * @ingroup hx509_ca
+ */
+
void
hx509_ca_tbs_free(hx509_ca_tbs *tbs)
{
@@ -93,6 +120,19 @@ hx509_ca_tbs_free(hx509_ca_tbs *tbs)
*tbs = NULL;
}
+/**
+ * Set the absolute time when the certificate is valid from. If not
+ * set the current time will be used.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param t time the certificated will start to be valid
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_notBefore(hx509_context context,
hx509_ca_tbs tbs,
@@ -102,6 +142,18 @@ hx509_ca_tbs_set_notBefore(hx509_context context,
return 0;
}
+/**
+ * Set the absolute time when the certificate is valid to.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param t time when the certificate will expire
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_notAfter(hx509_context context,
hx509_ca_tbs tbs,
@@ -111,6 +163,18 @@ hx509_ca_tbs_set_notAfter(hx509_context context,
return 0;
}
+/**
+ * Set the relative time when the certificiate is going to expire.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param delta seconds to the certificate is going to expire.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_notAfter_lifetime(hx509_context context,
hx509_ca_tbs tbs,
@@ -130,12 +194,35 @@ static const struct units templatebits[] = {
{ NULL, 0 }
};
+/**
+ * Make of template units, use to build flags argument to
+ * hx509_ca_tbs_set_template() with parse_units().
+ *
+ * @return an units structure.
+ *
+ * @ingroup hx509_ca
+ */
+
const struct units *
hx509_ca_tbs_template_units(void)
{
return templatebits;
}
+/**
+ * Initialize the to-be-signed certificate object from a template certifiate.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param flags bit field selecting what to copy from the template
+ * certifiate.
+ * @param cert template certificate.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_template(hx509_context context,
hx509_ca_tbs tbs,
@@ -170,12 +257,10 @@ hx509_ca_tbs_set_template(hx509_context context,
tbs->notAfter = hx509_cert_get_notAfter(cert);
if (flags & HX509_CA_TEMPLATE_SPKI) {
free_SubjectPublicKeyInfo(&tbs->spki);
- ret = hx509_cert_get_SPKI(cert, &tbs->spki);
+ ret = hx509_cert_get_SPKI(context, cert, &tbs->spki);
tbs->flags.key = !ret;
- if (ret) {
- hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
+ if (ret)
return ret;
- }
}
if (flags & HX509_CA_TEMPLATE_KU) {
KeyUsage ku;
@@ -202,6 +287,20 @@ hx509_ca_tbs_set_template(hx509_context context,
return 0;
}
+/**
+ * Make the to-be-signed certificate object a CA certificate. If the
+ * pathLenConstraint is negative path length constraint is used.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param pathLenConstraint path length constraint, negative, no
+ * constraint.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_ca(hx509_context context,
hx509_ca_tbs tbs,
@@ -212,6 +311,20 @@ hx509_ca_tbs_set_ca(hx509_context context,
return 0;
}
+/**
+ * Make the to-be-signed certificate object a proxy certificate. If the
+ * pathLenConstraint is negative path length constraint is used.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param pathLenConstraint path length constraint, negative, no
+ * constraint.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_proxy(hx509_context context,
hx509_ca_tbs tbs,
@@ -223,6 +336,17 @@ hx509_ca_tbs_set_proxy(hx509_context context,
}
+/**
+ * Make the to-be-signed certificate object a windows domain controller certificate.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_domaincontroller(hx509_context context,
hx509_ca_tbs tbs)
@@ -231,6 +355,20 @@ hx509_ca_tbs_set_domaincontroller(hx509_context context,
return 0;
}
+/**
+ * Set the subject public key info (SPKI) in the to-be-signed certificate
+ * object. SPKI is the public key and key related parameters in the
+ * certificate.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param spki subject public key info to use for the to-be-signed certificate object.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_spki(hx509_context context,
hx509_ca_tbs tbs,
@@ -243,6 +381,19 @@ hx509_ca_tbs_set_spki(hx509_context context,
return ret;
}
+/**
+ * Set the serial number to use for to-be-signed certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param serialNumber serial number to use for the to-be-signed
+ * certificate object.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_set_serialnumber(hx509_context context,
hx509_ca_tbs tbs,
@@ -255,6 +406,19 @@ hx509_ca_tbs_set_serialnumber(hx509_context context,
return ret;
}
+/**
+ * An an extended key usage to the to-be-signed certificate object.
+ * Duplicates will detected and not added.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param oid extended key usage to add.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_eku(hx509_context context,
hx509_ca_tbs tbs,
@@ -285,6 +449,20 @@ hx509_ca_tbs_add_eku(hx509_context context,
return 0;
}
+/**
+ * Add CRL distribution point URI to the to-be-signed certificate
+ * object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param uri uri to the CRL.
+ * @param issuername name of the issuer.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
hx509_ca_tbs tbs,
@@ -325,6 +503,9 @@ hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
if (issuername) {
#if 1
+ /**
+ * issuername not supported
+ */
hx509_set_error_string(context, 0, EINVAL,
"CRLDistributionPoints.name.issuername not yet supported");
return EINVAL;
@@ -372,6 +553,20 @@ out:
return ret;
}
+/**
+ * Add Subject Alternative Name otherName to the to-be-signed
+ * certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param oid the oid of the OtherName.
+ * @param os data in the other name.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_san_otherName(hx509_context context,
hx509_ca_tbs tbs,
@@ -388,6 +583,18 @@ hx509_ca_tbs_add_san_otherName(hx509_context context,
return add_GeneralNames(&tbs->san, &gn);
}
+/**
+ * Add Kerberos Subject Alternative Name to the to-be-signed
+ * certificate object. The principal string is a UTF8 string.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param principal Kerberos principal to add to the certificate.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
int
hx509_ca_tbs_add_san_pkinit(hx509_context context,
@@ -511,6 +718,19 @@ out:
return ret;
}
+/**
+ * Add Microsoft UPN Subject Alternative Name to the to-be-signed
+ * certificate object. The principal string is a UTF8 string.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param principal Microsoft UPN string.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_san_ms_upn(hx509_context context,
hx509_ca_tbs tbs,
@@ -519,6 +739,19 @@ hx509_ca_tbs_add_san_ms_upn(hx509_context context,
return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal);
}
+/**
+ * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed
+ * certificate object. The jid is an UTF8 string.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param jid string of an a jabber id in UTF8.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_san_jid(hx509_context context,
hx509_ca_tbs tbs,
@@ -528,6 +761,22 @@ hx509_ca_tbs_add_san_jid(hx509_context context,
}
+/**
+ * Add a Subject Alternative Name hostname to to-be-signed certificate
+ * object. A domain match starts with ., an exact match does not.
+ *
+ * Example of a an domain match: .domain.se matches the hostname
+ * host.domain.se.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param dnsname a hostame.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_san_hostname(hx509_context context,
hx509_ca_tbs tbs,
@@ -542,6 +791,19 @@ hx509_ca_tbs_add_san_hostname(hx509_context context,
return add_GeneralNames(&tbs->san, &gn);
}
+/**
+ * Add a Subject Alternative Name rfc822 (email address) to
+ * to-be-signed certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param rfc822Name a string to a email address.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_add_san_rfc822name(hx509_context context,
hx509_ca_tbs tbs,
@@ -556,6 +818,17 @@ hx509_ca_tbs_add_san_rfc822name(hx509_context context,
return add_GeneralNames(&tbs->san, &gn);
}
+/**
+ * Set the subject name of a to-be-signed certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param subject the name to set a subject.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
int
hx509_ca_tbs_set_subject(hx509_context context,
@@ -567,6 +840,20 @@ hx509_ca_tbs_set_subject(hx509_context context,
return hx509_name_copy(context, subject, &tbs->subject);
}
+/**
+ * Expand the the subject name in the to-be-signed certificate object
+ * using hx509_name_expand().
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param env enviroment variable to expand variables in the subject
+ * name, see hx509_env_init().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_tbs_subject_expand(hx509_context context,
hx509_ca_tbs tbs,
@@ -1148,6 +1435,30 @@ out:
}
+/**
+ * Sign a to-be-signed certificate object with a issuer certificate.
+ *
+ * The caller needs to at least have called the following functions on the
+ * to-be-signed certificate object:
+ * - hx509_ca_tbs_init()
+ * - hx509_ca_tbs_set_subject()
+ * - hx509_ca_tbs_set_spki()
+ *
+ * When done the to-be-signed certificate object should be freed with
+ * hx509_ca_tbs_free().
+ *
+ * When creating self-signed certificate use hx509_ca_sign_self() instead.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param signer the CA certificate object to sign with (need private key).
+ * @param certificate return cerificate, free with hx509_cert_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_sign(hx509_context context,
hx509_ca_tbs tbs,
@@ -1179,6 +1490,19 @@ out:
return ret;
}
+/**
+ * Work just like hx509_ca_sign() but signs it-self.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param signer private key to sign with.
+ * @param certificate return cerificate, free with hx509_cert_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
int
hx509_ca_sign_self(hx509_context context,
hx509_ca_tbs tbs,
diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c
index b7f19d152a..09c85bc084 100644
--- a/source4/heimdal/lib/hx509/cert.c
+++ b/source4/heimdal/lib/hx509/cert.c
@@ -32,10 +32,25 @@
*/
#include "hx_locl.h"
-RCSID("$Id: cert.c 21380 2007-06-28 07:38:38Z lha $");
+RCSID("$Id: cert.c 22583 2008-02-11 20:46:21Z lha $");
#include "crypto-headers.h"
#include <rtbl.h>
+/**
+ * @page page_cert The basic certificate
+ *
+ * The basic hx509 cerificate object in hx509 is hx509_cert. The
+ * hx509_cert object is representing one X509/PKIX certificate and
+ * associated attributes; like private key, friendly name, etc.
+ *
+ * A hx509_cert object is usully found via the keyset interfaces (@ref
+ * page_keyset), but its also possible to create a certificate
+ * directly from a parsed object with hx509_cert_init() and
+ * hx509_cert_init_data().
+ *
+ * See the library functions here: @ref hx509_cert
+ */
+
struct hx509_verify_ctx_data {
hx509_certs trust_anchors;
int flags;
@@ -78,8 +93,16 @@ typedef struct hx509_name_constraints {
#define GeneralSubtrees_SET(g,var) \
(g)->len = (var)->len, (g)->val = (var)->val;
-/*
+/**
+ * Creates a hx509 context that most functions in the library
+ * uses. The context is only allowed to be used by one thread at each
+ * moment. Free the context with hx509_context_free().
*
+ * @param context Returns a pointer to new hx509 context.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509
*/
int
@@ -113,6 +136,19 @@ hx509_context_init(hx509_context *context)
return 0;
}
+/**
+ * Selects if the hx509_revoke_verify() function is going to require
+ * the existans of a revokation method (OSCP, CRL) or not. Note that
+ * hx509_verify_path(), hx509_cms_verify_signed(), and other function
+ * call hx509_revoke_verify().
+ *
+ * @param context hx509 context to change the flag for.
+ * @param flag zero, revokation method required, non zero missing
+ * revokation method ok
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_context_set_missing_revoke(hx509_context context, int flag)
{
@@ -122,6 +158,14 @@ hx509_context_set_missing_revoke(hx509_context context, int flag)
context->flags &= ~HX509_CTX_VERIFY_MISSING_OK;
}
+/**
+ * Free the context allocated by hx509_context_init().
+ *
+ * @param context context to be freed.
+ *
+ * @ingroup hx509
+ */
+
void
hx509_context_free(hx509_context *context)
{
@@ -139,7 +183,6 @@ hx509_context_free(hx509_context *context)
*context = NULL;
}
-
/*
*
*/
@@ -154,39 +197,25 @@ _hx509_get_cert(hx509_cert cert)
*
*/
-#if 0
-void
-_hx509_print_cert_subject(hx509_cert cert)
-{
- char *subject_name;
- hx509_name name;
- int ret;
-
- ret = hx509_cert_get_subject(cert, &name);
- if (ret)
- abort();
-
- ret = hx509_name_to_string(name, &subject_name);
- hx509_name_free(&name);
- if (ret)
- abort();
-
- printf("name: %s\n", subject_name);
-
- free(subject_name);
-}
-#endif
-
-/*
- *
- */
-
int
_hx509_cert_get_version(const Certificate *t)
{
return t->tbsCertificate.version ? *t->tbsCertificate.version + 1 : 1;
}
+/**
+ * Allocate and init an hx509 certificate object from the decoded
+ * certificate `c´.
+ *
+ * @param context A hx509 context.
+ * @param c
+ * @param cert
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert)
{
@@ -218,9 +247,29 @@ hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert)
return ret;
}
+/**
+ * Just like hx509_cert_init(), but instead of a decode certificate
+ * takes an pointer and length to a memory region that contains a
+ * DER/BER encoded certificate.
+ *
+ * If the memory region doesn't contain just the certificate and
+ * nothing more the function will fail with
+ * HX509_EXTRA_DATA_AFTER_STRUCTURE.
+ *
+ * @param context A hx509 context.
+ * @param ptr pointer to memory region containing encoded certificate.
+ * @param len length of memory region.
+ * @param cert a return pointer to a hx509 certificate object, will
+ * contain NULL on error.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_init_data(hx509_context context,
- const void *ptr,
+ const void *ptr,
size_t len,
hx509_cert *cert)
{
@@ -265,6 +314,15 @@ _hx509_cert_assign_key(hx509_cert cert, hx509_private_key private_key)
return 0;
}
+/**
+ * Free reference to the hx509 certificate object, if the refcounter
+ * reaches 0, the object if freed. Its allowed to pass in NULL.
+ *
+ * @param cert the cert to free.
+ *
+ * @ingroup hx509_cert
+ */
+
void
hx509_cert_free(hx509_cert cert)
{
@@ -274,7 +332,7 @@ hx509_cert_free(hx509_cert cert)
return;
if (cert->ref <= 0)
- _hx509_abort("refcount <= 0");
+ _hx509_abort("cert refcount <= 0 on free");
if (--cert->ref > 0)
return;
@@ -300,9 +358,21 @@ hx509_cert_free(hx509_cert cert)
free(cert);
}
+/**
+ * Add a reference to a hx509 certificate object.
+ *
+ * @param cert a pointer to an hx509 certificate object.
+ *
+ * @return the same object as is passed in.
+ *
+ * @ingroup hx509_cert
+ */
+
hx509_cert
hx509_cert_ref(hx509_cert cert)
{
+ if (cert == NULL)
+ return NULL;
if (cert->ref <= 0)
_hx509_abort("cert refcount <= 0");
cert->ref++;
@@ -311,6 +381,18 @@ hx509_cert_ref(hx509_cert cert)
return cert;
}
+/**
+ * Allocate an verification context that is used fo control the
+ * verification process.
+ *
+ * @param context A hx509 context.
+ * @param ctx returns a pointer to a hx509_verify_ctx object.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
int
hx509_verify_init_ctx(hx509_context context, hx509_verify_ctx *ctx)
{
@@ -327,26 +409,75 @@ hx509_verify_init_ctx(hx509_context context, hx509_verify_ctx *ctx)
return 0;
}
+/**
+ * Free an hx509 verification context.
+ *
+ * @param ctx the context to be freed.
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_destroy_ctx(hx509_verify_ctx ctx)
{
- if (ctx)
+ if (ctx) {
+ hx509_certs_free(&ctx->trust_anchors);
+ hx509_revoke_free(&ctx->revoke_ctx);
memset(ctx, 0, sizeof(*ctx));
+ }
free(ctx);
}
+/**
+ * Set the trust anchors in the verification context, makes an
+ * reference to the keyset, so the consumer can free the keyset
+ * independent of the destruction of the verification context (ctx).
+ *
+ * @param ctx a verification context
+ * @param set a keyset containing the trust anchors.
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
{
- ctx->trust_anchors = set;
+ ctx->trust_anchors = _hx509_certs_ref(set);
}
+/**
+ * Attach an revocation context to the verfication context, , makes an
+ * reference to the revoke context, so the consumer can free the
+ * revoke context independent of the destruction of the verification
+ * context. If there is no revoke context, the verification process is
+ * NOT going to check any verification status.
+ *
+ * @param ctx a verification context.
+ * @param revoke_ctx a revoke context.
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_attach_revoke(hx509_verify_ctx ctx, hx509_revoke_ctx revoke_ctx)
{
- ctx->revoke_ctx = revoke_ctx;
+ if (ctx->revoke_ctx)
+ hx509_revoke_free(&ctx->revoke_ctx);
+ ctx->revoke_ctx = _hx509_revoke_ref(revoke_ctx);
}
+/**
+ * Set the clock time the the verification process is going to
+ * use. Used to check certificate in the past and future time. If not
+ * set the current time will be used.
+ *
+ * @param ctx a verification context.
+ * @param t the time the verifiation is using.
+ *
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
{
@@ -354,12 +485,32 @@ hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
ctx->time_now = t;
}
+/**
+ * Set the maximum depth of the certificate chain that the path
+ * builder is going to try.
+ *
+ * @param ctx a verification context
+ * @param max_depth maxium depth of the certificate chain, include
+ * trust anchor.
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_set_max_depth(hx509_verify_ctx ctx, unsigned int max_depth)
{
ctx->max_depth = max_depth;
}
+/**
+ * Allow or deny the use of proxy certificates
+ *
+ * @param ctx a verification context
+ * @param boolean if non zero, allow proxy certificates.
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean)
{
@@ -369,6 +520,17 @@ hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean)
ctx->flags &= ~HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE;
}
+/**
+ * Select strict RFC3280 verification of certificiates. This means
+ * checking key usage on CA certificates, this will make version 1
+ * certificiates unuseable.
+ *
+ * @param ctx a verification context
+ * @param boolean if non zero, use strict verification.
+ *
+ * @ingroup hx509_verify
+ */
+
void
hx509_verify_set_strict_rfc3280_verification(hx509_verify_ctx ctx, int boolean)
{
@@ -378,6 +540,20 @@ hx509_verify_set_strict_rfc3280_verification(hx509_verify_ctx ctx, int boolean)
ctx->flags &= ~HX509_VERIFY_CTX_F_REQUIRE_RFC3280;
}
+/**
+ * Allow using the operating system builtin trust anchors if no other
+ * trust anchors are configured.
+ *
+ * @param ctx a verification context
+ * @param boolean if non zero, useing the operating systems builtin
+ * trust anchors.
+ *
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
void
hx509_verify_ctx_f_allow_default_trustanchors(hx509_verify_ctx ctx, int boolean)
{
@@ -512,6 +688,15 @@ add_to_list(hx509_octet_string_list *list, const heim_octet_string *entry)
return 0;
}
+/**
+ * Free a list of octet strings returned by another hx509 library
+ * function.
+ *
+ * @param list list to be freed.
+ *
+ * @ingroup hx509_misc
+ */
+
void
hx509_free_octet_string_list(hx509_octet_string_list *list)
{
@@ -523,8 +708,26 @@ hx509_free_octet_string_list(hx509_octet_string_list *list)
list->len = 0;
}
+/**
+ * Return a list of subjectAltNames specified by oid in the
+ * certificate. On error the
+ *
+ * The returned list of octet string should be freed with
+ * hx509_free_octet_string_list().
+ *
+ * @param context A hx509 context.
+ * @param cert a hx509 certificate object.
+ * @param oid an oid to for SubjectAltName.
+ * @param list list of matching SubjectAltName.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
-hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
+hx509_cert_find_subjectAltName_otherName(hx509_context context,
+ hx509_cert cert,
const heim_oid *oid,
hx509_octet_string_list *list)
{
@@ -541,9 +744,11 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
if (ret == HX509_EXTENSION_NOT_FOUND) {
ret = 0;
break;
- } else if (ret != 0)
- break;
-
+ } else if (ret != 0) {
+ hx509_set_error_string(context, 0, ret, "Error searching for SAN");
+ hx509_free_octet_string_list(list);
+ return ret;
+ }
for (j = 0; j < sa.len; j++) {
if (sa.val[j].element == choice_GeneralName_otherName &&
@@ -551,6 +756,10 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
{
ret = add_to_list(list, &sa.val[j].u.otherName.value);
if (ret) {
+ hx509_set_error_string(context, 0, ret,
+ "Error adding an exra SAN to "
+ "return list");
+ hx509_free_octet_string_list(list);
free_GeneralNames(&sa);
return ret;
}
@@ -558,7 +767,7 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
}
free_GeneralNames(&sa);
}
- return ret;
+ return 0;
}
@@ -605,6 +814,12 @@ check_key_usage(hx509_context context, const Certificate *cert,
return 0;
}
+/*
+ * Return 0 on matching key usage 'flags' for 'cert', otherwise return
+ * an error code. If 'req_present' the existance is required of the
+ * KeyUsage extension.
+ */
+
int
_hx509_check_key_usage(hx509_context context, hx509_cert cert,
unsigned flags, int req_present)
@@ -678,10 +893,13 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
int diff;
AuthorityKeyIdentifier ai;
SubjectKeyIdentifier si;
- int ret_ai, ret_si;
+ int ret_ai, ret_si, ret;
- diff = _hx509_name_cmp(&issuer->tbsCertificate.subject,
- &subject->tbsCertificate.issuer);
+ ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
+ &subject->tbsCertificate.issuer,
+ &diff);
+ if (ret)
+ return ret;
if (diff)
return diff;
@@ -689,7 +907,7 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
memset(&si, 0, sizeof(si));
/*
- * Try to find AuthorityKeyIdentifier, if its not present in the
+ * Try to find AuthorityKeyIdentifier, if it's not present in the
* subject certificate nor the parent.
*/
@@ -736,8 +954,11 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
name.u.rdnSequence =
ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence;
- diff = _hx509_name_cmp(&issuer->tbsCertificate.subject,
- &name);
+ ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
+ &name,
+ &diff);
+ if (ret)
+ return ret;
if (diff)
return diff;
diff = 0;
@@ -776,13 +997,22 @@ certificate_is_anchor(hx509_context context,
}
static int
-certificate_is_self_signed(const Certificate *cert)
-{
- return _hx509_cert_is_parent_cmp(cert, cert, 1) == 0;
+certificate_is_self_signed(hx509_context context,
+ const Certificate *cert,
+ int *self_signed)
+{
+ int ret, diff;
+ ret = _hx509_name_cmp(&cert->tbsCertificate.subject,
+ &cert->tbsCertificate.issuer, &diff);
+ *self_signed = (diff == 0);
+ if (ret)
+ hx509_set_error_string(context, 0, ret,
+ "Failed to check if self signed");
+ return ret;
}
/*
- * The subjectName is "null" when its empty set of relative DBs.
+ * The subjectName is "null" when it's empty set of relative DBs.
*/
static int
@@ -1032,9 +1262,9 @@ _hx509_calculate_path(hx509_context context,
return 0;
}
-static int
-AlgorithmIdentifier_cmp(const AlgorithmIdentifier *p,
- const AlgorithmIdentifier *q)
+int
+_hx509_AlgorithmIdentifier_cmp(const AlgorithmIdentifier *p,
+ const AlgorithmIdentifier *q)
{
int diff;
diff = der_heim_oid_cmp(&p->algorithm, &q->algorithm);
@@ -1061,8 +1291,8 @@ _hx509_Certificate_cmp(const Certificate *p, const Certificate *q)
diff = der_heim_bit_string_cmp(&p->signatureValue, &q->signatureValue);
if (diff)
return diff;
- diff = AlgorithmIdentifier_cmp(&p->signatureAlgorithm,
- &q->signatureAlgorithm);
+ diff = _hx509_AlgorithmIdentifier_cmp(&p->signatureAlgorithm,
+ &q->signatureAlgorithm);
if (diff)
return diff;
diff = der_heim_octet_string_cmp(&p->tbsCertificate._save,
@@ -1070,24 +1300,77 @@ _hx509_Certificate_cmp(const Certificate *p, const Certificate *q)
return diff;
}
+/**
+ * Compare to hx509 certificate object, useful for sorting.
+ *
+ * @param p a hx509 certificate object.
+ * @param q a hx509 certificate object.
+ *
+ * @return 0 the objects are the same, returns > 0 is p is "larger"
+ * then q, < 0 if p is "smaller" then q.
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_cmp(hx509_cert p, hx509_cert q)
{
return _hx509_Certificate_cmp(p->data, q->data);
}
+/**
+ * Return the name of the issuer of the hx509 certificate.
+ *
+ * @param p a hx509 certificate object.
+ * @param name a pointer to a hx509 name, should be freed by
+ * hx509_name_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_get_issuer(hx509_cert p, hx509_name *name)
{
return _hx509_name_from_Name(&p->data->tbsCertificate.issuer, name);
}
+/**
+ * Return the name of the subject of the hx509 certificate.
+ *
+ * @param p a hx509 certificate object.
+ * @param name a pointer to a hx509 name, should be freed by
+ * hx509_name_free(). See also hx509_cert_get_base_subject().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_get_subject(hx509_cert p, hx509_name *name)
{
return _hx509_name_from_Name(&p->data->tbsCertificate.subject, name);
}
+/**
+ * Return the name of the base subject of the hx509 certificate. If
+ * the certiicate is a verified proxy certificate, the this function
+ * return the base certificate (root of the proxy chain). If the proxy
+ * certificate is not verified with the base certificate
+ * HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED is returned.
+ *
+ * @param context a hx509 context.
+ * @param c a hx509 certificate object.
+ * @param name a pointer to a hx509 name, should be freed by
+ * hx509_name_free(). See also hx509_cert_get_subject().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_get_base_subject(hx509_context context, hx509_cert c,
hx509_name *name)
@@ -1104,31 +1387,107 @@ hx509_cert_get_base_subject(hx509_context context, hx509_cert c,
return _hx509_name_from_Name(&c->data->tbsCertificate.subject, name);
}
+/**
+ * Get serial number of the certificate.
+ *
+ * @param p a hx509 certificate object.
+ * @param i serial number, should be freed ith der_free_heim_integer().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_get_serialnumber(hx509_cert p, heim_integer *i)
{
return der_copy_heim_integer(&p->data->tbsCertificate.serialNumber, i);
}
+/**
+ * Get notBefore time of the certificate.
+ *
+ * @param p a hx509 certificate object.
+ *
+ * @return return not before time
+ *
+ * @ingroup hx509_cert
+ */
+
time_t
hx509_cert_get_notBefore(hx509_cert p)
{
return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notBefore);
}
+/**
+ * Get notAfter time of the certificate.
+ *
+ * @param p a hx509 certificate object.
+ *
+ * @return return not after time.
+ *
+ * @ingroup hx509_cert
+ */
+
time_t
hx509_cert_get_notAfter(hx509_cert p)
{
return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notAfter);
}
+/**
+ * Get the SubjectPublicKeyInfo structure from the hx509 certificate.
+ *
+ * @param context a hx509 context.
+ * @param p a hx509 certificate object.
+ * @param spki SubjectPublicKeyInfo, should be freed with
+ * free_SubjectPublicKeyInfo().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_cert_get_SPKI(hx509_context context, hx509_cert p, SubjectPublicKeyInfo *spki)
+{
+ int ret;
+
+ ret = copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo, spki);
+ if (ret)
+ hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
+ return ret;
+}
+
+/**
+ * Get the AlgorithmIdentifier from the hx509 certificate.
+ *
+ * @param context a hx509 context.
+ * @param p a hx509 certificate object.
+ * @param alg AlgorithmIdentifier, should be freed with
+ * free_AlgorithmIdentifier().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
-hx509_cert_get_SPKI(hx509_cert p, SubjectPublicKeyInfo *spki)
+hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context,
+ hx509_cert p,
+ AlgorithmIdentifier *alg)
{
- return copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo,
- spki);
+ int ret;
+
+ ret = copy_AlgorithmIdentifier(&p->data->tbsCertificate.subjectPublicKeyInfo.algorithm, alg);
+ if (ret)
+ hx509_set_error_string(context, 0, ret,
+ "Failed to copy SPKI AlgorithmIdentifier");
+ return ret;
}
+
hx509_private_key
_hx509_cert_private_key(hx509_cert p)
{
@@ -1136,6 +1495,13 @@ _hx509_cert_private_key(hx509_cert p)
}
int
+hx509_cert_have_private_key(hx509_cert p)
+{
+ return p->private_key ? 1 : 0;
+}
+
+
+int
_hx509_cert_private_key_exportable(hx509_cert p)
{
if (p->private_key == NULL)
@@ -1253,9 +1619,14 @@ match_RDN(const RelativeDistinguishedName *c,
return HX509_NAME_CONSTRAINT_ERROR;
for (i = 0; i < n->len; i++) {
+ int diff, ret;
+
if (der_heim_oid_cmp(&c->val[i].type, &n->val[i].type) != 0)
return HX509_NAME_CONSTRAINT_ERROR;
- if (_hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value) != 0)
+ ret = _hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value, &diff);
+ if (ret)
+ return ret;
+ if (diff != 0)
return HX509_NAME_CONSTRAINT_ERROR;
}
return 0;
@@ -1316,7 +1687,7 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match)
return HX509_NAME_CONSTRAINT_ERROR;
if (strcasecmp(s + 1 + len2 - len1, c->u.rfc822Name) != 0)
return HX509_NAME_CONSTRAINT_ERROR;
- if (len1 < len2 && s[len2 - len1] != '.')
+ if (len1 < len2 && s[len2 - len1 + 1] != '.')
return HX509_NAME_CONSTRAINT_ERROR;
}
*match = 1;
@@ -1387,7 +1758,6 @@ match_alt_name(const GeneralName *n, const Certificate *c,
}
free_GeneralNames(&sa);
} while (1);
-
return ret;
}
@@ -1457,7 +1827,10 @@ check_name_constraints(hx509_context context,
}
/* allow null subjectNames, they wont matches anything */
if (match == 0 && !subject_null_p(c)) {
- hx509_clear_error_string(context);
+ hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS,
+ "Error verify constraints, "
+ "certificate didn't match any "
+ "permitted subtree");
return HX509_VERIFY_CONSTRAINTS;
}
}
@@ -1469,7 +1842,10 @@ check_name_constraints(hx509_context context,
return ret;
}
if (match) {
- hx509_clear_error_string(context);
+ hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS,
+ "Error verify constraints, "
+ "certificate included in excluded "
+ "subtree");
return HX509_VERIFY_CONSTRAINTS;
}
}
@@ -1487,6 +1863,21 @@ free_name_constraints(hx509_name_constraints *nc)
free(nc->val);
}
+/**
+ * Build and verify the path for the certificate to the trust anchor
+ * specified in the verify context. The path is constructed from the
+ * certificate, the pool and the trust anchors.
+ *
+ * @param context A hx509 context.
+ * @param ctx A hx509 verification context.
+ * @param cert the certificate to build the path from.
+ * @param pool A keyset of certificates to build the chain from.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
int
hx509_verify_path(hx509_context context,
hx509_verify_ctx ctx,
@@ -1495,10 +1886,7 @@ hx509_verify_path(hx509_context context,
{
hx509_name_constraints nc;
hx509_path path;
-#if 0
- const AlgorithmIdentifier *alg_id;
-#endif
- int ret, i, proxy_cert_depth;
+ int ret, i, proxy_cert_depth, selfsigned_depth, diff;
enum certtype type;
Name proxy_issuer;
hx509_certs anchors = NULL;
@@ -1538,10 +1926,6 @@ hx509_verify_path(hx509_context context,
if (ret)
goto out;
-#if 0
- alg_id = path.val[path->len - 1]->data->tbsCertificate.signature;
-#endif
-
/*
* Check CA and proxy certificate chain from the top of the
* certificate chain. Also check certificate is valid with respect
@@ -1550,6 +1934,7 @@ hx509_verify_path(hx509_context context,
*/
proxy_cert_depth = 0;
+ selfsigned_depth = 0;
if (ctx->flags & HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE)
type = PROXY_CERT;
@@ -1570,6 +1955,7 @@ hx509_verify_path(hx509_context context,
switch (type) {
case CA_CERT:
+
/* XXX make constants for keyusage */
ret = check_key_usage(context, c, 1 << 5,
REQUIRE_RFC3280(ctx) ? TRUE : FALSE);
@@ -1578,6 +1964,18 @@ hx509_verify_path(hx509_context context,
"Key usage missing from CA certificate");
goto out;
}
+
+ /* self signed cert doesn't add to path length */
+ if (i + 1 != path.len) {
+ int selfsigned;
+
+ ret = certificate_is_self_signed(context, c, &selfsigned);
+ if (ret)
+ goto out;
+ if (selfsigned)
+ selfsigned_depth++;
+ }
+
break;
case PROXY_CERT: {
ProxyCertInfo info;
@@ -1624,8 +2022,12 @@ hx509_verify_path(hx509_context context,
*/
if (proxy_cert_depth) {
- ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject);
+ ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject, &diff);
if (ret) {
+ hx509_set_error_string(context, 0, ret, "Out of memory");
+ goto out;
+ }
+ if (diff) {
ret = HX509_PROXY_CERT_NAME_WRONG;
hx509_set_error_string(context, 0, ret,
"Base proxy name not right");
@@ -1658,8 +2060,12 @@ hx509_verify_path(hx509_context context,
free_RelativeDistinguishedName(&proxy_issuer.u.rdnSequence.val[j - 1]);
proxy_issuer.u.rdnSequence.len -= 1;
- ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer);
- if (ret != 0) {
+ ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer, &diff);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret, "Out of memory");
+ goto out;
+ }
+ if (diff != 0) {
ret = HX509_PROXY_CERT_NAME_WRONG;
hx509_set_error_string(context, 0, ret,
"Proxy issuer name not as expected");
@@ -1685,9 +2091,13 @@ hx509_verify_path(hx509_context context,
*/
if (proxy_cert_depth) {
- ret = _hx509_name_cmp(&proxy_issuer,
- &c->tbsCertificate.subject);
+ ret = _hx509_name_cmp(&proxy_issuer,
+ &c->tbsCertificate.subject, &diff);
if (ret) {
+ hx509_set_error_string(context, 0, ret, "out of memory");
+ goto out;
+ }
+ if (diff) {
ret = HX509_PROXY_CERT_NAME_WRONG;
hx509_clear_error_string(context);
goto out;
@@ -1705,7 +2115,8 @@ hx509_verify_path(hx509_context context,
break;
}
- ret = check_basic_constraints(context, c, type, i - proxy_cert_depth);
+ ret = check_basic_constraints(context, c, type,
+ i - proxy_cert_depth - selfsigned_depth);
if (ret)
goto out;
@@ -1742,22 +2153,16 @@ hx509_verify_path(hx509_context context,
for (ret = 0, i = path.len - 1; i >= 0; i--) {
Certificate *c;
+ int selfsigned;
c = _hx509_get_cert(path.val[i]);
-#if 0
- /* check that algorithm and parameters is the same */
- /* XXX this is wrong */
- ret = alg_cmp(&c->tbsCertificate.signature, alg_id);
- if (ret) {
- hx509_clear_error_string(context);
- ret = HX509_PATH_ALGORITHM_CHANGED;
+ ret = certificate_is_self_signed(context, c, &selfsigned);
+ if (ret)
goto out;
- }
-#endif
/* verify name constraints, not for selfsigned and anchor */
- if (!certificate_is_self_signed(c) || i == path.len - 1) {
+ if (!selfsigned || i + 1 != path.len) {
ret = check_name_constraints(context, &nc, c);
if (ret) {
goto out;
@@ -1813,12 +2218,6 @@ hx509_verify_path(hx509_context context,
hx509_certs_free(&certs);
}
-#if 0
- for (i = path.len - 1; i >= 0; i--) {
- _hx509_print_cert_subject(path.val[i]);
- }
-#endif
-
/*
* Verify signatures, do this backward so public key working
* parameter is passed up from the anchor up though the chain.
@@ -1830,11 +2229,17 @@ hx509_verify_path(hx509_context context,
c = _hx509_get_cert(path.val[i]);
/* is last in chain (trust anchor) */
- if (i == path.len - 1) {
+ if (i + 1 == path.len) {
+ int selfsigned;
+
signer = path.val[i]->data;
+ ret = certificate_is_self_signed(context, signer, &selfsigned);
+ if (ret)
+ goto out;
+
/* if trust anchor is not self signed, don't check sig */
- if (!certificate_is_self_signed(signer))
+ if (!selfsigned)
continue;
} else {
/* take next certificate in chain */
@@ -1863,6 +2268,20 @@ out:
return ret;
}
+/**
+ * Verify a signature made using the private key of an certificate.
+ *
+ * @param context A hx509 context.
+ * @param signer the certificate that made the signature.
+ * @param alg algorthm that was used to sign the data.
+ * @param data the data that was signed.
+ * @param sig the sigature to verify.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_crypto
+ */
+
int
hx509_verify_signature(hx509_context context,
const hx509_cert signer,
@@ -1873,7 +2292,26 @@ hx509_verify_signature(hx509_context context,
return _hx509_verify_signature(context, signer->data, alg, data, sig);
}
-#define HX509_VHN_F_ALLOW_NO_MATCH 1
+
+/**
+ * Verify that the certificate is allowed to be used for the hostname
+ * and address.
+ *
+ * @param context A hx509 context.
+ * @param cert the certificate to match with
+ * @param flags Flags to modify the behavior:
+ * - HX509_VHN_F_ALLOW_NO_MATCH no match is ok
+ * @param type type of hostname:
+ * - HX509_HN_HOSTNAME for plain hostname.
+ * - HX509_HN_DNSSRV for DNS SRV names.
+ * @param hostname the hostname to check
+ * @param sa address of the host
+ * @param sa_size length of address
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
int
hx509_verify_hostname(hx509_context context,
@@ -1984,6 +2422,19 @@ _hx509_set_cert_attribute(hx509_context context,
return 0;
}
+/**
+ * Get an external attribute for the certificate, examples are
+ * friendly name and id.
+ *
+ * @param cert hx509 certificate object to search
+ * @param oid an oid to search for.
+ *
+ * @return an hx509_cert_attribute, only valid as long as the
+ * certificate is referenced.
+ *
+ * @ingroup hx509_cert
+ */
+
hx509_cert_attribute
hx509_cert_get_attribute(hx509_cert cert, const heim_oid *oid)
{
@@ -1994,6 +2445,17 @@ hx509_cert_get_attribute(hx509_cert cert, const heim_oid *oid)
return NULL;
}
+/**
+ * Set the friendly name on the certificate.
+ *
+ * @param cert The certificate to set the friendly name on
+ * @param name Friendly name.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_set_friendly_name(hx509_cert cert, const char *name)
{
@@ -2005,6 +2467,16 @@ hx509_cert_set_friendly_name(hx509_cert cert, const char *name)
return 0;
}
+/**
+ * Get friendly name of the certificate.
+ *
+ * @param cert cert to get the friendly name from.
+ *
+ * @return an friendly name or NULL if there is. The friendly name is
+ * only valid as long as the certificate is referenced.
+ *
+ * @ingroup hx509_cert
+ */
const char *
hx509_cert_get_friendly_name(hx509_cert cert)
@@ -2056,6 +2528,17 @@ _hx509_query_clear(hx509_query *q)
memset(q, 0, sizeof(*q));
}
+/**
+ * Allocate an query controller. Free using hx509_query_free().
+ *
+ * @param context A hx509 context.
+ * @param q return pointer to a hx509_query.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_query_alloc(hx509_context context, hx509_query **q)
{
@@ -2065,6 +2548,17 @@ hx509_query_alloc(hx509_context context, hx509_query **q)
return 0;
}
+/**
+ * Set match options for the hx509 query controller.
+ *
+ * @param q query controller.
+ * @param option options to control the query controller.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
void
hx509_query_match_option(hx509_query *q, hx509_query_option option)
{
@@ -2087,6 +2581,19 @@ hx509_query_match_option(hx509_query *q, hx509_query_option option)
}
}
+/**
+ * Set the issuer and serial number of match in the query
+ * controller. The function make copies of the isser and serial number.
+ *
+ * @param q a hx509 query controller
+ * @param issuer issuer to search for
+ * @param serialNumber the serialNumber of the issuer.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_query_match_issuer_serial(hx509_query *q,
const Name *issuer,
@@ -2123,6 +2630,16 @@ hx509_query_match_issuer_serial(hx509_query *q,
return 0;
}
+/**
+ * Set the query controller to match on a friendly name
+ *
+ * @param q a hx509 query controller.
+ * @param name a friendly name to match on
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
int
hx509_query_match_friendly_name(hx509_query *q, const char *name)
@@ -2136,6 +2653,63 @@ hx509_query_match_friendly_name(hx509_query *q, const char *name)
return 0;
}
+/**
+ * Set the query controller to require an one specific EKU (extended
+ * key usage). Any previous EKU matching is overwitten. If NULL is
+ * passed in as the eku, the EKU requirement is reset.
+ *
+ * @param q a hx509 query controller.
+ * @param eku an EKU to match on.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_query_match_eku(hx509_query *q, const heim_oid *eku)
+{
+ int ret;
+
+ if (eku == NULL) {
+ if (q->eku) {
+ der_free_oid(q->eku);
+ free(q->eku);
+ q->eku = NULL;
+ }
+ q->match &= ~HX509_QUERY_MATCH_EKU;
+ } else {
+ if (q->eku) {
+ der_free_oid(q->eku);
+ } else {
+ q->eku = calloc(1, sizeof(*q->eku));
+ if (q->eku == NULL)
+ return ENOMEM;
+ }
+ ret = der_copy_oid(eku, q->eku);
+ if (ret) {
+ free(q->eku);
+ q->eku = NULL;
+ return ret;
+ }
+ q->match |= HX509_QUERY_MATCH_EKU;
+ }
+ return 0;
+}
+
+/**
+ * Set the query controller to match using a specific match function.
+ *
+ * @param q a hx509 query controller.
+ * @param func function to use for matching, if the argument is NULL,
+ * the match function is removed.
+ * @param ctx context passed to the function.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_query_match_cmp_func(hx509_query *q,
int (*func)(void *, hx509_cert),
@@ -2150,24 +2724,36 @@ hx509_query_match_cmp_func(hx509_query *q,
return 0;
}
+/**
+ * Free the query controller.
+ *
+ * @param context A hx509 context.
+ * @param q a pointer to the query controller.
+ *
+ * @ingroup hx509_cert
+ */
void
hx509_query_free(hx509_context context, hx509_query *q)
{
+ if (q == NULL)
+ return;
+
if (q->serial) {
der_free_heim_integer(q->serial);
free(q->serial);
- q->serial = NULL;
}
if (q->issuer_name) {
free_Name(q->issuer_name);
free(q->issuer_name);
- q->issuer_name = NULL;
}
- if (q) {
- free(q->friendlyname);
- memset(q, 0, sizeof(*q));
+ if (q->eku) {
+ der_free_oid(q->eku);
+ free(q->eku);
}
+ if (q->friendlyname)
+ free(q->friendlyname);
+ memset(q, 0, sizeof(*q));
free(q);
}
@@ -2175,6 +2761,7 @@ int
_hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert)
{
Certificate *c = _hx509_get_cert(cert);
+ int ret, diff;
_hx509_query_statistic(context, 1, q);
@@ -2190,17 +2777,20 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
&& der_heim_integer_cmp(&c->tbsCertificate.serialNumber, q->serial) != 0)
return 0;
- if ((q->match & HX509_QUERY_MATCH_ISSUER_NAME)
- && _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name) != 0)
- return 0;
+ if (q->match & HX509_QUERY_MATCH_ISSUER_NAME) {
+ ret = _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name, &diff);
+ if (ret || diff)
+ return 0;
+ }
- if ((q->match & HX509_QUERY_MATCH_SUBJECT_NAME)
- && _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name) != 0)
- return 0;
+ if (q->match & HX509_QUERY_MATCH_SUBJECT_NAME) {
+ ret = _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name, &diff);
+ if (ret || diff)
+ return 0;
+ }
if (q->match & HX509_QUERY_MATCH_SUBJECT_KEY_ID) {
SubjectKeyIdentifier si;
- int ret;
ret = _hx509_find_extension_subject_key_id(c, &si);
if (ret == 0) {
@@ -2264,14 +2854,13 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
return 0;
}
if (q->match & HX509_QUERY_MATCH_FUNCTION) {
- int ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
+ ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
if (ret != 0)
return 0;
}
if (q->match & HX509_QUERY_MATCH_KEY_HASH_SHA1) {
heim_octet_string os;
- int ret;
os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
os.length =
@@ -2296,12 +2885,26 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
return 0;
}
+ /* If an EKU is required, check the cert for it. */
+ if ((q->match & HX509_QUERY_MATCH_EKU) &&
+ hx509_cert_check_eku(context, cert, q->eku, 0))
+ return 0;
+
if (q->match & ~HX509_QUERY_MASK)
return 0;
return 1;
}
+/**
+ * Set a statistic file for the query statistics.
+ *
+ * @param context A hx509 context.
+ * @param fn statistics file name
+ *
+ * @ingroup hx509_cert
+ */
+
void
hx509_query_statistic_file(hx509_context context, const char *fn)
{
@@ -2362,6 +2965,16 @@ stat_sort(const void *a, const void *b)
return be->stats - ae->stats;
}
+/**
+ * Unparse the statistics file and print the result on a FILE descriptor.
+ *
+ * @param context A hx509 context.
+ * @param printtype tyep to print
+ * @param out the FILE to write the data on.
+ *
+ * @ingroup hx509_cert
+ */
+
void
hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
{
@@ -2435,6 +3048,20 @@ hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
multiqueries, totalqueries);
}
+/**
+ * Check the extended key usage on the hx509 certificate.
+ *
+ * @param context A hx509 context.
+ * @param cert A hx509 context.
+ * @param eku the EKU to check for
+ * @param allow_any_eku if the any EKU is set, allow that to be a
+ * substitute.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_check_eku(hx509_context context, hx509_cert cert,
const heim_oid *eku, int allow_any_eku)
@@ -2511,6 +3138,19 @@ _hx509_cert_get_eku(hx509_context context,
return 0;
}
+/**
+ * Encodes the hx509 certificate as a DER encode binary.
+ *
+ * @param context A hx509 context.
+ * @param c the certificate to encode.
+ * @param os the encode certificate, set to NULL, 0 on case of
+ * error. Free the returned structure with hx509_xfree().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
int
hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
{
@@ -2522,8 +3162,11 @@ hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
_hx509_get_cert(c), &size, ret);
- if (ret)
+ if (ret) {
+ os->data = NULL;
+ os->length = 0;
return ret;
+ }
if (os->length != size)
_hx509_abort("internal ASN.1 encoder error");
@@ -2550,3 +3193,16 @@ _hx509_abort(const char *fmt, ...)
abort();
}
+/**
+ * Free a data element allocated in the library.
+ *
+ * @param ptr data to be freed.
+ *
+ * @ingroup hx509_misc
+ */
+
+void
+hx509_xfree(void *ptr)
+{
+ free(ptr);
+}
diff --git a/source4/heimdal/lib/hx509/cms.c b/source4/heimdal/lib/hx509/cms.c
index 30f364060d..80bcaac6c9 100644
--- a/source4/heimdal/lib/hx509/cms.c
+++ b/source4/heimdal/lib/hx509/cms.c
@@ -32,11 +32,46 @@
*/
#include "hx_locl.h"
-RCSID("$Id: cms.c 21319 2007-06-25 19:46:52Z lha $");
+RCSID("$Id: cms.c 22327 2007-12-15 04:49:37Z lha $");
+
+/**
+ * @page page_cms CMS/PKCS7 message functions.
+ *
+ * CMS is defined in RFC 3369 and is an continuation of the RSA Labs
+ * standard PKCS7. The basic messages in CMS is
+ *
+ * - SignedData
+ * Data signed with private key (RSA, DSA, ECDSA) or secret
+ * (symmetric) key
+ * - EnvelopedData
+ * Data encrypted with private key (RSA)
+ * - EncryptedData
+ * Data encrypted with secret (symmetric) key.
+ * - ContentInfo
+ * Wrapper structure including type and data.
+ *
+ *
+ * See the library functions here: @ref hx509_cms
+ */
#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
#define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
+/**
+ * Wrap data and oid in a ContentInfo and encode it.
+ *
+ * @param oid type of the content.
+ * @param buf data to be wrapped. If a NULL pointer is passed in, the
+ * optional content field in the ContentInfo is not going be filled
+ * in.
+ * @param res the encoded buffer, the result should be freed with
+ * der_free_octet_string().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_cms
+ */
+
int
hx509_cms_wrap_ContentInfo(const heim_oid *oid,
const heim_octet_string *buf,
@@ -52,18 +87,20 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
ret = der_copy_oid(oid, &ci.contentType);
if (ret)
return ret;
- ALLOC(ci.content, 1);
- if (ci.content == NULL) {
- free_ContentInfo(&ci);
- return ENOMEM;
- }
- ci.content->data = malloc(buf->length);
- if (ci.content->data == NULL) {
- free_ContentInfo(&ci);
- return ENOMEM;
+ if (buf) {
+ ALLOC(ci.content, 1);
+ if (ci.content == NULL) {
+ free_ContentInfo(&ci);
+ return ENOMEM;
+ }
+ ci.content->data = malloc(buf->length);
+ if (ci.content->data == NULL) {
+ free_ContentInfo(&ci);
+ return ENOMEM;
+ }
+ memcpy(ci.content->data, buf->data, buf->length);
+ ci.content->length = buf->length;
}
- memcpy(ci.content->data, buf->data, buf->length);
- ci.content->length = buf->length;
ASN1_MALLOC_ENCODE(ContentInfo, res->data, res->length, &ci, &size, ret);
free_ContentInfo(&ci);
@@ -75,6 +112,20 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
return 0;
}
+/**
+ * Decode an ContentInfo and unwrap data and oid it.
+ *
+ * @param in the encoded buffer.
+ * @param oid type of the content.
+ * @param out data to be wrapped.
+ * @param have_data since the data is optional, this flags show dthe
+ * diffrence between no data and the zero length data.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_cms
+ */
+
int
hx509_cms_unwrap_ContentInfo(const heim_octet_string *in,
heim_oid *oid,
@@ -267,6 +318,27 @@ find_CMSIdentifier(hx509_context context,
return 0;
}
+/**
+ * Decode and unencrypt EnvelopedData.
+ *
+ * Extract data and parameteres from from the EnvelopedData. Also
+ * supports using detached EnvelopedData.
+ *
+ * @param context A hx509 context.
+ * @param certs Certificate that can decrypt the EnvelopedData
+ * encryption key.
+ * @param flags HX509_CMS_UE flags to control the behavior.
+ * @param data pointer the structure the contains the DER/BER encoded
+ * EnvelopedData stucture.
+ * @param length length of the data that data point to.
+ * @param encryptedContent in case of detached signature, this
+ * contains the actual encrypted data, othersize its should be NULL.
+ * @param contentType output type oid, should be freed with der_free_oid().
+ * @param content the data, free with der_free_octet_string().
+ *
+ * @ingroup hx509_cms
+ */
+
int
hx509_cms_unenvelope(hx509_context context,
hx509_certs certs,
@@ -335,11 +407,6 @@ hx509_cms_unenvelope(hx509_context context,
ri = &ed.recipientInfos.val[i];
- /* ret = search_keyset(ri,
- * PRIVATE_KEY,
- * ki->keyEncryptionAlgorithm.algorithm);
- */
-
ret = find_CMSIdentifier(context, &ri->rid, certs, &cert,
HX509_QUERY_PRIVATE_KEY|findflags);
if (ret)
@@ -444,6 +511,29 @@ out:
return ret;
}
+/**
+ * Encrypt end encode EnvelopedData.
+ *
+ * Encrypt and encode EnvelopedData. The data is encrypted with a
+ * random key and the the random key is encrypted with the
+ * certificates private key. This limits what private key type can be
+ * used to RSA.
+ *
+ * @param context A hx509 context.
+ * @param flags flags to control the behavior, no flags today
+ * @param cert Certificate to encrypt the EnvelopedData encryption key
+ * with.
+ * @param data pointer the data to encrypt.
+ * @param length length of the data that data point to.
+ * @param encryption_type Encryption cipher to use for the bulk data,
+ * use NULL to get default.
+ * @param contentType type of the data that is encrypted
+ * @param content the output of the function,
+ * free with der_free_octet_string().
+ *
+ * @ingroup hx509_cms
+ */
+
int
hx509_cms_envelope_1(hx509_context context,
int flags,
@@ -637,13 +727,31 @@ find_attribute(const CMSAttributes *attr, const heim_oid *oid)
return NULL;
}
+/**
+ * Decode SignedData and verify that the signature is correct.
+ *
+ * @param context A hx509 context.
+ * @param ctx a hx509 version context
+ * @param data
+ * @param length length of the data that data point to.
+ * @param signedContent
+ * @param pool certificate pool to build certificates paths.
+ * @param contentType free with der_free_oid()
+ * @param content the output of the function, free with
+ * der_free_octet_string().
+ * @param signer_certs list of the cerficates used to sign this
+ * request, free with hx509_certs_free().
+ *
+ * @ingroup hx509_cms
+ */
+
int
hx509_cms_verify_signed(hx509_context context,
hx509_verify_ctx ctx,
const void *data,
size_t length,
const heim_octet_string *signedContent,
- hx509_certs store,
+ hx509_certs pool,
heim_oid *contentType,
heim_octet_string *content,
hx509_certs *signer_certs)
@@ -701,8 +809,8 @@ hx509_cms_verify_signed(hx509_context context,
if (ret)
goto out;
- if (store) {
- ret = hx509_certs_merge(context, certs, store);
+ if (pool) {
+ ret = hx509_certs_merge(context, certs, pool);
if (ret)
goto out;
}
@@ -946,6 +1054,29 @@ add_one_attribute(Attribute **attr,
return 0;
}
+/**
+ * Decode SignedData and verify that the signature is correct.
+ *
+ * @param context A hx509 context.
+ * @param flags
+ * @param eContentType the type of the data.
+ * @param data data to sign
+ * @param length length of the data that data point to.
+ * @param digest_alg digest algorithm to use, use NULL to get the
+ * default or the peer determined algorithm.
+ * @param cert certificate to use for sign the data.
+ * @param peer info about the peer the message to send the message to,
+ * like what digest algorithm to use.
+ * @param anchors trust anchors that the client will use, used to
+ * polulate the certificates included in the message
+ * @param pool certificates to use in try to build the path to the
+ * trust anchors.
+ * @param signed_data the output of the function, free with
+ * der_free_octet_string().
+ *
+ * @ingroup hx509_cms
+ */
+
int
hx509_cms_create_signed_1(hx509_context context,
int flags,
@@ -1050,7 +1181,7 @@ hx509_cms_create_signed_1(hx509_context context,
}
/*
- * If its not pkcs7-data send signedAttributes
+ * If it isn't pkcs7-data send signedAttributes
*/
if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) {
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index d86300bd58..e0f00ad7b4 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -32,7 +32,7 @@
*/
#include "hx_locl.h"
-RCSID("$Id: crypto.c 21318 2007-06-25 19:46:32Z lha $");
+RCSID("$Id: crypto.c 22435 2008-01-14 20:53:56Z lha $");
struct hx509_crypto;
@@ -64,6 +64,7 @@ struct hx509_private_key_ops {
int (*generate_private_key)(hx509_context,
struct hx509_generate_private_context *,
hx509_private_key);
+ BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
int (*handle_alg)(const hx509_private_key,
const AlgorithmIdentifier *,
enum crypto_op_type);
@@ -115,6 +116,9 @@ struct signature_alg {
#define SIG_PUBLIC_SIG 0x200
#define SIG_SECRET 0x400
+#define RA_RSA_USES_DIGEST_INFO 0x1000000
+
+
int (*verify_signature)(hx509_context context,
const struct signature_alg *,
const Certificate *,
@@ -248,43 +252,57 @@ rsa_verify_signature(hx509_context context,
}
if (retsize > tosize)
_hx509_abort("internal rsa decryption failure: ret > tosize");
- ret = decode_DigestInfo(to, retsize, &di, &size);
- free(to);
- if (ret) {
- goto out;
- }
- /* Check for extra data inside the sigature */
- if (size != retsize) {
- ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
- hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
- goto out;
- }
+ if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
- if (sig_alg->digest_oid &&
- der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
- (*sig_alg->digest_oid)()) != 0)
- {
- ret = HX509_CRYPTO_OID_MISMATCH;
- hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
- goto out;
- }
+ ret = decode_DigestInfo(to, retsize, &di, &size);
+ free(to);
+ if (ret) {
+ goto out;
+ }
+
+ /* Check for extra data inside the sigature */
+ if (size != retsize) {
+ ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+ hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
+ goto out;
+ }
+
+ if (sig_alg->digest_oid &&
+ der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
+ (*sig_alg->digest_oid)()) != 0)
+ {
+ ret = HX509_CRYPTO_OID_MISMATCH;
+ hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
+ goto out;
+ }
+
+ /* verify that the parameters are NULL or the NULL-type */
+ if (di.digestAlgorithm.parameters != NULL &&
+ (di.digestAlgorithm.parameters->length != 2 ||
+ memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
+ {
+ ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+ hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
+ goto out;
+ }
- /* verify that the parameters are NULL or the NULL-type */
- if (di.digestAlgorithm.parameters != NULL &&
- (di.digestAlgorithm.parameters->length != 2 ||
- memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
- {
- ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
- hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
- goto out;
+ ret = _hx509_verify_signature(context,
+ NULL,
+ &di.digestAlgorithm,
+ data,
+ &di.digest);
+ } else {
+ if (retsize != data->length ||
+ memcmp(to, data->data, retsize) != 0)
+ {
+ ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+ hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
+ goto out;
+ }
+ free(to);
}
- ret = _hx509_verify_signature(context,
- NULL,
- &di.digestAlgorithm,
- data,
- &di.digest);
out:
free_DigestInfo(&di);
RSA_free(rsa);
@@ -303,7 +321,6 @@ rsa_create_signature(hx509_context context,
const AlgorithmIdentifier *digest_alg;
heim_octet_string indata;
const heim_oid *sig_oid;
- DigestInfo di;
size_t size;
int ret;
@@ -324,6 +341,8 @@ rsa_create_signature(hx509_context context,
digest_alg = hx509_signature_sha1();
} else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {
digest_alg = hx509_signature_sha1();
+ } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {
+ digest_alg = NULL;
} else
return HX509_ALG_NOT_SUPP;
@@ -335,29 +354,34 @@ rsa_create_signature(hx509_context context,
}
}
- memset(&di, 0, sizeof(di));
+ if (digest_alg) {
+ DigestInfo di;
+ memset(&di, 0, sizeof(di));
- ret = _hx509_create_signature(context,
- NULL,
- digest_alg,
- data,
- &di.digestAlgorithm,
- &di.digest);
- if (ret)
- return ret;
- ASN1_MALLOC_ENCODE(DigestInfo,
- indata.data,
- indata.length,
- &di,
- &size,
- ret);
- free_DigestInfo(&di);
- if (ret) {
- hx509_set_error_string(context, 0, ret, "out of memory");
- return ret;
+ ret = _hx509_create_signature(context,
+ NULL,
+ digest_alg,
+ data,
+ &di.digestAlgorithm,
+ &di.digest);
+ if (ret)
+ return ret;
+ ASN1_MALLOC_ENCODE(DigestInfo,
+ indata.data,
+ indata.length,
+ &di,
+ &size,
+ ret);
+ free_DigestInfo(&di);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret, "out of memory");
+ return ret;
+ }
+ if (indata.length != size)
+ _hx509_abort("internal ASN.1 encoder error");
+ } else {
+ indata = *data;
}
- if (indata.length != size)
- _hx509_abort("internal ASN.1 encoder error");
sig->length = RSA_size(signer->private_key.rsa);
sig->data = malloc(sig->length);
@@ -371,7 +395,8 @@ rsa_create_signature(hx509_context context,
sig->data,
signer->private_key.rsa,
RSA_PKCS1_PADDING);
- der_free_octet_string(&indata);
+ if (indata.data != data->data)
+ der_free_octet_string(&indata);
if (ret <= 0) {
ret = HX509_CMS_FAILED_CREATE_SIGATURE;
hx509_set_error_string(context, 0, ret,
@@ -517,6 +542,18 @@ rsa_private_key_export(hx509_context context,
return 0;
}
+static BIGNUM *
+rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
+{
+ if (strcasecmp(type, "rsa-modulus") == 0) {
+ return BN_dup(key->private_key.rsa->n);
+ } else if (strcasecmp(type, "rsa-exponent") == 0) {
+ return BN_dup(key->private_key.rsa->e);
+ } else
+ return NULL;
+}
+
+
static hx509_private_key_ops rsa_private_key_ops = {
"RSA PRIVATE KEY",
@@ -524,7 +561,8 @@ static hx509_private_key_ops rsa_private_key_ops = {
rsa_private_key2SPKI,
rsa_private_key_export,
rsa_private_key_import,
- rsa_generate_private_key
+ rsa_generate_private_key,
+ rsa_get_internal
};
@@ -833,13 +871,24 @@ md2_verify_signature(hx509_context context,
return 0;
}
+static const struct signature_alg heim_rsa_pkcs1_x509 = {
+ "rsa-pkcs1-x509",
+ oid_id_heim_rsa_pkcs1_x509,
+ hx509_signature_rsa_pkcs1_x509,
+ oid_id_pkcs1_rsaEncryption,
+ NULL,
+ PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ rsa_verify_signature,
+ rsa_create_signature
+};
+
static const struct signature_alg pkcs1_rsa_sha1_alg = {
"rsa",
oid_id_pkcs1_rsaEncryption,
hx509_signature_rsa_with_sha1,
oid_id_pkcs1_rsaEncryption,
NULL,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -850,7 +899,7 @@ static const struct signature_alg rsa_with_sha256_alg = {
hx509_signature_rsa_with_sha256,
oid_id_pkcs1_rsaEncryption,
oid_id_sha256,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -861,7 +910,7 @@ static const struct signature_alg rsa_with_sha1_alg = {
hx509_signature_rsa_with_sha1,
oid_id_pkcs1_rsaEncryption,
oid_id_secsig_sha_1,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -872,7 +921,7 @@ static const struct signature_alg rsa_with_md5_alg = {
hx509_signature_rsa_with_md5,
oid_id_pkcs1_rsaEncryption,
oid_id_rsa_digest_md5,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -883,7 +932,7 @@ static const struct signature_alg rsa_with_md2_alg = {
hx509_signature_rsa_with_md2,
oid_id_pkcs1_rsaEncryption,
oid_id_rsa_digest_md2,
- PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
rsa_verify_signature,
rsa_create_signature
};
@@ -952,7 +1001,7 @@ static const struct signature_alg *sig_algs[] = {
&pkcs1_rsa_sha1_alg,
&rsa_with_md5_alg,
&rsa_with_md2_alg,
- &pkcs1_rsa_sha1_alg,
+ &heim_rsa_pkcs1_x509,
&dsa_sha1_alg,
&sha256_alg,
&sha1_alg,
@@ -1423,6 +1472,11 @@ const AlgorithmIdentifier _hx509_signature_rsa_data = {
{ 7, rk_UNCONST(rsa_oid) }, NULL
};
+static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
+ { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
+};
+
static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
{ 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
@@ -1491,6 +1545,10 @@ hx509_signature_rsa(void)
{ return &_hx509_signature_rsa_data; }
const AlgorithmIdentifier *
+hx509_signature_rsa_pkcs1_x509(void)
+{ return &_hx509_signature_rsa_pkcs1_x509_data; }
+
+const AlgorithmIdentifier *
hx509_crypto_des_rsdi_ede3_cbc(void)
{ return &_hx509_des_rsdi_ede3_cbc_oid; }
@@ -1597,6 +1655,16 @@ _hx509_private_key_exportable(hx509_private_key key)
return 1;
}
+BIGNUM *
+_hx509_private_key_get_internal(hx509_context context,
+ hx509_private_key key,
+ const char *type)
+{
+ if (key->ops->get_internal == NULL)
+ return NULL;
+ return (*key->ops->get_internal)(context, key, type);
+}
+
int
_hx509_private_key_export(hx509_context context,
const hx509_private_key key,
diff --git a/source4/heimdal/lib/hx509/env.c b/source4/heimdal/lib/hx509/env.c
index 4cb2f9f4b1..f868c22488 100644
--- a/source4/heimdal/lib/hx509/env.c
+++ b/source4/heimdal/lib/hx509/env.c
@@ -32,7 +32,13 @@
*/
#include "hx_locl.h"
-RCSID("$Id: env.c 19878 2007-01-13 00:58:39Z lha $");
+RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $");
+
+/**
+ * @page page_env Hx509 enviroment functions
+ *
+ * See the library functions here: @ref hx509_env
+ */
struct hx509_env {
struct {
@@ -42,6 +48,17 @@ struct hx509_env {
size_t len;
};
+/**
+ * Allocate a new hx509_env container object.
+ *
+ * @param context A hx509 context.
+ * @param env return a hx509_env structure, free with hx509_env_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_env
+ */
+
int
hx509_env_init(hx509_context context, hx509_env *env)
{
@@ -53,6 +70,19 @@ hx509_env_init(hx509_context context, hx509_env *env)
return 0;
}
+/**
+ * Add a new key/value pair to the hx509_env.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to add
+ * @param value value to add
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_env
+ */
+
int
hx509_env_add(hx509_context context, hx509_env env,
const char *key, const char *value)
@@ -80,6 +110,19 @@ hx509_env_add(hx509_context context, hx509_env env,
return 0;
}
+/**
+ * Search the hx509_env for a key.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to search for.
+ * @param len length of key.
+ *
+ * @return the value if the key is found, NULL otherwise.
+ *
+ * @ingroup hx509_env
+ */
+
const char *
hx509_env_lfind(hx509_context context, hx509_env env,
const char *key, size_t len)
@@ -94,6 +137,13 @@ hx509_env_lfind(hx509_context context, hx509_env env,
return NULL;
}
+/**
+ * Free an hx509_env enviroment context.
+ *
+ * @param env the enviroment to free.
+ *
+ * @ingroup hx509_env
+ */
void
hx509_env_free(hx509_env *env)
diff --git a/source4/heimdal/lib/hx509/error.c b/source4/heimdal/lib/hx509/error.c
index 9f3a014873..25119ed288 100644
--- a/source4/heimdal/lib/hx509/error.c
+++ b/source4/heimdal/lib/hx509/error.c
@@ -32,7 +32,13 @@
*/
#include "hx_locl.h"
-RCSID("$Id: error.c 20912 2007-06-05 03:53:52Z lha $");
+RCSID("$Id: error.c 22332 2007-12-17 01:03:22Z lha $");
+
+/**
+ * @page page_error Hx509 error reporting functions
+ *
+ * See the library functions here: @ref hx509_error
+ */
struct hx509_error_data {
hx509_error next;
@@ -51,6 +57,14 @@ free_error_string(hx509_error msg)
}
}
+/**
+ * Resets the error strings the hx509 context.
+ *
+ * @param context A hx509 context.
+ *
+ * @ingroup hx509_error
+ */
+
void
hx509_clear_error_string(hx509_context context)
{
@@ -58,6 +72,20 @@ hx509_clear_error_string(hx509_context context)
context->error = NULL;
}
+/**
+ * Add an error message to the hx509 context.
+ *
+ * @param context A hx509 context.
+ * @param flags
+ * - HX509_ERROR_APPEND appends the error string to the old messages
+ (code is updated).
+ * @param code error code related to error message
+ * @param fmt error message format
+ * @param ap arguments to error message format
+ *
+ * @ingroup hx509_error
+ */
+
void
hx509_set_error_stringv(hx509_context context, int flags, int code,
const char *fmt, va_list ap)
@@ -86,6 +114,20 @@ hx509_set_error_stringv(hx509_context context, int flags, int code,
}
}
+/**
+ * See hx509_set_error_stringv().
+ *
+ * @param context A hx509 context.
+ * @param flags
+ * - HX509_ERROR_APPEND appends the error string to the old messages
+ (code is updated).
+ * @param code error code related to error message
+ * @param fmt error message format
+ * @param ... arguments to error message format
+ *
+ * @ingroup hx509_error
+ */
+
void
hx509_set_error_string(hx509_context context, int flags, int code,
const char *fmt, ...)
@@ -97,6 +139,17 @@ hx509_set_error_string(hx509_context context, int flags, int code,
va_end(ap);
}
+/**
+ * Get an error string from context associated with error_code.
+ *
+ * @param context A hx509 context.
+ * @param error_code Get error message for this error code.
+ *
+ * @return error string, free with hx509_free_error_string().
+ *
+ * @ingroup hx509_error
+ */
+
char *
hx509_get_error_string(hx509_context context, int error_code)
{
@@ -125,6 +178,32 @@ hx509_get_error_string(hx509_context context, int error_code)
return rk_strpoolcollect(p);
}
+/**
+ * Free error string returned by hx509_get_error_string().
+ *
+ * @param str error string to free.
+ *
+ * @ingroup hx509_error
+ */
+
+void
+hx509_free_error_string(char *str)
+{
+ free(str);
+}
+
+/**
+ * Print error message and fatally exit from error code
+ *
+ * @param context A hx509 context.
+ * @param exit_code exit() code from process.
+ * @param error_code Error code for the reason to exit.
+ * @param fmt format string with the exit message.
+ * @param ... argument to format string.
+ *
+ * @ingroup hx509_error
+ */
+
void
hx509_err(hx509_context context, int exit_code,
int error_code, const char *fmt, ...)
diff --git a/source4/heimdal/lib/hx509/hx509-private.h b/source4/heimdal/lib/hx509/hx509-private.h
index acbc3218c6..be36c07421 100644
--- a/source4/heimdal/lib/hx509/hx509-private.h
+++ b/source4/heimdal/lib/hx509/hx509-private.h
@@ -9,6 +9,11 @@
#endif
int
+_hx509_AlgorithmIdentifier_cmp (
+ const AlgorithmIdentifier */*p*/,
+ const AlgorithmIdentifier */*q*/);
+
+int
_hx509_Certificate_cmp (
const Certificate */*p*/,
const Certificate */*q*/);
@@ -269,12 +274,14 @@ _hx509_match_keys (
int
_hx509_name_cmp (
const Name */*n1*/,
- const Name */*n2*/);
+ const Name */*n2*/,
+ int */*c*/);
int
_hx509_name_ds_cmp (
const DirectoryString */*ds1*/,
- const DirectoryString */*ds2*/);
+ const DirectoryString */*ds2*/,
+ int */*diff*/);
int
_hx509_name_from_Name (
@@ -314,6 +321,14 @@ _hx509_pbe_decrypt (
const heim_octet_string */*econtent*/,
heim_octet_string */*content*/);
+int
+_hx509_pbe_encrypt (
+ hx509_context /*context*/,
+ hx509_lock /*lock*/,
+ const AlgorithmIdentifier */*ai*/,
+ const heim_octet_string */*content*/,
+ heim_octet_string */*econtent*/);
+
void
_hx509_pi_printf (
int (*/*func*/)(void *, const char *),
@@ -344,6 +359,12 @@ _hx509_private_key_exportable (hx509_private_key /*key*/);
int
_hx509_private_key_free (hx509_private_key */*key*/);
+BIGNUM *
+_hx509_private_key_get_internal (
+ hx509_context /*context*/,
+ hx509_private_key /*key*/,
+ const char */*type*/);
+
int
_hx509_private_key_init (
hx509_private_key */*key*/,
@@ -415,11 +436,35 @@ void
_hx509_request_free (hx509_request */*req*/);
int
+_hx509_request_get_SubjectPublicKeyInfo (
+ hx509_context /*context*/,
+ hx509_request /*req*/,
+ SubjectPublicKeyInfo */*key*/);
+
+int
+_hx509_request_get_name (
+ hx509_context /*context*/,
+ hx509_request /*req*/,
+ hx509_name */*name*/);
+
+int
_hx509_request_init (
hx509_context /*context*/,
hx509_request */*req*/);
int
+_hx509_request_parse (
+ hx509_context /*context*/,
+ const char */*path*/,
+ hx509_request */*req*/);
+
+int
+_hx509_request_print (
+ hx509_context /*context*/,
+ hx509_request /*req*/,
+ FILE */*f*/);
+
+int
_hx509_request_set_SubjectPublicKeyInfo (
hx509_context /*context*/,
hx509_request /*req*/,
@@ -438,6 +483,9 @@ _hx509_request_to_pkcs10 (
const hx509_private_key /*signer*/,
heim_octet_string */*request*/);
+hx509_revoke_ctx
+_hx509_revoke_ref (hx509_revoke_ctx /*ctx*/);
+
int
_hx509_set_cert_attribute (
hx509_context /*context*/,
diff --git a/source4/heimdal/lib/hx509/hx509-protos.h b/source4/heimdal/lib/hx509/hx509-protos.h
index 71fb29d59d..3e297424cc 100644
--- a/source4/heimdal/lib/hx509/hx509-protos.h
+++ b/source4/heimdal/lib/hx509/hx509-protos.h
@@ -183,6 +183,7 @@ hx509_cert_cmp (
int
hx509_cert_find_subjectAltName_otherName (
+ hx509_context /*context*/,
hx509_cert /*cert*/,
const heim_oid */*oid*/,
hx509_octet_string_list */*list*/);
@@ -192,9 +193,16 @@ hx509_cert_free (hx509_cert /*cert*/);
int
hx509_cert_get_SPKI (
+ hx509_context /*context*/,
hx509_cert /*p*/,
SubjectPublicKeyInfo */*spki*/);
+int
+hx509_cert_get_SPKI_AlgorithmIdentifier (
+ hx509_context /*context*/,
+ hx509_cert /*p*/,
+ AlgorithmIdentifier */*alg*/);
+
hx509_cert_attribute
hx509_cert_get_attribute (
hx509_cert /*cert*/,
@@ -231,6 +239,9 @@ hx509_cert_get_subject (
hx509_name */*name*/);
int
+hx509_cert_have_private_key (hx509_cert /*p*/);
+
+int
hx509_cert_init (
hx509_context /*context*/,
const Certificate */*c*/,
@@ -305,7 +316,7 @@ int
hx509_certs_iter (
hx509_context /*context*/,
hx509_certs /*certs*/,
- int (*/*fn*/)(hx509_context, void *, hx509_cert),
+ int (*/*func*/)(hx509_context, void *, hx509_cert),
void */*ctx*/);
int
@@ -402,7 +413,7 @@ hx509_cms_verify_signed (
const void */*data*/,
size_t /*length*/,
const heim_octet_string */*signedContent*/,
- hx509_certs /*store*/,
+ hx509_certs /*pool*/,
heim_oid */*contentType*/,
heim_octet_string */*content*/,
hx509_certs */*signer_certs*/);
@@ -581,6 +592,9 @@ hx509_err (
...);
void
+hx509_free_error_string (char */*str*/);
+
+void
hx509_free_octet_string_list (hx509_octet_string_list */*list*/);
int
@@ -652,6 +666,11 @@ hx509_lock_set_prompter (
void */*data*/);
int
+hx509_name_binary (
+ const hx509_name /*name*/,
+ heim_octet_string */*os*/);
+
+int
hx509_name_cmp (
hx509_name /*n1*/,
hx509_name /*n2*/);
@@ -685,12 +704,6 @@ hx509_name_to_Name (
Name */*to*/);
int
-hx509_name_to_der_name (
- const hx509_name /*name*/,
- void **/*data*/,
- size_t */*length*/);
-
-int
hx509_name_to_string (
const hx509_name /*name*/,
char **/*str*/);
@@ -783,13 +796,6 @@ hx509_pem_write (
size_t /*size*/);
void
-hx509_print_func (
- hx509_vprint_func /*func*/,
- void */*ctx*/,
- const char */*fmt*/,
- ...);
-
-void
hx509_print_stdout (
void */*ctx*/,
const char */*fmt*/,
@@ -815,6 +821,11 @@ hx509_query_match_cmp_func (
void */*ctx*/);
int
+hx509_query_match_eku (
+ hx509_query */*q*/,
+ const heim_oid */*eku*/);
+
+int
hx509_query_match_friendly_name (
hx509_query */*q*/,
const char */*name*/);
@@ -902,6 +913,9 @@ const AlgorithmIdentifier *
hx509_signature_rsa (void);
const AlgorithmIdentifier *
+hx509_signature_rsa_pkcs1_x509 (void);
+
+const AlgorithmIdentifier *
hx509_signature_rsa_with_md2 (void);
const AlgorithmIdentifier *
@@ -1030,6 +1044,9 @@ hx509_verify_signature (
const heim_octet_string */*data*/,
const heim_octet_string */*sig*/);
+void
+hx509_xfree (void */*ptr*/);
+
#ifdef __cplusplus
}
#endif
diff --git a/source4/heimdal/lib/hx509/hx509.h b/source4/heimdal/lib/hx509/hx509.h
index 2f22cedfbc..be02f63474 100644
--- a/source4/heimdal/lib/hx509/hx509.h
+++ b/source4/heimdal/lib/hx509/hx509.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: hx509.h 21310 2007-06-25 18:26:06Z lha $ */
+/* $Id: hx509.h 22464 2008-01-16 14:24:50Z lha $ */
typedef struct hx509_cert_attribute_data *hx509_cert_attribute;
typedef struct hx509_cert_data *hx509_cert;
@@ -56,6 +56,10 @@ typedef struct hx509_crl *hx509_crl;
typedef void (*hx509_vprint_func)(void *, const char *, va_list);
enum {
+ HX509_VHN_F_ALLOW_NO_MATCH = 1
+};
+
+enum {
HX509_VALIDATE_F_VALIDATE = 1,
HX509_VALIDATE_F_VERBOSE = 2
};
@@ -107,6 +111,7 @@ typedef enum {
/* flags to hx509_certs_init */
#define HX509_CERTS_CREATE 0x01
+#define HX509_CERTS_UNPROTECT_ALL 0x02
/* flags to hx509_set_error_string */
#define HX509_ERROR_APPEND 0x01
diff --git a/source4/heimdal/lib/hx509/hx509_err.et b/source4/heimdal/lib/hx509/hx509_err.et
index 90f3b3d907..8fc5cb8f2f 100644
--- a/source4/heimdal/lib/hx509/hx509_err.et
+++ b/source4/heimdal/lib/hx509/hx509_err.et
@@ -3,7 +3,7 @@
#
# This might look like a com_err file, but is not
#
-id "$Id: hx509_err.et 20807 2007-06-03 03:11:20Z lha $"
+id "$Id: hx509_err.et 22329 2007-12-15 05:13:14Z lha $"
error_table hx
prefix HX509
@@ -72,7 +72,7 @@ prefix HX509
error_code CRL_USED_BEFORE_TIME, "CRL used before it became valid"
error_code CRL_USED_AFTER_TIME, "CRL used after it became invalid"
error_code CRL_INVALID_FORMAT, "CRL have invalid format"
-error_code CRL_CERT_REVOKED, "Certificate is included in CRL"
+error_code CERT_REVOKED, "Certificate is revoked"
error_code REVOKE_STATUS_MISSING, "No revoke status found for certificates"
error_code CRL_UNKNOWN_EXTENSION, "Unknown extension"
error_code REVOKE_WRONG_DATA, "Got wrong CRL/OCSP data from server"
diff --git a/source4/heimdal/lib/hx509/hx_locl.h b/source4/heimdal/lib/hx509/hx_locl.h
index 145bfcc006..6d89167bfc 100644
--- a/source4/heimdal/lib/hx509/hx_locl.h
+++ b/source4/heimdal/lib/hx509/hx_locl.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: hx_locl.h 21083 2007-06-13 02:11:19Z lha $ */
+/* $Id: hx_locl.h 22538 2008-01-27 13:05:47Z lha $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -128,7 +128,8 @@ struct hx509_query_data {
#define HX509_QUERY_MATCH_FUNCTION 0x080000
#define HX509_QUERY_MATCH_KEY_HASH_SHA1 0x100000
#define HX509_QUERY_MATCH_TIME 0x200000
-#define HX509_QUERY_MASK 0x3fffff
+#define HX509_QUERY_MATCH_EKU 0x400000
+#define HX509_QUERY_MASK 0x7fffff
Certificate *subject;
Certificate *certificate;
heim_integer *serial;
@@ -142,6 +143,7 @@ struct hx509_query_data {
void *cmp_func_ctx;
heim_octet_string *keyhash_sha1;
time_t timenow;
+ heim_oid *eku;
};
struct hx509_keyset_ops {
diff --git a/source4/heimdal/lib/hx509/keyset.c b/source4/heimdal/lib/hx509/keyset.c
index 7da5705a80..2fcff7b03b 100644
--- a/source4/heimdal/lib/hx509/keyset.c
+++ b/source4/heimdal/lib/hx509/keyset.c
@@ -32,7 +32,31 @@
*/
#include "hx_locl.h"
-RCSID("$Id: keyset.c 21140 2007-06-18 21:24:19Z lha $");
+RCSID("$Id: keyset.c 22466 2008-01-16 14:26:35Z lha $");
+
+/**
+ * @page page_keyset Certificate store operations
+ *
+ * Type of certificates store:
+ * - MEMORY
+ * In memory based format. Doesnt support storing.
+ * - FILE
+ * FILE supports raw DER certicates and PEM certicates. When PEM is
+ * used the file can contain may certificates and match private
+ * keys. Support storing the certificates. DER format only supports
+ * on certificate and no private key.
+ * - PEM-FILE
+ * Same as FILE, defaulting to PEM encoded certificates.
+ * - PEM-FILE
+ * Same as FILE, defaulting to DER encoded certificates.
+ * - PKCS11
+ * - PKCS12
+ * - DIR
+ * - KEYCHAIN
+ * Apple Mac OS X KeyChain backed keychain object.
+ *
+ * See the library functions here: @ref hx509_keyset
+ */
struct hx509_certs_data {
int ref;
@@ -69,6 +93,22 @@ _hx509_ks_register(hx509_context context, struct hx509_keyset_ops *ops)
context->ks_num_ops++;
}
+/**
+ * Open or creates a new hx509 certificate store.
+ *
+ * @param context A hx509 context
+ * @param name name of the store, format is TYPE:type-specific-string,
+ * if NULL is used the MEMORY store is used.
+ * @param flags list of flags:
+ * - HX509_CERTS_CREATE create a new keystore of the specific TYPE.
+ * - HX509_CERTS_UNPROTECT_ALL fails if any private key failed to be extracted.
+ * @param lock a lock that unlocks the certificates store, use NULL to
+ * select no password/certifictes/prompt lock (see @ref page_lock).
+ * @param certs return pointer, free with hx509_certs_free().
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_init(hx509_context context,
const char *name, int flags,
@@ -125,6 +165,21 @@ hx509_certs_init(hx509_context context,
return 0;
}
+/**
+ * Write the certificate store to stable storage.
+ *
+ * @param context A hx509 context.
+ * @param certs a certificate store to store.
+ * @param flags currently unused, use 0.
+ * @param lock a lock that unlocks the certificates store, use NULL to
+ * select no password/certifictes/prompt lock (see @ref page_lock).
+ *
+ * @return Returns an hx509 error code. HX509_UNSUPPORTED_OPERATION if
+ * the certificate store doesn't support the store operation.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_store(hx509_context context,
hx509_certs certs,
@@ -132,11 +187,11 @@ hx509_certs_store(hx509_context context,
hx509_lock lock)
{
if (certs->ops->store == NULL) {
- hx509_set_error_string(context, 0, EINVAL,
+ hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION,
"keystore if type %s doesn't support "
"store operation",
certs->ops->name);
- return EINVAL;
+ return HX509_UNSUPPORTED_OPERATION;
}
return (*certs->ops->store)(context, certs, certs->ops_data, flags, lock);
@@ -146,6 +201,8 @@ hx509_certs_store(hx509_context context,
hx509_certs
_hx509_certs_ref(hx509_certs certs)
{
+ if (certs == NULL)
+ return NULL;
if (certs->ref <= 0)
_hx509_abort("certs refcount <= 0");
certs->ref++;
@@ -154,6 +211,14 @@ _hx509_certs_ref(hx509_certs certs)
return certs;
}
+/**
+ * Free a certificate store.
+ *
+ * @param certs certificate store to free.
+ *
+ * @ingroup hx509_keyset
+ */
+
void
hx509_certs_free(hx509_certs *certs)
{
@@ -169,6 +234,21 @@ hx509_certs_free(hx509_certs *certs)
}
}
+/**
+ * Start the integration
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over
+ * @param cursor cursor that will keep track of progress, free with
+ * hx509_certs_end_seq().
+ *
+ * @return Returns an hx509 error code. HX509_UNSUPPORTED_OPERATION is
+ * returned if the certificate store doesn't support the iteration
+ * operation.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_start_seq(hx509_context context,
hx509_certs certs,
@@ -177,10 +257,10 @@ hx509_certs_start_seq(hx509_context context,
int ret;
if (certs->ops->iter_start == NULL) {
- hx509_set_error_string(context, 0, ENOENT,
+ hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION,
"Keyset type %s doesn't support iteration",
certs->ops->name);
- return ENOENT;
+ return HX509_UNSUPPORTED_OPERATION;
}
ret = (*certs->ops->iter_start)(context, certs, certs->ops_data, cursor);
@@ -190,6 +270,21 @@ hx509_certs_start_seq(hx509_context context,
return 0;
}
+/**
+ * Get next ceritificate from the certificate keystore pointed out by
+ * cursor.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over.
+ * @param cursor cursor that keeps track of progress.
+ * @param cert return certificate next in store, NULL if the store
+ * contains no more certificates. Free with hx509_cert_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_next_cert(hx509_context context,
hx509_certs certs,
@@ -200,6 +295,18 @@ hx509_certs_next_cert(hx509_context context,
return (*certs->ops->iter)(context, certs, certs->ops_data, cursor, cert);
}
+/**
+ * End the iteration over certificates.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over.
+ * @param cursor cursor that will keep track of progress, freed.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_end_seq(hx509_context context,
hx509_certs certs,
@@ -209,11 +316,26 @@ hx509_certs_end_seq(hx509_context context,
return 0;
}
+/**
+ * Iterate over all certificates in a keystore and call an function
+ * for each fo them.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over.
+ * @param func function to call for each certificate. The function
+ * should return non-zero to abort the iteration, that value is passed
+ * back to te caller of hx509_certs_iter().
+ * @param ctx context variable that will passed to the function.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
int
hx509_certs_iter(hx509_context context,
hx509_certs certs,
- int (*fn)(hx509_context, void *, hx509_cert),
+ int (*func)(hx509_context, void *, hx509_cert),
void *ctx)
{
hx509_cursor cursor;
@@ -232,7 +354,7 @@ hx509_certs_iter(hx509_context context,
ret = 0;
break;
}
- ret = (*fn)(context, ctx, c);
+ ret = (*func)(context, ctx, c);
hx509_cert_free(c);
if (ret)
break;
@@ -243,6 +365,20 @@ hx509_certs_iter(hx509_context context,
return ret;
}
+
+/**
+ * Function to use to hx509_certs_iter() as a function argument, the
+ * ctx variable to hx509_certs_iter() should be a FILE file descriptor.
+ *
+ * @param context a hx509 context.
+ * @param ctx used by hx509_certs_iter().
+ * @param c a certificate
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_ci_print_names(hx509_context context, void *ctx, hx509_cert c)
{
@@ -264,10 +400,20 @@ hx509_ci_print_names(hx509_context context, void *ctx, hx509_cert c)
return 0;
}
-/*
- * The receiving keyset `certs´ will either increase reference counter
- * of the `cert´ or make a deep copy, either way, the caller needs to
- * free the `cert´ itself.
+/**
+ * Add a certificate to the certificiate store.
+ *
+ * The receiving keyset certs will either increase reference counter
+ * of the cert or make a deep copy, either way, the caller needs to
+ * free the cert itself.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to add the certificate to.
+ * @param cert certificate to add.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
*/
int
@@ -283,6 +429,20 @@ hx509_certs_add(hx509_context context, hx509_certs certs, hx509_cert cert)
return (*certs->ops->add)(context, certs, certs->ops_data, cert);
}
+/**
+ * Find a certificate matching the query.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to search.
+ * @param q query allocated with @ref hx509_query functions.
+ * @param r return certificate (or NULL on error), should be freed
+ * with hx509_cert_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_find(hx509_context context,
hx509_certs certs,
@@ -335,6 +495,19 @@ certs_merge_func(hx509_context context, void *ctx, hx509_cert c)
return hx509_certs_add(context, (hx509_certs)ctx, c);
}
+/**
+ * Merge a certificate store into another. The from store is keep
+ * intact.
+ *
+ * @param context a hx509 context.
+ * @param to the store to merge into.
+ * @param from the store to copy the object from.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_merge(hx509_context context, hx509_certs to, hx509_certs from)
{
@@ -343,6 +516,21 @@ hx509_certs_merge(hx509_context context, hx509_certs to, hx509_certs from)
return hx509_certs_iter(context, from, certs_merge_func, to);
}
+/**
+ * Same a hx509_certs_merge() but use a lock and name to describe the
+ * from source.
+ *
+ * @param context a hx509 context.
+ * @param to the store to merge into.
+ * @param lock a lock that unlocks the certificates store, use NULL to
+ * select no password/certifictes/prompt lock (see @ref page_lock).
+ * @param name name of the source store
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_append(hx509_context context,
hx509_certs to,
@@ -360,6 +548,18 @@ hx509_certs_append(hx509_context context,
return ret;
}
+/**
+ * Get one random certificate from the certificate store.
+ *
+ * @param context a hx509 context.
+ * @param certs a certificate store to get the certificate from.
+ * @param c return certificate, should be freed with hx509_cert_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_get_one_cert(hx509_context context, hx509_certs certs, hx509_cert *c)
{
@@ -388,6 +588,21 @@ certs_info_stdio(void *ctx, const char *str)
return 0;
}
+/**
+ * Print some info about the certificate store.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to print information about.
+ * @param func function that will get each line of the information, if
+ * NULL is used the data is printed on a FILE descriptor that should
+ * be passed in ctx, if ctx also is NULL, stdout is used.
+ * @param ctx parameter to func.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
int
hx509_certs_info(hx509_context context,
hx509_certs certs,
diff --git a/source4/heimdal/lib/hx509/ks_file.c b/source4/heimdal/lib/hx509/ks_file.c
index 269afd03b1..87b97af401 100644
--- a/source4/heimdal/lib/hx509/ks_file.c
+++ b/source4/heimdal/lib/hx509/ks_file.c
@@ -32,7 +32,7 @@
*/
#include "hx_locl.h"
-RCSID("$Id: ks_file.c 21314 2007-06-25 18:45:07Z lha $");
+RCSID("$Id: ks_file.c 22465 2008-01-16 14:25:24Z lha $");
typedef enum { USE_PEM, USE_DER } outformat;
@@ -289,19 +289,25 @@ struct pem_formats {
};
+struct pem_ctx {
+ int flags;
+ struct hx509_collector *c;
+};
+
static int
pem_func(hx509_context context, const char *type,
const hx509_pem_header *header,
const void *data, size_t len, void *ctx)
{
- struct hx509_collector *c = ctx;
- int ret, j;
+ struct pem_ctx *pem_ctx = (struct pem_ctx*)ctx;
+ int ret = 0, j;
for (j = 0; j < sizeof(formats)/sizeof(formats[0]); j++) {
const char *q = formats[j].name;
if (strcasecmp(type, q) == 0) {
- ret = (*formats[j].func)(context, NULL, c, header, data, len);
- break;
+ ret = (*formats[j].func)(context, NULL, pem_ctx->c, header, data, len);
+ if (ret == 0)
+ break;
}
}
if (j == sizeof(formats)/sizeof(formats[0])) {
@@ -310,6 +316,8 @@ pem_func(hx509_context context, const char *type,
"Found no matching PEM format for %s", type);
return ret;
}
+ if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL))
+ return ret;
return 0;
}
@@ -324,9 +332,12 @@ file_init_common(hx509_context context,
{
char *p, *pnext;
struct ks_file *f = NULL;
- struct hx509_collector *c = NULL;
hx509_private_key *keys = NULL;
int ret;
+ struct pem_ctx pem_ctx;
+
+ pem_ctx.flags = flags;
+ pem_ctx.c = NULL;
*data = NULL;
@@ -361,7 +372,7 @@ file_init_common(hx509_context context,
return 0;
}
- ret = _hx509_collector_alloc(context, lock, &c);
+ ret = _hx509_collector_alloc(context, lock, &pem_ctx.c);
if (ret)
goto out;
@@ -381,7 +392,7 @@ file_init_common(hx509_context context,
goto out;
}
- ret = hx509_pem_read(context, f, pem_func, c);
+ ret = hx509_pem_read(context, f, pem_func, &pem_ctx);
fclose(f);
if (ret != 0 && ret != HX509_PARSING_KEY_FAILED)
goto out;
@@ -397,7 +408,7 @@ file_init_common(hx509_context context,
}
for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
- ret = (*formats[i].func)(context, p, c, NULL, ptr, length);
+ ret = (*formats[i].func)(context, p, pem_ctx.c, NULL, ptr, length);
if (ret == 0)
break;
}
@@ -407,11 +418,11 @@ file_init_common(hx509_context context,
}
}
- ret = _hx509_collector_collect_certs(context, c, &f->certs);
+ ret = _hx509_collector_collect_certs(context, pem_ctx.c, &f->certs);
if (ret)
goto out;
- ret = _hx509_collector_collect_private_keys(context, c, &keys);
+ ret = _hx509_collector_collect_private_keys(context, pem_ctx.c, &keys);
if (ret == 0) {
int i;
@@ -428,8 +439,9 @@ out:
free(f->fn);
free(f);
}
- if (c)
- _hx509_collector_free(c);
+ if (pem_ctx.c)
+ _hx509_collector_free(pem_ctx.c);
+
return ret;
}
diff --git a/source4/heimdal/lib/hx509/ks_keychain.c b/source4/heimdal/lib/hx509/ks_keychain.c
index 33c4d6774b..f8181975d9 100644
--- a/source4/heimdal/lib/hx509/ks_keychain.c
+++ b/source4/heimdal/lib/hx509/ks_keychain.c
@@ -32,17 +32,19 @@
*/
#include "hx_locl.h"
-RCSID("$Id: ks_keychain.c 21097 2007-06-16 07:00:49Z lha $");
+RCSID("$Id: ks_keychain.c 22084 2007-11-16 20:12:30Z lha $");
#ifdef HAVE_FRAMEWORK_SECURITY
#include <Security/Security.h>
-/* Missing function decls */
+/* Missing function decls in pre Leopard */
+#ifdef NEED_SECKEYGETCSPHANDLE_PROTO
OSStatus SecKeyGetCSPHandle(SecKeyRef, CSSM_CSP_HANDLE *);
OSStatus SecKeyGetCredentials(SecKeyRef, CSSM_ACL_AUTHORIZATION_TAG,
int, const CSSM_ACCESS_CREDENTIALS **);
#define kSecCredentialTypeDefault 0
+#endif
static int
@@ -50,7 +52,7 @@ getAttribute(SecKeychainItemRef itemRef, SecItemAttr item,
SecKeychainAttributeList **attrs)
{
SecKeychainAttributeInfo attrInfo;
- uint32 attrFormat = 0;
+ UInt32 attrFormat = 0;
OSStatus ret;
*attrs = NULL;
@@ -408,7 +410,7 @@ keychain_iter(hx509_context context,
{
SecKeychainAttributeList *attrs = NULL;
SecKeychainAttributeInfo attrInfo;
- uint32 attrFormat[1] = { 0 };
+ UInt32 attrFormat[1] = { 0 };
SecKeychainItemRef itemRef;
SecItemAttr item[1];
struct iter *iter = cursor;
diff --git a/source4/heimdal/lib/hx509/ks_p11.c b/source4/heimdal/lib/hx509/ks_p11.c
index e3066bbcfa..0d7c312c72 100644
--- a/source4/heimdal/lib/hx509/ks_p11.c
+++ b/source4/heimdal/lib/hx509/ks_p11.c
@@ -32,7 +32,7 @@
*/
#include "hx_locl.h"
-RCSID("$Id: ks_p11.c 21387 2007-06-28 08:53:45Z lha $");
+RCSID("$Id: ks_p11.c 22071 2007-11-14 20:04:50Z lha $");
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
@@ -403,7 +403,7 @@ p11_get_session(hx509_context context,
* prompter or known to work pin code.
*
* This code is very conversative and only uses the prompter in
- * the hx509_lock, the reason is that its bad to try many
+ * the hx509_lock, the reason is that it's bad to try many
* passwords on a pkcs11 token, it might lock up and have to be
* unlocked by a administrator.
*
diff --git a/source4/heimdal/lib/hx509/lock.c b/source4/heimdal/lib/hx509/lock.c
index de326f2e2d..e835aee35a 100644
--- a/source4/heimdal/lib/hx509/lock.c
+++ b/source4/heimdal/lib/hx509/lock.c
@@ -32,7 +32,13 @@
*/
#include "hx_locl.h"
-RCSID("$Id: lock.c 18452 2006-10-14 09:41:05Z lha $");
+RCSID("$Id: lock.c 22327 2007-12-15 04:49:37Z lha $");
+
+/**
+ * @page page_lock Locking and unlocking certificates and encrypted data.
+ *
+ * See the library functions here: @ref hx509_lock
+ */
struct hx509_lock_data {
struct _hx509_password password;
diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c
index 5198633b1e..3f0806ddc0 100644
--- a/source4/heimdal/lib/hx509/name.c
+++ b/source4/heimdal/lib/hx509/name.c
@@ -32,17 +32,39 @@
*/
#include "hx_locl.h"
-RCSID("$Id: name.c 20891 2007-06-04 22:51:41Z lha $");
+#include <wind.h>
+RCSID("$Id: name.c 22583 2008-02-11 20:46:21Z lha $");
-/*
- * name parsing from rfc2253
- * fix so parsing rfc1779 works too
- * rfc3280
+/**
+ * @page page_name PKIX/X.509 Names
+ *
+ * There are several names in PKIX/X.509, GeneralName and Name.
+ *
+ * A Name consists of an ordered list of Relative Distinguished Names
+ * (RDN). Each RDN consists of an unordered list of typed strings. The
+ * types are defined by OID and have long and short description. For
+ * example id-at-commonName (2.5.4.3) have the long name CommonName
+ * and short name CN. The string itself can be of serveral encoding,
+ * UTF8, UTF16, Teltex string, etc. The type limit what encoding
+ * should be used.
+ *
+ * GeneralName is a broader nametype that can contains al kind of
+ * stuff like Name, IP addresses, partial Name, etc.
+ *
+ * Name is mapped into a hx509_name object.
+ *
+ * Parse and string name into a hx509_name object with hx509_parse_name(),
+ * make it back into string representation with hx509_name_to_string().
+ *
+ * Name string are defined rfc2253, rfc1779 and X.501.
+ *
+ * See the library functions here: @ref hx509_name
*/
static const struct {
const char *n;
const heim_oid *(*o)(void);
+ wind_profile_flags flags;
} no[] = {
{ "C", oid_id_at_countryName },
{ "CN", oid_id_at_commonName },
@@ -153,6 +175,18 @@ stringtooid(const char *name, size_t len, heim_oid *oid)
return ret;
}
+/**
+ * Convert the hx509 name object into a printable string.
+ * The resulting string should be freed with free().
+ *
+ * @param name name to print
+ * @param str the string to return
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_name_to_string(const hx509_name name, char **str)
{
@@ -247,82 +281,185 @@ _hx509_Name_to_string(const Name *n, char **str)
return 0;
}
-/*
- * XXX this function is broken, it needs to compare code points, not
- * bytes.
- */
+#define COPYCHARARRAY(_ds,_el,_l,_n) \
+ (_l) = strlen(_ds->u._el); \
+ (_n) = malloc((_l) * sizeof((_n)[0])); \
+ if ((_n) == NULL) \
+ return ENOMEM; \
+ for (i = 0; i < (_l); i++) \
+ (_n)[i] = _ds->u._el[i]
-int
-_hx509_name_ds_cmp(const DirectoryString *ds1, const DirectoryString *ds2)
+
+#define COPYVALARRAY(_ds,_el,_l,_n) \
+ (_l) = _ds->u._el.length; \
+ (_n) = malloc((_l) * sizeof((_n)[0])); \
+ if ((_n) == NULL) \
+ return ENOMEM; \
+ for (i = 0; i < (_l); i++) \
+ (_n)[i] = _ds->u._el.data[i]
+
+#define COPYVOIDARRAY(_ds,_el,_l,_n) \
+ (_l) = _ds->u._el.length; \
+ (_n) = malloc((_l) * sizeof((_n)[0])); \
+ if ((_n) == NULL) \
+ return ENOMEM; \
+ for (i = 0; i < (_l); i++) \
+ (_n)[i] = ((unsigned char *)_ds->u._el.data)[i]
+
+
+
+static int
+dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
{
- int c;
+ wind_profile_flags flags = 0;
+ size_t i, len;
+ int ret;
+ uint32_t *name;
- c = ds1->element - ds2->element;
- if (c)
- return c;
+ *rname = NULL;
+ *rlen = 0;
- switch(ds1->element) {
+ switch(ds->element) {
case choice_DirectoryString_ia5String:
- c = strcmp(ds1->u.ia5String, ds2->u.ia5String);
- break;
- case choice_DirectoryString_teletexString:
- c = der_heim_octet_string_cmp(&ds1->u.teletexString,
- &ds2->u.teletexString);
+ COPYCHARARRAY(ds, ia5String, len, name);
break;
case choice_DirectoryString_printableString:
- c = strcasecmp(ds1->u.printableString, ds2->u.printableString);
+ flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
+ COPYCHARARRAY(ds, printableString, len, name);
break;
- case choice_DirectoryString_utf8String:
- c = strcmp(ds1->u.utf8String, ds2->u.utf8String);
+ case choice_DirectoryString_teletexString:
+ COPYVOIDARRAY(ds, teletexString, len, name);
+ break;
+ case choice_DirectoryString_bmpString:
+ COPYVALARRAY(ds, bmpString, len, name);
break;
case choice_DirectoryString_universalString:
- c = der_heim_universal_string_cmp(&ds1->u.universalString,
- &ds2->u.universalString);
+ COPYVALARRAY(ds, universalString, len, name);
break;
- case choice_DirectoryString_bmpString:
- c = der_heim_bmp_string_cmp(&ds1->u.bmpString,
- &ds2->u.bmpString);
+ case choice_DirectoryString_utf8String:
+ ret = wind_utf8ucs4_length(ds->u.utf8String, &len);
+ if (ret)
+ return ret;
+ name = malloc(len * sizeof(name[0]));
+ if (name == NULL)
+ return ENOMEM;
+ ret = wind_utf8ucs4(ds->u.utf8String, name, &len);
+ if (ret)
+ return ret;
break;
default:
- c = 1;
- break;
+ _hx509_abort("unknown directory type: %d", ds->element);
+ }
+
+ *rlen = len;
+ /* try a couple of times to get the length right, XXX gross */
+ for (i = 0; i < 4; i++) {
+ *rlen = *rlen * 2;
+ *rname = malloc(*rlen * sizeof((*rname)[0]));
+
+ ret = wind_stringprep(name, len, *rname, rlen,
+ WIND_PROFILE_LDAP|flags);
+ if (ret == WIND_ERR_OVERRUN) {
+ free(*rname);
+ *rname = NULL;
+ continue;
+ } else
+ break;
+ }
+ free(name);
+ if (ret) {
+ if (*rname)
+ free(*rname);
+ *rname = NULL;
+ *rlen = 0;
+ return ret;
+ }
+
+ return 0;
+}
+
+int
+_hx509_name_ds_cmp(const DirectoryString *ds1,
+ const DirectoryString *ds2,
+ int *diff)
+{
+ uint32_t *ds1lp, *ds2lp;
+ size_t ds1len, ds2len;
+ int ret;
+
+ ret = dsstringprep(ds1, &ds1lp, &ds1len);
+ if (ret)
+ return ret;
+ ret = dsstringprep(ds2, &ds2lp, &ds2len);
+ if (ret) {
+ free(ds1lp);
+ return ret;
}
- return c;
+
+ if (ds1len != ds2len)
+ *diff = ds1len - ds2len;
+ else
+ *diff = memcmp(ds1lp, ds2lp, ds1len * sizeof(ds1lp[0]));
+
+ free(ds1lp);
+ free(ds2lp);
+
+ return 0;
}
int
-_hx509_name_cmp(const Name *n1, const Name *n2)
+_hx509_name_cmp(const Name *n1, const Name *n2, int *c)
{
- int i, j, c;
+ int ret, i, j;
- c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
- if (c)
- return c;
+ *c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
+ if (*c)
+ return 0;
for (i = 0 ; i < n1->u.rdnSequence.len; i++) {
- c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
- if (c)
- return c;
+ *c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
+ if (*c)
+ return 0;
for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {
- c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
- &n1->u.rdnSequence.val[i].val[j].type);
- if (c)
- return c;
+ *c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
+ &n1->u.rdnSequence.val[i].val[j].type);
+ if (*c)
+ return 0;
- c = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
- &n2->u.rdnSequence.val[i].val[j].value);
- if (c)
- return c;
+ ret = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
+ &n2->u.rdnSequence.val[i].val[j].value,
+ c);
+ if (ret)
+ return ret;
+ if (*c)
+ return 0;
}
}
+ *c = 0;
return 0;
}
+/**
+ * Compare to hx509 name object, useful for sorting.
+ *
+ * @param n1 a hx509 name object.
+ * @param n2 a hx509 name object.
+ *
+ * @return 0 the objects are the same, returns > 0 is n2 is "larger"
+ * then n2, < 0 if n1 is "smaller" then n2.
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_name_cmp(hx509_name n1, hx509_name n2)
{
- return _hx509_name_cmp(&n1->der_name, &n2->der_name);
+ int ret, diff;
+ ret = _hx509_name_cmp(&n1->der_name, &n2->der_name, &diff);
+ if (ret)
+ return ret;
+ return diff;
}
@@ -341,19 +478,6 @@ _hx509_name_from_Name(const Name *n, hx509_name *name)
return ret;
}
-static int
-hx509_der_parse_name(const void *data, size_t length, hx509_name *name)
-{
- int ret;
- Name n;
-
- *name = NULL;
- ret = decode_Name(data, length, &n, NULL);
- if (ret)
- return ret;
- return _hx509_name_from_Name(&n, name);
-}
-
int
_hx509_name_modify(hx509_context context,
Name *name,
@@ -400,6 +524,18 @@ _hx509_name_modify(hx509_context context,
return 0;
}
+/**
+ * Parse a string into a hx509 name object.
+ *
+ * @param context A hx509 context.
+ * @param str a string to parse.
+ * @param name the resulting object, NULL in case of error.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_parse_name(hx509_context context, const char *str, hx509_name *name)
{
@@ -492,6 +628,18 @@ out:
return HX509_NAME_MALFORMED;
}
+/**
+ * Copy a hx509 name object.
+ *
+ * @param context A hx509 cotext.
+ * @param from the name to copy from
+ * @param to the name to copy to
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_name_copy(hx509_context context, const hx509_name from, hx509_name *to)
{
@@ -509,6 +657,17 @@ hx509_name_copy(hx509_context context, const hx509_name from, hx509_name *to)
return 0;
}
+/**
+ * Convert a hx509_name into a Name.
+ *
+ * @param from the name to copy from
+ * @param to the name to copy to
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_name_to_Name(const hx509_name from, Name *to)
{
@@ -521,6 +680,19 @@ hx509_name_normalize(hx509_context context, hx509_name name)
return 0;
}
+/**
+ * Expands variables in the name using env. Variables are on the form
+ * ${name}. Useful when dealing with certificate templates.
+ *
+ * @param context A hx509 cotext.
+ * @param name the name to expand.
+ * @param env environment variable to expand.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_name_expand(hx509_context context,
hx509_name name,
@@ -539,6 +711,7 @@ hx509_name_expand(hx509_context context,
for (i = 0 ; i < n->u.rdnSequence.len; i++) {
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
+ /** Only UTF8String rdnSequence names are allowed */
/*
THIS SHOULD REALLY BE:
COMP = n->u.rdnSequence.val[i].val[j];
@@ -615,6 +788,13 @@ hx509_name_expand(hx509_context context,
return 0;
}
+/**
+ * Free a hx509 name object, upond return *name will be NULL.
+ *
+ * @param name a hx509 name object to be freed.
+ *
+ * @ingroup hx509_name
+ */
void
hx509_name_free(hx509_name *name)
@@ -625,37 +805,61 @@ hx509_name_free(hx509_name *name)
*name = NULL;
}
+/**
+ * Convert a DER encoded name info a string.
+ *
+ * @param data data to a DER/BER encoded name
+ * @param length length of data
+ * @param str the resulting string, is NULL on failure.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_unparse_der_name(const void *data, size_t length, char **str)
{
- hx509_name name;
+ Name name;
int ret;
- ret = hx509_der_parse_name(data, length, &name);
+ *str = NULL;
+
+ ret = decode_Name(data, length, &name, NULL);
if (ret)
return ret;
-
- ret = hx509_name_to_string(name, str);
- hx509_name_free(&name);
+ ret = _hx509_Name_to_string(&name, str);
+ free_Name(&name);
return ret;
}
+/**
+ * Convert a hx509_name object to DER encoded name.
+ *
+ * @param name name to concert
+ * @param os data to a DER encoded name, free the resulting octet
+ * string with hx509_xfree(os->data).
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
-hx509_name_to_der_name(const hx509_name name, void **data, size_t *length)
+hx509_name_binary(const hx509_name name, heim_octet_string *os)
{
size_t size;
int ret;
- ASN1_MALLOC_ENCODE(Name, *data, *length, &name->der_name, &size, ret);
+ ASN1_MALLOC_ENCODE(Name, os->data, os->length, &name->der_name, &size, ret);
if (ret)
return ret;
- if (*length != size)
+ if (os->length != size)
_hx509_abort("internal ASN.1 encoder error");
return 0;
}
-
int
_hx509_unparse_Name(const Name *aname, char **str)
{
@@ -671,12 +875,33 @@ _hx509_unparse_Name(const Name *aname, char **str)
return ret;
}
+/**
+ * Unparse the hx509 name in name into a string.
+ *
+ * @param name the name to check if its empty/null.
+ *
+ * @return non zero if the name is empty/null.
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_name_is_null_p(const hx509_name name)
{
return name->der_name.u.rdnSequence.len == 0;
}
+/**
+ * Unparse the hx509 name in name into a string.
+ *
+ * @param name the name to print
+ * @param str an allocated string returns the name in string form
+ *
+ * @return An hx509 error code, see krb5_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
int
hx509_general_name_unparse(GeneralName *name, char **str)
{
diff --git a/source4/heimdal/lib/hx509/peer.c b/source4/heimdal/lib/hx509/peer.c
index e90f8f34b0..eb0ecd2bde 100644
--- a/source4/heimdal/lib/hx509/peer.c
+++ b/source4/heimdal/lib/hx509/peer.c
@@ -32,7 +32,27 @@
*/
#include "hx_locl.h"
-RCSID("$Id: peer.c 21481 2007-07-10 16:33:23Z lha $");
+RCSID("$Id: peer.c 22345 2007-12-26 19:03:51Z lha $");
+
+/**
+ * @page page_peer Hx509 crypto selecting functions
+ *
+ * Peer info structures are used togeter with hx509_crypto_select() to
+ * select the best avaible crypto algorithm to use.
+ *
+ * See the library functions here: @ref hx509_peer
+ */
+
+/**
+ * Allocate a new peer info structure an init it to default values.
+ *
+ * @param context A hx509 context.
+ * @param peer return an allocated peer, free with hx509_peer_info_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
int
hx509_peer_info_alloc(hx509_context context, hx509_peer_info *peer)
@@ -59,6 +79,14 @@ free_cms_alg(hx509_peer_info peer)
}
}
+/**
+ * Free a peer info structure.
+ *
+ * @param peer peer info to be freed.
+ *
+ * @ingroup hx509_peer
+ */
+
void
hx509_peer_info_free(hx509_peer_info peer)
{
@@ -71,6 +99,17 @@ hx509_peer_info_free(hx509_peer_info peer)
free(peer);
}
+/**
+ * Set the certificate that remote peer is using.
+ *
+ * @param peer peer info to update
+ * @param cert cerificate of the remote peer.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
+
int
hx509_peer_info_set_cert(hx509_peer_info peer,
hx509_cert cert)
@@ -81,6 +120,19 @@ hx509_peer_info_set_cert(hx509_peer_info peer,
return 0;
}
+/**
+ * Set the algorithms that the peer supports.
+ *
+ * @param context A hx509 context.
+ * @param peer the peer to set the new algorithms for
+ * @param val array of supported AlgorithmsIdentiers
+ * @param len length of array val.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
+
int
hx509_peer_info_set_cms_algs(hx509_context context,
hx509_peer_info peer,
diff --git a/source4/heimdal/lib/hx509/print.c b/source4/heimdal/lib/hx509/print.c
index e6f71ea2ce..c1594ff047 100644
--- a/source4/heimdal/lib/hx509/print.c
+++ b/source4/heimdal/lib/hx509/print.c
@@ -32,8 +32,13 @@
*/
#include "hx_locl.h"
-RCSID("$Id: print.c 21381 2007-06-28 08:29:22Z lha $");
+RCSID("$Id: print.c 22538 2008-01-27 13:05:47Z lha $");
+/**
+ * @page page_print Hx509 printing functions
+ *
+ * See the library functions here: @ref hx509_print
+ */
struct hx509_validate_ctx_data {
int flags;
@@ -75,15 +80,31 @@ Time2string(const Time *T, char **str)
return 0;
}
+/**
+ * Helper function to print on stdout for:
+ * - hx509_oid_print(),
+ * - hx509_bitstring_print(),
+ * - hx509_validate_ctx_set_print().
+ *
+ * @param ctx the context to the print function. If the ctx is NULL,
+ * stdout is used.
+ * @param fmt the printing format.
+ * @param va the argumet list.
+ *
+ * @ingroup hx509_print
+ */
+
void
hx509_print_stdout(void *ctx, const char *fmt, va_list va)
{
FILE *f = ctx;
+ if (f == NULL)
+ f = stdout;
vfprintf(f, fmt, va);
}
-void
-hx509_print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
+static void
+print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
@@ -91,36 +112,82 @@ hx509_print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
va_end(va);
}
+/**
+ * Print a oid to a string.
+ *
+ * @param oid oid to print
+ * @param str allocated string, free with hx509_xfree().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
int
hx509_oid_sprint(const heim_oid *oid, char **str)
{
return der_print_heim_oid(oid, '.', str);
}
+/**
+ * Print a oid using a hx509_vprint_func function. To print to stdout
+ * use hx509_print_stdout().
+ *
+ * @param oid oid to print
+ * @param func hx509_vprint_func to print with.
+ * @param ctx context variable to hx509_vprint_func function.
+ *
+ * @ingroup hx509_print
+ */
+
void
hx509_oid_print(const heim_oid *oid, hx509_vprint_func func, void *ctx)
{
char *str;
hx509_oid_sprint(oid, &str);
- hx509_print_func(func, ctx, "%s", str);
+ print_func(func, ctx, "%s", str);
free(str);
}
+/**
+ * Print a bitstring using a hx509_vprint_func function. To print to
+ * stdout use hx509_print_stdout().
+ *
+ * @param b bit string to print.
+ * @param func hx509_vprint_func to print with.
+ * @param ctx context variable to hx509_vprint_func function.
+ *
+ * @ingroup hx509_print
+ */
+
void
hx509_bitstring_print(const heim_bit_string *b,
hx509_vprint_func func, void *ctx)
{
int i;
- hx509_print_func(func, ctx, "\tlength: %d\n\t", b->length);
+ print_func(func, ctx, "\tlength: %d\n\t", b->length);
for (i = 0; i < (b->length + 7) / 8; i++)
- hx509_print_func(func, ctx, "%02x%s%s",
- ((unsigned char *)b->data)[i],
- i < (b->length - 7) / 8
- && (i == 0 || (i % 16) != 15) ? ":" : "",
- i != 0 && (i % 16) == 15 ?
- (i <= ((b->length + 7) / 8 - 2) ? "\n\t" : "\n"):"");
+ print_func(func, ctx, "%02x%s%s",
+ ((unsigned char *)b->data)[i],
+ i < (b->length - 7) / 8
+ && (i == 0 || (i % 16) != 15) ? ":" : "",
+ i != 0 && (i % 16) == 15 ?
+ (i <= ((b->length + 7) / 8 - 2) ? "\n\t" : "\n"):"");
}
+/**
+ * Print certificate usage for a certificate to a string.
+ *
+ * @param context A hx509 context.
+ * @param c a certificate print the keyusage for.
+ * @param s the return string with the keysage printed in to, free
+ * with hx509_xfree().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
int
hx509_cert_keyusage_print(hx509_context context, hx509_cert c, char **s)
{
@@ -268,9 +335,6 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
status->haveAKI = 1;
check_Null(ctx, status, cf, e);
- status->haveSKI = 1;
- check_Null(ctx, status, cf, e);
-
ret = decode_AuthorityKeyIdentifier(e->extnValue.data,
e->extnValue.length,
&ai, &size);
@@ -298,6 +362,56 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
return 0;
}
+static int
+check_extKeyUsage(hx509_validate_ctx ctx,
+ struct cert_status *status,
+ enum critical_flag cf,
+ const Extension *e)
+{
+ ExtKeyUsage eku;
+ size_t size, i;
+ int ret;
+
+ check_Null(ctx, status, cf, e);
+
+ ret = decode_ExtKeyUsage(e->extnValue.data,
+ e->extnValue.length,
+ &eku, &size);
+ if (ret) {
+ validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+ "Decoding ExtKeyUsage failed: %d", ret);
+ return 1;
+ }
+ if (size != e->extnValue.length) {
+ validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+ "Padding data in EKU");
+ free_ExtKeyUsage(&eku);
+ return 1;
+ }
+ if (eku.len == 0) {
+ validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+ "ExtKeyUsage length is 0");
+ return 1;
+ }
+
+ for (i = 0; i < eku.len; i++) {
+ char *str;
+ ret = der_print_heim_oid (&eku.val[i], '.', &str);
+ if (ret) {
+ validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+ "\tEKU: failed to print oid %d", i);
+ free_ExtKeyUsage(&eku);
+ return 1;
+ }
+ validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
+ "\teku-%d: %s\n", i, str);;
+ free(str);
+ }
+
+ free_ExtKeyUsage(&eku);
+
+ return 0;
+}
static int
check_pkinit_san(hx509_validate_ctx ctx, heim_any *a)
@@ -664,7 +778,7 @@ struct {
{ ext(policyMappings, Null), M_N_C },
{ ext(authorityKeyIdentifier, authorityKeyIdentifier), M_N_C },
{ ext(policyConstraints, Null), D_C },
- { ext(extKeyUsage, Null), D_C },
+ { ext(extKeyUsage, extKeyUsage), D_C },
{ ext(freshestCRL, Null), M_N_C },
{ ext(inhibitAnyPolicy, Null), M_C },
#undef ext
@@ -679,6 +793,18 @@ struct {
{ NULL }
};
+/**
+ * Allocate a hx509 validation/printing context.
+ *
+ * @param context A hx509 context.
+ * @param ctx a new allocated hx509 validation context, free with
+ * hx509_validate_ctx_free().
+
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
int
hx509_validate_ctx_init(hx509_context context, hx509_validate_ctx *ctx)
{
@@ -689,6 +815,18 @@ hx509_validate_ctx_init(hx509_context context, hx509_validate_ctx *ctx)
return 0;
}
+/**
+ * Set the printing functions for the validation context.
+ *
+ * @param ctx a hx509 valication context.
+ * @param func the printing function to usea.
+ * @param c the context variable to the printing function.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
void
hx509_validate_ctx_set_print(hx509_validate_ctx ctx,
hx509_vprint_func func,
@@ -698,18 +836,50 @@ hx509_validate_ctx_set_print(hx509_validate_ctx ctx,
ctx->ctx = c;
}
+/**
+ * Add flags to control the behaivor of the hx509_validate_cert()
+ * function.
+ *
+ * @param ctx A hx509 validation context.
+ * @param flags flags to add to the validation context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
void
hx509_validate_ctx_add_flags(hx509_validate_ctx ctx, int flags)
{
ctx->flags |= flags;
}
+/**
+ * Free an hx509 validate context.
+ *
+ * @param ctx the hx509 validate context to free.
+ *
+ * @ingroup hx509_print
+ */
+
void
hx509_validate_ctx_free(hx509_validate_ctx ctx)
{
free(ctx);
}
+/**
+ * Validate/Print the status of the certificate.
+ *
+ * @param context A hx509 context.
+ * @param ctx A hx509 validation context.
+ * @param cert the cerificate to validate/print.
+
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
int
hx509_validate_cert(hx509_context context,
hx509_validate_ctx ctx,
diff --git a/source4/heimdal/lib/hx509/revoke.c b/source4/heimdal/lib/hx509/revoke.c
index ddcb17ee38..2010f945f0 100644
--- a/source4/heimdal/lib/hx509/revoke.c
+++ b/source4/heimdal/lib/hx509/revoke.c
@@ -31,14 +31,33 @@
* SUCH DAMAGE.
*/
+/**
+ * @page page_revoke Revocation methods
+ *
+ * There are two revocation method for PKIX/X.509: CRL and OCSP.
+ * Revocation is needed if the private key is lost and
+ * stolen. Depending on how picky you are, you might want to make
+ * revocation for destroyed private keys too (smartcard broken), but
+ * that should not be a problem.
+ *
+ * CRL is a list of certifiates that have expired.
+ *
+ * OCSP is an online checking method where the requestor sends a list
+ * of certificates to the OCSP server to return a signed reply if they
+ * are valid or not. Some services sends a OCSP reply as part of the
+ * hand-shake to make the revoktion decision simpler/faster for the
+ * client.
+ */
+
#include "hx_locl.h"
-RCSID("$Id: revoke.c 21153 2007-06-18 21:55:46Z lha $");
+RCSID("$Id: revoke.c 22583 2008-02-11 20:46:21Z lha $");
struct revoke_crl {
char *path;
time_t last_modfied;
CRLCertificateList crl;
int verified;
+ int failed_verify;
};
struct revoke_ocsp {
@@ -51,6 +70,7 @@ struct revoke_ocsp {
struct hx509_revoke_ctx_data {
+ unsigned ref;
struct {
struct revoke_crl *val;
size_t len;
@@ -61,6 +81,17 @@ struct hx509_revoke_ctx_data {
} ocsps;
};
+/**
+ * Allocate a revokation context. Free with hx509_revoke_free().
+ *
+ * @param context A hx509 context.
+ * @param ctx returns a newly allocated revokation context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
int
hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
{
@@ -68,6 +99,7 @@ hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
if (*ctx == NULL)
return ENOMEM;
+ (*ctx)->ref = 1;
(*ctx)->crls.len = 0;
(*ctx)->crls.val = NULL;
(*ctx)->ocsps.len = 0;
@@ -76,6 +108,19 @@ hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
return 0;
}
+hx509_revoke_ctx
+_hx509_revoke_ref(hx509_revoke_ctx ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ if (ctx->ref <= 0)
+ _hx509_abort("revoke ctx refcount <= 0");
+ ctx->ref++;
+ if (ctx->ref == 0)
+ _hx509_abort("revoke ctx refcount == 0");
+ return ctx;
+}
+
static void
free_ocsp(struct revoke_ocsp *ocsp)
{
@@ -85,6 +130,14 @@ free_ocsp(struct revoke_ocsp *ocsp)
hx509_cert_free(ocsp->signer);
}
+/**
+ * Free a hx509 revokation context.
+ *
+ * @param ctx context to be freed
+ *
+ * @ingroup hx509_revoke
+ */
+
void
hx509_revoke_free(hx509_revoke_ctx *ctx)
{
@@ -93,6 +146,11 @@ hx509_revoke_free(hx509_revoke_ctx *ctx)
if (ctx == NULL || *ctx == NULL)
return;
+ if ((*ctx)->ref <= 0)
+ _hx509_abort("revoke ctx refcount <= 0 on free");
+ if (--(*ctx)->ref > 0)
+ return;
+
for (i = 0; i < (*ctx)->crls.len; i++) {
free((*ctx)->crls.val[i].path);
free_CRLCertificateList(&(*ctx)->crls.val[i].crl);
@@ -150,7 +208,7 @@ verify_ocsp(hx509_context context,
/*
* If signer certificate isn't the CA certificate, lets check the
- * its the CA that signed the signer certificate and the OCSP EKU
+ * it is the CA that signed the signer certificate and the OCSP EKU
* is set.
*/
if (hx509_cert_cmp(signer, parent) != 0) {
@@ -324,6 +382,18 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
return 0;
}
+/**
+ * Add a OCSP file to the revokation context.
+ *
+ * @param context hx509 context
+ * @param ctx hx509 revokation context
+ * @param path path to file that is going to be added to the context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
int
hx509_revoke_add_ocsp(hx509_context context,
hx509_revoke_ctx ctx,
@@ -380,6 +450,7 @@ hx509_revoke_add_ocsp(hx509_context context,
static int
verify_crl(hx509_context context,
+ hx509_revoke_ctx ctx,
CRLCertificateList *crl,
time_t time_now,
hx509_certs certs,
@@ -391,52 +462,44 @@ verify_crl(hx509_context context,
int ret;
t = _hx509_Time2time_t(&crl->tbsCertList.thisUpdate);
- if (t > time_now)
+ if (t > time_now) {
+ hx509_set_error_string(context, 0, HX509_CRL_USED_BEFORE_TIME,
+ "CRL used before time");
return HX509_CRL_USED_BEFORE_TIME;
+ }
- if (crl->tbsCertList.nextUpdate == NULL)
+ if (crl->tbsCertList.nextUpdate == NULL) {
+ hx509_set_error_string(context, 0, HX509_CRL_INVALID_FORMAT,
+ "CRL missing nextUpdate");
return HX509_CRL_INVALID_FORMAT;
+ }
t = _hx509_Time2time_t(crl->tbsCertList.nextUpdate);
- if (t < time_now)
+ if (t < time_now) {
+ hx509_set_error_string(context, 0, HX509_CRL_USED_AFTER_TIME,
+ "CRL used after time");
return HX509_CRL_USED_AFTER_TIME;
+ }
_hx509_query_clear(&q);
- q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
- q.subject_name = &crl->tbsCertList.issuer;
+ /*
+ * If it's the signer have CRLSIGN bit set, use that as the signer
+ * cert for the certificate, otherwise, search for a certificate.
+ */
+ if (_hx509_check_key_usage(context, parent, 1 << 6, FALSE) == 0) {
+ signer = hx509_cert_ref(parent);
+ } else {
+ q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
+ q.match |= HX509_QUERY_KU_CRLSIGN;
+ q.subject_name = &crl->tbsCertList.issuer;
- ret = hx509_certs_find(context, certs, &q, &signer);
- if (ret)
- return ret;
-
- /* verify is parent or CRLsigner */
- if (hx509_cert_cmp(signer, parent) != 0) {
- Certificate *p = _hx509_get_cert(parent);
- Certificate *s = _hx509_get_cert(signer);
-
- ret = _hx509_cert_is_parent_cmp(s, p, 0);
- if (ret != 0) {
- ret = HX509_PARENT_NOT_CA;
- hx509_set_error_string(context, 0, ret, "Revoke CRL signer is "
- "doesn't have CA as signer certificate");
- goto out;
- }
-
- ret = _hx509_verify_signature_bitstring(context,
- p,
- &s->signatureAlgorithm,
- &s->tbsCertificate._save,
- &s->signatureValue);
+ ret = hx509_certs_find(context, certs, &q, &signer);
if (ret) {
hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
- "CRL signer signature invalid");
- goto out;
+ "Failed to find certificate for CRL");
+ return ret;
}
-
- ret = _hx509_check_key_usage(context, signer, 1 << 6, TRUE); /* crl */
- if (ret != 0)
- goto out;
}
ret = _hx509_verify_signature_bitstring(context,
@@ -450,6 +513,44 @@ verify_crl(hx509_context context,
goto out;
}
+ /*
+ * If signer is not CA cert, need to check revoke status of this
+ * CRL signing cert too, this include all parent CRL signer cert
+ * up to the root *sigh*, assume root at least hve CERTSIGN flag
+ * set.
+ */
+ while (_hx509_check_key_usage(context, signer, 1 << 5, TRUE)) {
+ hx509_cert crl_parent;
+
+ _hx509_query_clear(&q);
+
+ q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
+ q.match |= HX509_QUERY_KU_CRLSIGN;
+ q.subject_name = &_hx509_get_cert(signer)->tbsCertificate.issuer;
+
+ ret = hx509_certs_find(context, certs, &q, &crl_parent);
+ if (ret) {
+ hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
+ "Failed to find parent of CRL signer");
+ goto out;
+ }
+
+ ret = hx509_revoke_verify(context,
+ ctx,
+ certs,
+ time_now,
+ signer,
+ crl_parent);
+ hx509_cert_free(signer);
+ signer = crl_parent;
+ if (ret) {
+ hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
+ "Failed to verify revoke "
+ "status of CRL signer");
+ goto out;
+ }
+ }
+
out:
hx509_cert_free(signer);
@@ -485,6 +586,18 @@ load_crl(const char *path, time_t *t, CRLCertificateList *crl)
return 0;
}
+/**
+ * Add a CRL file to the revokation context.
+ *
+ * @param context hx509 context
+ * @param ctx hx509 revokation context
+ * @param path path to file that is going to be added to the context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
int
hx509_revoke_add_crl(hx509_context context,
hx509_revoke_ctx ctx,
@@ -537,6 +650,23 @@ hx509_revoke_add_crl(hx509_context context,
return ret;
}
+/**
+ * Check that a certificate is not expired according to a revokation
+ * context. Also need the parent certificte to the check OCSP
+ * parent identifier.
+ *
+ * @param context hx509 context
+ * @param ctx hx509 revokation context
+ * @param certs
+ * @param now
+ * @param cert
+ * @param parent_cert
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
int
hx509_revoke_verify(hx509_context context,
@@ -551,6 +681,8 @@ hx509_revoke_verify(hx509_context context,
unsigned long i, j, k;
int ret;
+ hx509_clear_error_string(context);
+
for (i = 0; i < ctx->ocsps.len; i++) {
struct revoke_ocsp *ocsp = &ctx->ocsps.val[i];
struct stat sb;
@@ -604,6 +736,10 @@ hx509_revoke_verify(hx509_context context,
case choice_OCSPCertStatus_good:
break;
case choice_OCSPCertStatus_revoked:
+ hx509_set_error_string(context, 0,
+ HX509_CERT_REVOKED,
+ "Certificate revoked by issuer in OCSP");
+ return HX509_CERT_REVOKED;
case choice_OCSPCertStatus_unknown:
continue;
}
@@ -613,7 +749,7 @@ hx509_revoke_verify(hx509_context context,
now + context->ocsp_time_diff)
continue;
- /* don't allow the next updte to be in the past */
+ /* don't allow the next update to be in the past */
if (ocsp->ocsp.tbsResponseData.responses.val[j].nextUpdate) {
if (*ocsp->ocsp.tbsResponseData.responses.val[j].nextUpdate < now)
continue;
@@ -627,11 +763,12 @@ hx509_revoke_verify(hx509_context context,
for (i = 0; i < ctx->crls.len; i++) {
struct revoke_crl *crl = &ctx->crls.val[i];
struct stat sb;
+ int diff;
/* check if cert.issuer == crls.val[i].crl.issuer */
ret = _hx509_name_cmp(&c->tbsCertificate.issuer,
- &crl->crl.tbsCertList.issuer);
- if (ret)
+ &crl->crl.tbsCertList.issuer, &diff);
+ if (ret || diff)
continue;
ret = stat(crl->path, &sb);
@@ -643,21 +780,32 @@ hx509_revoke_verify(hx509_context context,
free_CRLCertificateList(&crl->crl);
crl->crl = cl;
crl->verified = 0;
+ crl->failed_verify = 0;
}
}
+ if (crl->failed_verify)
+ continue;
/* verify signature in crl if not already done */
if (crl->verified == 0) {
- ret = verify_crl(context, &crl->crl, now, certs, parent_cert);
- if (ret)
- return ret;
+ ret = verify_crl(context, ctx, &crl->crl, now, certs, parent_cert);
+ if (ret) {
+ crl->failed_verify = 1;
+ continue;
+ }
crl->verified = 1;
}
-
- if (crl->crl.tbsCertList.crlExtensions)
- for (j = 0; j < crl->crl.tbsCertList.crlExtensions->len; j++)
- if (crl->crl.tbsCertList.crlExtensions->val[j].critical)
+
+ if (crl->crl.tbsCertList.crlExtensions) {
+ for (j = 0; j < crl->crl.tbsCertList.crlExtensions->len; j++) {
+ if (crl->crl.tbsCertList.crlExtensions->val[j].critical) {
+ hx509_set_error_string(context, 0,
+ HX509_CRL_UNKNOWN_EXTENSION,
+ "Unknown CRL extension");
return HX509_CRL_UNKNOWN_EXTENSION;
+ }
+ }
+ }
if (crl->crl.tbsCertList.revokedCertificates == NULL)
return 0;
@@ -667,7 +815,7 @@ hx509_revoke_verify(hx509_context context,
time_t t;
ret = der_heim_integer_cmp(&crl->crl.tbsCertList.revokedCertificates->val[j].userCertificate,
- &c->tbsCertificate.serialNumber);
+ &c->tbsCertificate.serialNumber);
if (ret != 0)
continue;
@@ -680,7 +828,10 @@ hx509_revoke_verify(hx509_context context,
if (crl->crl.tbsCertList.revokedCertificates->val[j].crlEntryExtensions->val[k].critical)
return HX509_CRL_UNKNOWN_EXTENSION;
- return HX509_CRL_CERT_REVOKED;
+ hx509_set_error_string(context, 0,
+ HX509_CERT_REVOKED,
+ "Certificate revoked by issuer in CRL");
+ return HX509_CERT_REVOKED;
}
return 0;
@@ -689,6 +840,10 @@ hx509_revoke_verify(hx509_context context,
if (context->flags & HX509_CTX_VERIFY_MISSING_OK)
return 0;
+ hx509_set_error_string(context, HX509_ERROR_APPEND,
+ HX509_REVOKE_STATUS_MISSING,
+ "No revoke status found for "
+ "certificates");
return HX509_REVOKE_STATUS_MISSING;
}
@@ -785,6 +940,22 @@ out:
return ret;
}
+/**
+ * Create an OCSP request for a set of certificates.
+ *
+ * @param context a hx509 context
+ * @param reqcerts list of certificates to request ocsp data for
+ * @param pool certificate pool to use when signing
+ * @param signer certificate to use to sign the request
+ * @param digest the signing algorithm in the request, if NULL use the
+ * default signature algorithm,
+ * @param request the encoded request, free with free_heim_octet_string().
+ * @param nonce nonce in the request, free with free_heim_octet_string().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
int
hx509_ocsp_request(hx509_context context,
@@ -813,41 +984,49 @@ hx509_ocsp_request(hx509_context context,
ret = hx509_certs_iter(context, reqcerts, add_to_req, &ctx);
hx509_cert_free(ctx.parent);
- if (ret) {
- free_OCSPRequest(&req);
- return ret;
- }
+ if (ret)
+ goto out;
if (nonce) {
-
req.tbsRequest.requestExtensions =
calloc(1, sizeof(*req.tbsRequest.requestExtensions));
if (req.tbsRequest.requestExtensions == NULL) {
- free_OCSPRequest(&req);
- return ENOMEM;
+ ret = ENOMEM;
+ goto out;
}
es = req.tbsRequest.requestExtensions;
- es->len = 1;
es->val = calloc(es->len, sizeof(es->val[0]));
+ if (es->val == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ es->len = 1;
ret = der_copy_oid(oid_id_pkix_ocsp_nonce(), &es->val[0].extnID);
- if (ret)
- abort();
-
+ if (ret) {
+ free_OCSPRequest(&req);
+ return ret;
+ }
+
es->val[0].extnValue.data = malloc(10);
if (es->val[0].extnValue.data == NULL) {
- free_OCSPRequest(&req);
- return ENOMEM;
+ ret = ENOMEM;
+ goto out;
}
es->val[0].extnValue.length = 10;
ret = RAND_bytes(es->val[0].extnValue.data,
es->val[0].extnValue.length);
if (ret != 1) {
- free_OCSPRequest(&req);
- return HX509_CRYPTO_INTERNAL_ERROR;
+ ret = HX509_CRYPTO_INTERNAL_ERROR;
+ goto out;
+ }
+ ret = der_copy_octet_string(nonce, &es->val[0].extnValue);
+ if (ret) {
+ ret = ENOMEM;
+ goto out;
}
}
@@ -855,12 +1034,15 @@ hx509_ocsp_request(hx509_context context,
&req, &size, ret);
free_OCSPRequest(&req);
if (ret)
- return ret;
+ goto out;
if (size != request->length)
_hx509_abort("internal ASN.1 encoder error");
-
return 0;
+
+out:
+ free_OCSPRequest(&req);
+ return ret;
}
static char *
@@ -872,6 +1054,18 @@ printable_time(time_t t)
return s;
}
+/**
+ * Print the OCSP reply stored in a file.
+ *
+ * @param context a hx509 context
+ * @param path path to a file with a OCSP reply
+ * @param out the out FILE descriptor to print the reply on
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
int
hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
{
@@ -959,10 +1153,23 @@ hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
return ret;
}
-/*
- * Verify that the `cert' is part of the OCSP reply and its not
- * expired. Doesn't verify signature the OCSP reply or its done by a
+/**
+ * Verify that the certificate is part of the OCSP reply and it's not
+ * expired. Doesn't verify signature the OCSP reply or it's done by a
* authorized sender, that is assumed to be already done.
+ *
+ * @param context a hx509 context
+ * @param now the time right now, if 0, use the current time.
+ * @param cert the certificate to verify
+ * @param flags flags control the behavior
+ * @param data pointer to the encode ocsp reply
+ * @param length the length of the encode ocsp reply
+ * @param expiration return the time the OCSP will expire and need to
+ * be rechecked.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
*/
int
@@ -1062,6 +1269,17 @@ struct hx509_crl {
time_t expire;
};
+/**
+ * Create a CRL context. Use hx509_crl_free() to free the CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl return pointer to a newly allocated CRL context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
int
hx509_crl_alloc(hx509_context context, hx509_crl *crl)
{
@@ -1083,6 +1301,18 @@ hx509_crl_alloc(hx509_context context, hx509_crl *crl)
return ret;
}
+/**
+ * Add revoked certificate to an CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl the CRL to add the revoked certificate to.
+ * @param certs keyset of certificate to revoke.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
int
hx509_crl_add_revoked_certs(hx509_context context,
hx509_crl crl,
@@ -1091,6 +1321,19 @@ hx509_crl_add_revoked_certs(hx509_context context,
return hx509_certs_merge(context, crl->revoked, certs);
}
+/**
+ * Set the lifetime of a CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl a CRL context
+ * @param delta delta time the certificate is valid, library adds the
+ * current time to this.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
int
hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
{
@@ -1098,6 +1341,14 @@ hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
return 0;
}
+/**
+ * Free a CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl a CRL context to free.
+ *
+ * @ingroup hx509_verify
+ */
void
hx509_crl_free(hx509_context context, hx509_crl *crl)
@@ -1144,6 +1395,19 @@ add_revoked(hx509_context context, void *ctx, hx509_cert cert)
return 0;
}
+/**
+ * Sign a CRL and return an encode certificate.
+ *
+ * @param context a hx509 context.
+ * @param signer certificate to sign the CRL with
+ * @param crl the CRL to sign
+ * @param os return the signed and encoded CRL, free with
+ * free_heim_octet_string()
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
int
hx509_crl_sign(hx509_context context,
diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c
index 999ce7f120..775239cf6d 100644
--- a/source4/heimdal/lib/krb5/acache.c
+++ b/source4/heimdal/lib/krb5/acache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -37,7 +37,7 @@
#include <dlfcn.h>
#endif
-RCSID("$Id: acache.c 19764 2007-01-08 15:31:01Z lha $");
+RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $");
/* XXX should we fetch these for each open ? */
static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
@@ -188,11 +188,10 @@ make_cred_from_ccred(krb5_context context,
;
if (i) {
- cred->authdata.val = malloc(sizeof(cred->authdata.val[0]) * i);
+ cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0]));
if (cred->authdata.val == NULL)
goto nomem;
cred->authdata.len = i;
- memset(cred->authdata.val, 0, sizeof(cred->authdata.val[0]) * i);
for (i = 0; i < cred->authdata.len; i++) {
cred->authdata.val[i].ad_type = incred->authdata[i]->type;
ret = krb5_data_copy(&cred->authdata.val[i].ad_data,
@@ -207,11 +206,10 @@ make_cred_from_ccred(krb5_context context,
;
if (i) {
- cred->addresses.val = malloc(sizeof(cred->addresses.val[0]) * i);
+ cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0]));
if (cred->addresses.val == NULL)
goto nomem;
cred->addresses.len = i;
- memset(cred->addresses.val, 0, sizeof(cred->addresses.val[0]) * i);
for (i = 0; i < cred->addresses.len; i++) {
cred->addresses.val[i].addr_type = incred->addresses[i]->type;
@@ -260,7 +258,7 @@ nomem:
krb5_set_error_string(context, "malloc - out of memory");
fail:
- krb5_free_creds_contents(context, cred);
+ krb5_free_cred_contents(context, cred);
return ret;
}
@@ -331,6 +329,10 @@ make_ccred_from_cred(krb5_context context,
for (i = 0; i < incred->addresses.len; i++) {
cc_data *addr;
addr = malloc(sizeof(*addr));
+ if (addr == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
addr->type = incred->addresses.val[i].addr_type;
addr->length = incred->addresses.val[i].address.length;
addr->data = malloc(addr->length);
@@ -383,20 +385,21 @@ fail:
return ret;
}
-static char *
-get_cc_name(cc_ccache_t cache)
+static cc_int32
+get_cc_name(krb5_acc *a)
{
cc_string_t name;
cc_int32 error;
- char *str;
- error = (*cache->func->get_name)(cache, &name);
+ error = (*a->ccache->func->get_name)(a->ccache, &name);
if (error)
- return NULL;
+ return error;
- str = strdup(name->data);
+ a->cache_name = strdup(name->data);
(*name->func->release)(name);
- return str;
+ if (a->cache_name == NULL)
+ return ccErrNoMem;
+ return ccNoError;
}
@@ -405,17 +408,36 @@ acc_get_name(krb5_context context,
krb5_ccache id)
{
krb5_acc *a = ACACHE(id);
- static char n[255];
- char *name;
+ int32_t error;
- name = get_cc_name(a->ccache);
- if (name == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return NULL;
- }
- strlcpy(n, name, sizeof(n));
- free(name);
- return n;
+ if (a->cache_name == NULL) {
+ krb5_error_code ret;
+ krb5_principal principal;
+ char *name;
+
+ ret = _krb5_get_default_principal_local(context, &principal);
+ if (ret)
+ return NULL;
+
+ ret = krb5_unparse_name(context, principal, &name);
+ krb5_free_principal(context, principal);
+ if (ret)
+ return NULL;
+
+ error = (*a->context->func->create_new_ccache)(a->context,
+ cc_credentials_v5,
+ name,
+ &a->ccache);
+ krb5_xfree(name);
+ if (error)
+ return NULL;
+
+ error = get_cc_name(a);
+ if (error)
+ return NULL;
+ }
+
+ return a->cache_name;
}
static krb5_error_code
@@ -449,23 +471,6 @@ acc_alloc(krb5_context context, krb5_ccache *id)
}
static krb5_error_code
-get_default_principal(krb5_context context, char **p)
-{
- krb5_error_code ret;
- krb5_principal principal;
-
- *p = NULL;
-
- ret = _krb5_get_default_principal_local(context, &principal);
- if (ret)
- return ret;
-
- ret = krb5_unparse_name(context, principal, p);
- krb5_free_principal(context, principal);
- return ret;
-}
-
-static krb5_error_code
acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
krb5_error_code ret;
@@ -478,38 +483,22 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
a = ACACHE(*id);
- if (res == NULL || res[0] == '\0') {
- error = (*a->context->func->open_default_ccache)(a->context,
- &a->ccache);
- if (error == ccErrCCacheNotFound) {
- char *p;
-
- ret = get_default_principal(context, &p);
- if (ret == 0) {
- error = (*a->context->func->create_default_ccache)(a->context,
- cc_credentials_v5,
- p,
- &a->ccache);
- free(p);
- }
+ error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
+ if (error == ccNoError) {
+ error = get_cc_name(a);
+ if (error != ccNoError) {
+ acc_close(context, *id);
+ *id = NULL;
+ return translate_cc_error(context, error);
}
- if (error == 0)
- a->cache_name = get_cc_name(a->ccache);
+ } else if (error == ccErrCCacheNotFound) {
+ a->ccache = NULL;
+ a->cache_name = NULL;
+ error = 0;
} else {
- error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
- if (error == 0)
- a->cache_name = strdup(res);
- }
- if (error != 0) {
*id = NULL;
return translate_cc_error(context, error);
}
- if (a->cache_name == NULL) {
- acc_close(context, *id);
- *id = NULL;
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
return 0;
}
@@ -518,35 +507,17 @@ static krb5_error_code
acc_gen_new(krb5_context context, krb5_ccache *id)
{
krb5_error_code ret;
- cc_int32 error;
krb5_acc *a;
- char *p;
-
- ret = get_default_principal(context, &p);
ret = acc_alloc(context, id);
- if (ret) {
- free(p);
+ if (ret)
return ret;
- }
a = ACACHE(*id);
- error = (*a->context->func->create_new_ccache)(a->context,
- cc_credentials_v5,
- p, &a->ccache);
- free(p);
- if (error) {
- *id = NULL;
- return translate_cc_error(context, error);
- }
- a->cache_name = get_cc_name(a->ccache);
- if (a->cache_name == NULL) {
- acc_close(context, *id);
- *id = NULL;
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
+ a->ccache = NULL;
+ a->cache_name = NULL;
+
return 0;
}
@@ -555,9 +526,7 @@ acc_initialize(krb5_context context,
krb5_ccache id,
krb5_principal primary_principal)
{
- cc_credentials_iterator_t iter;
krb5_acc *a = ACACHE(id);
- cc_credentials_t ccred;
krb5_error_code ret;
int32_t error;
char *name;
@@ -566,12 +535,17 @@ acc_initialize(krb5_context context,
if (ret)
return ret;
- if (a->ccache == NULL) {
+ if (a->cache_name == NULL) {
error = (*a->context->func->create_new_ccache)(a->context,
cc_credentials_v5,
name,
&a->ccache);
- } else {
+ free(name);
+ if (error == ccNoError)
+ error = get_cc_name(a);
+ } else {
+ cc_credentials_iterator_t iter;
+ cc_credentials_t ccred;
error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
if (error) {
@@ -593,8 +567,6 @@ acc_initialize(krb5_context context,
name);
}
- free(name);
-
return translate_cc_error(context, error);
}
@@ -629,6 +601,10 @@ acc_destroy(krb5_context context,
error = (*a->ccache->func->destroy)(a->ccache);
a->ccache = NULL;
}
+ if (a->context) {
+ error = (a->context->func->release)(a->context);
+ a->context = NULL;
+ }
return translate_cc_error(context, error);
}
@@ -643,6 +619,11 @@ acc_store_cred(krb5_context context,
krb5_error_code ret;
cc_int32 error;
+ if (a->ccache == NULL) {
+ krb5_set_error_string(context, "No API credential found");
+ return KRB5_CC_NOTFOUND;
+ }
+
cred.version = cc_credentials_v5;
cred.credentials.credentials_v5 = &v5cred;
@@ -671,8 +652,10 @@ acc_get_principal(krb5_context context,
int32_t error;
cc_string_t name;
- if (a->ccache == NULL)
- return ENOENT;
+ if (a->ccache == NULL) {
+ krb5_set_error_string(context, "No API credential found");
+ return KRB5_CC_NOTFOUND;
+ }
error = (*a->ccache->func->get_principal)(a->ccache,
cc_credentials_v5,
@@ -695,6 +678,11 @@ acc_get_first (krb5_context context,
krb5_acc *a = ACACHE(id);
int32_t error;
+ if (a->ccache == NULL) {
+ krb5_set_error_string(context, "No API credential found");
+ return KRB5_CC_NOTFOUND;
+ }
+
error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
if (error) {
krb5_clear_error_string(context);
@@ -755,6 +743,11 @@ acc_remove_cred(krb5_context context,
cc_int32 error;
char *client, *server;
+ if (a->ccache == NULL) {
+ krb5_set_error_string(context, "No API credential found");
+ return KRB5_CC_NOTFOUND;
+ }
+
if (cred->client) {
ret = krb5_unparse_name(context, cred->client, &client);
if (ret)
@@ -894,12 +887,11 @@ acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
a = ACACHE(*id);
a->ccache = cache;
- a->cache_name = get_cc_name(a->ccache);
- if (a->cache_name == NULL) {
+ error = get_cc_name(a);
+ if (error) {
acc_close(context, *id);
*id = NULL;
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
+ return translate_cc_error(context, error);
}
return 0;
}
@@ -917,6 +909,76 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
+static krb5_error_code
+acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+ krb5_acc *afrom = ACACHE(from);
+ krb5_acc *ato = ACACHE(to);
+ int32_t error;
+
+ if (ato->ccache == NULL) {
+ cc_string_t name;
+
+ error = (*afrom->ccache->func->get_principal)(afrom->ccache,
+ cc_credentials_v5,
+ &name);
+ if (error)
+ return translate_cc_error(context, error);
+
+ error = (*ato->context->func->create_new_ccache)(ato->context,
+ cc_credentials_v5,
+ name->data,
+ &ato->ccache);
+ (*name->func->release)(name);
+ if (error)
+ return translate_cc_error(context, error);
+ }
+
+
+ error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache);
+ return translate_cc_error(context, error);
+}
+
+static krb5_error_code
+acc_default_name(krb5_context context, char **str)
+{
+ krb5_error_code ret;
+ cc_context_t cc;
+ cc_string_t name;
+ int32_t error;
+
+ ret = init_ccapi(context);
+ if (ret)
+ return ret;
+
+ error = (*init_func)(&cc, ccapi_version_3, NULL, NULL);
+ if (error)
+ return translate_cc_error(context, error);
+
+ error = (*cc->func->get_default_ccache_name)(cc, &name);
+ if (error) {
+ (*cc->func->release)(cc);
+ return translate_cc_error(context, error);
+ }
+
+ asprintf(str, "API:%s", name->data);
+ (*name->func->release)(name);
+ (*cc->func->release)(cc);
+
+ if (*str == NULL) {
+ krb5_set_error_string(context, "out of memory");
+ return ENOMEM;
+ }
+ return 0;
+}
+
+
+/**
+ * Variable containing the API based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
const krb5_cc_ops krb5_acc_ops = {
"API",
acc_get_name,
@@ -936,5 +998,7 @@ const krb5_cc_ops krb5_acc_ops = {
acc_get_version,
acc_get_cache_first,
acc_get_cache_next,
- acc_end_cache_get
+ acc_end_cache_get,
+ acc_move,
+ acc_default_name
};
diff --git a/source4/heimdal/lib/krb5/add_et_list.c b/source4/heimdal/lib/krb5/add_et_list.c
index a6005c6859..5455d8ac99 100644
--- a/source4/heimdal/lib/krb5/add_et_list.c
+++ b/source4/heimdal/lib/krb5/add_et_list.c
@@ -33,12 +33,20 @@
#include "krb5_locl.h"
-RCSID("$Id: add_et_list.c 13713 2004-04-13 14:33:45Z lha $");
+RCSID("$Id: add_et_list.c 22603 2008-02-21 18:44:57Z lha $");
-/*
+/**
* Add a specified list of error messages to the et list in context.
* Call func (probably a comerr-generated function) with a pointer to
* the current et_list.
+ *
+ * @param context A kerberos context.
+ * @param func The generated com_err et function.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
*/
krb5_error_code KRB5_LIB_FUNCTION
diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c
index 8c31843058..f364f5974d 100644
--- a/source4/heimdal/lib/krb5/addr_families.c
+++ b/source4/heimdal/lib/krb5/addr_families.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: addr_families.c 18805 2006-10-22 06:54:00Z lha $");
+RCSID("$Id: addr_families.c 22039 2007-11-10 11:47:35Z lha $");
struct addr_operations {
int af;
@@ -767,6 +767,19 @@ find_atype(int atype)
return NULL;
}
+/**
+ * krb5_sockaddr2address stores a address a "struct sockaddr" sa in
+ * the krb5_address addr.
+ *
+ * @param context a Keberos context
+ * @param sa a struct sockaddr to extract the address from
+ * @param addr an Kerberos 5 address to store the address in.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_sockaddr2address (krb5_context context,
const struct sockaddr *sa, krb5_address *addr)
@@ -780,6 +793,20 @@ krb5_sockaddr2address (krb5_context context,
return (*a->sockaddr2addr)(sa, addr);
}
+/**
+ * krb5_sockaddr2port extracts a port (if possible) from a "struct
+ * sockaddr.
+ *
+ * @param context a Keberos context
+ * @param sa a struct sockaddr to extract the port from
+ * @param port a pointer to an int16_t store the port in.
+ *
+ * @return Return an error code or 0. Will return
+ * KRB5_PROG_ATYPE_NOSUPP in case address type is not supported.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_sockaddr2port (krb5_context context,
const struct sockaddr *sa, int16_t *port)
@@ -793,6 +820,27 @@ krb5_sockaddr2port (krb5_context context,
return (*a->sockaddr2port)(sa, port);
}
+/**
+ * krb5_addr2sockaddr sets the "struct sockaddr sockaddr" from addr
+ * and port. The argument sa_size should initially contain the size of
+ * the sa and after the call, it will contain the actual length of the
+ * address. In case of the sa is too small to fit the whole address,
+ * the up to *sa_size will be stored, and then *sa_size will be set to
+ * the required length.
+ *
+ * @param context a Keberos context
+ * @param addr the address to copy the from
+ * @param sa the struct sockaddr that will be filled in
+ * @param sa_size pointer to length of sa, and after the call, it will
+ * contain the actual length of the address.
+ * @param port set port in sa.
+ *
+ * @return Return an error code or 0. Will return
+ * KRB5_PROG_ATYPE_NOSUPP in case address type is not supported.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_addr2sockaddr (krb5_context context,
const krb5_address *addr,
@@ -808,7 +856,8 @@ krb5_addr2sockaddr (krb5_context context,
return KRB5_PROG_ATYPE_NOSUPP;
}
if (a->addr2sockaddr == NULL) {
- krb5_set_error_string (context, "Can't convert address type %d to sockaddr",
+ krb5_set_error_string (context,
+ "Can't convert address type %d to sockaddr",
addr->addr_type);
return KRB5_PROG_ATYPE_NOSUPP;
}
@@ -816,6 +865,15 @@ krb5_addr2sockaddr (krb5_context context,
return 0;
}
+/**
+ * krb5_max_sockaddr_size returns the max size of the .Li struct
+ * sockaddr that the Kerberos library will return.
+ *
+ * @return Return an size_t of the maximum struct sockaddr.
+ *
+ * @ingroup krb5_address
+ */
+
size_t KRB5_LIB_FUNCTION
krb5_max_sockaddr_size (void)
{
@@ -828,6 +886,18 @@ krb5_max_sockaddr_size (void)
return max_sockaddr_size;
}
+/**
+ * krb5_sockaddr_uninteresting returns TRUE for all .Fa sa that the
+ * kerberos library thinks are uninteresting. One example are link
+ * local addresses.
+ *
+ * @param sa pointer to struct sockaddr that might be interesting.
+ *
+ * @return Return a non zero for uninteresting addresses.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_sockaddr_uninteresting(const struct sockaddr *sa)
{
@@ -837,6 +907,25 @@ krb5_sockaddr_uninteresting(const struct sockaddr *sa)
return (*a->uninteresting)(sa);
}
+/**
+ * krb5_h_addr2sockaddr initializes a "struct sockaddr sa" from af and
+ * the "struct hostent" (see gethostbyname(3) ) h_addr_list
+ * component. The argument sa_size should initially contain the size
+ * of the sa, and after the call, it will contain the actual length of
+ * the address.
+ *
+ * @param context a Keberos context
+ * @param af addresses
+ * @param addr address
+ * @param sa returned struct sockaddr
+ * @param sa_size size of sa
+ * @param port port to set in sa.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_h_addr2sockaddr (krb5_context context,
int af,
@@ -853,6 +942,20 @@ krb5_h_addr2sockaddr (krb5_context context,
return 0;
}
+/**
+ * krb5_h_addr2addr works like krb5_h_addr2sockaddr with the exception
+ * that it operates on a krb5_address instead of a struct sockaddr.
+ *
+ * @param context a Keberos context
+ * @param af address family
+ * @param haddr host address from struct hostent.
+ * @param addr returned krb5_address.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_h_addr2addr (krb5_context context,
int af,
@@ -866,6 +969,23 @@ krb5_h_addr2addr (krb5_context context,
return (*a->h_addr2addr)(haddr, addr);
}
+/**
+ * krb5_anyaddr fills in a "struct sockaddr sa" that can be used to
+ * bind(2) to. The argument sa_size should initially contain the size
+ * of the sa, and after the call, it will contain the actual length
+ * of the address.
+ *
+ * @param context a Keberos context
+ * @param af address family
+ * @param sa sockaddr
+ * @param sa_size lenght of sa.
+ * @param port for to fill into sa.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_anyaddr (krb5_context context,
int af,
@@ -884,6 +1004,22 @@ krb5_anyaddr (krb5_context context,
return 0;
}
+/**
+ * krb5_print_address prints the address in addr to the string string
+ * that have the length len. If ret_len is not NULL, it will be filled
+ * with the length of the string if size were unlimited (not including
+ * the final NUL) .
+ *
+ * @param addr address to be printed
+ * @param str pointer string to print the address into
+ * @param len length that will fit into area pointed to by "str".
+ * @param ret_len return length the str.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_print_address (const krb5_address *addr,
char *str, size_t len, size_t *ret_len)
@@ -921,6 +1057,19 @@ krb5_print_address (const krb5_address *addr,
return 0;
}
+/**
+ * krb5_parse_address returns the resolved hostname in string to the
+ * krb5_addresses addresses .
+ *
+ * @param context a Keberos context
+ * @param string
+ * @param addresses
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_parse_address(krb5_context context,
const char *string,
@@ -980,6 +1129,21 @@ krb5_parse_address(krb5_context context,
return 0;
}
+/**
+ * krb5_address_order compares the addresses addr1 and addr2 so that
+ * it can be used for sorting addresses. If the addresses are the same
+ * address krb5_address_order will return 0. Behavies like memcmp(2).
+ *
+ * @param context a Keberos context
+ * @param addr1 krb5_address to compare
+ * @param addr2 krb5_address to compare
+ *
+ * @return < 0 if address addr1 in "less" then addr2. 0 if addr1 and
+ * addr2 is the same address, > 0 if addr2 is "less" then addr1.
+ *
+ * @ingroup krb5_address
+ */
+
int KRB5_LIB_FUNCTION
krb5_address_order(krb5_context context,
const krb5_address *addr1,
@@ -1014,6 +1178,19 @@ krb5_address_order(krb5_context context,
addr1->address.length);
}
+/**
+ * krb5_address_compare compares the addresses addr1 and addr2.
+ * Returns TRUE if the two addresses are the same.
+ *
+ * @param context a Keberos context
+ * @param addr1 address to compare
+ * @param addr2 address to compare
+ *
+ * @return Return an TRUE is the address are the same FALSE if not
+ *
+ * @ingroup krb5_address
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_address_compare(krb5_context context,
const krb5_address *addr1,
@@ -1022,6 +1199,19 @@ krb5_address_compare(krb5_context context,
return krb5_address_order (context, addr1, addr2) == 0;
}
+/**
+ * krb5_address_search checks if the address addr is a member of the
+ * address set list addrlist .
+ *
+ * @param context a Keberos context.
+ * @param addr address to search for.
+ * @param addrlist list of addresses to look in for addr.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_address_search(krb5_context context,
const krb5_address *addr,
@@ -1035,6 +1225,18 @@ krb5_address_search(krb5_context context,
return FALSE;
}
+/**
+ * krb5_free_address frees the data stored in the address that is
+ * alloced with any of the krb5_address functions.
+ *
+ * @param context a Keberos context
+ * @param address addresss to be freed.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_address(krb5_context context,
krb5_address *address)
@@ -1047,6 +1249,18 @@ krb5_free_address(krb5_context context,
return 0;
}
+/**
+ * krb5_free_addresses frees the data stored in the address that is
+ * alloced with any of the krb5_address functions.
+ *
+ * @param context a Keberos context
+ * @param addresses addressses to be freed.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_addresses(krb5_context context,
krb5_addresses *addresses)
@@ -1060,6 +1274,19 @@ krb5_free_addresses(krb5_context context,
return 0;
}
+/**
+ * krb5_copy_address copies the content of address
+ * inaddr to outaddr.
+ *
+ * @param context a Keberos context
+ * @param inaddr pointer to source address
+ * @param outaddr pointer to destination address
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_copy_address(krb5_context context,
const krb5_address *inaddr,
@@ -1071,6 +1298,19 @@ krb5_copy_address(krb5_context context,
return copy_HostAddress(inaddr, outaddr);
}
+/**
+ * krb5_copy_addresses copies the content of addresses
+ * inaddr to outaddr.
+ *
+ * @param context a Keberos context
+ * @param inaddr pointer to source addresses
+ * @param outaddr pointer to destination addresses
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_copy_addresses(krb5_context context,
const krb5_addresses *inaddr,
@@ -1085,6 +1325,19 @@ krb5_copy_addresses(krb5_context context,
return 0;
}
+/**
+ * krb5_append_addresses adds the set of addresses in source to
+ * dest. While copying the addresses, duplicates are also sorted out.
+ *
+ * @param context a Keberos context
+ * @param dest destination of copy operation
+ * @param source adresses that are going to be added to dest
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_append_addresses(krb5_context context,
krb5_addresses *dest,
@@ -1115,8 +1368,17 @@ krb5_append_addresses(krb5_context context,
return 0;
}
-/*
+/**
* Create an address of type KRB5_ADDRESS_ADDRPORT from (addr, port)
+ *
+ * @param context a Keberos context
+ * @param res built address from addr/port
+ * @param addr address to use
+ * @param port port to use
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -1170,9 +1432,19 @@ krb5_make_addrport (krb5_context context,
return 0;
}
-/*
+/**
* Calculate the boundary addresses of `inaddr'/`prefixlen' and store
* them in `low' and `high'.
+ *
+ * @param context a Keberos context
+ * @param inaddr address in prefixlen that the bondery searched
+ * @param prefixlen width of boundery
+ * @param low lowest address
+ * @param high highest address
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
*/
krb5_error_code KRB5_LIB_FUNCTION
diff --git a/source4/heimdal/lib/krb5/asn1_glue.c b/source4/heimdal/lib/krb5/asn1_glue.c
index 6b7d40d453..b3f775b4be 100644
--- a/source4/heimdal/lib/krb5/asn1_glue.c
+++ b/source4/heimdal/lib/krb5/asn1_glue.c
@@ -37,7 +37,7 @@
#include "krb5_locl.h"
-RCSID("$Id: asn1_glue.c 18269 2006-10-06 17:02:48Z lha $");
+RCSID("$Id: asn1_glue.c 21745 2007-07-31 16:11:25Z lha $");
krb5_error_code KRB5_LIB_FUNCTION
_krb5_principal2principalname (PrincipalName *p,
@@ -53,8 +53,12 @@ _krb5_principalname2krb5_principal (krb5_context context,
const Realm realm)
{
krb5_principal p = malloc(sizeof(*p));
+ if (p == NULL)
+ return ENOMEM;
copy_PrincipalName(&from, &p->name);
p->realm = strdup(realm);
+ if (p->realm == NULL)
+ return ENOMEM;
*principal = p;
return 0;
}
diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c
index 5e08f15ad4..323f17a245 100644
--- a/source4/heimdal/lib/krb5/auth_context.c
+++ b/source4/heimdal/lib/krb5/auth_context.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: auth_context.c 14452 2005-01-05 02:34:08Z lukeh $");
+RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $");
krb5_error_code KRB5_LIB_FUNCTION
krb5_auth_con_init(krb5_context context,
@@ -141,14 +141,16 @@ krb5_auth_con_setaddrs(krb5_context context,
if (auth_context->local_address)
krb5_free_address (context, auth_context->local_address);
else
- auth_context->local_address = malloc(sizeof(krb5_address));
+ if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL)
+ return ENOMEM;
krb5_copy_address(context, local_addr, auth_context->local_address);
}
if (remote_addr) {
if (auth_context->remote_address)
krb5_free_address (context, auth_context->remote_address);
else
- auth_context->remote_address = malloc(sizeof(krb5_address));
+ if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL)
+ return ENOMEM;
krb5_copy_address(context, remote_addr, auth_context->remote_address);
}
return 0;
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c
index 59aae40d28..5db6d2b2cf 100644
--- a/source4/heimdal/lib/krb5/cache.c
+++ b/source4/heimdal/lib/krb5/cache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,12 +33,20 @@
#include "krb5_locl.h"
-RCSID("$Id: cache.c 21498 2007-07-11 09:41:43Z lha $");
+RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $");
-/*
+/**
* Add a new ccache type with operations `ops', overwriting any
* existing one if `override'.
- * Return an error code or 0.
+ *
+ * @param context a Keberos context
+ * @param ops type of plugin symbol
+ * @param override flag to select if the registration is to overide
+ * an existing ops with the same name.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_ccache
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -101,8 +109,7 @@ _krb5_cc_allocate(krb5_context context,
/*
* Allocate memory for a new ccache in `id' with operations `ops'
- * and name `residual'.
- * Return 0 or an error code.
+ * and name `residual'. Return 0 or an error code.
*/
static krb5_error_code
@@ -122,12 +129,21 @@ allocate_ccache (krb5_context context,
return ret;
}
-/*
+/**
* Find and allocate a ccache in `id' from the specification in `residual'.
* If the ccache name doesn't contain any colon, interpret it as a file name.
- * Return 0 or an error code.
+ *
+ * @param context a Keberos context.
+ * @param name string name of a credential cache.
+ * @param id return pointer to a found credential cache.
+ *
+ * @return Return 0 or an error code. In case of an error, id is set
+ * to NULL.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_resolve(krb5_context context,
const char *name,
@@ -135,6 +151,8 @@ krb5_cc_resolve(krb5_context context,
{
int i;
+ *id = NULL;
+
for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
size_t prefix_len = strlen(context->cc_ops[i].prefix);
@@ -153,57 +171,64 @@ krb5_cc_resolve(krb5_context context,
}
}
-/*
+/**
* Generate a new ccache of type `ops' in `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_gen_new(krb5_context context,
const krb5_cc_ops *ops,
krb5_ccache *id)
{
- krb5_error_code ret;
-
- ret = _krb5_cc_allocate(context, ops, id);
- if (ret)
- return ret;
- return (*id)->ops->gen_new(context, id);
+ return krb5_cc_new_unique(context, ops->prefix, NULL, id);
}
-/*
+/**
* Generates a new unique ccache of `type` in `id'. If `type' is NULL,
* the library chooses the default credential cache type. The supplied
* `hint' (that can be NULL) is a string that the credential cache
* type can use to base the name of the credential on, this is to make
- * its easier for the user to differentiate the credentials.
+ * it easier for the user to differentiate the credentials.
+ *
+ * @return Returns 0 or an error code.
*
- * Returns 0 or an error code.
+ * @ingroup krb5_ccache
*/
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_new_unique(krb5_context context, const char *type,
const char *hint, krb5_ccache *id)
{
- const krb5_cc_ops *ops;
-
- if (type == NULL)
- type = KRB5_DEFAULT_CCNAME;
+ const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+ krb5_error_code ret;
- ops = krb5_cc_get_prefix_ops(context, type);
- if (ops == NULL) {
- krb5_set_error_string(context, "Credential cache type %s is unknown",
- type);
- return KRB5_CC_UNKNOWN_TYPE;
+ if (type) {
+ ops = krb5_cc_get_prefix_ops(context, type);
+ if (ops == NULL) {
+ krb5_set_error_string(context,
+ "Credential cache type %s is unknown", type);
+ return KRB5_CC_UNKNOWN_TYPE;
+ }
}
- return krb5_cc_gen_new(context, ops, id);
+ ret = _krb5_cc_allocate(context, ops, id);
+ if (ret)
+ return ret;
+ return (*id)->ops->gen_new(context, id);
}
-/*
+/**
* Return the name of the ccache `id'
+ *
+ * @ingroup krb5_ccache
*/
+
const char* KRB5_LIB_FUNCTION
krb5_cc_get_name(krb5_context context,
krb5_ccache id)
@@ -211,10 +236,13 @@ krb5_cc_get_name(krb5_context context,
return id->ops->get_name(context, id);
}
-/*
+/**
* Return the type of the ccache `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
const char* KRB5_LIB_FUNCTION
krb5_cc_get_type(krb5_context context,
krb5_ccache id)
@@ -222,12 +250,15 @@ krb5_cc_get_type(krb5_context context,
return id->ops->prefix;
}
-/*
+/**
* Return the complete resolvable name the ccache `id' in `str´.
* `str` should be freed with free(3).
* Returns 0 or an error (and then *str is set to NULL).
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_get_full_name(krb5_context context,
krb5_ccache id,
@@ -257,10 +288,13 @@ krb5_cc_get_full_name(krb5_context context,
return 0;
}
-/*
+/**
* Return krb5_cc_ops of a the ccache `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
const krb5_cc_ops *
krb5_cc_get_ops(krb5_context context, krb5_ccache id)
{
@@ -348,6 +382,10 @@ environment_changed(krb5_context context)
{
const char *e;
+ /* if the cc name was set, don't change it */
+ if (context->default_cc_name_set)
+ return 0;
+
if(issuid())
return 0;
@@ -367,10 +405,13 @@ environment_changed(krb5_context context)
return 0;
}
-/*
+/**
* Set the default cc name for `context' to `name'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_set_default_name(krb5_context context, const char *name)
{
@@ -392,14 +433,23 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
if (e == NULL) {
e = krb5_config_get_string(context, NULL, "libdefaults",
"default_cc_name", NULL);
- if (e == NULL)
- e = KRB5_DEFAULT_CCNAME;
- ret = _krb5_expand_default_cc_name(context, e, &p);
- if (ret)
- return ret;
+ if (e) {
+ ret = _krb5_expand_default_cc_name(context, e, &p);
+ if (ret)
+ return ret;
+ }
+ if (e == NULL) {
+ const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+ ret = (*ops->default_name)(context, &p);
+ if (ret)
+ return ret;
+ }
}
- } else
+ context->default_cc_name_set = 0;
+ } else {
p = strdup(name);
+ context->default_cc_name_set = 1;
+ }
if (p == NULL) {
krb5_set_error_string(context, "malloc - out of memory");
@@ -414,11 +464,16 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
return ret;
}
-/*
+/**
* Return a pointer to a context static string containing the default
* ccache name.
+ *
+ * @return String to the default credential cache name.
+ *
+ * @ingroup krb5_ccache
*/
+
const char* KRB5_LIB_FUNCTION
krb5_cc_default_name(krb5_context context)
{
@@ -428,11 +483,15 @@ krb5_cc_default_name(krb5_context context)
return context->default_cc_name;
}
-/*
+/**
* Open the default ccache in `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_default(krb5_context context,
krb5_ccache *id)
@@ -446,11 +505,15 @@ krb5_cc_default(krb5_context context,
return krb5_cc_resolve(context, p, id);
}
-/*
+/**
* Create a new ccache in `id' for `primary_principal'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_initialize(krb5_context context,
krb5_ccache id,
@@ -460,11 +523,15 @@ krb5_cc_initialize(krb5_context context,
}
-/*
+/**
* Remove the ccache `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_destroy(krb5_context context,
krb5_ccache id)
@@ -476,11 +543,15 @@ krb5_cc_destroy(krb5_context context,
return ret;
}
-/*
+/**
* Stop using the ccache `id' and free the related resources.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_close(krb5_context context,
krb5_ccache id)
@@ -491,11 +562,15 @@ krb5_cc_close(krb5_context context,
return ret;
}
-/*
+/**
* Store `creds' in the ccache `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_store_cred(krb5_context context,
krb5_ccache id,
@@ -504,13 +579,17 @@ krb5_cc_store_cred(krb5_context context,
return (*id->ops->store)(context, id, creds);
}
-/*
+/**
* Retrieve the credential identified by `mcreds' (and `whichfields')
* from `id' in `creds'. 'creds' must be free by the caller using
* krb5_free_cred_contents.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_retrieve_cred(krb5_context context,
krb5_ccache id,
@@ -526,7 +605,9 @@ krb5_cc_retrieve_cred(krb5_context context,
mcreds, creds);
}
- krb5_cc_start_seq_get(context, id, &cursor);
+ ret = krb5_cc_start_seq_get(context, id, &cursor);
+ if (ret)
+ return ret;
while((ret = krb5_cc_next_cred(context, id, &cursor, creds)) == 0){
if(krb5_compare_creds(context, whichfields, mcreds, creds)){
ret = 0;
@@ -538,11 +619,15 @@ krb5_cc_retrieve_cred(krb5_context context,
return ret;
}
-/*
+/**
* Return the principal of `id' in `principal'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_get_principal(krb5_context context,
krb5_ccache id,
@@ -551,12 +636,16 @@ krb5_cc_get_principal(krb5_context context,
return (*id->ops->get_princ)(context, id, principal);
}
-/*
+/**
* Start iterating over `id', `cursor' is initialized to the
* beginning.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_start_seq_get (krb5_context context,
const krb5_ccache id,
@@ -565,12 +654,16 @@ krb5_cc_start_seq_get (krb5_context context,
return (*id->ops->get_first)(context, id, cursor);
}
-/*
+/**
* Retrieve the next cred pointed to by (`id', `cursor') in `creds'
* and advance `cursor'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_next_cred (krb5_context context,
const krb5_ccache id,
@@ -580,7 +673,12 @@ krb5_cc_next_cred (krb5_context context,
return (*id->ops->get_next)(context, id, cursor, creds);
}
-/* like krb5_cc_next_cred, but allow for selective retrieval */
+/**
+ * Like krb5_cc_next_cred, but allow for selective retrieval
+ *
+ * @ingroup krb5_ccache
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_next_cred_match(krb5_context context,
@@ -601,10 +699,13 @@ krb5_cc_next_cred_match(krb5_context context,
}
}
-/*
+/**
* Destroy the cursor `cursor'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_end_seq_get (krb5_context context,
const krb5_ccache id,
@@ -613,10 +714,13 @@ krb5_cc_end_seq_get (krb5_context context,
return (*id->ops->end_get)(context, id, cursor);
}
-/*
+/**
* Remove the credential identified by `cred', `which' from `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_remove_cred(krb5_context context,
krb5_ccache id,
@@ -632,10 +736,13 @@ krb5_cc_remove_cred(krb5_context context,
return (*id->ops->remove_cred)(context, id, which, cred);
}
-/*
+/**
* Set the flags of `id' to `flags'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_set_flags(krb5_context context,
krb5_ccache id,
@@ -644,10 +751,13 @@ krb5_cc_set_flags(krb5_context context,
return (*id->ops->set_flags)(context, id, flags);
}
-/*
+/**
* Copy the contents of `from' to `to'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_copy_cache_match(krb5_context context,
const krb5_ccache from,
@@ -689,6 +799,13 @@ krb5_cc_copy_cache_match(krb5_context context,
return ret;
}
+/**
+ * Just like krb5_cc_copy_cache_match, but copy everything.
+ *
+ * @ingroup krb5_ccache
+ */
+
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_copy_cache(krb5_context context,
const krb5_ccache from,
@@ -697,10 +814,13 @@ krb5_cc_copy_cache(krb5_context context,
return krb5_cc_copy_cache_match(context, from, to, 0, NULL, NULL);
}
-/*
+/**
* Return the version of `id'.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_get_version(krb5_context context,
const krb5_ccache id)
@@ -711,23 +831,30 @@ krb5_cc_get_version(krb5_context context,
return 0;
}
-/*
+/**
* Clear `mcreds' so it can be used with krb5_cc_retrieve_cred
+ *
+ * @ingroup krb5_ccache
*/
+
void KRB5_LIB_FUNCTION
krb5_cc_clear_mcred(krb5_creds *mcred)
{
memset(mcred, 0, sizeof(*mcred));
}
-/*
+/**
* Get the cc ops that is registered in `context' to handle the
* `prefix'. `prefix' can be a complete credential cache name or a
* prefix, the function will only use part up to the first colon (:)
- * if there is one. Returns NULL if ops not found.
+ * if there is one.
+ * Returns NULL if ops not found.
+ *
+ * @ingroup krb5_ccache
*/
+
const krb5_cc_ops *
krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
{
@@ -761,12 +888,16 @@ struct krb5_cc_cache_cursor_data {
krb5_cc_cursor cursor;
};
-/*
+/**
* Start iterating over all caches of `type'. If `type' is NULL, the
* default type is * used. `cursor' is initialized to the beginning.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_get_first (krb5_context context,
const char *type,
@@ -807,12 +938,16 @@ krb5_cc_cache_get_first (krb5_context context,
return ret;
}
-/*
+/**
* Retrieve the next cache pointed to by (`cursor') in `id'
* and advance `cursor'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_next (krb5_context context,
krb5_cc_cache_cursor cursor,
@@ -821,10 +956,15 @@ krb5_cc_cache_next (krb5_context context,
return cursor->ops->get_cache_next(context, cursor->cursor, id);
}
-/*
+/**
* Destroy the cursor `cursor'.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_end_seq_get (krb5_context context,
krb5_cc_cache_cursor cursor)
@@ -836,14 +976,18 @@ krb5_cc_cache_end_seq_get (krb5_context context,
return ret;
}
-/*
+/**
* Search for a matching credential cache of type `type' that have the
* `principal' as the default principal. If NULL is used for `type',
* the default type is used. On success, `id' needs to be freed with
- * krb5_cc_close or krb5_cc_destroy. On failure, error code is
- * returned and `id' is set to NULL.
+ * krb5_cc_close or krb5_cc_destroy.
+ *
+ * @return On failure, error code is returned and `id' is set to NULL.
+ *
+ * @ingroup krb5_ccache
*/
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_cache_match (krb5_context context,
krb5_principal client,
@@ -895,3 +1039,35 @@ krb5_cc_cache_match (krb5_context context,
return 0;
}
+/**
+ * Move the content from one credential cache to another. The
+ * operation is an atomic switch.
+ *
+ * @param context a Keberos context
+ * @param from the credential cache to move the content from
+ * @param to the credential cache to move the content to
+
+ * @return On sucess, from is freed. On failure, error code is
+ * returned and from and to are both still allocated.
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code
+krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+ krb5_error_code ret;
+
+ if (strcmp(from->ops->prefix, to->ops->prefix) != 0) {
+ krb5_set_error_string(context, "Moving credentials between diffrent "
+ "types not yet supported");
+ return KRB5_CC_NOSUPP;
+ }
+
+ ret = (*to->ops->move)(context, from, to);
+ if (ret == 0) {
+ memset(from, 0, sizeof(*from));
+ free(from);
+ }
+ return ret;
+}
diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c
index b54e293a60..256783310e 100644
--- a/source4/heimdal/lib/krb5/context.c
+++ b/source4/heimdal/lib/krb5/context.c
@@ -34,12 +34,19 @@
#include "krb5_locl.h"
#include <com_err.h>
-RCSID("$Id: context.c 19107 2006-11-24 14:24:33Z lha $");
+RCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $");
#define INIT_FIELD(C, T, E, D, F) \
(C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \
"libdefaults", F, NULL)
+#define INIT_FLAG(C, O, V, D, F) \
+ do { \
+ if (krb5_config_get_bool_default((C), NULL, (D),"libdefaults", F, NULL)) { \
+ (C)->O |= V; \
+ } \
+ } while(0)
+
/*
* Set the list of etypes `ret_etypes' from the configuration variable
* `name'
@@ -181,11 +188,28 @@ init_context_from_config_file(krb5_context context)
INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc");
INIT_FIELD(context, int, large_msg_size, 1400, "large_message_size");
- INIT_FIELD(context, bool, dns_canonicalize_hostname, TRUE, "dns_canonicalize_hostname");
+ INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname");
+ INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac");
context->default_cc_name = NULL;
+ context->default_cc_name_set = 0;
return 0;
}
+/**
+ * Initializes the context structure and reads the configuration file
+ * /etc/krb5.conf. The structure should be freed by calling
+ * krb5_free_context() when it is no longer being used.
+ *
+ * @param context pointer to returned context
+ *
+ * @return Returns 0 to indicate success. Otherwise an errno code is
+ * returned. Failure means either that something bad happened during
+ * initialization (typically ENOMEM) or that Kerberos should not be
+ * used ENXIO.
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_init_context(krb5_context *context)
{
@@ -246,11 +270,21 @@ out:
return ret;
}
+/**
+ * Frees the krb5_context allocated by krb5_init_context().
+ *
+ * @param context context to be freed.
+ *
+ * @ingroup krb5
+*/
+
void KRB5_LIB_FUNCTION
krb5_free_context(krb5_context context)
{
if (context->default_cc_name)
free(context->default_cc_name);
+ if (context->default_cc_name_env)
+ free(context->default_cc_name_env);
free(context->etypes);
free(context->etypes_des);
krb5_free_host_realm (context, context->default_realms);
@@ -272,6 +306,18 @@ krb5_free_context(krb5_context context)
free(context);
}
+/**
+ * Reinit the context from a new set of filenames.
+ *
+ * @param context context to add configuration too.
+ * @param filenames array of filenames, end of list is indicated with a NULL filename.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_config_files(krb5_context context, char **filenames)
{
@@ -324,7 +370,7 @@ add_file(char ***pfilenames, int *len, char *file)
}
/*
- * `pq' isn't free, its up the the caller
+ * `pq' isn't free, it's up the the caller
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -380,6 +426,18 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
return 0;
}
+/**
+ * Prepend the filename to the global configuration list.
+ *
+ * @param filelist a filename to add to the default list of filename
+ * @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
{
@@ -399,6 +457,17 @@ krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
return 0;
}
+/**
+ * Get the global configuration list.
+ *
+ * @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_default_config_files(char ***pfilenames)
{
@@ -414,6 +483,17 @@ krb5_get_default_config_files(char ***pfilenames)
return krb5_prepend_config_files(files, NULL, pfilenames);
}
+/**
+ * Free a list of configuration files.
+ *
+ * @param filenames list to be freed.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_free_config_files(char **filenames)
{
@@ -423,12 +503,17 @@ krb5_free_config_files(char **filenames)
free(filenames);
}
-/*
+/**
* Returns the list of Kerberos encryption types sorted in order of
- * most preferred to least preferred encryption type. The array ends
- * with ETYPE_NULL. Note that some encryption types might be
- * disabled, so you need to check with krb5_enctype_valid() before
- * using the encryption type.
+ * most preferred to least preferred encryption type. Note that some
+ * encryption types might be disabled, so you need to check with
+ * krb5_enctype_valid() before using the encryption type.
+ *
+ * @return list of enctypes, terminated with ETYPE_NULL. Its a static
+ * array completed into the Kerberos library so the content doesn't
+ * need to be freed.
+ *
+ * @ingroup krb5
*/
const krb5_enctype * KRB5_LIB_FUNCTION
@@ -479,6 +564,19 @@ default_etypes(krb5_context context, krb5_enctype **etype)
return 0;
}
+/**
+ * Set the default encryption types that will be use in communcation
+ * with the KDC, clients and servers.
+ *
+ * @param context Kerberos 5 context.
+ * @param etypes Encryption types, array terminated with ETYPE_NULL (0).
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_default_in_tkt_etypes(krb5_context context,
const krb5_enctype *etypes)
@@ -507,6 +605,19 @@ krb5_set_default_in_tkt_etypes(krb5_context context,
return 0;
}
+/**
+ * Get the default encryption types that will be use in communcation
+ * with the KDC, clients and servers.
+ *
+ * @param context Kerberos 5 context.
+ * @param etypes Encryption types, array terminated with
+ * ETYPE_NULL(0), caller should free array with krb5_xfree():
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_default_in_tkt_etypes(krb5_context context,
@@ -534,6 +645,18 @@ krb5_get_default_in_tkt_etypes(krb5_context context,
return 0;
}
+/**
+ * Return the error string for the error code. The caller must not
+ * free the string.
+ *
+ * @param context Kerberos 5 context.
+ * @param code Kerberos error code.
+ *
+ * @return the error message matching code
+ *
+ * @ingroup krb5
+ */
+
const char* KRB5_LIB_FUNCTION
krb5_get_err_text(krb5_context context, krb5_error_code code)
{
@@ -547,6 +670,14 @@ krb5_get_err_text(krb5_context context, krb5_error_code code)
return p;
}
+/**
+ * Init the built-in ets in the Kerberos library.
+ *
+ * @param context kerberos context to add the ets too
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_init_ets(krb5_context context)
{
@@ -561,18 +692,50 @@ krb5_init_ets(krb5_context context)
}
}
+/**
+ * Make the kerberos library default to the admin KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param flag boolean flag to select if the use the admin KDC or not.
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
{
context->use_admin_kdc = flag;
}
+/**
+ * Make the kerberos library default to the admin KDC.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return boolean flag to telling the context will use admin KDC as the default KDC.
+ *
+ * @ingroup krb5
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_get_use_admin_kdc (krb5_context context)
{
return context->use_admin_kdc;
}
+/**
+ * Add extra address to the address list that the library will add to
+ * the client's address list when communicating with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to add
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
{
@@ -584,6 +747,19 @@ krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
return krb5_set_extra_addresses(context, addresses);
}
+/**
+ * Set extra address to the address list that the library will add to
+ * the client's address list when communicating with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to set
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
{
@@ -607,6 +783,19 @@ krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
return krb5_copy_addresses(context, addresses, context->extra_addresses);
}
+/**
+ * Get extra address to the address list that the library will add to
+ * the client's address list when communicating with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to set
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
{
@@ -617,6 +806,19 @@ krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
return krb5_copy_addresses(context,context->extra_addresses, addresses);
}
+/**
+ * Add extra addresses to ignore when fetching addresses from the
+ * underlaying operating system.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to ignore
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
{
@@ -628,6 +830,19 @@ krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
return krb5_set_ignore_addresses(context, addresses);
}
+/**
+ * Set extra addresses to ignore when fetching addresses from the
+ * underlaying operating system.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to ignore
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
{
@@ -650,6 +865,19 @@ krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
return krb5_copy_addresses(context, addresses, context->ignore_addresses);
}
+/**
+ * Get extra addresses to ignore when fetching addresses from the
+ * underlaying operating system.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses list addreses ignored
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
{
@@ -660,6 +888,18 @@ krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
return krb5_copy_addresses(context, context->ignore_addresses, addresses);
}
+/**
+ * Set version of fcache that the library should use.
+ *
+ * @param context Kerberos 5 context.
+ * @param version version number.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_fcache_version(krb5_context context, int version)
{
@@ -667,6 +907,18 @@ krb5_set_fcache_version(krb5_context context, int version)
return 0;
}
+/**
+ * Get version of fcache that the library should use.
+ *
+ * @param context Kerberos 5 context.
+ * @param version version number.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_fcache_version(krb5_context context, int *version)
{
@@ -674,6 +926,15 @@ krb5_get_fcache_version(krb5_context context, int *version)
return 0;
}
+/**
+ * Runtime check if the Kerberos library was complied with thread support.
+ *
+ * @return TRUE if the library was compiled with thread support, FALSE if not.
+ *
+ * @ingroup krb5
+ */
+
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_is_thread_safe(void)
{
@@ -684,18 +945,52 @@ krb5_is_thread_safe(void)
#endif
}
+/**
+ * Set if the library should use DNS to canonicalize hostnames.
+ *
+ * @param context Kerberos 5 context.
+ * @param flag if its dns canonicalizion is used or not.
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag)
{
- context->dns_canonicalize_hostname = flag;
+ if (flag)
+ context->flags |= KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
+ else
+ context->flags &= ~KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
}
+/**
+ * Get if the library uses DNS to canonicalize hostnames.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return return non zero if the library uses DNS to canonicalize hostnames.
+ *
+ * @ingroup krb5
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_get_dns_canonicalize_hostname (krb5_context context)
{
- return context->dns_canonicalize_hostname;
+ return (context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) ? 1 : 0;
}
+/**
+ * Get current offset in time to the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param sec seconds part of offset.
+ * @param usec micro seconds part of offset.
+ *
+ * @return return non zero if the library uses DNS to canonicalize hostnames.
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
{
@@ -706,12 +1001,31 @@ krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
return 0;
}
+/**
+ * Get max time skew allowed.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return timeskew in seconds.
+ *
+ * @ingroup krb5
+ */
+
time_t KRB5_LIB_FUNCTION
krb5_get_max_time_skew (krb5_context context)
{
return context->max_skew;
}
+/**
+ * Set max time skew allowed.
+ *
+ * @param context Kerberos 5 context.
+ * @param t timeskew in seconds.
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_set_max_time_skew (krb5_context context, time_t t)
{
diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c
index 1d1b4d7070..b2af0187ea 100644
--- a/source4/heimdal/lib/krb5/convert_creds.c
+++ b/source4/heimdal/lib/krb5/convert_creds.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: convert_creds.c 14897 2005-04-23 19:40:57Z lha $");
+RCSID("$Id: convert_creds.c 22050 2007-11-11 11:20:46Z lha $");
#include "krb5-v4compat.h"
@@ -42,10 +42,20 @@ check_ticket_flags(TicketFlags f)
return 0; /* maybe add some more tests here? */
}
-/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'.
- * This is done by sending them to the 524 function in the KDC. If
+/**
+ * Convert the v5 credentials in in_cred to v4-dito in v4creds. This
+ * is done by sending them to the 524 function in the KDC. If
* `in_cred' doesn't contain a DES session key, then a new one is
* gotten from the KDC and stored in the cred cache `ccache'.
+ *
+ * @param context Kerberos 5 context.
+ * @param in_cred the credential to convert
+ * @param v4creds the converted credential
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5_v4compat
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -134,6 +144,21 @@ out2:
return ret;
}
+/**
+ * Convert the v5 credentials in in_cred to v4-dito in v4creds,
+ * check the credential cache ccache before checking with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param ccache credential cache used to check for des-ticket.
+ * @param in_cred the credential to convert
+ * @param v4creds the converted credential
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5_v4compat
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb524_convert_creds_kdc_ccache(krb5_context context,
krb5_ccache ccache,
diff --git a/source4/heimdal/lib/krb5/copy_host_realm.c b/source4/heimdal/lib/krb5/copy_host_realm.c
index 4e668c2a14..8c4f39b4ac 100644
--- a/source4/heimdal/lib/krb5/copy_host_realm.c
+++ b/source4/heimdal/lib/krb5/copy_host_realm.c
@@ -33,10 +33,19 @@
#include "krb5_locl.h"
-RCSID("$Id: copy_host_realm.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: copy_host_realm.c 22057 2007-11-11 15:13:13Z lha $");
-/*
+/**
* Copy the list of realms from `from' to `to'.
+ *
+ * @param context Kerberos 5 context.
+ * @param from list of realms to copy from.
+ * @param to list of realms to copy to, free list of krb5_free_host_realm().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
*/
krb5_error_code KRB5_LIB_FUNCTION
diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c
index d4d83162f1..17ef46dfa3 100644
--- a/source4/heimdal/lib/krb5/creds.c
+++ b/source4/heimdal/lib/krb5/creds.c
@@ -33,15 +33,30 @@
#include "krb5_locl.h"
-RCSID("$Id: creds.c 15167 2005-05-18 04:21:57Z lha $");
+RCSID("$Id: creds.c 22062 2007-11-11 15:41:50Z lha $");
+
+#undef __attribute__
+#define __attribute__(X)
/* keep this for compatibility with older code */
-krb5_error_code KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION __attribute__((deprecated))
krb5_free_creds_contents (krb5_context context, krb5_creds *c)
{
return krb5_free_cred_contents (context, c);
}
+/**
+ * Free content of krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param c krb5_creds to free.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_cred_contents (krb5_context context, krb5_creds *c)
{
@@ -58,6 +73,19 @@ krb5_free_cred_contents (krb5_context context, krb5_creds *c)
return 0;
}
+/**
+ * Copy content of krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param incred source credential
+ * @param c destination credential, free with krb5_free_cred_contents().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_copy_creds_contents (krb5_context context,
const krb5_creds *incred,
@@ -102,6 +130,19 @@ fail:
return ret;
}
+/**
+ * Copy krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param incred source credential
+ * @param outcred destination credential, free with krb5_free_creds().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_copy_creds (krb5_context context,
const krb5_creds *incred,
@@ -119,6 +160,18 @@ krb5_copy_creds (krb5_context context,
return krb5_copy_creds_contents (context, incred, c);
}
+/**
+ * Free krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param c krb5_creds to free.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_creds (krb5_context context, krb5_creds *c)
{
@@ -127,15 +180,7 @@ krb5_free_creds (krb5_context context, krb5_creds *c)
return 0;
}
-/* XXX these do not belong here */
-static krb5_boolean
-krb5_data_equal(const krb5_data *a, const krb5_data *b)
-{
- if(a->length != b->length)
- return FALSE;
- return memcmp(a->data, b->data, a->length) == 0;
-}
-
+/* XXX this do not belong here */
static krb5_boolean
krb5_times_equal(const krb5_times *a, const krb5_times *b)
{
@@ -145,9 +190,18 @@ krb5_times_equal(const krb5_times *a, const krb5_times *b)
a->renew_till == b->renew_till;
}
-/*
+/**
* Return TRUE if `mcreds' and `creds' are equal (`whichfields'
* determines what equal means).
+ *
+ * @param context Kerberos 5 context.
+ * @param whichfields which fields to compare.
+ * @param mcreds cred to compare with.
+ * @param creds cred to compare with.
+ *
+ * @return return TRUE if mcred and creds are equal, FALSE if not.
+ *
+ * @ingroup krb5
*/
krb5_boolean KRB5_LIB_FUNCTION
@@ -201,11 +255,11 @@ krb5_compare_creds(krb5_context context, krb5_flags whichfields,
for(i = 0; match && i < mcreds->authdata.len; i++)
match = (mcreds->authdata.val[i].ad_type ==
creds->authdata.val[i].ad_type) &&
- krb5_data_equal(&mcreds->authdata.val[i].ad_data,
- &creds->authdata.val[i].ad_data);
+ (krb5_data_cmp(&mcreds->authdata.val[i].ad_data,
+ &creds->authdata.val[i].ad_data) == 0);
}
if (match && (whichfields & KRB5_TC_MATCH_2ND_TKT))
- match = krb5_data_equal(&mcreds->second_ticket, &creds->second_ticket);
+ match = (krb5_data_cmp(&mcreds->second_ticket, &creds->second_ticket) == 0);
if (match && (whichfields & KRB5_TC_MATCH_IS_SKEY))
match = ((mcreds->second_ticket.length == 0) ==
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 12f75d0bcd..2e63490946 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: crypto.c 21130 2007-06-18 20:45:21Z lha $");
+RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $");
#undef CRYPTO_DEBUG
#ifdef CRYPTO_DEBUG
@@ -184,7 +184,7 @@ krb5_DES_schedule(krb5_context context,
#ifdef ENABLE_AFS_STRING_TO_KEY
/* This defines the Andrew string_to_key function. It accepts a password
- * string as input and converts its via a one-way encryption algorithm to a DES
+ * string as input and converts it via a one-way encryption algorithm to a DES
* encryption key. It is compatible with the original Andrew authentication
* service password database.
*/
@@ -425,6 +425,7 @@ DES3_string_to_key(krb5_context context,
size_t len;
unsigned char tmp[24];
DES_cblock keys[3];
+ krb5_error_code ret;
len = password.length + salt.saltvalue.length;
str = malloc(len);
@@ -439,7 +440,13 @@ DES3_string_to_key(krb5_context context,
DES_key_schedule s[3];
int i;
- _krb5_n_fold(str, len, tmp, 24);
+ ret = _krb5_n_fold(str, len, tmp, 24);
+ if (ret) {
+ memset(str, 0, len);
+ free(str);
+ krb5_set_error_string(context, "out of memory");
+ return ret;
+ }
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
@@ -557,12 +564,14 @@ ARCFOUR_string_to_key(krb5_context context,
size_t len;
int i;
MD4_CTX m;
+ krb5_error_code ret;
len = 2 * password.length;
s = malloc (len);
if (len != 0 && s == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
+ ret = ENOMEM;
+ goto out;
}
for (p = s, i = 0; i < password.length; ++i) {
*p++ = ((char *)password.data)[i];
@@ -571,11 +580,17 @@ ARCFOUR_string_to_key(krb5_context context,
MD4_Init (&m);
MD4_Update (&m, s, len);
key->keytype = enctype;
- krb5_data_alloc (&key->keyvalue, 16);
+ ret = krb5_data_alloc (&key->keyvalue, 16);
+ if (ret) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ goto out;
+ }
MD4_Final (key->keyvalue.data, &m);
memset (s, 0, len);
+ ret = 0;
+out:
free (s);
- return 0;
+ return ret;
}
/*
@@ -1829,7 +1844,9 @@ create_checksum (krb5_context context,
} else
dkey = NULL;
result->cksumtype = ct->type;
- krb5_data_alloc(&result->checksum, ct->checksumsize);
+ ret = krb5_data_alloc(&result->checksum, ct->checksumsize);
+ if (ret)
+ return (ret);
(*ct->checksum)(context, dkey, data, len, usage, result);
return 0;
}
@@ -2751,6 +2768,7 @@ krb5_enctype_to_string(krb5_context context,
if(e == NULL) {
krb5_set_error_string (context, "encryption type %d not supported",
etype);
+ *string = NULL;
return KRB5_PROG_ETYPE_NOSUPP;
}
*string = strdup(e->name);
@@ -3525,15 +3543,19 @@ derive_key(krb5_context context,
ret = _key_schedule(context, key);
if(ret)
return ret;
- if(et->blocksize * 8 < kt->bits ||
- len != et->blocksize) {
+ if(et->blocksize * 8 < kt->bits || len != et->blocksize) {
nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
k = malloc(nblocks * et->blocksize);
if(k == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
}
- _krb5_n_fold(constant, len, k, et->blocksize);
+ ret = _krb5_n_fold(constant, len, k, et->blocksize);
+ if (ret) {
+ free(k);
+ krb5_set_error_string(context, "out of memory");
+ return ret;
+ }
for(i = 0; i < nblocks; i++) {
if(i > 0)
memcpy(k + i * et->blocksize,
@@ -3559,7 +3581,12 @@ derive_key(krb5_context context,
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
}
- _krb5_n_fold(c, len, k, res_len);
+ ret = _krb5_n_fold(c, len, k, res_len);
+ if (ret) {
+ free(k);
+ krb5_set_error_string(context, "out of memory");
+ return ret;
+ }
free(c);
}
@@ -3821,7 +3848,12 @@ krb5_string_to_key_derived(krb5_context context,
krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
- _krb5_n_fold(str, len, tmp, keylen);
+ ret = _krb5_n_fold(str, len, tmp, keylen);
+ if (ret) {
+ free(tmp);
+ krb5_set_error_string(context, "out of memory");
+ return ret;
+ }
kd.schedule = NULL;
DES3_postproc (context, tmp, keylen, &kd); /* XXX */
memset(tmp, 0, keylen);
@@ -4122,7 +4154,7 @@ main()
d = _new_derived_key(crypto, usage);
if(d == NULL)
- return ENOMEM;
+ krb5_errx(context, 1, "_new_derived_key failed");
krb5_copy_keyblock(context, crypto->key.key, &d->key);
_krb5_put_int(constant, usage, 4);
derive_key(context, crypto->et, d, constant, sizeof(constant));
@@ -4148,11 +4180,10 @@ main()
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */
key.keyvalue.length = 4;
- d = calloc(1, sizeof(*d));
-
+ d = ecalloc(1, sizeof(*d));
d->key = &key;
res.checksum.length = 20;
- res.checksum.data = malloc(res.checksum.length);
+ res.checksum.data = emalloc(res.checksum.length);
SP_HMAC_SHA1_checksum(context, d, data, 28, &res);
return 0;
diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c
index 2ece85bdb3..eda1a8b259 100644
--- a/source4/heimdal/lib/krb5/data.c
+++ b/source4/heimdal/lib/krb5/data.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,15 @@
#include "krb5_locl.h"
-RCSID("$Id: data.c 20039 2007-01-23 20:34:01Z lha $");
+RCSID("$Id: data.c 22064 2007-11-11 16:28:14Z lha $");
+
+/**
+ * Reset the (potentially uninitalized) krb5_data structure.
+ *
+ * @param p krb5_data to reset.
+ *
+ * @ingroup krb5
+ */
void KRB5_LIB_FUNCTION
krb5_data_zero(krb5_data *p)
@@ -42,6 +50,15 @@ krb5_data_zero(krb5_data *p)
p->data = NULL;
}
+/**
+ * Free the content of krb5_data structure, its ok to free a zeroed
+ * structure. When done, the structure will be zeroed.
+ *
+ * @param p krb5_data to free.
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_data_free(krb5_data *p)
{
@@ -50,12 +67,30 @@ krb5_data_free(krb5_data *p)
krb5_data_zero(p);
}
+/**
+ * Same as krb5_data_free().
+ *
+ * @param context Kerberos 5 context.
+ * @param data krb5_data to free.
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_free_data_contents(krb5_context context, krb5_data *data)
{
krb5_data_free(data);
}
+/**
+ * Free krb5_data (and its content).
+ *
+ * @param context Kerberos 5 context.
+ * @param p krb5_data to free.
+ *
+ * @ingroup krb5
+ */
+
void KRB5_LIB_FUNCTION
krb5_free_data(krb5_context context,
krb5_data *p)
@@ -64,6 +99,18 @@ krb5_free_data(krb5_context context,
free(p);
}
+/**
+ * Allocate data of and krb5_data.
+ *
+ * @param p krb5_data to free.
+ * @param len size to allocate.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_data_alloc(krb5_data *p, int len)
{
@@ -74,6 +121,18 @@ krb5_data_alloc(krb5_data *p, int len)
return 0;
}
+/**
+ * Grow (or shrink) the content of krb5_data to a new size.
+ *
+ * @param p krb5_data to free.
+ * @param len new size.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_data_realloc(krb5_data *p, int len)
{
@@ -86,6 +145,19 @@ krb5_data_realloc(krb5_data *p, int len)
return 0;
}
+/**
+ * Copy the data of len into the krb5_data.
+ *
+ * @param p krb5_data to copy into.
+ * @param data data to copy..
+ * @param len new size.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_data_copy(krb5_data *p, const void *data, size_t len)
{
@@ -99,6 +171,19 @@ krb5_data_copy(krb5_data *p, const void *data, size_t len)
return 0;
}
+/**
+ * Copy the data into a newly allocated krb5_data.
+ *
+ * @param context Kerberos 5 context.
+ * @param indata the krb5_data data to copy
+ * @param outdata new krb5_date to copy too. Free with krb5_free_data().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_copy_data(krb5_context context,
const krb5_data *indata,
@@ -119,6 +204,17 @@ krb5_copy_data(krb5_context context,
return ret;
}
+/**
+ * Compare to data.
+ *
+ * @param data1 krb5_data to compare
+ * @param data2 krb5_data to compare
+ *
+ * @return return the same way as memcmp(), useful when sorting.
+ *
+ * @ingroup krb5
+ */
+
int KRB5_LIB_FUNCTION
krb5_data_cmp(const krb5_data *data1, const krb5_data *data2)
{
diff --git a/source4/heimdal/lib/krb5/eai_to_heim_errno.c b/source4/heimdal/lib/krb5/eai_to_heim_errno.c
index c6b5cfb18b..19315cea86 100644
--- a/source4/heimdal/lib/krb5/eai_to_heim_errno.c
+++ b/source4/heimdal/lib/krb5/eai_to_heim_errno.c
@@ -33,12 +33,17 @@
#include <krb5_locl.h>
-RCSID("$Id: eai_to_heim_errno.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: eai_to_heim_errno.c 22065 2007-11-11 16:41:06Z lha $");
-/*
- * convert the getaddrinfo error code in `eai_errno' into a
- * krb5_error_code. `system_error' should have the value of the errno
- * after the failed call.
+/**
+ * Convert the getaddrinfo() error code to a Kerberos et error code.
+ *
+ * @param eai_errno contains the error code from getaddrinfo().
+ * @param system_error should have the value of errno after the failed getaddrinfo().
+ *
+ * @return Kerberos error code representing the EAI errors.
+ *
+ * @ingroup krb5_error
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -78,6 +83,17 @@ krb5_eai_to_heim_errno(int eai_errno, int system_error)
}
}
+/**
+ * Convert the gethostname() error code (h_error) to a Kerberos et
+ * error code.
+ *
+ * @param eai_errno contains the error code from gethostname().
+ *
+ * @return Kerberos error code representing the gethostname errors.
+ *
+ * @ingroup krb5_error
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_h_errno_to_heim_errno(int eai_errno)
{
diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c
index 1ba6494487..ff6e98a3dc 100644
--- a/source4/heimdal/lib/krb5/error_string.c
+++ b/source4/heimdal/lib/krb5/error_string.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: error_string.c 16746 2006-02-16 07:49:23Z lha $");
+RCSID("$Id: error_string.c 22142 2007-12-04 16:56:02Z lha $");
#undef __attribute__
#define __attribute__(X)
@@ -86,14 +86,26 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
return 0;
}
+/**
+ * Return the error message in context. On error or no error string,
+ * the function returns NULL.
+ *
+ * @param context Kerberos 5 context
+ *
+ * @return an error string, needs to be freed with
+ * krb5_free_error_string(). The functions return NULL on error.
+ *
+ * @ingroup krb5_error
+ */
+
char * KRB5_LIB_FUNCTION
krb5_get_error_string(krb5_context context)
{
- char *ret;
+ char *ret = NULL;
HEIMDAL_MUTEX_lock(context->mutex);
- ret = context->error_string;
- context->error_string = NULL;
+ if (context->error_string)
+ ret = strdup(context->error_string);
HEIMDAL_MUTEX_unlock(context->mutex);
return ret;
}
@@ -108,6 +120,19 @@ krb5_have_error_string(krb5_context context)
return str != NULL;
}
+/**
+ * Return the error message for `code' in context. On error the
+ * function returns NULL.
+ *
+ * @param context Kerberos 5 context
+ * @param code Error code related to the error
+ *
+ * @return an error string, needs to be freed with
+ * krb5_free_error_string(). The functions return NULL on error.
+ *
+ * @ingroup krb5_error
+ */
+
char * KRB5_LIB_FUNCTION
krb5_get_error_message(krb5_context context, krb5_error_code code)
{
diff --git a/source4/heimdal/lib/krb5/expand_hostname.c b/source4/heimdal/lib/krb5/expand_hostname.c
index b2b410269e..28e39afb42 100644
--- a/source4/heimdal/lib/krb5/expand_hostname.c
+++ b/source4/heimdal/lib/krb5/expand_hostname.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: expand_hostname.c 18906 2006-11-04 03:34:57Z lha $");
+RCSID("$Id: expand_hostname.c 22229 2007-12-08 21:40:59Z lha $");
static krb5_error_code
copy_hostname(krb5_context context,
@@ -62,7 +62,7 @@ krb5_expand_hostname (krb5_context context,
struct addrinfo *ai, *a, hints;
int error;
- if (!context->dns_canonicalize_hostname)
+ if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
return copy_hostname (context, orig_hostname, new_hostname);
memset (&hints, 0, sizeof(hints));
@@ -127,7 +127,7 @@ krb5_expand_hostname_realms (krb5_context context,
int error;
krb5_error_code ret = 0;
- if (!context->dns_canonicalize_hostname)
+ if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
return vanilla_hostname (context, orig_hostname, new_hostname,
realms);
diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c
index 864efa8d7d..484df059ab 100644
--- a/source4/heimdal/lib/krb5/fcache.c
+++ b/source4/heimdal/lib/krb5/fcache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: fcache.c 19379 2006-12-15 21:35:52Z lha $");
+RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $");
typedef struct krb5_fcache{
char *filename;
@@ -108,7 +108,7 @@ int
_krb5_xunlock(krb5_context context, int fd)
{
int ret;
-#ifdef HAVE_FCNTL_LOCK
+#ifdef HAVE_FCNTL
struct flock l;
l.l_start = 0;
l.l_len = 0;
@@ -463,9 +463,13 @@ init_fcc (krb5_context context,
krb5_storage_set_eof_code(sp, KRB5_CC_END);
ret = krb5_ret_int8(sp, &pvno);
if(ret != 0) {
- if(ret == KRB5_CC_END)
- ret = ENOENT; /* empty file */
- krb5_clear_error_string(context);
+ if(ret == KRB5_CC_END) {
+ krb5_set_error_string(context, "Empty credential cache file: %s",
+ FILENAME(id));
+ ret = ENOENT;
+ } else
+ krb5_set_error_string(context, "Error reading pvno in "
+ "cache file: %s", FILENAME(id));
goto out;
}
if(pvno != 5) {
@@ -476,7 +480,8 @@ init_fcc (krb5_context context,
}
ret = krb5_ret_int8(sp, &tag); /* should not be host byte order */
if(ret != 0) {
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading tag in "
+ "cache file: %s", FILENAME(id));
ret = KRB5_CC_FORMAT;
goto out;
}
@@ -489,7 +494,8 @@ init_fcc (krb5_context context,
ret = krb5_ret_int16 (sp, &length);
if(ret) {
ret = KRB5_CC_FORMAT;
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading tag length in "
+ "cache file: %s", FILENAME(id));
goto out;
}
while(length > 0) {
@@ -499,13 +505,15 @@ init_fcc (krb5_context context,
ret = krb5_ret_int16 (sp, &dtag);
if(ret) {
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading dtag in "
+ "cache file: %s", FILENAME(id));
ret = KRB5_CC_FORMAT;
goto out;
}
ret = krb5_ret_int16 (sp, &data_len);
if(ret) {
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading dlength in "
+ "cache file: %s", FILENAME(id));
ret = KRB5_CC_FORMAT;
goto out;
}
@@ -513,13 +521,15 @@ init_fcc (krb5_context context,
case FCC_TAG_DELTATIME :
ret = krb5_ret_int32 (sp, &context->kdc_sec_offset);
if(ret) {
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading kdc_sec in "
+ "cache file: %s", FILENAME(id));
ret = KRB5_CC_FORMAT;
goto out;
}
ret = krb5_ret_int32 (sp, &context->kdc_usec_offset);
if(ret) {
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading kdc_usec in "
+ "cache file: %s", FILENAME(id));
ret = KRB5_CC_FORMAT;
goto out;
}
@@ -528,7 +538,9 @@ init_fcc (krb5_context context,
for (i = 0; i < data_len; ++i) {
ret = krb5_ret_int8 (sp, &dummy);
if(ret) {
- krb5_clear_error_string(context);
+ krb5_set_error_string(context, "Error reading unknown "
+ "tag in cache file: %s",
+ FILENAME(id));
ret = KRB5_CC_FORMAT;
goto out;
}
@@ -755,6 +767,95 @@ fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
+static krb5_error_code
+fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+ krb5_error_code ret = 0;
+
+ ret = rename(FILENAME(from), FILENAME(to));
+ if (ret && errno != EXDEV) {
+ ret = errno;
+ krb5_set_error_string(context,
+ "Rename of file from %s to %s failed: %s",
+ FILENAME(from), FILENAME(to),
+ strerror(ret));
+ return ret;
+ } else if (ret && errno == EXDEV) {
+ /* make a copy and delete the orignal */
+ krb5_ssize_t sz1, sz2;
+ int fd1, fd2;
+ char buf[BUFSIZ];
+
+ ret = fcc_open(context, from, &fd1, O_RDONLY | O_BINARY, 0);
+ if(ret)
+ return ret;
+
+ unlink(FILENAME(to));
+
+ ret = fcc_open(context, to, &fd2,
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600);
+ if(ret)
+ goto out1;
+
+ while((sz1 = read(fd1, buf, sizeof(buf))) > 0) {
+ sz2 = write(fd2, buf, sz1);
+ if (sz1 != sz2) {
+ ret = EIO;
+ krb5_set_error_string(context,
+ "Failed to write data from one file "
+ "credential cache to the other");
+ goto out2;
+ }
+ }
+ if (sz1 < 0) {
+ ret = EIO;
+ krb5_set_error_string(context,
+ "Failed to read data from one file "
+ "credential cache to the other");
+ goto out2;
+ }
+ erase_file(FILENAME(from));
+
+ out2:
+ fcc_unlock(context, fd2);
+ close(fd2);
+
+ out1:
+ fcc_unlock(context, fd1);
+ close(fd1);
+
+ if (ret) {
+ erase_file(FILENAME(to));
+ return ret;
+ }
+ }
+
+ /* make sure ->version is uptodate */
+ {
+ krb5_storage *sp;
+ int fd;
+ ret = init_fcc (context, to, &sp, &fd);
+ krb5_storage_free(sp);
+ fcc_unlock(context, fd);
+ close(fd);
+ }
+ return ret;
+}
+
+static krb5_error_code
+fcc_default_name(krb5_context context, char **str)
+{
+ return _krb5_expand_default_cc_name(context,
+ KRB5_DEFAULT_CCNAME_FILE,
+ str);
+}
+
+/**
+ * Variable containing the FILE based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
const krb5_cc_ops krb5_fcc_ops = {
"FILE",
fcc_get_name,
@@ -774,5 +875,7 @@ const krb5_cc_ops krb5_fcc_ops = {
fcc_get_version,
fcc_get_cache_first,
fcc_get_cache_next,
- fcc_end_cache_get
+ fcc_end_cache_get,
+ fcc_move,
+ fcc_default_name
};
diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c
index 7c3f128ae5..fc78945c63 100644
--- a/source4/heimdal/lib/krb5/get_cred.c
+++ b/source4/heimdal/lib/krb5/get_cred.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: get_cred.c 21669 2007-07-22 11:29:13Z lha $");
+RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $");
/*
* Take the `body' and encode it into `padata' using the credentials
@@ -761,14 +761,6 @@ get_cred_from_kdc_flags(krb5_context context,
try_realm = krb5_config_get_string(context, NULL, "capaths",
client_realm, server_realm, NULL);
-
-#if 1
- /* XXX remove in future release */
- if(try_realm == NULL)
- try_realm = krb5_config_get_string(context, NULL, "libdefaults",
- "capath", server_realm, NULL);
-#endif
-
if (try_realm == NULL)
try_realm = client_realm;
diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c
index 1bb98737d1..cb8b7c8641 100644
--- a/source4/heimdal/lib/krb5/get_for_creds.c
+++ b/source4/heimdal/lib/krb5/get_for_creds.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: get_for_creds.c 17036 2006-04-10 09:28:15Z lha $");
+RCSID("$Id: get_for_creds.c 22504 2008-01-21 15:49:58Z lha $");
static krb5_error_code
add_addrs(krb5_context context,
@@ -83,11 +83,23 @@ fail:
return ret;
}
-/*
- * Forward credentials for `client' to host `hostname`,
- * making them forwardable if `forwardable', and returning the
- * blob of data to sent in `out_data'.
- * If hostname == NULL, pick it from `server'
+/**
+ * Forward credentials for client to host hostname , making them
+ * forwardable if forwardable, and returning the blob of data to sent
+ * in out_data. If hostname == NULL, pick it from server.
+ *
+ * @param context A kerberos 5 context.
+ * @param auth_context the auth context with the key to encrypt the out_data.
+ * @param hostname the host to forward the tickets too.
+ * @param client the client to delegate from.
+ * @param server the server to delegate the credential too.
+ * @param ccache credential cache to use.
+ * @param forwardable make the forwarded ticket forwabledable.
+ * @param out_data the resulting credential.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_credential
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -147,8 +159,31 @@ krb5_fwd_tgt_creds (krb5_context context,
return ret;
}
-/*
+/**
+ * Gets tickets forwarded to hostname. If the tickets that are
+ * forwarded are address-less, the forwarded tickets will also be
+ * address-less.
+ *
+ * If the ticket have any address, hostname will be used for figure
+ * out the address to forward the ticket too. This since this might
+ * use DNS, its insecure and also doesn't represent configured all
+ * addresses of the host. For example, the host might have two
+ * adresses, one IPv4 and one IPv6 address where the later is not
+ * published in DNS. This IPv6 address might be used communications
+ * and thus the resulting ticket useless.
*
+ * @param context A kerberos 5 context.
+ * @param auth_context the auth context with the key to encrypt the out_data.
+ * @param ccache credential cache to use
+ * @param flags the flags to control the resulting ticket flags
+ * @param hostname the host to forward the tickets too.
+ * @param in_creds the in client and server ticket names. The client
+ * and server components forwarded to the remote host.
+ * @param out_data the resulting credential.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_credential
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -174,39 +209,31 @@ krb5_get_forwarded_creds (krb5_context context,
struct addrinfo *ai;
int save_errno;
krb5_creds *ticket;
- char *realm;
-
- realm = in_creds->client->realm;
+ paddrs = NULL;
addrs.len = 0;
addrs.val = NULL;
- paddrs = &addrs;
- {
+ ret = krb5_get_credentials(context, 0, ccache, in_creds, &ticket);
+ if(ret == 0) {
+ if (ticket->addresses.len)
+ paddrs = &addrs;
+ krb5_free_creds (context, ticket);
+ } else {
krb5_boolean noaddr;
- krb5_appdefault_boolean(context, NULL, realm,
+ krb5_appdefault_boolean(context, NULL,
+ krb5_principal_get_realm(context,
+ in_creds->client),
"no-addresses", KRB5_ADDRESSLESS_DEFAULT,
&noaddr);
- if (noaddr)
- paddrs = NULL;
+ if (!noaddr)
+ paddrs = &addrs;
}
/*
- * If tickets are address-less, forward address-less tickets.
+ * If tickets have addresses, get the address of the remote host.
*/
- if (paddrs) {
- ret = _krb5_get_krbtgt (context,
- ccache,
- realm,
- &ticket);
- if(ret == 0) {
- if (ticket->addresses.len == 0)
- paddrs = NULL;
- krb5_free_creds (context, ticket);
- }
- }
-
if (paddrs != NULL) {
ret = getaddrinfo (hostname, NULL, NULL, &ai);
@@ -233,9 +260,8 @@ krb5_get_forwarded_creds (krb5_context context,
in_creds,
&out_creds);
krb5_free_addresses (context, &addrs);
- if (ret) {
+ if (ret)
return ret;
- }
memset (&cred, 0, sizeof(cred));
cred.pvno = 5;
@@ -373,6 +399,14 @@ krb5_get_forwarded_creds (krb5_context context,
if(buf_size != len)
krb5_abortx(context, "internal error in ASN.1 encoder");
+ /**
+ * Some older of the MIT gssapi library used clear-text tickets
+ * (warped inside AP-REQ encryption), use the krb5_auth_context
+ * flag KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED to support those
+ * tickets. The session key is used otherwise to encrypt the
+ * forwarded ticket.
+ */
+
if (auth_context->flags & KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED) {
cred.enc_part.etype = ENCTYPE_NULL;
cred.enc_part.kvno = NULL;
diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c
index ec106bb7ec..a9ed3857d0 100644
--- a/source4/heimdal/lib/krb5/get_in_tkt.c
+++ b/source4/heimdal/lib/krb5/get_in_tkt.c
@@ -145,7 +145,7 @@ _krb5_extract_ticket(krb5_context context,
flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
- ret = _krb5_principalname2krb5_principal (context,
+ ret = _krb5_principalname2krb5_principal (context,
&tmp_principal,
rep->kdc_rep.cname,
rep->kdc_rep.crealm);
diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c
index bd250cef2b..a59c903bd9 100644
--- a/source4/heimdal/lib/krb5/init_creds.c
+++ b/source4/heimdal/lib/krb5/init_creds.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: init_creds.c 21712 2007-07-27 14:23:41Z lha $");
+RCSID("$Id: init_creds.c 21711 2007-07-27 14:22:02Z lha $");
void KRB5_LIB_FUNCTION
krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index 0043b5ef3c..441adff8fd 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: init_creds_pw.c 21428 2007-07-10 12:31:58Z lha $");
+RCSID("$Id: init_creds_pw.c 21931 2007-08-27 14:11:55Z lha $");
typedef struct krb5_get_init_creds_ctx {
KDCOptions flags;
@@ -1547,9 +1547,15 @@ krb5_get_init_creds_password(krb5_context context,
char buf[BUFSIZ];
krb5_error_code ret;
- if (in_options == NULL)
+ if (in_options == NULL) {
+ const char *realm = krb5_principal_get_realm(context, client);
ret = krb5_get_init_creds_opt_alloc(context, &options);
- else
+ if (ret == 0)
+ krb5_get_init_creds_opt_set_default_flags(context,
+ NULL,
+ realm,
+ options);
+ } else
ret = _krb5_get_init_creds_opt_copy(context, in_options, &options);
if (ret)
return ret;
diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c
index c945a9ce13..8afaa6ea80 100644
--- a/source4/heimdal/lib/krb5/kcm.c
+++ b/source4/heimdal/lib/krb5/kcm.c
@@ -43,7 +43,7 @@
#include "kcm.h"
-RCSID("$Id: kcm.c 17442 2006-05-05 09:31:15Z lha $");
+RCSID("$Id: kcm.c 22108 2007-12-03 17:23:53Z lha $");
typedef struct krb5_kcmcache {
char *name;
@@ -829,6 +829,27 @@ kcm_get_version(krb5_context context,
return 0;
}
+static krb5_error_code
+kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+ krb5_set_error_string(context, "kcm_move not implemented");
+ return EINVAL;
+}
+
+static krb5_error_code
+kcm_default_name(krb5_context context, char **str)
+{
+ return _krb5_expand_default_cc_name(context,
+ KRB5_DEFAULT_CCNAME_KCM,
+ str);
+}
+
+/**
+ * Variable containing the KCM based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
const krb5_cc_ops krb5_kcm_ops = {
"KCM",
kcm_get_name,
@@ -845,7 +866,12 @@ const krb5_cc_ops krb5_kcm_ops = {
kcm_end_get,
kcm_remove_cred,
kcm_set_flags,
- kcm_get_version
+ kcm_get_version,
+ NULL,
+ NULL,
+ NULL,
+ kcm_move,
+ kcm_default_name
};
krb5_boolean
diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c
index f6c7858c12..79a3f20e79 100644
--- a/source4/heimdal/lib/krb5/keytab.c
+++ b/source4/heimdal/lib/krb5/keytab.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab.c 20211 2007-02-09 07:11:03Z lha $");
+RCSID("$Id: keytab.c 22532 2008-01-27 11:59:18Z lha $");
/*
* Register a new keytab in `ops'
@@ -337,8 +337,9 @@ krb5_kt_get_entry(krb5_context context,
ret = krb5_kt_start_seq_get (context, id, &cursor);
if (ret) {
- krb5_clear_error_string(context);
- return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */
+ /* This is needed for krb5_verify_init_creds, but keep error
+ * string from previous error for the human. */
+ return KRB5_KT_NOTFOUND;
}
entry->vno = 0;
diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c
index 4ada3a463e..be195d96c2 100644
--- a/source4/heimdal/lib/krb5/keytab_file.c
+++ b/source4/heimdal/lib/krb5/keytab_file.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_file.c 17457 2006-05-05 12:36:57Z lha $");
+RCSID("$Id: keytab_file.c 22532 2008-01-27 11:59:18Z lha $");
#define KRB5_KT_VNO_1 1
#define KRB5_KT_VNO_2 2
@@ -334,8 +334,8 @@ fkt_start_seq_get_int(krb5_context context,
c->fd = open (d->filename, flags);
if (c->fd < 0) {
ret = errno;
- krb5_set_error_string(context, "%s: %s", d->filename,
- strerror(ret));
+ krb5_set_error_string(context, "keytab %s open failed: %s",
+ d->filename, strerror(ret));
return ret;
}
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c
index 77455ba5f7..aa612add09 100644
--- a/source4/heimdal/lib/krb5/keytab_keyfile.c
+++ b/source4/heimdal/lib/krb5/keytab_keyfile.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_keyfile.c 20695 2007-05-30 14:09:09Z lha $");
+RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $");
/* afs keyfile operations --------------------------------------- */
@@ -197,8 +197,8 @@ akf_start_seq_get(krb5_context context,
c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600);
if (c->fd < 0) {
ret = errno;
- krb5_set_error_string(context, "open(%s): %s", d->filename,
- strerror(ret));
+ krb5_set_error_string(context, "keytab afs keyfil open %s failed: %s",
+ d->filename, strerror(ret));
return ret;
}
diff --git a/source4/heimdal/lib/krb5/keytab_krb4.c b/source4/heimdal/lib/krb5/keytab_krb4.c
index 907836c144..32bb00141a 100644
--- a/source4/heimdal/lib/krb5/keytab_krb4.c
+++ b/source4/heimdal/lib/krb5/keytab_krb4.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_krb4.c 17046 2006-04-10 17:10:53Z lha $");
+RCSID("$Id: keytab_krb4.c 22532 2008-01-27 11:59:18Z lha $");
struct krb4_kt_data {
char *filename;
@@ -134,14 +134,15 @@ krb4_kt_start_seq_get_int (krb5_context context,
if (c->fd < 0) {
ret = errno;
free (ed);
- krb5_set_error_string(context, "open(%s): %s", d->filename,
- strerror(ret));
+ krb5_set_error_string(context, "keytab krb5 open %s failed: %s",
+ d->filename, strerror(ret));
return ret;
}
c->sp = krb5_storage_from_fd(c->fd);
if(c->sp == NULL) {
close(c->fd);
free(ed);
+ krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
}
krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
@@ -369,8 +370,11 @@ krb4_kt_remove_entry(krb5_context context,
if(fd < 0) {
memset(data.data, 0, data.length);
krb5_data_free(&data);
- if(errno == EACCES || errno == EROFS)
+ if(errno == EACCES || errno == EROFS) {
+ krb5_set_error_string(context, "failed to open %s for writing",
+ d->filename);
return KRB5_KT_NOWRITE;
+ }
return errno;
}
@@ -378,14 +382,16 @@ krb4_kt_remove_entry(krb5_context context,
memset(data.data, 0, data.length);
krb5_data_free(&data);
close(fd);
- krb5_set_error_string(context, "failed writing to \"%s\"", d->filename);
+ krb5_set_error_string(context, "failed writing to file %s",
+ d->filename);
return errno;
}
memset(data.data, 0, data.length);
if(fstat(fd, &st) < 0) {
krb5_data_free(&data);
close(fd);
- krb5_set_error_string(context, "failed getting size of \"%s\"", d->filename);
+ krb5_set_error_string(context, "failed getting size of file %s",
+ d->filename);
return errno;
}
st.st_size -= data.length;
@@ -396,7 +402,8 @@ krb4_kt_remove_entry(krb5_context context,
if(n <= 0) {
krb5_data_free(&data);
close(fd);
- krb5_set_error_string(context, "failed writing to \"%s\"", d->filename);
+ krb5_set_error_string(context, "failed writing to file %s",
+ d->filename);
return errno;
}
@@ -405,17 +412,20 @@ krb4_kt_remove_entry(krb5_context context,
if(ftruncate(fd, data.length) < 0) {
krb5_data_free(&data);
close(fd);
- krb5_set_error_string(context, "failed truncating \"%s\"", d->filename);
+ krb5_set_error_string(context, "failed truncating file %s",
+ d->filename);
return errno;
}
krb5_data_free(&data);
if(close(fd) < 0) {
- krb5_set_error_string(context, "error closing \"%s\"", d->filename);
+ krb5_set_error_string(context, "error closing %s",
+ d->filename);
return errno;
}
return 0;
} else {
krb5_storage_free(sp);
+ krb5_set_error_string(context, "Keytab entry not found");
return KRB5_KT_NOTFOUND;
}
}
diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h
index 9a84dde61a..7e04446fe0 100644
--- a/source4/heimdal/lib/krb5/krb5-private.h
+++ b/source4/heimdal/lib/krb5/krb5-private.h
@@ -276,7 +276,7 @@ _krb5_mk_req_internal (
krb5_key_usage /*checksum_usage*/,
krb5_key_usage /*encrypt_usage*/);
-void KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
_krb5_n_fold (
const void */*str*/,
size_t /*len*/,
@@ -292,7 +292,7 @@ _krb5_oid_to_enctype (
krb5_error_code
_krb5_pac_sign (
krb5_context /*context*/,
- struct krb5_pac */*p*/,
+ krb5_pac /*p*/,
time_t /*authtime*/,
krb5_principal /*principal*/,
const krb5_keyblock */*server_key*/,
@@ -396,13 +396,6 @@ _krb5_plugin_get_next (struct krb5_plugin */*p*/);
void *
_krb5_plugin_get_symbol (struct krb5_plugin */*p*/);
-krb5_error_code
-_krb5_plugin_register (
- krb5_context /*context*/,
- enum krb5_plugin_type /*type*/,
- const char */*name*/,
- void */*symbol*/);
-
krb5_error_code KRB5_LIB_FUNCTION
_krb5_principal2principalname (
PrincipalName */*p*/,
diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h
index 740b394be8..647d8886b7 100644
--- a/source4/heimdal/lib/krb5/krb5-protos.h
+++ b/source4/heimdal/lib/krb5/krb5-protos.h
@@ -670,6 +670,12 @@ krb5_cc_initialize (
krb5_ccache /*id*/,
krb5_principal /*primary_principal*/);
+krb5_error_code
+krb5_cc_move (
+ krb5_context /*context*/,
+ krb5_ccache /*from*/,
+ krb5_ccache /*to*/);
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_cc_new_unique (
krb5_context /*context*/,
@@ -1329,6 +1335,13 @@ krb5_digest_init_request (
krb5_realm /*realm*/,
krb5_ccache /*ccache*/);
+krb5_error_code
+krb5_digest_probe (
+ krb5_context /*context*/,
+ krb5_realm /*realm*/,
+ krb5_ccache /*ccache*/,
+ unsigned */*flags*/);
+
krb5_boolean
krb5_digest_rep_get_status (
krb5_context /*context*/,
@@ -1606,6 +1619,9 @@ krb5_err (
...)
__attribute__ ((noreturn, format (printf, 4, 5)));
+krb5_error_code KRB5_LIB_FUNCTION
+ __attribute__((deprecated)) krb5_free_creds_contents (krb5_context context, krb5_creds *c);
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_error_from_rd_error (
krb5_context /*context*/,
@@ -1694,11 +1710,6 @@ krb5_free_creds (
krb5_context /*context*/,
krb5_creds */*c*/);
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_free_creds_contents (
- krb5_context /*context*/,
- krb5_creds */*c*/);
-
void KRB5_LIB_FUNCTION
krb5_free_data (
krb5_context /*context*/,
@@ -2244,6 +2255,14 @@ krb5_get_pw_salt (
krb5_salt */*salt*/);
krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_renewed_creds (
+ krb5_context /*context*/,
+ krb5_creds */*creds*/,
+ krb5_const_principal /*client*/,
+ krb5_ccache /*ccache*/,
+ const char */*in_tkt_service*/);
+
+krb5_error_code KRB5_LIB_FUNCTION
krb5_get_server_rcache (
krb5_context /*context*/,
const krb5_data */*piece*/,
@@ -2797,45 +2816,45 @@ krb5_openlog (
krb5_error_code
krb5_pac_add_buffer (
krb5_context /*context*/,
- struct krb5_pac */*p*/,
+ krb5_pac /*p*/,
uint32_t /*type*/,
const krb5_data */*data*/);
void
krb5_pac_free (
krb5_context /*context*/,
- struct krb5_pac */*pac*/);
+ krb5_pac /*pac*/);
krb5_error_code
krb5_pac_get_buffer (
krb5_context /*context*/,
- struct krb5_pac */*p*/,
+ krb5_pac /*p*/,
uint32_t /*type*/,
krb5_data */*data*/);
krb5_error_code
krb5_pac_get_types (
krb5_context /*context*/,
- struct krb5_pac */*p*/,
+ krb5_pac /*p*/,
size_t */*len*/,
uint32_t **/*types*/);
krb5_error_code
krb5_pac_init (
krb5_context /*context*/,
- struct krb5_pac **/*pac*/);
+ krb5_pac */*pac*/);
krb5_error_code
krb5_pac_parse (
krb5_context /*context*/,
const void */*ptr*/,
size_t /*len*/,
- struct krb5_pac **/*pac*/);
+ krb5_pac */*pac*/);
krb5_error_code
krb5_pac_verify (
krb5_context /*context*/,
- const struct krb5_pac */*pac*/,
+ const krb5_pac /*pac*/,
time_t /*authtime*/,
krb5_const_principal /*principal*/,
const krb5_keyblock */*server*/,
@@ -2887,6 +2906,13 @@ krb5_password_key_proc (
krb5_const_pointer /*keyseed*/,
krb5_keyblock **/*key*/);
+krb5_error_code
+krb5_plugin_register (
+ krb5_context /*context*/,
+ enum krb5_plugin_type /*type*/,
+ const char */*name*/,
+ void */*symbol*/);
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_prepend_config_files (
const char */*filelist*/,
diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h
index 4f9a63bf05..571eb6192a 100644
--- a/source4/heimdal/lib/krb5/krb5.h
+++ b/source4/heimdal/lib/krb5/krb5.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: krb5.h 21551 2007-07-15 09:03:39Z lha $ */
+/* $Id: krb5.h 22100 2007-12-03 17:15:00Z lha $ */
#ifndef __KRB5_H__
#define __KRB5_H__
@@ -75,15 +75,16 @@ typedef struct krb5_crypto_data *krb5_crypto;
struct krb5_get_creds_opt_data;
typedef struct krb5_get_creds_opt_data *krb5_get_creds_opt;
-struct krb5_digest;
-typedef struct krb5_digest *krb5_digest;
-struct krb5_ntlm;
-typedef struct krb5_ntlm *krb5_ntlm;
+struct krb5_digest_data;
+typedef struct krb5_digest_data *krb5_digest;
+struct krb5_ntlm_data;
+typedef struct krb5_ntlm_data *krb5_ntlm;
-typedef struct krb5_pac *krb5_pac;
+struct krb5_pac_data;
+typedef struct krb5_pac_data *krb5_pac;
-typedef struct krb5_rd_req_in_ctx *krb5_rd_req_in_ctx;
-typedef struct krb5_rd_req_out_ctx *krb5_rd_req_out_ctx;
+typedef struct krb5_rd_req_in_ctx_data *krb5_rd_req_in_ctx;
+typedef struct krb5_rd_req_out_ctx_data *krb5_rd_req_out_ctx;
typedef CKSUMTYPE krb5_cksumtype;
@@ -417,6 +418,8 @@ typedef struct krb5_cc_ops {
krb5_error_code (*get_cache_first)(krb5_context, krb5_cc_cursor *);
krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *);
krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor);
+ krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache);
+ krb5_error_code (*default_name)(krb5_context, char **);
} krb5_cc_ops;
struct krb5_log_facility;
@@ -753,7 +756,7 @@ enum {
KRB5_PRINCIPAL_UNPARSE_DISPLAY = 4
};
-typedef struct krb5_sendto_ctx *krb5_sendto_ctx;
+typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx;
#define KRB5_SENDTO_DONE 0
#define KRB5_SENDTO_RESTART 1
diff --git a/source4/heimdal/lib/krb5/krb5_ccapi.h b/source4/heimdal/lib/krb5/krb5_ccapi.h
index b53d77ef18..59a38425c2 100644
--- a/source4/heimdal/lib/krb5/krb5_ccapi.h
+++ b/source4/heimdal/lib/krb5/krb5_ccapi.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: krb5_ccapi.h 17442 2006-05-05 09:31:15Z lha $ */
+/* $Id: krb5_ccapi.h 22090 2007-12-02 23:23:43Z lha $ */
#ifndef KRB5_CCAPI_H
#define KRB5_CCAPI_H 1
@@ -180,18 +180,18 @@ typedef struct cc_ccache_functions {
cc_int32 (*destroy)(cc_ccache_t);
cc_int32 (*set_default)(cc_ccache_t);
cc_int32 (*get_credentials_version)(cc_ccache_t, cc_uint32*);
- cc_int32 (*get_name)(cc_ccache_t ccache,cc_string_t*);
+ cc_int32 (*get_name)(cc_ccache_t, cc_string_t*);
cc_int32 (*get_principal)(cc_ccache_t, cc_uint32, cc_string_t*);
cc_int32 (*set_principal)(cc_ccache_t, cc_uint32, const char*);
cc_int32 (*store_credentials)(cc_ccache_t, const cc_credentials_union*);
cc_int32 (*remove_credentials)(cc_ccache_t, cc_credentials_t);
cc_int32 (*new_credentials_iterator)(cc_ccache_t,
cc_credentials_iterator_t*);
- cc_int32 (*move)(cc_ccache_t source, cc_ccache_t);
+ cc_int32 (*move)(cc_ccache_t, cc_ccache_t);
cc_int32 (*lock)(cc_ccache_t, cc_uint32, cc_uint32);
cc_int32 (*unlock)(cc_ccache_t);
cc_int32 (*get_last_default_time)(cc_ccache_t, cc_time_t*);
- cc_int32 (*get_change_time)(cc_ccache_t ccache, cc_time_t*);
+ cc_int32 (*get_change_time)(cc_ccache_t, cc_time_t*);
cc_int32 (*compare)(cc_ccache_t, cc_ccache_t, cc_uint32*);
cc_int32 (*get_kdc_time_offset)(cc_ccache_t, cc_int32, cc_time_t *);
cc_int32 (*set_kdc_time_offset)(cc_ccache_t, cc_int32, cc_time_t);
diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h
index b41e6e1182..8b7c41cc80 100644
--- a/source4/heimdal/lib/krb5/krb5_locl.h
+++ b/source4/heimdal/lib/krb5/krb5_locl.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: krb5_locl.h 21552 2007-07-15 09:04:00Z lha $ */
+/* $Id: krb5_locl.h 22226 2007-12-08 21:31:53Z lha $ */
#ifndef __KRB5_LOCL_H__
#define __KRB5_LOCL_H__
@@ -231,14 +231,18 @@ typedef struct krb5_context_data {
krb5_addresses *ignore_addresses;
char *default_cc_name;
char *default_cc_name_env;
+ int default_cc_name_set;
void *mutex; /* protects error_string/error_buf */
int large_msg_size;
- int dns_canonicalize_hostname;
+ int flags;
+#define KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME 1
+#define KRB5_CTX_F_CHECK_PAC 2
struct send_to_kdc *send_to_kdc;
} krb5_context_data;
#define KRB5_DEFAULT_CCNAME_FILE "FILE:/tmp/krb5cc_%{uid}"
#define KRB5_DEFAULT_CCNAME_API "API:"
+#define KRB5_DEFAULT_CCNAME_KCM "KCM:%{uid}"
#define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH 1
#define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH 2
@@ -248,11 +252,11 @@ typedef struct krb5_context_data {
* Configurable options
*/
-#ifndef KRB5_DEFAULT_CCNAME
+#ifndef KRB5_DEFAULT_CCTYPE
#ifdef __APPLE__
-#define KRB5_DEFAULT_CCNAME KRB5_DEFAULT_CCNAME_API
+#define KRB5_DEFAULT_CCTYPE (&krb5_acc_ops)
#else
-#define KRB5_DEFAULT_CCNAME KRB5_DEFAULT_CCNAME_FILE
+#define KRB5_DEFAULT_CCTYPE (&krb5_fcc_ops)
#endif
#endif
diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c
index ff9261a7db..01bcb09d3b 100644
--- a/source4/heimdal/lib/krb5/mcache.c
+++ b/source4/heimdal/lib/krb5/mcache.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: mcache.c 19834 2007-01-11 09:26:21Z lha $");
+RCSID("$Id: mcache.c 22107 2007-12-03 17:22:51Z lha $");
typedef struct krb5_mcache {
char *name;
@@ -401,6 +401,57 @@ mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
+static krb5_error_code
+mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+ krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to);
+ struct link *creds;
+ krb5_principal principal;
+ krb5_mcache **n;
+
+ HEIMDAL_MUTEX_lock(&mcc_mutex);
+
+ /* drop the from cache from the linked list to avoid lookups */
+ for(n = &mcc_head; n && *n; n = &(*n)->next) {
+ if(mfrom == *n) {
+ *n = mfrom->next;
+ break;
+ }
+ }
+
+ /* swap creds */
+ creds = mto->creds;
+ mto->creds = mfrom->creds;
+ mfrom->creds = creds;
+ /* swap principal */
+ principal = mto->primary_principal;
+ mto->primary_principal = mfrom->primary_principal;
+ mfrom->primary_principal = principal;
+
+ HEIMDAL_MUTEX_unlock(&mcc_mutex);
+ mcc_destroy(context, from);
+
+ return 0;
+}
+
+static krb5_error_code
+mcc_default_name(krb5_context context, char **str)
+{
+ *str = strdup("MEMORY:");
+ if (*str == NULL) {
+ krb5_set_error_string(context, "out of memory");
+ return ENOMEM;
+ }
+ return 0;
+}
+
+
+/**
+ * Variable containing the MEMORY based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
const krb5_cc_ops krb5_mcc_ops = {
"MEMORY",
mcc_get_name,
@@ -420,5 +471,7 @@ const krb5_cc_ops krb5_mcc_ops = {
NULL,
mcc_get_cache_first,
mcc_get_cache_next,
- mcc_end_cache_get
+ mcc_end_cache_get,
+ mcc_move,
+ mcc_default_name
};
diff --git a/source4/heimdal/lib/krb5/n-fold.c b/source4/heimdal/lib/krb5/n-fold.c
index 1474a76b77..53528cfd1f 100644
--- a/source4/heimdal/lib/krb5/n-fold.c
+++ b/source4/heimdal/lib/krb5/n-fold.c
@@ -32,21 +32,23 @@
#include "krb5_locl.h"
-RCSID("$Id: n-fold.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: n-fold.c 22190 2007-12-06 16:24:22Z lha $");
-static void
+static krb5_error_code
rr13(unsigned char *buf, size_t len)
{
unsigned char *tmp;
int bytes = (len + 7) / 8;
int i;
if(len == 0)
- return;
+ return 0;
{
const int bits = 13 % len;
const int lbit = len % 8;
tmp = malloc(bytes);
+ if (tmp == NULL)
+ return ENOMEM;
memcpy(tmp, buf, bytes);
if(lbit) {
/* pad final byte with inital bits */
@@ -75,9 +77,10 @@ rr13(unsigned char *buf, size_t len)
}
free(tmp);
}
+ return 0;
}
-/* Add `b' to `a', both beeing one's complement numbers. */
+/* Add `b' to `a', both being one's complement numbers. */
static void
add1(unsigned char *a, unsigned char *b, size_t len)
{
@@ -95,22 +98,28 @@ add1(unsigned char *a, unsigned char *b, size_t len)
}
}
-void KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
_krb5_n_fold(const void *str, size_t len, void *key, size_t size)
{
/* if len < size we need at most N * len bytes, ie < 2 * size;
if len > size we need at most 2 * len */
+ krb5_error_code ret = 0;
size_t maxlen = 2 * max(size, len);
size_t l = 0;
unsigned char *tmp = malloc(maxlen);
unsigned char *buf = malloc(len);
+ if (tmp == NULL || buf == NULL)
+ return ENOMEM;
+
memcpy(buf, str, len);
memset(key, 0, size);
do {
memcpy(tmp + l, buf, len);
l += len;
- rr13(buf, len * 8);
+ ret = rr13(buf, len * 8);
+ if (ret)
+ goto out;
while(l >= size) {
add1(key, tmp, size);
l -= size;
@@ -119,8 +128,10 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
memmove(tmp, tmp + size, l);
}
} while(l != 0);
+out:
memset(buf, 0, len);
free(buf);
memset(tmp, 0, maxlen);
free(tmp);
+ return ret;
}
diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c
index f7a5e83ea3..0b44ca1da3 100644
--- a/source4/heimdal/lib/krb5/pac.c
+++ b/source4/heimdal/lib/krb5/pac.c
@@ -32,8 +32,9 @@
*/
#include "krb5_locl.h"
+#include <wind.h>
-RCSID("$Id: pac.c 21149 2007-06-18 21:50:22Z lha $");
+RCSID("$Id: pac.c 22562 2008-02-03 17:38:35Z lha $");
struct PAC_INFO_BUFFER {
uint32_t type;
@@ -48,7 +49,7 @@ struct PACTYPE {
struct PAC_INFO_BUFFER buffers[1];
};
-struct krb5_pac {
+struct krb5_pac_data {
struct PACTYPE *pac;
krb5_data data;
struct PAC_INFO_BUFFER *server_checksum;
@@ -82,10 +83,10 @@ static const char zeros[PAC_ALIGNMENT] = { 0 };
krb5_error_code
krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
- struct krb5_pac **pac)
+ krb5_pac *pac)
{
krb5_error_code ret;
- struct krb5_pac *p;
+ krb5_pac p;
krb5_storage *sp = NULL;
uint32_t i, tmp, tmp2, header_end;
@@ -216,10 +217,10 @@ out:
}
krb5_error_code
-krb5_pac_init(krb5_context context, struct krb5_pac **pac)
+krb5_pac_init(krb5_context context, krb5_pac *pac)
{
krb5_error_code ret;
- struct krb5_pac *p;
+ krb5_pac p;
p = calloc(1, sizeof(*p));
if (p == NULL) {
@@ -248,7 +249,7 @@ krb5_pac_init(krb5_context context, struct krb5_pac **pac)
}
krb5_error_code
-krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p,
+krb5_pac_add_buffer(krb5_context context, krb5_pac p,
uint32_t type, const krb5_data *data)
{
krb5_error_code ret;
@@ -316,7 +317,7 @@ krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p,
}
krb5_error_code
-krb5_pac_get_buffer(krb5_context context, struct krb5_pac *p,
+krb5_pac_get_buffer(krb5_context context, krb5_pac p,
uint32_t type, krb5_data *data)
{
krb5_error_code ret;
@@ -361,7 +362,7 @@ krb5_pac_get_buffer(krb5_context context, struct krb5_pac *p,
krb5_error_code
krb5_pac_get_types(krb5_context context,
- struct krb5_pac *p,
+ krb5_pac p,
size_t *len,
uint32_t **types)
{
@@ -385,7 +386,7 @@ krb5_pac_get_types(krb5_context context,
*/
void
-krb5_pac_free(krb5_context context, struct krb5_pac *pac)
+krb5_pac_free(krb5_context context, krb5_pac pac)
{
krb5_data_free(&pac->data);
free(pac->pac);
@@ -564,51 +565,48 @@ verify_logonname(krb5_context context,
ret = krb5_storage_read(sp, s, len);
if (ret != len) {
krb5_storage_free(sp);
- krb5_set_error_string(context, "Failed to read pac logon name");
+ krb5_set_error_string(context, "Failed to read PAC logon name");
return EINVAL;
}
krb5_storage_free(sp);
-#if 1 /* cheat for now */
- {
- size_t i;
-
- if (len & 1) {
- krb5_set_error_string(context, "PAC logon name malformed");
- return EINVAL;
- }
-
- for (i = 0; i < len / 2; i++) {
- if (s[(i * 2) + 1]) {
- krb5_set_error_string(context, "PAC logon name not ASCII");
- return EINVAL;
- }
- s[i] = s[i * 2];
- }
- s[i] = '\0';
- }
-#else
{
+ size_t ucs2len = len / 2;
uint16_t *ucs2;
- ssize_t ucs2len;
size_t u8len;
+ unsigned int flags = WIND_RW_LE;
- ucs2 = malloc(sizeof(ucs2[0]) * len / 2);
- if (ucs2)
- abort();
- ucs2len = wind_ucs2read(s, len / 2, ucs2);
+ ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
+ if (ucs2 == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len);
free(s);
- if (len < 0)
- return -1;
- ret = wind_ucs2toutf8(ucs2, ucs2len, NULL, &u8len);
- if (ret < 0)
- abort();
- s = malloc(u8len + 1);
- if (s == NULL)
- abort();
- wind_ucs2toutf8(ucs2, ucs2len, s, &u8len);
+ if (ret) {
+ free(ucs2);
+ krb5_set_error_string(context, "Failed to convert string to UCS-2");
+ return ret;
+ }
+ ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
+ if (ret) {
+ free(ucs2);
+ krb5_set_error_string(context, "Failed to count length of UCS-2 string");
+ return ret;
+ }
+ u8len += 1; /* Add space for NUL */
+ s = malloc(u8len);
+ if (s == NULL) {
+ free(ucs2);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
free(ucs2);
+ if (ret) {
+ krb5_set_error_string(context, "Failed to convert to UTF-8");
+ return ret;
+ }
}
-#endif
ret = krb5_parse_name_flags(context, s, KRB5_PRINCIPAL_PARSE_NO_REALM, &p2);
free(s);
if (ret)
@@ -703,7 +701,7 @@ out:
krb5_error_code
krb5_pac_verify(krb5_context context,
- const struct krb5_pac *pac,
+ const krb5_pac pac,
time_t authtime,
krb5_const_principal principal,
const krb5_keyblock *server,
@@ -840,7 +838,7 @@ pac_checksum(krb5_context context,
krb5_error_code
_krb5_pac_sign(krb5_context context,
- struct krb5_pac *p,
+ krb5_pac p,
time_t authtime,
krb5_principal principal,
const krb5_keyblock *server_key,
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index c8587770f4..4a585bff07 100755
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: pkinit.c 21684 2007-07-23 23:09:10Z lha $");
+RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $");
struct krb5_dh_moduli {
char *name;
@@ -139,17 +139,59 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f)
return bn;
}
+struct certfind {
+ const char *type;
+ const heim_oid *oid;
+};
+
+/*
+ * Try searchin the key by to use by first looking for for PK-INIT
+ * EKU, then the Microsoft smart card EKU and last, no special EKU at all.
+ */
static krb5_error_code
-_krb5_pk_create_sign(krb5_context context,
- const heim_oid *eContentType,
- krb5_data *eContent,
- struct krb5_pk_identity *id,
- hx509_peer_info peer,
- krb5_data *sd_data)
+find_cert(krb5_context context, struct krb5_pk_identity *id,
+ hx509_query *q, hx509_cert *cert)
{
- hx509_cert cert;
- hx509_query *q;
+ struct certfind cf[3] = {
+ { "PKINIT EKU" },
+ { "MS EKU" },
+ { "no" }
+ };
+ int i, ret;
+
+ cf[0].oid = oid_id_pkekuoid();
+ cf[1].oid = oid_id_pkinit_ms_eku();
+ cf[2].oid = NULL;
+
+ for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {
+ ret = hx509_query_match_eku(q, cf[i].oid);
+ if (ret) {
+ _krb5_pk_copy_error(context, id->hx509ctx, ret,
+ "Failed setting %s OID", cf[i].type);
+ return ret;
+ }
+
+ ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert);
+ if (ret == 0)
+ break;
+ _krb5_pk_copy_error(context, id->hx509ctx, ret,
+ "Failed cert for finding %s OID", cf[i].type);
+ }
+ return ret;
+}
+
+
+static krb5_error_code
+create_signature(krb5_context context,
+ const heim_oid *eContentType,
+ krb5_data *eContent,
+ struct krb5_pk_identity *id,
+ hx509_peer_info peer,
+ krb5_data *sd_data)
+{
+ hx509_cert cert = NULL;
+ hx509_query *q = NULL;
int ret;
ret = hx509_query_alloc(id->hx509ctx, &q);
@@ -162,13 +204,10 @@ _krb5_pk_create_sign(krb5_context context,
hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
- ret = hx509_certs_find(id->hx509ctx, id->certs, q, &cert);
+ ret = find_cert(context, id, q, &cert);
hx509_query_free(id->hx509ctx, q);
- if (ret) {
- _krb5_pk_copy_error(context, id->hx509ctx, ret,
- "Find certificate to signed CMS data");
+ if (ret)
return ret;
- }
ret = hx509_cms_create_signed_1(id->hx509ctx,
0,
@@ -181,11 +220,14 @@ _krb5_pk_create_sign(krb5_context context,
NULL,
id->certs,
sd_data);
- if (ret)
- _krb5_pk_copy_error(context, id->hx509ctx, ret, "create CMS signedData");
hx509_cert_free(cert);
+ if (ret) {
+ _krb5_pk_copy_error(context, id->hx509ctx, ret,
+ "Create CMS signedData");
+ return ret;
+ }
- return ret;
+ return 0;
}
static int
@@ -212,8 +254,7 @@ cert2epi(hx509_context context, void *ctx, hx509_cert c)
return ENOMEM;
}
- ret = hx509_name_to_der_name(subject, &id.subjectName->data,
- &id.subjectName->length);
+ ret = hx509_name_binary(subject, id.subjectName);
if (ret) {
hx509_name_free(&subject);
free_ExternalPrincipalIdentifier(&id);
@@ -544,12 +585,8 @@ pk_mk_padata(krb5_context context,
} else
krb5_abortx(context, "internal pkinit error");
- ret = _krb5_pk_create_sign(context,
- oid,
- &buf,
- ctx->id,
- ctx->peer,
- &sd_buf);
+ ret = create_signature(context, oid, &buf, ctx->id,
+ ctx->peer, &sd_buf);
krb5_data_free(&buf);
if (ret)
goto out;
@@ -878,7 +915,8 @@ pk_verify_host(krb5_context context,
hx509_octet_string_list list;
int i;
- ret = hx509_cert_find_subjectAltName_otherName(host->cert,
+ ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,
+ host->cert,
oid_id_pkinit_san(),
&list);
if (ret) {
diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c
index 43fa3f5b45..bae28496aa 100644
--- a/source4/heimdal/lib/krb5/plugin.c
+++ b/source4/heimdal/lib/krb5/plugin.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: plugin.c 21702 2007-07-26 19:13:53Z lha $");
+RCSID("$Id: plugin.c 22033 2007-11-10 10:39:47Z lha $");
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
@@ -117,11 +117,23 @@ loadlib(krb5_context context,
}
#endif /* HAVE_DLOPEN */
+/**
+ * Register a plugin symbol name of specific type.
+ * @param context a Keberos context
+ * @param type type of plugin symbol
+ * @param name name of plugin symbol
+ * @param symbol a pointer to the named symbol
+ * @return In case of error a non zero error com_err error is returned
+ * and the Kerberos error string is set.
+ *
+ * @ingroup krb5_support
+ */
+
krb5_error_code
-_krb5_plugin_register(krb5_context context,
- enum krb5_plugin_type type,
- const char *name,
- void *symbol)
+krb5_plugin_register(krb5_context context,
+ enum krb5_plugin_type type,
+ const char *name,
+ void *symbol)
{
struct plugin *e;
@@ -250,4 +262,3 @@ _krb5_plugin_free(struct krb5_plugin *list)
list = next;
}
}
-
diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c
index c1a29d266b..cdad477115 100644
--- a/source4/heimdal/lib/krb5/principal.c
+++ b/source4/heimdal/lib/krb5/principal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,6 +31,22 @@
* SUCH DAMAGE.
*/
+/**
+ * @page page_principal The principal handing functions.
+ *
+ * A Kerberos principal is a email address looking string that
+ * contains to parts separeted by a @. The later part is the kerbero
+ * realm the principal belongs to and the former is a list of 0 or
+ * more components. For example
+ * @verbatim
+lha@SU.SE
+host/hummel.it.su.se@SU.SE
+host/admin@H5L.ORG
+@endverbatim
+ *
+ * See the library functions here: @ref krb5_principal
+ */
+
#include "krb5_locl.h"
#ifdef HAVE_RES_SEARCH
#define USE_RESOLVER
@@ -41,7 +57,7 @@
#include <fnmatch.h>
#include "resolve.h"
-RCSID("$Id: principal.c 21285 2007-06-25 12:30:55Z lha $");
+RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $");
#define princ_num_comp(P) ((P)->name.name_string.len)
#define princ_type(P) ((P)->name.name_type)
@@ -49,6 +65,21 @@ RCSID("$Id: principal.c 21285 2007-06-25 12:30:55Z lha $");
#define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
#define princ_realm(P) ((P)->realm)
+/**
+ * Frees a Kerberos principal allocated by the library with
+ * krb5_parse_name(), krb5_make_principal() or any other related
+ * principal functions.
+ *
+ * @param context A Kerberos context.
+ * @param p a principal to free.
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
+
+
void KRB5_LIB_FUNCTION
krb5_free_principal(krb5_context context,
krb5_principal p)
@@ -804,7 +835,7 @@ krb5_425_conv_principal_ext2(krb5_context context,
char local_hostname[MAXHOSTNAMELEN];
/* do the following: if the name is found in the
- `v4_name_convert:host' part, is is assumed to be a `host' type
+ `v4_name_convert:host' part, is assumed to be a `host' type
principal, and the instance is looked up in the
`v4_instance_convert' part. if not found there the name is
(optionally) looked up as a hostname, and if that doesn't yield
diff --git a/source4/heimdal/lib/krb5/rd_priv.c b/source4/heimdal/lib/krb5/rd_priv.c
index 47b5df85b2..ed7a2ccc52 100644
--- a/source4/heimdal/lib/krb5/rd_priv.c
+++ b/source4/heimdal/lib/krb5/rd_priv.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: rd_priv.c 21770 2007-08-01 04:04:33Z lha $");
+RCSID("$Id: rd_priv.c 21751 2007-07-31 20:42:20Z lha $");
krb5_error_code KRB5_LIB_FUNCTION
krb5_rd_priv(krb5_context context,
diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c
index 001b47f094..0f33b97164 100644
--- a/source4/heimdal/lib/krb5/rd_req.c
+++ b/source4/heimdal/lib/krb5/rd_req.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: rd_req.c 21004 2007-06-08 01:53:10Z lha $");
+RCSID("$Id: rd_req.c 22235 2007-12-08 21:52:07Z lha $");
static krb5_error_code
decrypt_tkt_enc_part (krb5_context context,
@@ -137,7 +137,7 @@ check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc)
krb5_error_code ret;
/*
- * Windows 2000 and 2003 uses this inside their TGT so its normaly
+ * Windows 2000 and 2003 uses this inside their TGT so it's normaly
* not seen by others, however, samba4 joined with a Windows AD as
* a Domain Controller gets exposed to this.
*/
@@ -512,13 +512,13 @@ krb5_verify_ap_req2(krb5_context context,
*
*/
-struct krb5_rd_req_in_ctx {
+struct krb5_rd_req_in_ctx_data {
krb5_keytab keytab;
krb5_keyblock *keyblock;
- krb5_boolean no_pac_check;
+ krb5_boolean check_pac;
};
-struct krb5_rd_req_out_ctx {
+struct krb5_rd_req_out_ctx_data {
krb5_keyblock *keyblock;
krb5_flags ap_req_options;
krb5_ticket *ticket;
@@ -536,6 +536,7 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx)
krb5_set_error_string(context, "out of memory");
return ENOMEM;
}
+ (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0;
return 0;
}
@@ -548,12 +549,24 @@ krb5_rd_req_in_set_keytab(krb5_context context,
return 0;
}
+/**
+ * Set if krb5_rq_red() is going to check the Windows PAC or not
+ *
+ * @param context Keberos 5 context.
+ * @param in krb5_rd_req_in_ctx to check the option on.
+ * @param flag flag to select if to check the pac (TRUE) or not (FALSE).
+ *
+ * @return Kerberos 5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_rd_req_in_set_pac_check(krb5_context context,
krb5_rd_req_in_ctx in,
krb5_boolean flag)
{
- in->no_pac_check = !flag;
+ in->check_pac = flag;
return 0;
}
@@ -826,20 +839,21 @@ krb5_rd_req_ctx(krb5_context context,
goto out;
}
- ret = krb5_verify_ap_req(context,
- auth_context,
- &ap_req,
- server,
- o->keyblock,
- 0,
- &o->ap_req_options,
- &o->ticket);
+ ret = krb5_verify_ap_req2(context,
+ auth_context,
+ &ap_req,
+ server,
+ o->keyblock,
+ 0,
+ &o->ap_req_options,
+ &o->ticket,
+ KRB5_KU_AP_REQ_AUTH);
if (ret)
goto out;
/* If there is a PAC, verify its server signature */
- if (inctx->no_pac_check == FALSE) {
+ if (inctx->check_pac) {
krb5_pac pac;
krb5_data data;
diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c
index c1a4df2b01..2582a615c0 100644
--- a/source4/heimdal/lib/krb5/send_to_kdc.c
+++ b/source4/heimdal/lib/krb5/send_to_kdc.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: send_to_kdc.c 21062 2007-06-12 17:58:57Z lha $");
+RCSID("$Id: send_to_kdc.c 21934 2007-08-27 14:21:04Z lha $");
struct send_to_kdc {
krb5_send_to_kdc_func func;
@@ -448,7 +448,7 @@ krb5_set_send_to_kdc_func(krb5_context context,
return 0;
}
-struct krb5_sendto_ctx {
+struct krb5_sendto_ctx_data {
int flags;
int type;
krb5_sendto_ctx_func func;
diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c
index 4abcf44a43..c9cbbb5cef 100644
--- a/source4/heimdal/lib/krb5/store.c
+++ b/source4/heimdal/lib/krb5/store.c
@@ -34,7 +34,7 @@
#include "krb5_locl.h"
#include "store-int.h"
-RCSID("$Id: store.c 20529 2007-04-22 14:28:19Z lha $");
+RCSID("$Id: store.c 22071 2007-11-14 20:04:50Z lha $");
#define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
#define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
@@ -838,8 +838,8 @@ krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
if(ret) goto cleanup;
/*
* Runtime detect the what is the higher bits of the bitfield. If
- * any of the higher bits are set in the input data, its either a
- * new ticket flag (and this code need to be removed), or its a
+ * any of the higher bits are set in the input data, it's either a
+ * new ticket flag (and this code need to be removed), or it's a
* MIT cache (or new Heimdal cache), lets change it to our current
* format.
*/
@@ -993,8 +993,8 @@ krb5_ret_creds_tag(krb5_storage *sp,
if(ret) goto cleanup;
/*
* Runtime detect the what is the higher bits of the bitfield. If
- * any of the higher bits are set in the input data, its either a
- * new ticket flag (and this code need to be removed), or its a
+ * any of the higher bits are set in the input data, it's either a
+ * new ticket flag (and this code need to be removed), or it's a
* MIT cache (or new Heimdal cache), lets change it to our current
* format.
*/
diff --git a/source4/heimdal/lib/krb5/store_emem.c b/source4/heimdal/lib/krb5/store_emem.c
index 07acdd1a00..c38c1b53c3 100644
--- a/source4/heimdal/lib/krb5/store_emem.c
+++ b/source4/heimdal/lib/krb5/store_emem.c
@@ -34,7 +34,7 @@
#include "krb5_locl.h"
#include "store-int.h"
-RCSID("$Id: store_emem.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: store_emem.c 22574 2008-02-05 20:31:55Z lha $");
typedef struct emem_storage{
unsigned char *base;
@@ -115,13 +115,28 @@ emem_free(krb5_storage *sp)
krb5_storage * KRB5_LIB_FUNCTION
krb5_storage_emem(void)
{
- krb5_storage *sp = malloc(sizeof(krb5_storage));
- emem_storage *s = malloc(sizeof(*s));
+ krb5_storage *sp;
+ emem_storage *s;
+
+ sp = malloc(sizeof(krb5_storage));
+ if (sp == NULL)
+ return NULL;
+
+ s = malloc(sizeof(*s));
+ if (s == NULL) {
+ free(sp);
+ return NULL;
+ }
sp->data = s;
sp->flags = 0;
sp->eof_code = HEIM_ERR_EOF;
s->size = 1024;
s->base = malloc(s->size);
+ if (s->base == NULL) {
+ free(sp);
+ free(s);
+ return NULL;
+ }
s->len = 0;
s->ptr = s->base;
sp->fetch = emem_fetch;
diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c
index 7f5498f592..9b67ecc04f 100644
--- a/source4/heimdal/lib/krb5/transited.c
+++ b/source4/heimdal/lib/krb5/transited.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: transited.c 17043 2006-04-10 10:26:35Z lha $");
+RCSID("$Id: transited.c 21745 2007-07-31 16:11:25Z lha $");
/* this is an attempt at one of the most horrible `compression'
schemes that has ever been invented; it's so amazingly brain-dead
@@ -87,6 +87,10 @@ make_path(krb5_context context, struct tr_realm *r,
if(strcmp(p, to) == 0)
break;
tmp = calloc(1, sizeof(*tmp));
+ if(tmp == NULL){
+ krb5_set_error_string (context, "malloc: out of memory");
+ return ENOMEM;
+ }
tmp->next = path;
path = tmp;
path->realm = strdup(p);
@@ -107,6 +111,10 @@ make_path(krb5_context context, struct tr_realm *r,
if(strncmp(to, from, p - from) == 0)
break;
tmp = calloc(1, sizeof(*tmp));
+ if(tmp == NULL){
+ krb5_set_error_string (context, "malloc: out of memory");
+ return ENOMEM;
+ }
tmp->next = path;
path = tmp;
path->realm = malloc(p - from + 1);
@@ -277,6 +285,10 @@ decode_realms(krb5_context context,
}
if(tr[i] == ','){
tmp = malloc(tr + i - start + 1);
+ if(tmp == NULL){
+ krb5_set_error_string (context, "malloc: out of memory");
+ return ENOMEM;
+ }
memcpy(tmp, start, tr + i - start);
tmp[tr + i - start] = '\0';
r = make_realm(tmp);
@@ -290,6 +302,11 @@ decode_realms(krb5_context context,
}
}
tmp = malloc(tr + i - start + 1);
+ if(tmp == NULL){
+ free(*realms);
+ krb5_set_error_string (context, "malloc: out of memory");
+ return ENOMEM;
+ }
memcpy(tmp, start, tr + i - start);
tmp[tr + i - start] = '\0';
r = make_realm(tmp);
diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c
index 3f99df6391..37b1e35dd1 100644
--- a/source4/heimdal/lib/krb5/v4_glue.c
+++ b/source4/heimdal/lib/krb5/v4_glue.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: v4_glue.c 21572 2007-07-16 05:13:08Z lha $");
+RCSID("$Id: v4_glue.c 22071 2007-11-14 20:04:50Z lha $");
#include "krb5-v4compat.h"
@@ -599,7 +599,7 @@ _krb5_krb_cr_err_reply(krb5_context context,
RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error);
RCHECK(ret, put_nir(sp, name, inst, realm), error);
RCHECK(ret, krb5_store_int32(sp, time_ws), error);
- /* If its a Kerberos 4 error-code, remove the et BASE */
+ /* If it is a Kerberos 4 error-code, remove the et BASE */
if (e >= ERROR_TABLE_BASE_krb && e <= ERROR_TABLE_BASE_krb + 255)
e -= ERROR_TABLE_BASE_krb;
RCHECK(ret, krb5_store_int32(sp, e), error);
diff --git a/source4/heimdal/lib/ntlm/heimntlm-protos.h b/source4/heimdal/lib/ntlm/heimntlm-protos.h
index 438ba2b94d..bc64791b43 100644
--- a/source4/heimdal/lib/ntlm/heimntlm-protos.h
+++ b/source4/heimdal/lib/ntlm/heimntlm-protos.h
@@ -43,7 +43,7 @@ heim_ntlm_calculate_ntlm2_sess (
int
heim_ntlm_decode_targetinfo (
- struct ntlm_buf */*data*/,
+ const struct ntlm_buf */*data*/,
int /*ucs2*/,
struct ntlm_targetinfo */*ti*/);
@@ -65,7 +65,7 @@ heim_ntlm_decode_type3 (
int
heim_ntlm_encode_targetinfo (
- struct ntlm_targetinfo */*ti*/,
+ const struct ntlm_targetinfo */*ti*/,
int /*ucs2*/,
struct ntlm_buf */*data*/);
@@ -76,15 +76,18 @@ heim_ntlm_encode_type1 (
int
heim_ntlm_encode_type2 (
- struct ntlm_type2 */*type2*/,
+ const struct ntlm_type2 */*type2*/,
struct ntlm_buf */*data*/);
int
heim_ntlm_encode_type3 (
- struct ntlm_type3 */*type3*/,
+ const struct ntlm_type3 */*type3*/,
struct ntlm_buf */*data*/);
void
+heim_ntlm_free_buf (struct ntlm_buf */*p*/);
+
+void
heim_ntlm_free_targetinfo (struct ntlm_targetinfo */*ti*/);
void
diff --git a/source4/heimdal/lib/ntlm/heimntlm.h b/source4/heimdal/lib/ntlm/heimntlm.h
index 1c1afe1eb1..09d2205fd2 100644
--- a/source4/heimdal/lib/ntlm/heimntlm.h
+++ b/source4/heimdal/lib/ntlm/heimntlm.h
@@ -31,17 +31,22 @@
* SUCH DAMAGE.
*/
-/* $Id: heimntlm.h 19469 2006-12-20 07:28:37Z lha $ */
+/* $Id: heimntlm.h 22376 2007-12-28 18:38:23Z lha $ */
#ifndef HEIM_NTLM_H
#define HEIM_NTLM_H
+/**
+ * Buffer for storing data in the NTLM library. When filled in by the
+ * library it should be freed with heim_ntlm_free_buf().
+ */
struct ntlm_buf {
- size_t length;
- void *data;
+ size_t length; /**< length buffer data */
+ void *data; /**< pointer to the data itself */
};
#define NTLM_NEG_UNICODE 0x00000001
+#define NTLM_NEG_TARGET 0x00000004
#define NTLM_NEG_SIGN 0x00000010
#define NTLM_NEG_SEAL 0x00000020
#define NTLM_NEG_NTLM 0x00000200
@@ -52,42 +57,66 @@ struct ntlm_buf {
#define NTLM_NEG_ALWAYS_SIGN 0x00008000
#define NTLM_NEG_NTLM2_SESSION 0x00080000
-#define NTLM_NEG_TARGET_DOMAIN 0x00010000
+#define NTLM_TARGET_DOMAIN 0x00010000
+#define NTLM_TARGET_SERVER 0x00020000
#define NTLM_ENC_128 0x20000000
#define NTLM_NEG_KEYEX 0x40000000
+/**
+ * Struct for the NTLM target info, the strings is assumed to be in
+ * UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_targetinfo().
+ */
struct ntlm_targetinfo {
- char *servername;
- char *domainname;
- char *dnsdomainname;
- char *dnsservername;
+ char *servername; /**< */
+ char *domainname; /**< */
+ char *dnsdomainname; /**< */
+ char *dnsservername; /**< */
};
+/**
+ * Struct for the NTLM type1 message info, the strings is assumed to
+ * be in UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_type1().
+ */
+
struct ntlm_type1 {
- uint32_t flags;
- char *domain;
- char *hostname;
- uint32_t os[2];
+ uint32_t flags; /**< */
+ char *domain; /**< */
+ char *hostname; /**< */
+ uint32_t os[2]; /**< */
};
+/**
+ * Struct for the NTLM type2 message info, the strings is assumed to
+ * be in UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_type2().
+ */
+
struct ntlm_type2 {
- uint32_t flags;
- char *targetname;
- struct ntlm_buf targetinfo;
- unsigned char challange[8];
- uint32_t context[2];
- uint32_t os[2];
+ uint32_t flags; /**< */
+ char *targetname; /**< */
+ struct ntlm_buf targetinfo; /**< */
+ unsigned char challange[8]; /**< */
+ uint32_t context[2]; /**< */
+ uint32_t os[2]; /**< */
};
+/**
+ * Struct for the NTLM type3 message info, the strings is assumed to
+ * be in UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_type3().
+ */
+
struct ntlm_type3 {
- uint32_t flags;
- char *username;
- char *targetname;
- struct ntlm_buf lm;
- struct ntlm_buf ntlm;
- struct ntlm_buf sessionkey;
- char *ws;
- uint32_t os[2];
+ uint32_t flags; /**< */
+ char *username; /**< */
+ char *targetname; /**< */
+ struct ntlm_buf lm; /**< */
+ struct ntlm_buf ntlm; /**< */
+ struct ntlm_buf sessionkey; /**< */
+ char *ws; /**< */
+ uint32_t os[2]; /**< */
};
#include <heimntlm-protos.h>
diff --git a/source4/heimdal/lib/ntlm/ntlm.c b/source4/heimdal/lib/ntlm/ntlm.c
index 671bf329e8..f3dccfaca1 100644
--- a/source4/heimdal/lib/ntlm/ntlm.c
+++ b/source4/heimdal/lib/ntlm/ntlm.c
@@ -33,7 +33,7 @@
#include <config.h>
-RCSID("$Id: ntlm.c 21604 2007-07-17 06:48:55Z lha $");
+RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $");
#include <stdio.h>
#include <stdlib.h>
@@ -51,12 +51,37 @@ RCSID("$Id: ntlm.c 21604 2007-07-17 06:48:55Z lha $");
#include <heimntlm.h>
-
-/*
- * Source of NTLM information:
- * http://davenport.sourceforge.net/ntlm.html
+/*! \mainpage Heimdal NTLM library
+ *
+ * \section intro Introduction
+ *
+ * Heimdal libheimntlm library is a implementation of the NTLM
+ * protocol, both version 1 and 2. The GSS-API mech that uses this
+ * library adds support for transport encryption and integrity
+ * checking.
+ *
+ * NTLM is a protocol for mutual authentication, its still used in
+ * many protocol where Kerberos is not support, one example is
+ * EAP/X802.1x mechanism LEAP from Microsoft and Cisco.
+ *
+ * This is a support library for the core protocol, its used in
+ * Heimdal to implement and GSS-API mechanism. There is also support
+ * in the KDC to do remote digest authenticiation, this to allow
+ * services to authenticate users w/o direct access to the users ntlm
+ * hashes (same as Kerberos arcfour enctype hashes).
+ *
+ * More information about the NTLM protocol can found here
+ * http://davenport.sourceforge.net/ntlm.html .
+ *
+ * The Heimdal projects web page: http://www.h5l.org/
*/
+/** @defgroup ntlm_core Heimdal NTLM library
+ *
+ * The NTLM core functions implement the string2key generation
+ * function, message encode and decode function, and the hash function
+ * functions.
+ */
struct sec_buffer {
uint16_t length;
@@ -73,8 +98,16 @@ static const unsigned char ntlmsigature[8] = "NTLMSSP\x00";
#define CHECK(f, e) \
do { ret = f ; if (ret != (e)) { ret = EINVAL; goto out; } } while(0)
-static void
-_ntlm_free_buf(struct ntlm_buf *p)
+/**
+ * heim_ntlm_free_buf frees the ntlm buffer
+ *
+ * @param p buffer to be freed
+ *
+ * @ingroup ntlm_core
+ */
+
+void
+heim_ntlm_free_buf(struct ntlm_buf *p)
{
if (p->data)
free(p->data);
@@ -96,7 +129,7 @@ ascii2ucs2le(const char *string, int up, struct ntlm_buf *buf)
buf->length = len * 2;
buf->data = malloc(buf->length);
if (buf->data == NULL && len != 0) {
- _ntlm_free_buf(buf);
+ heim_ntlm_free_buf(buf);
return ENOMEM;
}
@@ -104,7 +137,7 @@ ascii2ucs2le(const char *string, int up, struct ntlm_buf *buf)
for (i = 0; i < len; i++) {
unsigned char t = (unsigned char)string[i];
if (t & 0x80) {
- _ntlm_free_buf(buf);
+ heim_ntlm_free_buf(buf);
return EINVAL;
}
if (up)
@@ -201,7 +234,7 @@ put_string(krb5_storage *sp, int ucs2, const char *s)
CHECK(krb5_storage_write(sp, buf.data, buf.length), buf.length);
if (ucs2)
- _ntlm_free_buf(&buf);
+ heim_ntlm_free_buf(&buf);
ret = 0;
out:
return ret;
@@ -226,7 +259,7 @@ out:
}
static krb5_error_code
-put_buf(krb5_storage *sp, struct ntlm_buf *buf)
+put_buf(krb5_storage *sp, const struct ntlm_buf *buf)
{
krb5_error_code ret;
CHECK(krb5_storage_write(sp, buf->data, buf->length), buf->length);
@@ -235,8 +268,12 @@ out:
return ret;
}
-/*
+/**
+ * Frees the ntlm_targetinfo message
+ *
+ * @param ti targetinfo to be freed
*
+ * @ingroup ntlm_core
*/
void
@@ -260,8 +297,22 @@ out:
return ret;
}
+/**
+ * Encodes a ntlm_targetinfo message.
+ *
+ * @param ti the ntlm_targetinfo message to encode.
+ * @param ucs2 if the strings should be encoded with ucs2 (selected by flag in message).
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_encode_targetinfo(struct ntlm_targetinfo *ti,
+heim_ntlm_encode_targetinfo(const struct ntlm_targetinfo *ti,
int ucs2,
struct ntlm_buf *data)
{
@@ -299,16 +350,34 @@ out:
return ret;
}
+/**
+ * Decodes an NTLM targetinfo message
+ *
+ * @param data input data buffer with the encode NTLM targetinfo message
+ * @param ucs2 if the strings should be encoded with ucs2 (selected by flag in message).
+ * @param ti the decoded target info, should be freed with heim_ntlm_free_targetinfo().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_decode_targetinfo(struct ntlm_buf *data, int ucs2,
+heim_ntlm_decode_targetinfo(const struct ntlm_buf *data,
+ int ucs2,
struct ntlm_targetinfo *ti)
{
memset(ti, 0, sizeof(*ti));
return 0;
}
-/*
- * encoder/decoder type1 messages
+/**
+ * Frees the ntlm_type1 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
@@ -367,6 +436,19 @@ out:
return ret;
}
+/**
+ * Encodes an ntlm_type1 message.
+ *
+ * @param type1 the ntlm_type1 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
heim_ntlm_encode_type1(const struct ntlm_type1 *type1, struct ntlm_buf *data)
{
@@ -435,8 +517,12 @@ out:
return ret;
}
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type2 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
@@ -444,7 +530,7 @@ heim_ntlm_free_type2(struct ntlm_type2 *data)
{
if (data->targetname)
free(data->targetname);
- _ntlm_free_buf(&data->targetinfo);
+ heim_ntlm_free_buf(&data->targetinfo);
memset(data, 0, sizeof(*data));
}
@@ -499,8 +585,21 @@ out:
return ret;
}
+/**
+ * Encodes an ntlm_type2 message.
+ *
+ * @param type2 the ntlm_type2 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_encode_type2(struct ntlm_type2 *type2, struct ntlm_buf *data)
+heim_ntlm_encode_type2(const struct ntlm_type2 *type2, struct ntlm_buf *data)
{
struct sec_buffer targetname, targetinfo;
krb5_error_code ret;
@@ -562,22 +661,26 @@ out:
return ret;
}
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type3 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
heim_ntlm_free_type3(struct ntlm_type3 *data)
{
- _ntlm_free_buf(&data->lm);
- _ntlm_free_buf(&data->ntlm);
+ heim_ntlm_free_buf(&data->lm);
+ heim_ntlm_free_buf(&data->ntlm);
if (data->targetname)
free(data->targetname);
if (data->username)
free(data->username);
if (data->ws)
free(data->ws);
- _ntlm_free_buf(&data->sessionkey);
+ heim_ntlm_free_buf(&data->sessionkey);
memset(data, 0, sizeof(*data));
}
@@ -629,7 +732,7 @@ heim_ntlm_decode_type3(const struct ntlm_buf *buf,
CHECK(ret_buf(in, &ntlm, &type3->ntlm), 0);
CHECK(ret_string(in, ucs2, &target, &type3->targetname), 0);
CHECK(ret_string(in, ucs2, &username, &type3->username), 0);
- CHECK(ret_string(in, ucs2, &username, &type3->ws), 0);
+ CHECK(ret_string(in, ucs2, &ws, &type3->ws), 0);
if (sessionkey.offset)
CHECK(ret_buf(in, &sessionkey, &type3->sessionkey), 0);
@@ -641,8 +744,21 @@ out:
return ret;
}
+/**
+ * Encodes an ntlm_type3 message.
+ *
+ * @param type3 the ntlm_type3 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_encode_type3(struct ntlm_type3 *type3, struct ntlm_buf *data)
+heim_ntlm_encode_type3(const struct ntlm_type3 *type3, struct ntlm_buf *data)
{
struct sec_buffer lm, ntlm, target, username, sessionkey, ws;
krb5_error_code ret;
@@ -766,8 +882,16 @@ splitandenc(unsigned char *hash,
memset(key, 0, sizeof(key));
}
-/*
- * String-to-key function for NTLM
+/**
+ * Calculate the NTLM key, the password is assumed to be in UTF8.
+ *
+ * @param password password to calcute the key for.
+ * @param key calcuted key, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -784,18 +908,28 @@ heim_ntlm_nt_key(const char *password, struct ntlm_buf *key)
ret = ascii2ucs2le(password, 0, &buf);
if (ret) {
- _ntlm_free_buf(key);
+ heim_ntlm_free_buf(key);
return ret;
}
MD4_Init(&ctx);
MD4_Update(&ctx, buf.data, buf.length);
MD4_Final(key->data, &ctx);
- _ntlm_free_buf(&buf);
+ heim_ntlm_free_buf(&buf);
return 0;
}
-/*
+/**
* Calculate NTLMv1 response hash
+ *
+ * @param key the ntlm v1 key
+ * @param len length of key
+ * @param challange sent by the server
+ * @param answer calculated answer, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -823,8 +957,18 @@ heim_ntlm_calculate_ntlm1(void *key, size_t len,
return 0;
}
-/*
- * Calculate NTLMv1 master key
+/**
+ * Generates an NTLMv1 session random with assosited session master key.
+ *
+ * @param key the ntlm v1 key
+ * @param len length of key
+ * @param session generated session nonce, should be freed with heim_ntlm_free_buf().
+ * @param master calculated session master key, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -849,8 +993,8 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
master->length = MD4_DIGEST_LENGTH;
master->data = malloc(master->length);
if (master->data == NULL) {
- _ntlm_free_buf(master);
- _ntlm_free_buf(session);
+ heim_ntlm_free_buf(master);
+ heim_ntlm_free_buf(session);
return EINVAL;
}
@@ -866,8 +1010,8 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
}
if (RAND_bytes(session->data, session->length) != 1) {
- _ntlm_free_buf(master);
- _ntlm_free_buf(session);
+ heim_ntlm_free_buf(master);
+ heim_ntlm_free_buf(session);
return EINVAL;
}
@@ -877,8 +1021,16 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
return 0;
}
-/*
+/**
+ * Generates an NTLMv2 session key.
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param ntlmv2 the ntlmv2 session key
*
+ * @ingroup ntlm_core
*/
void
@@ -932,8 +1084,22 @@ nt2unixtime(uint64_t t)
}
-/*
+/**
* Calculate NTLMv2 response
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param serverchallange challange as sent by the server in the type2 message.
+ * @param infotarget infotarget as sent by the server in the type2 message.
+ * @param ntlmv2 calculated session key
+ * @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -1020,8 +1186,23 @@ out:
static const int authtimediff = 3600 * 2; /* 2 hours */
-/*
+/**
* Verify NTLMv2 response.
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param now the time now (0 if the library should pick it up itself)
+ * @param serverchallange challange as sent by the server in the type2 message.
+ * @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
+ * @param infotarget infotarget as sent by the server in the type2 message.
+ * @param ntlmv2 calculated session key
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -1110,13 +1291,13 @@ heim_ntlm_verify_ntlm2(const void *key, size_t len,
HMAC_CTX_cleanup(&c);
if (memcmp(serveranswer, clientanswer, 16) != 0) {
- _ntlm_free_buf(infotarget);
+ heim_ntlm_free_buf(infotarget);
return EINVAL;
}
return 0;
out:
- _ntlm_free_buf(infotarget);
+ heim_ntlm_free_buf(infotarget);
if (sp)
krb5_storage_free(sp);
return ret;
@@ -1125,6 +1306,17 @@ out:
/*
* Calculate the NTLM2 Session Response
+ *
+ * @param clnt_nonce client nonce
+ * @param svr_chal server challage
+ * @param ntlm2_hash ntlm hash
+ * @param lm The LM response, should be freed with heim_ntlm_free_buf().
+ * @param ntlm The NTLM response, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
diff --git a/source4/heimdal/lib/vers/print_version.c b/source4/heimdal/lib/vers/print_version.c
index 4337d591c4..325f3fa046 100644
--- a/source4/heimdal/lib/vers/print_version.c
+++ b/source4/heimdal/lib/vers/print_version.c
@@ -33,7 +33,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
-RCSID("$Id: print_version.c 19566 2006-12-29 16:00:16Z lha $");
+RCSID("$Id: print_version.c 22428 2008-01-13 09:58:05Z lha $");
#endif
#include "roken.h"
@@ -50,6 +50,6 @@ print_version(const char *progname)
if(*package_list == '\0')
package_list = "no version information";
fprintf(stderr, "%s (%s)\n", progname, package_list);
- fprintf(stderr, "Copyright 1995-2007 Kungliga Tekniska Högskolan\n");
+ fprintf(stderr, "Copyright 1995-2008 Kungliga Tekniska Högskolan\n");
fprintf(stderr, "Send bug-reports to %s\n", PACKAGE_BUGREPORT);
}
diff --git a/source4/heimdal/lib/wind/bidi.c b/source4/heimdal/lib/wind/bidi.c
new file mode 100644
index 0000000000..fa62989eac
--- /dev/null
+++ b/source4/heimdal/lib/wind/bidi.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "bidi_table.h"
+
+static int
+range_entry_cmp(const void *a, const void *b)
+{
+ const struct range_entry *ea = (const struct range_entry*)a;
+ const struct range_entry *eb = (const struct range_entry*)b;
+
+ if (ea->start >= eb->start && ea->start < eb->start + eb->len)
+ return 0;
+ return ea->start - eb->start;
+}
+
+static int
+is_ral(uint32_t cp)
+{
+ struct range_entry ee = {cp};
+ void *s = bsearch(&ee, _wind_ral_table, _wind_ral_table_size,
+ sizeof(_wind_ral_table[0]),
+ range_entry_cmp);
+ return s != NULL;
+}
+
+static int
+is_l(uint32_t cp)
+{
+ struct range_entry ee = {cp};
+ void *s = bsearch(&ee, _wind_l_table, _wind_l_table_size,
+ sizeof(_wind_l_table[0]),
+ range_entry_cmp);
+ return s != NULL;
+}
+
+int
+_wind_stringprep_testbidi(const uint32_t *in, size_t in_len, wind_profile_flags flags)
+{
+ size_t i;
+ unsigned ral = 0;
+ unsigned l = 0;
+
+ if ((flags & (WIND_PROFILE_NAME|WIND_PROFILE_SASL)) == 0)
+ return 0;
+
+ for (i = 0; i < in_len; ++i) {
+ ral |= is_ral(in[i]);
+ l |= is_l(in[i]);
+ }
+ if (ral) {
+ if (l)
+ return 1;
+ if (!is_ral(in[0]) || !is_ral(in[in_len - 1]))
+ return 1;
+ }
+ return 0;
+}
diff --git a/source4/heimdal/lib/wind/bidi_table.c b/source4/heimdal/lib/wind/bidi_table.c
new file mode 100644
index 0000000000..34530b933d
--- /dev/null
+++ b/source4/heimdal/lib/wind/bidi_table.c
@@ -0,0 +1,410 @@
+/* bidi_table.c */
+/* Automatically generated at 2008-03-18T11:38:07.839291 */
+
+
+#include "bidi_table.h"
+
+const struct range_entry _wind_ral_table[] = {
+ {0x5be, 1},
+ {0x5c0, 1},
+ {0x5c3, 1},
+ {0x5d0, 0x1b},
+ {0x5f0, 0x5},
+ {0x61b, 1},
+ {0x61f, 1},
+ {0x621, 0x1a},
+ {0x640, 0xb},
+ {0x66d, 0x3},
+ {0x671, 0x65},
+ {0x6dd, 1},
+ {0x6e5, 0x2},
+ {0x6fa, 0x5},
+ {0x700, 0xe},
+ {0x710, 1},
+ {0x712, 0x1b},
+ {0x780, 0x26},
+ {0x7b1, 1},
+ {0x200f, 1},
+ {0xfb1d, 1},
+ {0xfb1f, 0xa},
+ {0xfb2a, 0xd},
+ {0xfb38, 0x5},
+ {0xfb3e, 1},
+ {0xfb40, 0x2},
+ {0xfb43, 0x2},
+ {0xfb46, 0x6c},
+ {0xfbd3, 0x16b},
+ {0xfd50, 0x40},
+ {0xfd92, 0x36},
+ {0xfdf0, 0xd},
+ {0xfe70, 0x5},
+ {0xfe76, 0x87},
+};
+
+const size_t _wind_ral_table_size = 34;
+
+const struct range_entry _wind_l_table[] = {
+ {0x41, 0x1a},
+ {0x61, 0x1a},
+ {0xaa, 1},
+ {0xb5, 1},
+ {0xba, 1},
+ {0xc0, 0x17},
+ {0xd8, 0x1f},
+ {0xf8, 0x129},
+ {0x222, 0x12},
+ {0x250, 0x5e},
+ {0x2b0, 0x9},
+ {0x2bb, 0x7},
+ {0x2d0, 0x2},
+ {0x2e0, 0x5},
+ {0x2ee, 1},
+ {0x37a, 1},
+ {0x386, 1},
+ {0x388, 0x3},
+ {0x38c, 1},
+ {0x38e, 0x14},
+ {0x3a3, 0x2c},
+ {0x3d0, 0x26},
+ {0x400, 0x83},
+ {0x48a, 0x45},
+ {0x4d0, 0x26},
+ {0x4f8, 0x2},
+ {0x500, 0x10},
+ {0x531, 0x26},
+ {0x559, 0x7},
+ {0x561, 0x27},
+ {0x589, 1},
+ {0x903, 1},
+ {0x905, 0x35},
+ {0x93d, 0x4},
+ {0x949, 0x4},
+ {0x950, 1},
+ {0x958, 0xa},
+ {0x964, 0xd},
+ {0x982, 0x2},
+ {0x985, 0x8},
+ {0x98f, 0x2},
+ {0x993, 0x16},
+ {0x9aa, 0x7},
+ {0x9b2, 1},
+ {0x9b6, 0x4},
+ {0x9be, 0x3},
+ {0x9c7, 0x2},
+ {0x9cb, 0x2},
+ {0x9d7, 1},
+ {0x9dc, 0x2},
+ {0x9df, 0x3},
+ {0x9e6, 0xc},
+ {0x9f4, 0x7},
+ {0xa05, 0x6},
+ {0xa0f, 0x2},
+ {0xa13, 0x16},
+ {0xa2a, 0x7},
+ {0xa32, 0x2},
+ {0xa35, 0x2},
+ {0xa38, 0x2},
+ {0xa3e, 0x3},
+ {0xa59, 0x4},
+ {0xa5e, 1},
+ {0xa66, 0xa},
+ {0xa72, 0x3},
+ {0xa83, 1},
+ {0xa85, 0x7},
+ {0xa8d, 1},
+ {0xa8f, 0x3},
+ {0xa93, 0x16},
+ {0xaaa, 0x7},
+ {0xab2, 0x2},
+ {0xab5, 0x5},
+ {0xabd, 0x4},
+ {0xac9, 1},
+ {0xacb, 0x2},
+ {0xad0, 1},
+ {0xae0, 1},
+ {0xae6, 0xa},
+ {0xb02, 0x2},
+ {0xb05, 0x8},
+ {0xb0f, 0x2},
+ {0xb13, 0x16},
+ {0xb2a, 0x7},
+ {0xb32, 0x2},
+ {0xb36, 0x4},
+ {0xb3d, 0x2},
+ {0xb40, 1},
+ {0xb47, 0x2},
+ {0xb4b, 0x2},
+ {0xb57, 1},
+ {0xb5c, 0x2},
+ {0xb5f, 0x3},
+ {0xb66, 0xb},
+ {0xb83, 1},
+ {0xb85, 0x6},
+ {0xb8e, 0x3},
+ {0xb92, 0x4},
+ {0xb99, 0x2},
+ {0xb9c, 1},
+ {0xb9e, 0x2},
+ {0xba3, 0x2},
+ {0xba8, 0x3},
+ {0xbae, 0x8},
+ {0xbb7, 0x3},
+ {0xbbe, 0x2},
+ {0xbc1, 0x2},
+ {0xbc6, 0x3},
+ {0xbca, 0x3},
+ {0xbd7, 1},
+ {0xbe7, 0xc},
+ {0xc01, 0x3},
+ {0xc05, 0x8},
+ {0xc0e, 0x3},
+ {0xc12, 0x17},
+ {0xc2a, 0xa},
+ {0xc35, 0x5},
+ {0xc41, 0x4},
+ {0xc60, 0x2},
+ {0xc66, 0xa},
+ {0xc82, 0x2},
+ {0xc85, 0x8},
+ {0xc8e, 0x3},
+ {0xc92, 0x17},
+ {0xcaa, 0xa},
+ {0xcb5, 0x5},
+ {0xcbe, 1},
+ {0xcc0, 0x5},
+ {0xcc7, 0x2},
+ {0xcca, 0x2},
+ {0xcd5, 0x2},
+ {0xcde, 1},
+ {0xce0, 0x2},
+ {0xce6, 0xa},
+ {0xd02, 0x2},
+ {0xd05, 0x8},
+ {0xd0e, 0x3},
+ {0xd12, 0x17},
+ {0xd2a, 0x10},
+ {0xd3e, 0x3},
+ {0xd46, 0x3},
+ {0xd4a, 0x3},
+ {0xd57, 1},
+ {0xd60, 0x2},
+ {0xd66, 0xa},
+ {0xd82, 0x2},
+ {0xd85, 0x12},
+ {0xd9a, 0x18},
+ {0xdb3, 0x9},
+ {0xdbd, 1},
+ {0xdc0, 0x7},
+ {0xdcf, 0x3},
+ {0xdd8, 0x8},
+ {0xdf2, 0x3},
+ {0xe01, 0x30},
+ {0xe32, 0x2},
+ {0xe40, 0x7},
+ {0xe4f, 0xd},
+ {0xe81, 0x2},
+ {0xe84, 1},
+ {0xe87, 0x2},
+ {0xe8a, 1},
+ {0xe8d, 1},
+ {0xe94, 0x4},
+ {0xe99, 0x7},
+ {0xea1, 0x3},
+ {0xea5, 1},
+ {0xea7, 1},
+ {0xeaa, 0x2},
+ {0xead, 0x4},
+ {0xeb2, 0x2},
+ {0xebd, 1},
+ {0xec0, 0x5},
+ {0xec6, 1},
+ {0xed0, 0xa},
+ {0xedc, 0x2},
+ {0xf00, 0x18},
+ {0xf1a, 0x1b},
+ {0xf36, 1},
+ {0xf38, 1},
+ {0xf3e, 0xa},
+ {0xf49, 0x22},
+ {0xf7f, 1},
+ {0xf85, 1},
+ {0xf88, 0x4},
+ {0xfbe, 0x8},
+ {0xfc7, 0x6},
+ {0xfcf, 1},
+ {0x1000, 0x22},
+ {0x1023, 0x5},
+ {0x1029, 0x2},
+ {0x102c, 1},
+ {0x1031, 1},
+ {0x1038, 1},
+ {0x1040, 0x18},
+ {0x10a0, 0x26},
+ {0x10d0, 0x29},
+ {0x10fb, 1},
+ {0x1100, 0x5a},
+ {0x115f, 0x44},
+ {0x11a8, 0x52},
+ {0x1200, 0x7},
+ {0x1208, 0x3f},
+ {0x1248, 1},
+ {0x124a, 0x4},
+ {0x1250, 0x7},
+ {0x1258, 1},
+ {0x125a, 0x4},
+ {0x1260, 0x27},
+ {0x1288, 1},
+ {0x128a, 0x4},
+ {0x1290, 0x1f},
+ {0x12b0, 1},
+ {0x12b2, 0x4},
+ {0x12b8, 0x7},
+ {0x12c0, 1},
+ {0x12c2, 0x4},
+ {0x12c8, 0x7},
+ {0x12d0, 0x7},
+ {0x12d8, 0x17},
+ {0x12f0, 0x1f},
+ {0x1310, 1},
+ {0x1312, 0x4},
+ {0x1318, 0x7},
+ {0x1320, 0x27},
+ {0x1348, 0x13},
+ {0x1361, 0x1c},
+ {0x13a0, 0x55},
+ {0x1401, 0x276},
+ {0x1681, 0x1a},
+ {0x16a0, 0x51},
+ {0x1700, 0xd},
+ {0x170e, 0x4},
+ {0x1720, 0x12},
+ {0x1735, 0x2},
+ {0x1740, 0x12},
+ {0x1760, 0xd},
+ {0x176e, 0x3},
+ {0x1780, 0x37},
+ {0x17be, 0x8},
+ {0x17c7, 0x2},
+ {0x17d4, 0x7},
+ {0x17dc, 1},
+ {0x17e0, 0xa},
+ {0x1810, 0xa},
+ {0x1820, 0x58},
+ {0x1880, 0x29},
+ {0x1e00, 0x9c},
+ {0x1ea0, 0x5a},
+ {0x1f00, 0x16},
+ {0x1f18, 0x6},
+ {0x1f20, 0x26},
+ {0x1f48, 0x6},
+ {0x1f50, 0x8},
+ {0x1f59, 1},
+ {0x1f5b, 1},
+ {0x1f5d, 1},
+ {0x1f5f, 0x1f},
+ {0x1f80, 0x35},
+ {0x1fb6, 0x7},
+ {0x1fbe, 1},
+ {0x1fc2, 0x3},
+ {0x1fc6, 0x7},
+ {0x1fd0, 0x4},
+ {0x1fd6, 0x6},
+ {0x1fe0, 0xd},
+ {0x1ff2, 0x3},
+ {0x1ff6, 0x7},
+ {0x200e, 1},
+ {0x2071, 1},
+ {0x207f, 1},
+ {0x2102, 1},
+ {0x2107, 1},
+ {0x210a, 0xa},
+ {0x2115, 1},
+ {0x2119, 0x5},
+ {0x2124, 1},
+ {0x2126, 1},
+ {0x2128, 1},
+ {0x212a, 0x4},
+ {0x212f, 0x3},
+ {0x2133, 0x7},
+ {0x213d, 0x3},
+ {0x2145, 0x5},
+ {0x2160, 0x24},
+ {0x2336, 0x45},
+ {0x2395, 1},
+ {0x249c, 0x4e},
+ {0x3005, 0x3},
+ {0x3021, 0x9},
+ {0x3031, 0x5},
+ {0x3038, 0x5},
+ {0x3041, 0x56},
+ {0x309d, 0x3},
+ {0x30a1, 0x5a},
+ {0x30fc, 0x4},
+ {0x3105, 0x28},
+ {0x3131, 0x5e},
+ {0x3190, 0x28},
+ {0x31f0, 0x2d},
+ {0x3220, 0x24},
+ {0x3260, 0x1c},
+ {0x327f, 0x32},
+ {0x32c0, 0xc},
+ {0x32d0, 0x2f},
+ {0x3300, 0x77},
+ {0x337b, 0x63},
+ {0x33e0, 0x1f},
+ {0x3400, 0x19b6},
+ {0x4e00, 0x51a6},
+ {0xa000, 0x48d},
+ {0xac00, 0x2ba4},
+ {0xd800, 0x222e},
+ {0xfa30, 0x3b},
+ {0xfb00, 0x7},
+ {0xfb13, 0x5},
+ {0xff21, 0x1a},
+ {0xff41, 0x1a},
+ {0xff66, 0x59},
+ {0xffc2, 0x6},
+ {0xffca, 0x6},
+ {0xffd2, 0x6},
+ {0xffda, 0x3},
+ {0x10300, 0x1f},
+ {0x10320, 0x4},
+ {0x10330, 0x1b},
+ {0x10400, 0x26},
+ {0x10428, 0x26},
+ {0x1d000, 0xf6},
+ {0x1d100, 0x27},
+ {0x1d12a, 0x3d},
+ {0x1d16a, 0x9},
+ {0x1d183, 0x2},
+ {0x1d18c, 0x1e},
+ {0x1d1ae, 0x30},
+ {0x1d400, 0x55},
+ {0x1d456, 0x47},
+ {0x1d49e, 0x2},
+ {0x1d4a2, 1},
+ {0x1d4a5, 0x2},
+ {0x1d4a9, 0x4},
+ {0x1d4ae, 0xc},
+ {0x1d4bb, 1},
+ {0x1d4bd, 0x4},
+ {0x1d4c2, 0x2},
+ {0x1d4c5, 0x41},
+ {0x1d507, 0x4},
+ {0x1d50d, 0x8},
+ {0x1d516, 0x7},
+ {0x1d51e, 0x1c},
+ {0x1d53b, 0x4},
+ {0x1d540, 0x5},
+ {0x1d546, 1},
+ {0x1d54a, 0x7},
+ {0x1d552, 0x152},
+ {0x1d6a8, 0x122},
+ {0x20000, 0xa6d7},
+ {0x2f800, 0x21e},
+ {0xf0000, 0xfffe},
+ {0x100000, 0xfffe},
+};
+
+const size_t _wind_l_table_size = 360;
+
diff --git a/source4/heimdal/lib/wind/bidi_table.h b/source4/heimdal/lib/wind/bidi_table.h
new file mode 100644
index 0000000000..2e369f2d9a
--- /dev/null
+++ b/source4/heimdal/lib/wind/bidi_table.h
@@ -0,0 +1,21 @@
+/* bidi_table.h */
+/* Automatically generated at 2008-03-18T11:38:07.839121 */
+
+#ifndef BIDI_TABLE_H
+#define BIDI_TABLE_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+struct range_entry {
+ uint32_t start;
+ unsigned len;
+};
+
+extern const struct range_entry _wind_ral_table[];
+extern const struct range_entry _wind_l_table[];
+
+extern const size_t _wind_ral_table_size;
+extern const size_t _wind_l_table_size;
+
+#endif /* BIDI_TABLE_H */
diff --git a/source4/heimdal/lib/wind/combining.c b/source4/heimdal/lib/wind/combining.c
new file mode 100644
index 0000000000..8481cab859
--- /dev/null
+++ b/source4/heimdal/lib/wind/combining.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "combining_table.h"
+
+static int
+translation_cmp(const void *key, const void *data)
+{
+ const struct translation *t1 = (const struct translation *)key;
+ const struct translation *t2 = (const struct translation *)data;
+
+ return t1->key - t2->key;
+}
+
+int
+_wind_combining_class(uint32_t code_point)
+{
+ struct translation ts = {code_point};
+ void *s = bsearch(&ts, _wind_combining_table, _wind_combining_table_size,
+ sizeof(_wind_combining_table[0]),
+ translation_cmp);
+ if (s != NULL) {
+ const struct translation *t = (const struct translation *)s;
+ return t->combining_class;
+ } else {
+ return 0;
+ }
+}
diff --git a/source4/heimdal/lib/wind/combining_table.c b/source4/heimdal/lib/wind/combining_table.c
new file mode 100644
index 0000000000..7abd1cf76d
--- /dev/null
+++ b/source4/heimdal/lib/wind/combining_table.c
@@ -0,0 +1,362 @@
+/* combining_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.166082 */
+
+
+#include "combining_table.h"
+
+const struct translation _wind_combining_table[] = {
+{0x300, 230}, /* Mn */
+{0x301, 230}, /* Mn */
+{0x302, 230}, /* Mn */
+{0x303, 230}, /* Mn */
+{0x304, 230}, /* Mn */
+{0x305, 230}, /* Mn */
+{0x306, 230}, /* Mn */
+{0x307, 230}, /* Mn */
+{0x308, 230}, /* Mn */
+{0x309, 230}, /* Mn */
+{0x30a, 230}, /* Mn */
+{0x30b, 230}, /* Mn */
+{0x30c, 230}, /* Mn */
+{0x30d, 230}, /* Mn */
+{0x30e, 230}, /* Mn */
+{0x30f, 230}, /* Mn */
+{0x310, 230}, /* Mn */
+{0x311, 230}, /* Mn */
+{0x312, 230}, /* Mn */
+{0x313, 230}, /* Mn */
+{0x314, 230}, /* Mn */
+{0x315, 232}, /* Mn */
+{0x316, 220}, /* Mn */
+{0x317, 220}, /* Mn */
+{0x318, 220}, /* Mn */
+{0x319, 220}, /* Mn */
+{0x31a, 232}, /* Mn */
+{0x31b, 216}, /* Mn */
+{0x31c, 220}, /* Mn */
+{0x31d, 220}, /* Mn */
+{0x31e, 220}, /* Mn */
+{0x31f, 220}, /* Mn */
+{0x320, 220}, /* Mn */
+{0x321, 202}, /* Mn */
+{0x322, 202}, /* Mn */
+{0x323, 220}, /* Mn */
+{0x324, 220}, /* Mn */
+{0x325, 220}, /* Mn */
+{0x326, 220}, /* Mn */
+{0x327, 202}, /* Mn */
+{0x328, 202}, /* Mn */
+{0x329, 220}, /* Mn */
+{0x32a, 220}, /* Mn */
+{0x32b, 220}, /* Mn */
+{0x32c, 220}, /* Mn */
+{0x32d, 220}, /* Mn */
+{0x32e, 220}, /* Mn */
+{0x32f, 220}, /* Mn */
+{0x330, 220}, /* Mn */
+{0x331, 220}, /* Mn */
+{0x332, 220}, /* Mn */
+{0x333, 220}, /* Mn */
+{0x334, 1}, /* Mn */
+{0x335, 1}, /* Mn */
+{0x336, 1}, /* Mn */
+{0x337, 1}, /* Mn */
+{0x338, 1}, /* Mn */
+{0x339, 220}, /* Mn */
+{0x33a, 220}, /* Mn */
+{0x33b, 220}, /* Mn */
+{0x33c, 220}, /* Mn */
+{0x33d, 230}, /* Mn */
+{0x33e, 230}, /* Mn */
+{0x33f, 230}, /* Mn */
+{0x340, 230}, /* Mn */
+{0x341, 230}, /* Mn */
+{0x342, 230}, /* Mn */
+{0x343, 230}, /* Mn */
+{0x344, 230}, /* Mn */
+{0x345, 240}, /* Mn */
+{0x346, 230}, /* Mn */
+{0x347, 220}, /* Mn */
+{0x348, 220}, /* Mn */
+{0x349, 220}, /* Mn */
+{0x34a, 230}, /* Mn */
+{0x34b, 230}, /* Mn */
+{0x34c, 230}, /* Mn */
+{0x34d, 220}, /* Mn */
+{0x34e, 220}, /* Mn */
+{0x350, 230}, /* Mn */
+{0x351, 230}, /* Mn */
+{0x352, 230}, /* Mn */
+{0x353, 220}, /* Mn */
+{0x354, 220}, /* Mn */
+{0x355, 220}, /* Mn */
+{0x356, 220}, /* Mn */
+{0x357, 230}, /* Mn */
+{0x35d, 234}, /* Mn */
+{0x35e, 234}, /* Mn */
+{0x35f, 233}, /* Mn */
+{0x360, 234}, /* Mn */
+{0x361, 234}, /* Mn */
+{0x362, 233}, /* Mn */
+{0x363, 230}, /* Mn */
+{0x364, 230}, /* Mn */
+{0x365, 230}, /* Mn */
+{0x366, 230}, /* Mn */
+{0x367, 230}, /* Mn */
+{0x368, 230}, /* Mn */
+{0x369, 230}, /* Mn */
+{0x36a, 230}, /* Mn */
+{0x36b, 230}, /* Mn */
+{0x36c, 230}, /* Mn */
+{0x36d, 230}, /* Mn */
+{0x36e, 230}, /* Mn */
+{0x36f, 230}, /* Mn */
+{0x483, 230}, /* Mn */
+{0x484, 230}, /* Mn */
+{0x485, 230}, /* Mn */
+{0x486, 230}, /* Mn */
+{0x591, 220}, /* Mn */
+{0x592, 230}, /* Mn */
+{0x593, 230}, /* Mn */
+{0x594, 230}, /* Mn */
+{0x595, 230}, /* Mn */
+{0x596, 220}, /* Mn */
+{0x597, 230}, /* Mn */
+{0x598, 230}, /* Mn */
+{0x599, 230}, /* Mn */
+{0x59a, 222}, /* Mn */
+{0x59b, 220}, /* Mn */
+{0x59c, 230}, /* Mn */
+{0x59d, 230}, /* Mn */
+{0x59e, 230}, /* Mn */
+{0x59f, 230}, /* Mn */
+{0x5a0, 230}, /* Mn */
+{0x5a1, 230}, /* Mn */
+{0x5a3, 220}, /* Mn */
+{0x5a4, 220}, /* Mn */
+{0x5a5, 220}, /* Mn */
+{0x5a6, 220}, /* Mn */
+{0x5a7, 220}, /* Mn */
+{0x5a8, 230}, /* Mn */
+{0x5a9, 230}, /* Mn */
+{0x5aa, 220}, /* Mn */
+{0x5ab, 230}, /* Mn */
+{0x5ac, 230}, /* Mn */
+{0x5ad, 222}, /* Mn */
+{0x5ae, 228}, /* Mn */
+{0x5af, 230}, /* Mn */
+{0x5b0, 10}, /* Mn */
+{0x5b1, 11}, /* Mn */
+{0x5b2, 12}, /* Mn */
+{0x5b3, 13}, /* Mn */
+{0x5b4, 14}, /* Mn */
+{0x5b5, 15}, /* Mn */
+{0x5b6, 16}, /* Mn */
+{0x5b7, 17}, /* Mn */
+{0x5b8, 18}, /* Mn */
+{0x5b9, 19}, /* Mn */
+{0x5bb, 20}, /* Mn */
+{0x5bc, 21}, /* Mn */
+{0x5bd, 22}, /* Mn */
+{0x5bf, 23}, /* Mn */
+{0x5c1, 24}, /* Mn */
+{0x5c2, 25}, /* Mn */
+{0x5c4, 230}, /* Mn */
+{0x610, 230}, /* Mn */
+{0x611, 230}, /* Mn */
+{0x612, 230}, /* Mn */
+{0x613, 230}, /* Mn */
+{0x614, 230}, /* Mn */
+{0x615, 230}, /* Mn */
+{0x64b, 27}, /* Mn */
+{0x64c, 28}, /* Mn */
+{0x64d, 29}, /* Mn */
+{0x64e, 30}, /* Mn */
+{0x64f, 31}, /* Mn */
+{0x650, 32}, /* Mn */
+{0x651, 33}, /* Mn */
+{0x652, 34}, /* Mn */
+{0x653, 230}, /* Mn */
+{0x654, 230}, /* Mn */
+{0x655, 220}, /* Mn */
+{0x656, 220}, /* Mn */
+{0x657, 230}, /* Mn */
+{0x658, 230}, /* Mn */
+{0x670, 35}, /* Mn */
+{0x6d6, 230}, /* Mn */
+{0x6d7, 230}, /* Mn */
+{0x6d8, 230}, /* Mn */
+{0x6d9, 230}, /* Mn */
+{0x6da, 230}, /* Mn */
+{0x6db, 230}, /* Mn */
+{0x6dc, 230}, /* Mn */
+{0x6df, 230}, /* Mn */
+{0x6e0, 230}, /* Mn */
+{0x6e1, 230}, /* Mn */
+{0x6e2, 230}, /* Mn */
+{0x6e3, 220}, /* Mn */
+{0x6e4, 230}, /* Mn */
+{0x6e7, 230}, /* Mn */
+{0x6e8, 230}, /* Mn */
+{0x6ea, 220}, /* Mn */
+{0x6eb, 230}, /* Mn */
+{0x6ec, 230}, /* Mn */
+{0x6ed, 220}, /* Mn */
+{0x711, 36}, /* Mn */
+{0x730, 230}, /* Mn */
+{0x731, 220}, /* Mn */
+{0x732, 230}, /* Mn */
+{0x733, 230}, /* Mn */
+{0x734, 220}, /* Mn */
+{0x735, 230}, /* Mn */
+{0x736, 230}, /* Mn */
+{0x737, 220}, /* Mn */
+{0x738, 220}, /* Mn */
+{0x739, 220}, /* Mn */
+{0x73a, 230}, /* Mn */
+{0x73b, 220}, /* Mn */
+{0x73c, 220}, /* Mn */
+{0x73d, 230}, /* Mn */
+{0x73e, 220}, /* Mn */
+{0x73f, 230}, /* Mn */
+{0x740, 230}, /* Mn */
+{0x741, 230}, /* Mn */
+{0x742, 220}, /* Mn */
+{0x743, 230}, /* Mn */
+{0x744, 220}, /* Mn */
+{0x745, 230}, /* Mn */
+{0x746, 220}, /* Mn */
+{0x747, 230}, /* Mn */
+{0x748, 220}, /* Mn */
+{0x749, 230}, /* Mn */
+{0x74a, 230}, /* Mn */
+{0x93c, 7}, /* Mn */
+{0x94d, 9}, /* Mn */
+{0x951, 230}, /* Mn */
+{0x952, 220}, /* Mn */
+{0x953, 230}, /* Mn */
+{0x954, 230}, /* Mn */
+{0x9bc, 7}, /* Mn */
+{0x9cd, 9}, /* Mn */
+{0xa3c, 7}, /* Mn */
+{0xa4d, 9}, /* Mn */
+{0xabc, 7}, /* Mn */
+{0xacd, 9}, /* Mn */
+{0xb3c, 7}, /* Mn */
+{0xb4d, 9}, /* Mn */
+{0xbcd, 9}, /* Mn */
+{0xc4d, 9}, /* Mn */
+{0xc55, 84}, /* Mn */
+{0xc56, 91}, /* Mn */
+{0xcbc, 7}, /* Mn */
+{0xccd, 9}, /* Mn */
+{0xd4d, 9}, /* Mn */
+{0xdca, 9}, /* Mn */
+{0xe38, 103}, /* Mn */
+{0xe39, 103}, /* Mn */
+{0xe3a, 9}, /* Mn */
+{0xe48, 107}, /* Mn */
+{0xe49, 107}, /* Mn */
+{0xe4a, 107}, /* Mn */
+{0xe4b, 107}, /* Mn */
+{0xeb8, 118}, /* Mn */
+{0xeb9, 118}, /* Mn */
+{0xec8, 122}, /* Mn */
+{0xec9, 122}, /* Mn */
+{0xeca, 122}, /* Mn */
+{0xecb, 122}, /* Mn */
+{0xf18, 220}, /* Mn */
+{0xf19, 220}, /* Mn */
+{0xf35, 220}, /* Mn */
+{0xf37, 220}, /* Mn */
+{0xf39, 216}, /* Mn */
+{0xf71, 129}, /* Mn */
+{0xf72, 130}, /* Mn */
+{0xf74, 132}, /* Mn */
+{0xf7a, 130}, /* Mn */
+{0xf7b, 130}, /* Mn */
+{0xf7c, 130}, /* Mn */
+{0xf7d, 130}, /* Mn */
+{0xf80, 130}, /* Mn */
+{0xf82, 230}, /* Mn */
+{0xf83, 230}, /* Mn */
+{0xf84, 9}, /* Mn */
+{0xf86, 230}, /* Mn */
+{0xf87, 230}, /* Mn */
+{0xfc6, 220}, /* Mn */
+{0x1037, 7}, /* Mn */
+{0x1039, 9}, /* Mn */
+{0x1714, 9}, /* Mn */
+{0x1734, 9}, /* Mn */
+{0x17d2, 9}, /* Mn */
+{0x17dd, 230}, /* Mn */
+{0x18a9, 228}, /* Mn */
+{0x1939, 222}, /* Mn */
+{0x193a, 230}, /* Mn */
+{0x193b, 220}, /* Mn */
+{0x20d0, 230}, /* Mn */
+{0x20d1, 230}, /* Mn */
+{0x20d2, 1}, /* Mn */
+{0x20d3, 1}, /* Mn */
+{0x20d4, 230}, /* Mn */
+{0x20d5, 230}, /* Mn */
+{0x20d6, 230}, /* Mn */
+{0x20d7, 230}, /* Mn */
+{0x20d8, 1}, /* Mn */
+{0x20d9, 1}, /* Mn */
+{0x20da, 1}, /* Mn */
+{0x20db, 230}, /* Mn */
+{0x20dc, 230}, /* Mn */
+{0x20e1, 230}, /* Mn */
+{0x20e5, 1}, /* Mn */
+{0x20e6, 1}, /* Mn */
+{0x20e7, 230}, /* Mn */
+{0x20e8, 220}, /* Mn */
+{0x20e9, 230}, /* Mn */
+{0x20ea, 1}, /* Mn */
+{0x302a, 218}, /* Mn */
+{0x302b, 228}, /* Mn */
+{0x302c, 232}, /* Mn */
+{0x302d, 222}, /* Mn */
+{0x302e, 224}, /* Mn */
+{0x302f, 224}, /* Mn */
+{0x3099, 8}, /* Mn */
+{0x309a, 8}, /* Mn */
+{0xfb1e, 26}, /* Mn */
+{0xfe20, 230}, /* Mn */
+{0xfe21, 230}, /* Mn */
+{0xfe22, 230}, /* Mn */
+{0xfe23, 230}, /* Mn */
+{0x1d165, 216}, /* Mc */
+{0x1d166, 216}, /* Mc */
+{0x1d167, 1}, /* Mn */
+{0x1d168, 1}, /* Mn */
+{0x1d169, 1}, /* Mn */
+{0x1d16d, 226}, /* Mc */
+{0x1d16e, 216}, /* Mc */
+{0x1d16f, 216}, /* Mc */
+{0x1d170, 216}, /* Mc */
+{0x1d171, 216}, /* Mc */
+{0x1d172, 216}, /* Mc */
+{0x1d17b, 220}, /* Mn */
+{0x1d17c, 220}, /* Mn */
+{0x1d17d, 220}, /* Mn */
+{0x1d17e, 220}, /* Mn */
+{0x1d17f, 220}, /* Mn */
+{0x1d180, 220}, /* Mn */
+{0x1d181, 220}, /* Mn */
+{0x1d182, 220}, /* Mn */
+{0x1d185, 230}, /* Mn */
+{0x1d186, 230}, /* Mn */
+{0x1d187, 230}, /* Mn */
+{0x1d188, 230}, /* Mn */
+{0x1d189, 230}, /* Mn */
+{0x1d18a, 220}, /* Mn */
+{0x1d18b, 220}, /* Mn */
+{0x1d1aa, 230}, /* Mn */
+{0x1d1ab, 230}, /* Mn */
+{0x1d1ac, 230}, /* Mn */
+{0x1d1ad, 230}, /* Mn */
+
+};
+const size_t _wind_combining_table_size = 352;
diff --git a/source4/heimdal/lib/wind/combining_table.h b/source4/heimdal/lib/wind/combining_table.h
new file mode 100644
index 0000000000..000af13ea8
--- /dev/null
+++ b/source4/heimdal/lib/wind/combining_table.h
@@ -0,0 +1,18 @@
+/* combining_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.165877 */
+
+#ifndef COMBINING_TABLE_H
+#define COMBINING_TABLE_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct translation {
+ uint32_t key;
+ unsigned combining_class;
+};
+
+extern const struct translation _wind_combining_table[];
+
+extern const size_t _wind_combining_table_size;
+#endif /* COMBINING_TABLE_H */
diff --git a/source4/heimdal/lib/wind/errorlist.c b/source4/heimdal/lib/wind/errorlist.c
new file mode 100644
index 0000000000..9a65338cd2
--- /dev/null
+++ b/source4/heimdal/lib/wind/errorlist.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "errorlist_table.h"
+
+static int
+error_entry_cmp(const void *a, const void *b)
+{
+ const struct error_entry *ea = (const struct error_entry*)a;
+ const struct error_entry *eb = (const struct error_entry*)b;
+
+ if (ea->start >= eb->start && ea->start < eb->start + eb->len)
+ return 0;
+ return ea->start - eb->start;
+}
+
+int
+_wind_stringprep_error(uint32_t cp, wind_profile_flags flags)
+{
+ struct error_entry ee = {cp};
+ const struct error_entry *s;
+
+ s = (const struct error_entry *)
+ bsearch(&ee, _wind_errorlist_table,
+ _wind_errorlist_table_size,
+ sizeof(_wind_errorlist_table[0]),
+ error_entry_cmp);
+ if (s == NULL)
+ return 0;
+ return (s->flags & flags);
+}
+
+int
+_wind_stringprep_prohibited(const uint32_t *in, size_t in_len,
+ wind_profile_flags flags)
+{
+ unsigned i;
+
+ for (i = 0; i < in_len; ++i)
+ if (_wind_stringprep_error(in[i], flags))
+ return 1;
+ return 0;
+}
diff --git a/source4/heimdal/lib/wind/errorlist_table.c b/source4/heimdal/lib/wind/errorlist_table.c
new file mode 100644
index 0000000000..5d5d8caaf2
--- /dev/null
+++ b/source4/heimdal/lib/wind/errorlist_table.c
@@ -0,0 +1,88 @@
+/* errorlist_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.266475 */
+
+
+#include "errorlist_table.h"
+
+const struct error_entry _wind_errorlist_table[] = {
+ {0x0, 0x20, WIND_PROFILE_SASL}, /* C.2.1: [CONTROL CHARACTERS] */
+ {0x7f, 0x1, WIND_PROFILE_SASL}, /* C.2.1: DELETE */
+ {0x80, 0x20, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: [CONTROL CHARACTERS] */
+ {0xa0, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: NO-BREAK SPACE */
+ {0x340, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: COMBINING GRAVE TONE MARK */
+ {0x341, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: COMBINING ACUTE TONE MARK */
+ {0x6dd, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ARABIC END OF AYAH */
+ {0x70f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: SYRIAC ABBREVIATION MARK */
+ {0x1680, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: OGHAM SPACE MARK */
+ {0x180e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: MONGOLIAN VOWEL SEPARATOR */
+ {0x2000, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EN QUAD */
+ {0x2001, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EM QUAD */
+ {0x2002, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EN SPACE */
+ {0x2003, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EM SPACE */
+ {0x2004, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: THREE-PER-EM SPACE */
+ {0x2005, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: FOUR-PER-EM SPACE */
+ {0x2006, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: SIX-PER-EM SPACE */
+ {0x2007, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: FIGURE SPACE */
+ {0x2008, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: PUNCTUATION SPACE */
+ {0x2009, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: THIN SPACE */
+ {0x200a, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: HAIR SPACE */
+ {0x200b, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: ZERO WIDTH SPACE */
+ {0x200c, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ZERO WIDTH NON-JOINER */
+ {0x200d, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ZERO WIDTH JOINER */
+ {0x200e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: LEFT-TO-RIGHT MARK */
+ {0x200f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: RIGHT-TO-LEFT MARK */
+ {0x2028, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: LINE SEPARATOR */
+ {0x2029, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: PARAGRAPH SEPARATOR */
+ {0x202a, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: LEFT-TO-RIGHT EMBEDDING */
+ {0x202b, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: RIGHT-TO-LEFT EMBEDDING */
+ {0x202c, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: POP DIRECTIONAL FORMATTING */
+ {0x202d, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: LEFT-TO-RIGHT OVERRIDE */
+ {0x202e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: RIGHT-TO-LEFT OVERRIDE */
+ {0x202f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: NARROW NO-BREAK SPACE */
+ {0x205f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: MEDIUM MATHEMATICAL SPACE */
+ {0x2060, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: WORD JOINER */
+ {0x2061, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: FUNCTION APPLICATION */
+ {0x2062, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: INVISIBLE TIMES */
+ {0x2063, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: INVISIBLE SEPARATOR */
+ {0x206a, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL|WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.8,C.2.2: INHIBIT SYMMETRIC SWAPPING */
+ {0x206b, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: ACTIVATE SYMMETRIC SWAPPING */
+ {0x206c, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: INHIBIT ARABIC FORM SHAPING */
+ {0x206d, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: ACTIVATE ARABIC FORM SHAPING */
+ {0x206e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: NATIONAL DIGIT SHAPES */
+ {0x206f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: NOMINAL DIGIT SHAPES */
+ {0x2ff0, 0xc, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.7: [IDEOGRAPHIC DESCRIPTION CHARACTERS] */
+ {0x3000, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: IDEOGRAPHIC SPACE */
+ {0xd800, 0x800, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.5: [SURROGATE CODES] */
+ {0xe000, 0x1900, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.3: [PRIVATE USE, PLANE 0] */
+ {0xfdd0, 0x20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xfeff, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ZERO WIDTH NO-BREAK SPACE */
+ {0xfff9, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6,C.2.2: INTERLINEAR ANNOTATION ANCHOR */
+ {0xfffa, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6: INTERLINEAR ANNOTATION SEPARATOR */
+ {0xfffb, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6: INTERLINEAR ANNOTATION TERMINATOR */
+ {0xfffc, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6: OBJECT REPLACEMENT CHARACTER */
+ {0xfffd, 0x1, WIND_PROFILE_LDAP|WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* rfc4518-error,C.6: */
+ {0xfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x1d173, 0x8, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: [MUSICAL CONTROL CHARACTERS] */
+ {0x1fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x2fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x3fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x4fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x5fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x6fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x7fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x8fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x9fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xafffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xbfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xcfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xdfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xe0001, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.9: LANGUAGE TAG */
+ {0xe0020, 0x60, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.9: [TAGGING CHARACTERS] */
+ {0xefffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0xf0000, 0xfffe, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.3: [PRIVATE USE, PLANE 15] */
+ {0xffffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+ {0x100000, 0xfffe, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.3: [PRIVATE USE, PLANE 16] */
+ {0x10fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+};
+
+const size_t _wind_errorlist_table_size = 78;
diff --git a/source4/heimdal/lib/wind/errorlist_table.h b/source4/heimdal/lib/wind/errorlist_table.h
new file mode 100644
index 0000000000..5fc9ddbf04
--- /dev/null
+++ b/source4/heimdal/lib/wind/errorlist_table.h
@@ -0,0 +1,19 @@
+/* errorlist_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.266305 */
+
+#ifndef ERRORLIST_TABLE_H
+#define ERRORLIST_TABLE_H 1
+
+#include "windlocl.h"
+
+struct error_entry {
+ uint32_t start;
+ unsigned len;
+ wind_profile_flags flags;
+};
+
+extern const struct error_entry _wind_errorlist_table[];
+
+extern const size_t _wind_errorlist_table_size;
+
+#endif /* ERRORLIST_TABLE_H */
diff --git a/source4/heimdal/lib/wind/ldap.c b/source4/heimdal/lib/wind/ldap.c
new file mode 100644
index 0000000000..1ff681fc31
--- /dev/null
+++ b/source4/heimdal/lib/wind/ldap.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "windlocl.h"
+#include <assert.h>
+
+static int
+put_char(uint32_t *out, size_t *o, uint32_t c, size_t out_len)
+{
+ if (*o >= out_len)
+ return 1;
+ out[*o] = c;
+ (*o)++;
+ return 0;
+}
+
+int
+_wind_ldap_case_exact_attribute(const uint32_t *tmp,
+ size_t olen,
+ uint32_t *out,
+ size_t *out_len)
+{
+ size_t o = 0, i = 0;
+
+ if (olen == 0) {
+ *out_len = 0;
+ return 0;
+ }
+
+ if (put_char(out, &o, 0x20, *out_len))
+ return WIND_ERR_OVERRUN;
+ while(i < olen && tmp[i] == 0x20) /* skip initial spaces */
+ i++;
+
+ while (i < olen) {
+ if (tmp[i] == 0x20) {
+ if (put_char(out, &o, 0x20, *out_len) ||
+ put_char(out, &o, 0x20, *out_len))
+ return WIND_ERR_OVERRUN;
+ while(i < olen && tmp[i] == 0x20) /* skip middle spaces */
+ i++;
+ } else {
+ if (put_char(out, &o, tmp[i++], *out_len))
+ return WIND_ERR_OVERRUN;
+ }
+ }
+ assert(o > 0);
+
+ /* only one spaces at the end */
+ if (o == 1 && out[0] == 0x20)
+ o = 0;
+ else if (out[o - 1] == 0x20) {
+ if (out[o - 2] == 0x20)
+ o--;
+ } else
+ put_char(out, &o, 0x20, *out_len);
+
+ *out_len = o;
+
+ return 0;
+}
diff --git a/source4/heimdal/lib/wind/map.c b/source4/heimdal/lib/wind/map.c
new file mode 100644
index 0000000000..ae6d10e512
--- /dev/null
+++ b/source4/heimdal/lib/wind/map.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "map_table.h"
+
+RCSID("$Id: map.c 22556 2008-02-01 16:38:46Z lha $");
+
+static int
+translation_cmp(const void *key, const void *data)
+{
+ const struct translation *t1 = (const struct translation *)key;
+ const struct translation *t2 = (const struct translation *)data;
+
+ return t1->key - t2->key;
+}
+
+int
+_wind_stringprep_map(const uint32_t *in, size_t in_len,
+ uint32_t *out, size_t *out_len,
+ wind_profile_flags flags)
+{
+ unsigned i;
+ unsigned o = 0;
+
+ for (i = 0; i < in_len; ++i) {
+ struct translation ts = {in[i]};
+ const struct translation *s;
+
+ s = (const struct translation *)
+ bsearch(&ts, _wind_map_table, _wind_map_table_size,
+ sizeof(_wind_map_table[0]),
+ translation_cmp);
+ if (s != NULL && (s->flags & flags)) {
+ unsigned j;
+
+ for (j = 0; j < s->val_len; ++j) {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ out[o++] = _wind_map_table_val[s->val_offset + j];
+ }
+ } else {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ out[o++] = in[i];
+
+ }
+ }
+ *out_len = o;
+ return 0;
+}
diff --git a/source4/heimdal/lib/wind/map_table.c b/source4/heimdal/lib/wind/map_table.c
new file mode 100644
index 0000000000..e4dba94ea6
--- /dev/null
+++ b/source4/heimdal/lib/wind/map_table.c
@@ -0,0 +1,2613 @@
+/* map_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.353797 */
+
+
+#include "map_table.h"
+
+const struct translation _wind_map_table[] = {
+ {0x0, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x2, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x3, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x4, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x5, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x6, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x7, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x9, 1, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0xa, 1, 1, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0xb, 1, 2, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0xc, 1, 3, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0xd, 1, 4, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0xe, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xf, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x10, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x11, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x12, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x13, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x14, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x15, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x16, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x17, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x18, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x19, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1a, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1b, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1c, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1e, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x20, 1, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x41, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x43, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x44, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x45, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x46, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x47, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x48, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x49, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4a, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4b, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4c, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4d, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4e, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4f, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x50, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x51, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x52, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x55, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x56, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x57, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x58, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x59, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x5a, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x7f, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x80, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x81, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x82, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x83, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x85, 1, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x86, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x87, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x88, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x89, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x8a, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x8b, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x8c, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x8d, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x8e, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x8f, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x90, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x91, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x92, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x93, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x94, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x95, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x96, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x97, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x98, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x99, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x9a, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x9b, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x9c, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x9d, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x9e, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xa0, 1, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0xad, 0, 34, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xb5, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc0, 1, 35, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc1, 1, 36, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc2, 1, 37, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc3, 1, 38, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc4, 1, 39, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc5, 1, 40, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc6, 1, 41, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc7, 1, 42, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc8, 1, 43, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xc9, 1, 44, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xca, 1, 45, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xcb, 1, 46, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xcc, 1, 47, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xcd, 1, 48, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xce, 1, 49, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xcf, 1, 50, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd0, 1, 51, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd1, 1, 52, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd2, 1, 53, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd3, 1, 54, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd4, 1, 55, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd5, 1, 56, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd6, 1, 57, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd8, 1, 58, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xd9, 1, 59, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xda, 1, 60, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xdb, 1, 61, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xdc, 1, 62, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xdd, 1, 63, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xde, 1, 64, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xdf, 2, 65, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x100, 1, 67, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x102, 1, 68, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x104, 1, 69, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x106, 1, 70, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x108, 1, 71, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10a, 1, 72, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10c, 1, 73, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10e, 1, 74, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x110, 1, 75, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x112, 1, 76, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x114, 1, 77, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x116, 1, 78, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x118, 1, 79, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x11a, 1, 80, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x11c, 1, 81, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x11e, 1, 82, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x120, 1, 83, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x122, 1, 84, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x124, 1, 85, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x126, 1, 86, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x128, 1, 87, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x12a, 1, 88, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x12c, 1, 89, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x12e, 1, 90, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x130, 2, 91, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x132, 1, 93, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x134, 1, 94, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x136, 1, 95, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x139, 1, 96, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x13b, 1, 97, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x13d, 1, 98, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x13f, 1, 99, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x141, 1, 100, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x143, 1, 101, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x145, 1, 102, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x147, 1, 103, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x149, 2, 104, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x14a, 1, 106, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x14c, 1, 107, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x14e, 1, 108, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x150, 1, 109, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x152, 1, 110, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x154, 1, 111, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x156, 1, 112, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x158, 1, 113, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x15a, 1, 114, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x15c, 1, 115, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x15e, 1, 116, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x160, 1, 117, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x162, 1, 118, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x164, 1, 119, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x166, 1, 120, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x168, 1, 121, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x16a, 1, 122, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x16c, 1, 123, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x16e, 1, 124, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x170, 1, 125, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x172, 1, 126, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x174, 1, 127, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x176, 1, 128, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x178, 1, 129, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x179, 1, 130, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x17b, 1, 131, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x17d, 1, 132, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x17f, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x181, 1, 133, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x182, 1, 134, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x184, 1, 135, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x186, 1, 136, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x187, 1, 137, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x189, 1, 138, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x18a, 1, 139, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x18b, 1, 140, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x18e, 1, 141, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x18f, 1, 142, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x190, 1, 143, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x191, 1, 144, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x193, 1, 145, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x194, 1, 146, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x196, 1, 147, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x197, 1, 148, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x198, 1, 149, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x19c, 1, 150, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x19d, 1, 151, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x19f, 1, 152, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1a0, 1, 153, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1a2, 1, 154, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1a4, 1, 155, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1a6, 1, 156, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1a7, 1, 157, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1a9, 1, 158, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ac, 1, 159, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ae, 1, 160, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1af, 1, 161, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1b1, 1, 162, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1b2, 1, 163, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1b3, 1, 164, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1b5, 1, 165, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1b7, 1, 166, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1b8, 1, 167, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1bc, 1, 168, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1c4, 1, 169, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1c5, 1, 169, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1c7, 1, 170, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1c8, 1, 170, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ca, 1, 171, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1cb, 1, 171, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1cd, 1, 172, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1cf, 1, 173, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1d1, 1, 174, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1d3, 1, 175, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1d5, 1, 176, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1d7, 1, 177, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1d9, 1, 178, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1db, 1, 179, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1de, 1, 180, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e0, 1, 181, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e2, 1, 182, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e4, 1, 183, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e6, 1, 184, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e8, 1, 185, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ea, 1, 186, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ec, 1, 187, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ee, 1, 188, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0, 2, 189, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f1, 1, 191, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2, 1, 191, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f4, 1, 192, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6, 1, 193, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f7, 1, 194, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8, 1, 195, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa, 1, 196, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc, 1, 197, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe, 1, 198, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x200, 1, 199, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x202, 1, 200, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x204, 1, 201, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x206, 1, 202, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x208, 1, 203, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x20a, 1, 204, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x20c, 1, 205, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x20e, 1, 206, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x210, 1, 207, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x212, 1, 208, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x214, 1, 209, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216, 1, 210, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x218, 1, 211, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x21a, 1, 212, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x21c, 1, 213, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x21e, 1, 214, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x220, 1, 215, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x222, 1, 216, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x224, 1, 217, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x226, 1, 218, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x228, 1, 219, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x22a, 1, 220, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x22c, 1, 221, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x22e, 1, 222, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x230, 1, 223, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x232, 1, 224, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x345, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x34f, 0, 226, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x37a, 2, 226, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x386, 1, 228, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x388, 1, 229, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x389, 1, 230, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x38a, 1, 231, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x38c, 1, 232, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x38e, 1, 233, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x38f, 1, 234, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x390, 3, 235, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x391, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x392, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x393, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x394, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x395, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x396, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x397, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x398, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x399, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x39a, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x39b, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x39c, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x39d, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x39e, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x39f, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a0, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a1, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a3, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a4, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a5, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a6, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a7, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a8, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3a9, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3aa, 1, 260, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3ab, 1, 261, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3b0, 3, 262, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3c2, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3d0, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3d1, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3d2, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3d3, 1, 233, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3d4, 1, 261, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3d5, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3d6, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3d8, 1, 265, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3da, 1, 266, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3dc, 1, 267, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3de, 1, 268, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3e0, 1, 269, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3e2, 1, 270, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3e4, 1, 271, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3e6, 1, 272, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3e8, 1, 273, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3ea, 1, 274, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3ec, 1, 275, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3ee, 1, 276, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3f0, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3f1, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3f2, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3f4, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3f5, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x400, 1, 277, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x401, 1, 278, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x402, 1, 279, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x403, 1, 280, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x404, 1, 281, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x405, 1, 282, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x406, 1, 283, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x407, 1, 284, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x408, 1, 285, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x409, 1, 286, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x40a, 1, 287, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x40b, 1, 288, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x40c, 1, 289, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x40d, 1, 290, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x40e, 1, 291, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x40f, 1, 292, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x410, 1, 293, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x411, 1, 294, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x412, 1, 295, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x413, 1, 296, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x414, 1, 297, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x415, 1, 298, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x416, 1, 299, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x417, 1, 300, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x418, 1, 301, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x419, 1, 302, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x41a, 1, 303, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x41b, 1, 304, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x41c, 1, 305, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x41d, 1, 306, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x41e, 1, 307, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x41f, 1, 308, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x420, 1, 309, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x421, 1, 310, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x422, 1, 311, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x423, 1, 312, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x424, 1, 313, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x425, 1, 314, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x426, 1, 315, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x427, 1, 316, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x428, 1, 317, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x429, 1, 318, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42a, 1, 319, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42b, 1, 320, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42c, 1, 321, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42d, 1, 322, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42e, 1, 323, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x42f, 1, 324, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x460, 1, 325, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x462, 1, 326, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x464, 1, 327, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x466, 1, 328, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x468, 1, 329, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x46a, 1, 330, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x46c, 1, 331, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x46e, 1, 332, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x470, 1, 333, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x472, 1, 334, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x474, 1, 335, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x476, 1, 336, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x478, 1, 337, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x47a, 1, 338, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x47c, 1, 339, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x47e, 1, 340, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x480, 1, 341, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x48a, 1, 342, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x48c, 1, 343, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x48e, 1, 344, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x490, 1, 345, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x492, 1, 346, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x494, 1, 347, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x496, 1, 348, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x498, 1, 349, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x49a, 1, 350, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x49c, 1, 351, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x49e, 1, 352, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4a0, 1, 353, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4a2, 1, 354, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4a4, 1, 355, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4a6, 1, 356, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4a8, 1, 357, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4aa, 1, 358, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4ac, 1, 359, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4ae, 1, 360, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4b0, 1, 361, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4b2, 1, 362, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4b4, 1, 363, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4b6, 1, 364, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4b8, 1, 365, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4ba, 1, 366, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4bc, 1, 367, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4be, 1, 368, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4c1, 1, 369, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4c3, 1, 370, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4c5, 1, 371, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4c7, 1, 372, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4c9, 1, 373, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4cb, 1, 374, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4cd, 1, 375, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4d0, 1, 376, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4d2, 1, 377, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4d4, 1, 378, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4d6, 1, 379, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4d8, 1, 380, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4da, 1, 381, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4dc, 1, 382, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4de, 1, 383, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4e0, 1, 384, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4e2, 1, 385, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4e4, 1, 386, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4e6, 1, 387, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4e8, 1, 388, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4ea, 1, 389, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4ec, 1, 390, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4ee, 1, 391, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4f0, 1, 392, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4f2, 1, 393, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4f4, 1, 394, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x4f8, 1, 395, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x500, 1, 396, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x502, 1, 397, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x504, 1, 398, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x506, 1, 399, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x508, 1, 400, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x50a, 1, 401, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x50c, 1, 402, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x50e, 1, 403, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x531, 1, 404, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x532, 1, 405, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x533, 1, 406, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x534, 1, 407, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x535, 1, 408, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x536, 1, 409, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x537, 1, 410, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x538, 1, 411, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x539, 1, 412, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53a, 1, 413, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53b, 1, 414, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53c, 1, 415, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53d, 1, 416, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53e, 1, 417, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x53f, 1, 418, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x540, 1, 419, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x541, 1, 420, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x542, 1, 421, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x543, 1, 422, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x544, 1, 423, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x545, 1, 424, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x546, 1, 425, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x547, 1, 426, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x548, 1, 427, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x549, 1, 428, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54a, 1, 429, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54b, 1, 430, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54c, 1, 431, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54d, 1, 432, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54e, 1, 433, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x54f, 1, 434, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x550, 1, 435, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x551, 1, 436, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x552, 1, 437, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x553, 1, 438, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x554, 1, 439, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x555, 1, 440, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x556, 1, 441, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x587, 2, 442, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x6dd, 0, 444, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x70f, 0, 444, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1680, 1, 444, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x1806, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x180b, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x180c, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x180d, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x180e, 0, 445, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1e00, 1, 445, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e02, 1, 446, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e04, 1, 447, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e06, 1, 448, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e08, 1, 449, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e0a, 1, 450, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e0c, 1, 451, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e0e, 1, 452, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e10, 1, 453, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e12, 1, 454, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e14, 1, 455, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e16, 1, 456, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e18, 1, 457, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e1a, 1, 458, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e1c, 1, 459, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e1e, 1, 460, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e20, 1, 461, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e22, 1, 462, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e24, 1, 463, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e26, 1, 464, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e28, 1, 465, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e2a, 1, 466, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e2c, 1, 467, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e2e, 1, 468, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e30, 1, 469, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e32, 1, 470, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e34, 1, 471, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e36, 1, 472, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e38, 1, 473, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e3a, 1, 474, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e3c, 1, 475, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e3e, 1, 476, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e40, 1, 477, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e42, 1, 478, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e44, 1, 479, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e46, 1, 480, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e48, 1, 481, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e4a, 1, 482, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e4c, 1, 483, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e4e, 1, 484, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e50, 1, 485, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e52, 1, 486, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e54, 1, 487, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e56, 1, 488, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e58, 1, 489, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e5a, 1, 490, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e5c, 1, 491, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e5e, 1, 492, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e60, 1, 493, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e62, 1, 494, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e64, 1, 495, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e66, 1, 496, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e68, 1, 497, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e6a, 1, 498, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e6c, 1, 499, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e6e, 1, 500, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e70, 1, 501, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e72, 1, 502, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e74, 1, 503, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e76, 1, 504, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e78, 1, 505, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e7a, 1, 506, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e7c, 1, 507, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e7e, 1, 508, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e80, 1, 509, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e82, 1, 510, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e84, 1, 511, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e86, 1, 512, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e88, 1, 513, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e8a, 1, 514, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e8c, 1, 515, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e8e, 1, 516, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e90, 1, 517, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e92, 1, 518, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e94, 1, 519, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e96, 2, 520, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e97, 2, 522, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e98, 2, 524, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e99, 2, 526, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e9a, 2, 528, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1e9b, 1, 493, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ea0, 1, 530, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ea2, 1, 531, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ea4, 1, 532, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ea6, 1, 533, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ea8, 1, 534, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eaa, 1, 535, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eac, 1, 536, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eae, 1, 537, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eb0, 1, 538, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eb2, 1, 539, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eb4, 1, 540, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eb6, 1, 541, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eb8, 1, 542, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eba, 1, 543, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ebc, 1, 544, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ebe, 1, 545, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ec0, 1, 546, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ec2, 1, 547, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ec4, 1, 548, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ec6, 1, 549, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ec8, 1, 550, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eca, 1, 551, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ecc, 1, 552, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ece, 1, 553, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ed0, 1, 554, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ed2, 1, 555, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ed4, 1, 556, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ed6, 1, 557, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ed8, 1, 558, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eda, 1, 559, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1edc, 1, 560, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ede, 1, 561, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ee0, 1, 562, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ee2, 1, 563, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ee4, 1, 564, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ee6, 1, 565, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ee8, 1, 566, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eea, 1, 567, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eec, 1, 568, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1eee, 1, 569, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ef0, 1, 570, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ef2, 1, 571, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ef4, 1, 572, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ef6, 1, 573, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ef8, 1, 574, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f08, 1, 575, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f09, 1, 576, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0a, 1, 577, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0b, 1, 578, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0c, 1, 579, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0d, 1, 580, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0e, 1, 581, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f0f, 1, 582, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f18, 1, 583, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f19, 1, 584, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f1a, 1, 585, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f1b, 1, 586, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f1c, 1, 587, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f1d, 1, 588, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f28, 1, 589, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f29, 1, 590, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2a, 1, 591, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2b, 1, 592, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2c, 1, 593, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2d, 1, 594, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2e, 1, 595, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f2f, 1, 596, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f38, 1, 597, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f39, 1, 598, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f3a, 1, 599, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f3b, 1, 600, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f3c, 1, 601, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f3d, 1, 602, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f3e, 1, 603, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f3f, 1, 604, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f48, 1, 605, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f49, 1, 606, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f4a, 1, 607, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f4b, 1, 608, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f4c, 1, 609, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f4d, 1, 610, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f50, 2, 611, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f52, 3, 613, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f54, 3, 616, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f56, 3, 619, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f59, 1, 622, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f5b, 1, 623, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f5d, 1, 624, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f5f, 1, 625, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f68, 1, 626, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f69, 1, 627, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6a, 1, 628, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6b, 1, 629, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6c, 1, 630, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6d, 1, 631, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6e, 1, 632, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f6f, 1, 633, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f80, 2, 634, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f81, 2, 636, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f82, 2, 638, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f83, 2, 640, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f84, 2, 642, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f85, 2, 644, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f86, 2, 646, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f87, 2, 648, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f88, 2, 634, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f89, 2, 636, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8a, 2, 638, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8b, 2, 640, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8c, 2, 642, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8d, 2, 644, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8e, 2, 646, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f8f, 2, 648, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f90, 2, 650, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f91, 2, 652, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f92, 2, 654, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f93, 2, 656, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f94, 2, 658, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f95, 2, 660, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f96, 2, 662, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f97, 2, 664, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f98, 2, 650, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f99, 2, 652, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f9a, 2, 654, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f9b, 2, 656, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f9c, 2, 658, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f9d, 2, 660, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f9e, 2, 662, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1f9f, 2, 664, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa0, 2, 666, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa1, 2, 668, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa2, 2, 670, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa3, 2, 672, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa4, 2, 674, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa5, 2, 676, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa6, 2, 678, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa7, 2, 680, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa8, 2, 666, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fa9, 2, 668, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1faa, 2, 670, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fab, 2, 672, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fac, 2, 674, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fad, 2, 676, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fae, 2, 678, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1faf, 2, 680, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb2, 2, 682, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb3, 2, 684, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb4, 2, 686, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb6, 2, 688, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb7, 3, 690, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb8, 1, 693, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fb9, 1, 694, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fba, 1, 682, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fbb, 1, 695, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fbc, 2, 684, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fbe, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc2, 2, 696, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc3, 2, 698, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc4, 2, 700, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc6, 2, 702, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc7, 3, 704, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc8, 1, 707, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fc9, 1, 708, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fca, 1, 696, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fcb, 1, 709, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fcc, 2, 698, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fd2, 3, 710, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fd3, 3, 235, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fd6, 2, 713, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fd7, 3, 715, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fd8, 1, 718, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fd9, 1, 719, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fda, 1, 720, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fdb, 1, 721, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe2, 3, 722, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe3, 3, 262, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe4, 2, 725, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe6, 2, 727, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe7, 3, 729, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe8, 1, 732, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fe9, 1, 733, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fea, 1, 734, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1feb, 1, 735, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1fec, 1, 736, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff2, 2, 737, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff3, 2, 739, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff4, 2, 234, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff6, 2, 741, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff7, 3, 743, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff8, 1, 746, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ff9, 1, 747, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ffa, 1, 737, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ffb, 1, 748, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1ffc, 2, 739, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2000, 1, 749, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2001, 1, 750, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2002, 1, 751, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2003, 1, 752, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2004, 1, 753, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2005, 1, 754, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2006, 1, 755, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2007, 1, 756, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2008, 1, 757, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2009, 1, 758, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x200b, 0, 759, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x200c, 0, 759, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x200d, 0, 759, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x200e, 0, 759, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x2028, 1, 759, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x202a, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x202b, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x202c, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x202d, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x202f, 1, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x205f, 1, 761, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x2060, 0, 762, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0x2061, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x2062, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x206a, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x206b, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x206c, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x206d, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x206e, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x20a8, 2, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2102, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2103, 2, 762, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2107, 1, 143, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2109, 2, 764, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x210b, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x210c, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x210d, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2110, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2111, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2112, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2115, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2116, 2, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2119, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x211a, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x211b, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x211c, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x211d, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2120, 2, 766, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2121, 3, 768, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2122, 2, 771, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2124, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2126, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2128, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x212a, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x212b, 1, 40, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x212c, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x212d, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2130, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2131, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2133, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x213e, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x213f, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2145, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x2160, 1, 773, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2161, 1, 774, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2162, 1, 775, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2163, 1, 776, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2164, 1, 777, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2165, 1, 778, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2166, 1, 779, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2167, 1, 780, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2168, 1, 781, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x2169, 1, 782, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216a, 1, 783, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216b, 1, 784, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216c, 1, 785, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216d, 1, 786, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216e, 1, 787, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x216f, 1, 788, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24b6, 1, 789, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24b7, 1, 790, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24b8, 1, 791, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24b9, 1, 792, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24ba, 1, 793, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24bb, 1, 794, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24bc, 1, 795, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24bd, 1, 796, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24be, 1, 797, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24bf, 1, 798, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c0, 1, 799, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c1, 1, 800, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c2, 1, 801, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c3, 1, 802, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c4, 1, 803, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c5, 1, 804, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c6, 1, 805, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c7, 1, 806, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c8, 1, 807, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24c9, 1, 808, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24ca, 1, 809, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24cb, 1, 810, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24cc, 1, 811, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24cd, 1, 812, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24ce, 1, 813, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x24cf, 1, 814, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x3000, 1, 815, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+ {0x3371, 3, 816, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3373, 2, 819, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3375, 2, 821, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3380, 2, 817, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3381, 2, 823, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3382, 2, 825, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3383, 2, 827, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3384, 2, 829, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3385, 2, 831, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3386, 2, 833, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3387, 2, 835, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x338a, 2, 837, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x338b, 2, 839, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x338c, 2, 841, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3390, 2, 843, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3391, 3, 845, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3392, 3, 848, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3393, 3, 851, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x3394, 3, 854, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33a9, 2, 817, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33aa, 3, 857, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33ab, 3, 860, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33ac, 3, 863, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33b4, 2, 866, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33b5, 2, 868, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33b6, 2, 870, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33b7, 2, 872, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33b8, 2, 874, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33b9, 2, 872, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33ba, 2, 876, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33bb, 2, 878, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33bc, 2, 880, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33bd, 2, 882, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33be, 2, 884, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33bf, 2, 882, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c0, 2, 886, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c1, 2, 888, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c3, 2, 890, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c6, 4, 892, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c7, 3, 896, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c8, 2, 899, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33c9, 2, 901, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33cb, 2, 816, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33cd, 2, 903, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33ce, 2, 905, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33d7, 2, 907, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33d9, 3, 909, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33da, 2, 912, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33dc, 2, 914, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x33dd, 2, 916, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0xfb00, 2, 918, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb01, 2, 920, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb02, 2, 922, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb03, 3, 919, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb04, 3, 924, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb05, 2, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb06, 2, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb13, 2, 927, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb14, 2, 929, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb15, 2, 931, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb16, 2, 933, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfb17, 2, 935, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfe00, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe01, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe02, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe03, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe04, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe05, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe06, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe07, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe08, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe09, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe0a, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe0b, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe0c, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe0d, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe0e, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfe0f, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xfeff, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+ {0xff21, 1, 937, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff22, 1, 938, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff23, 1, 939, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff24, 1, 940, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff25, 1, 941, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff26, 1, 942, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff27, 1, 943, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff28, 1, 944, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff29, 1, 945, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff2a, 1, 946, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff2b, 1, 947, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff2c, 1, 948, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff2d, 1, 949, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff2e, 1, 950, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff2f, 1, 951, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff30, 1, 952, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff31, 1, 953, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff32, 1, 954, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff33, 1, 955, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff34, 1, 956, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff35, 1, 957, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff36, 1, 958, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff37, 1, 959, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff38, 1, 960, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff39, 1, 961, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xff3a, 1, 962, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0xfff9, 0, 963, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xfffa, 0, 963, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xfffc, 0, 963, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x10400, 1, 963, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10401, 1, 964, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10402, 1, 965, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10403, 1, 966, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10404, 1, 967, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10405, 1, 968, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10406, 1, 969, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10407, 1, 970, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10408, 1, 971, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10409, 1, 972, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1040a, 1, 973, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1040b, 1, 974, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1040c, 1, 975, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1040d, 1, 976, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1040e, 1, 977, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1040f, 1, 978, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10410, 1, 979, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10411, 1, 980, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10412, 1, 981, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10413, 1, 982, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10414, 1, 983, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10415, 1, 984, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10416, 1, 985, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10417, 1, 986, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10418, 1, 987, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10419, 1, 988, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1041a, 1, 989, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1041b, 1, 990, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1041c, 1, 991, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1041d, 1, 992, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1041e, 1, 993, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1041f, 1, 994, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10420, 1, 995, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10421, 1, 996, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10422, 1, 997, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10423, 1, 998, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10424, 1, 999, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x10425, 1, 1000, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+ {0x1d173, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d174, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d175, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d176, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d177, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d178, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d179, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0x1d400, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d401, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d402, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d403, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d404, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d405, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d406, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d407, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d408, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d409, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d40a, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d40b, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d40c, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d40d, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d40e, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d40f, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d410, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d411, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d412, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d413, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d414, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d415, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d416, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d417, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d418, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d419, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d434, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d435, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d436, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d437, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d438, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d439, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d43a, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d43b, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d43c, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d43d, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d43e, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d43f, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d440, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d441, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d442, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d443, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d444, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d445, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d446, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d447, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d448, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d449, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d44a, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d44b, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d44c, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d44d, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d468, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d469, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d46a, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d46b, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d46c, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d46d, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d46e, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d46f, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d470, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d471, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d472, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d473, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d474, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d475, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d476, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d477, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d478, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d479, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d47a, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d47b, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d47c, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d47d, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d47e, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d47f, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d480, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d481, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d49c, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d49e, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d49f, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4a2, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4a5, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4a6, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4a9, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4aa, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4ab, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4ac, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4ae, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4af, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4b0, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4b1, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4b2, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4b3, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4b4, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4b5, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d0, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d1, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d2, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d3, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d4, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d5, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d6, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d7, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d8, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4d9, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4da, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4db, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4dc, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4dd, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4de, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4df, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e0, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e1, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e2, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e3, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e4, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e5, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e6, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e7, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e8, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d4e9, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d504, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d505, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d507, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d508, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d509, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d50a, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d50d, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d50e, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d50f, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d510, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d511, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d512, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d513, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d514, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d516, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d517, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d518, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d519, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d51a, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d51b, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d51c, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d538, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d539, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d53b, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d53c, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d53d, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d53e, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d540, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d541, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d542, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d543, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d544, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d546, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d54a, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d54b, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d54c, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d54d, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d54e, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d54f, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d550, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d56c, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d56d, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d56e, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d56f, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d570, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d571, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d572, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d573, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d574, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d575, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d576, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d577, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d578, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d579, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d57a, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d57b, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d57c, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d57d, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d57e, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d57f, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d580, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d581, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d582, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d583, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d584, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d585, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a0, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a1, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a2, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a3, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a4, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a5, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a6, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a7, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a8, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5a9, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5aa, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ab, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ac, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ad, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ae, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5af, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b0, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b1, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b2, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b3, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b4, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b5, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b6, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b7, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b8, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5b9, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5d4, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5d5, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5d6, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5d7, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5d8, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5d9, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5da, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5db, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5dc, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5dd, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5de, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5df, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e0, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e1, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e2, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e3, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e4, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e5, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e6, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e7, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e8, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5e9, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ea, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5eb, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ec, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d5ed, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d608, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d609, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d60a, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d60b, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d60c, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d60d, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d60e, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d60f, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d610, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d611, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d612, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d613, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d614, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d615, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d616, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d617, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d618, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d619, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d61a, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d61b, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d61c, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d61d, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d61e, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d61f, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d620, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d621, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d63c, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d63d, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d63e, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d63f, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d640, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d641, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d642, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d643, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d644, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d645, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d646, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d647, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d648, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d649, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d64a, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d64b, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d64c, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d64d, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d64e, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d64f, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d650, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d651, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d652, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d653, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d654, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d655, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d670, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d671, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d672, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d673, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d674, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d675, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d676, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d677, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d678, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d679, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d67a, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d67b, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d67c, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d67d, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d67e, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d67f, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d680, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d681, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d682, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d683, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d684, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d685, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d686, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d687, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d688, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d689, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6a8, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6a9, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6aa, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ab, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ac, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ad, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ae, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6af, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b0, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b1, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b2, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b3, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b4, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b5, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b6, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b7, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b8, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6b9, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ba, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6bb, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6bc, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6bd, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6be, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6bf, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6c0, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6d3, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e2, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e3, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e4, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e5, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e6, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e7, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e8, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6e9, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ea, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6eb, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ec, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ed, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ee, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6ef, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f0, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f1, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f2, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f3, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f4, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f5, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f6, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f7, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f8, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6f9, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d6fa, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d70d, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d71c, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d71d, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d71e, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d71f, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d720, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d721, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d722, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d723, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d724, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d725, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d726, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d727, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d728, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d729, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d72a, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d72b, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d72c, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d72d, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d72e, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d72f, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d730, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d731, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d732, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d733, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d734, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d747, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d756, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d757, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d758, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d759, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d75a, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d75b, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d75c, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d75d, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d75e, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d75f, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d760, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d761, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d762, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d763, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d764, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d765, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d766, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d767, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d768, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d769, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d76a, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d76b, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d76c, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d76d, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d76e, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d781, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d790, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d791, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d792, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d793, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d794, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d795, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d796, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d797, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d798, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d799, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d79a, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d79b, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d79c, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d79d, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d79e, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d79f, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a0, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a1, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a2, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a3, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a4, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a5, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a6, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a7, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7a8, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0x1d7bb, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+ {0xe0001, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0020, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0021, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0022, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0023, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0024, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0025, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0026, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0027, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0028, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0029, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe002a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe002b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe002c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe002d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe002e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe002f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0030, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0031, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0032, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0033, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0034, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0035, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0036, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0037, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0038, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0039, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe003a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe003b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe003c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe003d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe003e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe003f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0040, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0041, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0042, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0043, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0044, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0045, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0046, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0047, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0048, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0049, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe004a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe004b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe004c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe004d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe004e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe004f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0050, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0051, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0052, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0053, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0054, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0055, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0056, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0057, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0058, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0059, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe005a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe005b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe005c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe005d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe005e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe005f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0060, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0061, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0062, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0063, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0064, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0065, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0066, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0067, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0068, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0069, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe006a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe006b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe006c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe006d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe006e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe006f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0070, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0071, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0072, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0073, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0074, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0075, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0076, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0077, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0078, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe0079, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe007a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe007b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe007c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe007d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+ {0xe007e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+
+};
+
+const size_t _wind_map_table_size = 1597;
+
+const uint32_t _wind_map_table_val[] = {
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0061,
+ 0x0062,
+ 0x0063,
+ 0x0064,
+ 0x0065,
+ 0x0066,
+ 0x0067,
+ 0x0068,
+ 0x0069,
+ 0x006A,
+ 0x006B,
+ 0x006C,
+ 0x006D,
+ 0x006E,
+ 0x006F,
+ 0x0070,
+ 0x0071,
+ 0x0072,
+ 0x0073,
+ 0x0074,
+ 0x0075,
+ 0x0076,
+ 0x0077,
+ 0x0078,
+ 0x0079,
+ 0x007A,
+ 0x0020,
+ 0x0020,
+ 0x03BC,
+ 0x00E0,
+ 0x00E1,
+ 0x00E2,
+ 0x00E3,
+ 0x00E4,
+ 0x00E5,
+ 0x00E6,
+ 0x00E7,
+ 0x00E8,
+ 0x00E9,
+ 0x00EA,
+ 0x00EB,
+ 0x00EC,
+ 0x00ED,
+ 0x00EE,
+ 0x00EF,
+ 0x00F0,
+ 0x00F1,
+ 0x00F2,
+ 0x00F3,
+ 0x00F4,
+ 0x00F5,
+ 0x00F6,
+ 0x00F8,
+ 0x00F9,
+ 0x00FA,
+ 0x00FB,
+ 0x00FC,
+ 0x00FD,
+ 0x00FE,
+ 0x0073,
+ 0x0073,
+ 0x0101,
+ 0x0103,
+ 0x0105,
+ 0x0107,
+ 0x0109,
+ 0x010B,
+ 0x010D,
+ 0x010F,
+ 0x0111,
+ 0x0113,
+ 0x0115,
+ 0x0117,
+ 0x0119,
+ 0x011B,
+ 0x011D,
+ 0x011F,
+ 0x0121,
+ 0x0123,
+ 0x0125,
+ 0x0127,
+ 0x0129,
+ 0x012B,
+ 0x012D,
+ 0x012F,
+ 0x0069,
+ 0x0307,
+ 0x0133,
+ 0x0135,
+ 0x0137,
+ 0x013A,
+ 0x013C,
+ 0x013E,
+ 0x0140,
+ 0x0142,
+ 0x0144,
+ 0x0146,
+ 0x0148,
+ 0x02BC,
+ 0x006E,
+ 0x014B,
+ 0x014D,
+ 0x014F,
+ 0x0151,
+ 0x0153,
+ 0x0155,
+ 0x0157,
+ 0x0159,
+ 0x015B,
+ 0x015D,
+ 0x015F,
+ 0x0161,
+ 0x0163,
+ 0x0165,
+ 0x0167,
+ 0x0169,
+ 0x016B,
+ 0x016D,
+ 0x016F,
+ 0x0171,
+ 0x0173,
+ 0x0175,
+ 0x0177,
+ 0x00FF,
+ 0x017A,
+ 0x017C,
+ 0x017E,
+ 0x0253,
+ 0x0183,
+ 0x0185,
+ 0x0254,
+ 0x0188,
+ 0x0256,
+ 0x0257,
+ 0x018C,
+ 0x01DD,
+ 0x0259,
+ 0x025B,
+ 0x0192,
+ 0x0260,
+ 0x0263,
+ 0x0269,
+ 0x0268,
+ 0x0199,
+ 0x026F,
+ 0x0272,
+ 0x0275,
+ 0x01A1,
+ 0x01A3,
+ 0x01A5,
+ 0x0280,
+ 0x01A8,
+ 0x0283,
+ 0x01AD,
+ 0x0288,
+ 0x01B0,
+ 0x028A,
+ 0x028B,
+ 0x01B4,
+ 0x01B6,
+ 0x0292,
+ 0x01B9,
+ 0x01BD,
+ 0x01C6,
+ 0x01C9,
+ 0x01CC,
+ 0x01CE,
+ 0x01D0,
+ 0x01D2,
+ 0x01D4,
+ 0x01D6,
+ 0x01D8,
+ 0x01DA,
+ 0x01DC,
+ 0x01DF,
+ 0x01E1,
+ 0x01E3,
+ 0x01E5,
+ 0x01E7,
+ 0x01E9,
+ 0x01EB,
+ 0x01ED,
+ 0x01EF,
+ 0x006A,
+ 0x030C,
+ 0x01F3,
+ 0x01F5,
+ 0x0195,
+ 0x01BF,
+ 0x01F9,
+ 0x01FB,
+ 0x01FD,
+ 0x01FF,
+ 0x0201,
+ 0x0203,
+ 0x0205,
+ 0x0207,
+ 0x0209,
+ 0x020B,
+ 0x020D,
+ 0x020F,
+ 0x0211,
+ 0x0213,
+ 0x0215,
+ 0x0217,
+ 0x0219,
+ 0x021B,
+ 0x021D,
+ 0x021F,
+ 0x019E,
+ 0x0223,
+ 0x0225,
+ 0x0227,
+ 0x0229,
+ 0x022B,
+ 0x022D,
+ 0x022F,
+ 0x0231,
+ 0x0233,
+ 0x03B9,
+ 0x0020,
+ 0x03B9,
+ 0x03AC,
+ 0x03AD,
+ 0x03AE,
+ 0x03AF,
+ 0x03CC,
+ 0x03CD,
+ 0x03CE,
+ 0x03B9,
+ 0x0308,
+ 0x0301,
+ 0x03B1,
+ 0x03B2,
+ 0x03B3,
+ 0x03B4,
+ 0x03B5,
+ 0x03B6,
+ 0x03B7,
+ 0x03B8,
+ 0x03BA,
+ 0x03BB,
+ 0x03BD,
+ 0x03BE,
+ 0x03BF,
+ 0x03C0,
+ 0x03C1,
+ 0x03C3,
+ 0x03C4,
+ 0x03C5,
+ 0x03C6,
+ 0x03C7,
+ 0x03C8,
+ 0x03C9,
+ 0x03CA,
+ 0x03CB,
+ 0x03C5,
+ 0x0308,
+ 0x0301,
+ 0x03D9,
+ 0x03DB,
+ 0x03DD,
+ 0x03DF,
+ 0x03E1,
+ 0x03E3,
+ 0x03E5,
+ 0x03E7,
+ 0x03E9,
+ 0x03EB,
+ 0x03ED,
+ 0x03EF,
+ 0x0450,
+ 0x0451,
+ 0x0452,
+ 0x0453,
+ 0x0454,
+ 0x0455,
+ 0x0456,
+ 0x0457,
+ 0x0458,
+ 0x0459,
+ 0x045A,
+ 0x045B,
+ 0x045C,
+ 0x045D,
+ 0x045E,
+ 0x045F,
+ 0x0430,
+ 0x0431,
+ 0x0432,
+ 0x0433,
+ 0x0434,
+ 0x0435,
+ 0x0436,
+ 0x0437,
+ 0x0438,
+ 0x0439,
+ 0x043A,
+ 0x043B,
+ 0x043C,
+ 0x043D,
+ 0x043E,
+ 0x043F,
+ 0x0440,
+ 0x0441,
+ 0x0442,
+ 0x0443,
+ 0x0444,
+ 0x0445,
+ 0x0446,
+ 0x0447,
+ 0x0448,
+ 0x0449,
+ 0x044A,
+ 0x044B,
+ 0x044C,
+ 0x044D,
+ 0x044E,
+ 0x044F,
+ 0x0461,
+ 0x0463,
+ 0x0465,
+ 0x0467,
+ 0x0469,
+ 0x046B,
+ 0x046D,
+ 0x046F,
+ 0x0471,
+ 0x0473,
+ 0x0475,
+ 0x0477,
+ 0x0479,
+ 0x047B,
+ 0x047D,
+ 0x047F,
+ 0x0481,
+ 0x048B,
+ 0x048D,
+ 0x048F,
+ 0x0491,
+ 0x0493,
+ 0x0495,
+ 0x0497,
+ 0x0499,
+ 0x049B,
+ 0x049D,
+ 0x049F,
+ 0x04A1,
+ 0x04A3,
+ 0x04A5,
+ 0x04A7,
+ 0x04A9,
+ 0x04AB,
+ 0x04AD,
+ 0x04AF,
+ 0x04B1,
+ 0x04B3,
+ 0x04B5,
+ 0x04B7,
+ 0x04B9,
+ 0x04BB,
+ 0x04BD,
+ 0x04BF,
+ 0x04C2,
+ 0x04C4,
+ 0x04C6,
+ 0x04C8,
+ 0x04CA,
+ 0x04CC,
+ 0x04CE,
+ 0x04D1,
+ 0x04D3,
+ 0x04D5,
+ 0x04D7,
+ 0x04D9,
+ 0x04DB,
+ 0x04DD,
+ 0x04DF,
+ 0x04E1,
+ 0x04E3,
+ 0x04E5,
+ 0x04E7,
+ 0x04E9,
+ 0x04EB,
+ 0x04ED,
+ 0x04EF,
+ 0x04F1,
+ 0x04F3,
+ 0x04F5,
+ 0x04F9,
+ 0x0501,
+ 0x0503,
+ 0x0505,
+ 0x0507,
+ 0x0509,
+ 0x050B,
+ 0x050D,
+ 0x050F,
+ 0x0561,
+ 0x0562,
+ 0x0563,
+ 0x0564,
+ 0x0565,
+ 0x0566,
+ 0x0567,
+ 0x0568,
+ 0x0569,
+ 0x056A,
+ 0x056B,
+ 0x056C,
+ 0x056D,
+ 0x056E,
+ 0x056F,
+ 0x0570,
+ 0x0571,
+ 0x0572,
+ 0x0573,
+ 0x0574,
+ 0x0575,
+ 0x0576,
+ 0x0577,
+ 0x0578,
+ 0x0579,
+ 0x057A,
+ 0x057B,
+ 0x057C,
+ 0x057D,
+ 0x057E,
+ 0x057F,
+ 0x0580,
+ 0x0581,
+ 0x0582,
+ 0x0583,
+ 0x0584,
+ 0x0585,
+ 0x0586,
+ 0x0565,
+ 0x0582,
+ 0x0020,
+ 0x1E01,
+ 0x1E03,
+ 0x1E05,
+ 0x1E07,
+ 0x1E09,
+ 0x1E0B,
+ 0x1E0D,
+ 0x1E0F,
+ 0x1E11,
+ 0x1E13,
+ 0x1E15,
+ 0x1E17,
+ 0x1E19,
+ 0x1E1B,
+ 0x1E1D,
+ 0x1E1F,
+ 0x1E21,
+ 0x1E23,
+ 0x1E25,
+ 0x1E27,
+ 0x1E29,
+ 0x1E2B,
+ 0x1E2D,
+ 0x1E2F,
+ 0x1E31,
+ 0x1E33,
+ 0x1E35,
+ 0x1E37,
+ 0x1E39,
+ 0x1E3B,
+ 0x1E3D,
+ 0x1E3F,
+ 0x1E41,
+ 0x1E43,
+ 0x1E45,
+ 0x1E47,
+ 0x1E49,
+ 0x1E4B,
+ 0x1E4D,
+ 0x1E4F,
+ 0x1E51,
+ 0x1E53,
+ 0x1E55,
+ 0x1E57,
+ 0x1E59,
+ 0x1E5B,
+ 0x1E5D,
+ 0x1E5F,
+ 0x1E61,
+ 0x1E63,
+ 0x1E65,
+ 0x1E67,
+ 0x1E69,
+ 0x1E6B,
+ 0x1E6D,
+ 0x1E6F,
+ 0x1E71,
+ 0x1E73,
+ 0x1E75,
+ 0x1E77,
+ 0x1E79,
+ 0x1E7B,
+ 0x1E7D,
+ 0x1E7F,
+ 0x1E81,
+ 0x1E83,
+ 0x1E85,
+ 0x1E87,
+ 0x1E89,
+ 0x1E8B,
+ 0x1E8D,
+ 0x1E8F,
+ 0x1E91,
+ 0x1E93,
+ 0x1E95,
+ 0x0068,
+ 0x0331,
+ 0x0074,
+ 0x0308,
+ 0x0077,
+ 0x030A,
+ 0x0079,
+ 0x030A,
+ 0x0061,
+ 0x02BE,
+ 0x1EA1,
+ 0x1EA3,
+ 0x1EA5,
+ 0x1EA7,
+ 0x1EA9,
+ 0x1EAB,
+ 0x1EAD,
+ 0x1EAF,
+ 0x1EB1,
+ 0x1EB3,
+ 0x1EB5,
+ 0x1EB7,
+ 0x1EB9,
+ 0x1EBB,
+ 0x1EBD,
+ 0x1EBF,
+ 0x1EC1,
+ 0x1EC3,
+ 0x1EC5,
+ 0x1EC7,
+ 0x1EC9,
+ 0x1ECB,
+ 0x1ECD,
+ 0x1ECF,
+ 0x1ED1,
+ 0x1ED3,
+ 0x1ED5,
+ 0x1ED7,
+ 0x1ED9,
+ 0x1EDB,
+ 0x1EDD,
+ 0x1EDF,
+ 0x1EE1,
+ 0x1EE3,
+ 0x1EE5,
+ 0x1EE7,
+ 0x1EE9,
+ 0x1EEB,
+ 0x1EED,
+ 0x1EEF,
+ 0x1EF1,
+ 0x1EF3,
+ 0x1EF5,
+ 0x1EF7,
+ 0x1EF9,
+ 0x1F00,
+ 0x1F01,
+ 0x1F02,
+ 0x1F03,
+ 0x1F04,
+ 0x1F05,
+ 0x1F06,
+ 0x1F07,
+ 0x1F10,
+ 0x1F11,
+ 0x1F12,
+ 0x1F13,
+ 0x1F14,
+ 0x1F15,
+ 0x1F20,
+ 0x1F21,
+ 0x1F22,
+ 0x1F23,
+ 0x1F24,
+ 0x1F25,
+ 0x1F26,
+ 0x1F27,
+ 0x1F30,
+ 0x1F31,
+ 0x1F32,
+ 0x1F33,
+ 0x1F34,
+ 0x1F35,
+ 0x1F36,
+ 0x1F37,
+ 0x1F40,
+ 0x1F41,
+ 0x1F42,
+ 0x1F43,
+ 0x1F44,
+ 0x1F45,
+ 0x03C5,
+ 0x0313,
+ 0x03C5,
+ 0x0313,
+ 0x0300,
+ 0x03C5,
+ 0x0313,
+ 0x0301,
+ 0x03C5,
+ 0x0313,
+ 0x0342,
+ 0x1F51,
+ 0x1F53,
+ 0x1F55,
+ 0x1F57,
+ 0x1F60,
+ 0x1F61,
+ 0x1F62,
+ 0x1F63,
+ 0x1F64,
+ 0x1F65,
+ 0x1F66,
+ 0x1F67,
+ 0x1F00,
+ 0x03B9,
+ 0x1F01,
+ 0x03B9,
+ 0x1F02,
+ 0x03B9,
+ 0x1F03,
+ 0x03B9,
+ 0x1F04,
+ 0x03B9,
+ 0x1F05,
+ 0x03B9,
+ 0x1F06,
+ 0x03B9,
+ 0x1F07,
+ 0x03B9,
+ 0x1F20,
+ 0x03B9,
+ 0x1F21,
+ 0x03B9,
+ 0x1F22,
+ 0x03B9,
+ 0x1F23,
+ 0x03B9,
+ 0x1F24,
+ 0x03B9,
+ 0x1F25,
+ 0x03B9,
+ 0x1F26,
+ 0x03B9,
+ 0x1F27,
+ 0x03B9,
+ 0x1F60,
+ 0x03B9,
+ 0x1F61,
+ 0x03B9,
+ 0x1F62,
+ 0x03B9,
+ 0x1F63,
+ 0x03B9,
+ 0x1F64,
+ 0x03B9,
+ 0x1F65,
+ 0x03B9,
+ 0x1F66,
+ 0x03B9,
+ 0x1F67,
+ 0x03B9,
+ 0x1F70,
+ 0x03B9,
+ 0x03B1,
+ 0x03B9,
+ 0x03AC,
+ 0x03B9,
+ 0x03B1,
+ 0x0342,
+ 0x03B1,
+ 0x0342,
+ 0x03B9,
+ 0x1FB0,
+ 0x1FB1,
+ 0x1F71,
+ 0x1F74,
+ 0x03B9,
+ 0x03B7,
+ 0x03B9,
+ 0x03AE,
+ 0x03B9,
+ 0x03B7,
+ 0x0342,
+ 0x03B7,
+ 0x0342,
+ 0x03B9,
+ 0x1F72,
+ 0x1F73,
+ 0x1F75,
+ 0x03B9,
+ 0x0308,
+ 0x0300,
+ 0x03B9,
+ 0x0342,
+ 0x03B9,
+ 0x0308,
+ 0x0342,
+ 0x1FD0,
+ 0x1FD1,
+ 0x1F76,
+ 0x1F77,
+ 0x03C5,
+ 0x0308,
+ 0x0300,
+ 0x03C1,
+ 0x0313,
+ 0x03C5,
+ 0x0342,
+ 0x03C5,
+ 0x0308,
+ 0x0342,
+ 0x1FE0,
+ 0x1FE1,
+ 0x1F7A,
+ 0x1F7B,
+ 0x1FE5,
+ 0x1F7C,
+ 0x03B9,
+ 0x03C9,
+ 0x03B9,
+ 0x03C9,
+ 0x0342,
+ 0x03C9,
+ 0x0342,
+ 0x03B9,
+ 0x1F78,
+ 0x1F79,
+ 0x1F7D,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x0020,
+ 0x00B0,
+ 0x0063,
+ 0x00B0,
+ 0x0066,
+ 0x0073,
+ 0x006D,
+ 0x0074,
+ 0x0065,
+ 0x006C,
+ 0x0074,
+ 0x006D,
+ 0x2170,
+ 0x2171,
+ 0x2172,
+ 0x2173,
+ 0x2174,
+ 0x2175,
+ 0x2176,
+ 0x2177,
+ 0x2178,
+ 0x2179,
+ 0x217A,
+ 0x217B,
+ 0x217C,
+ 0x217D,
+ 0x217E,
+ 0x217F,
+ 0x24D0,
+ 0x24D1,
+ 0x24D2,
+ 0x24D3,
+ 0x24D4,
+ 0x24D5,
+ 0x24D6,
+ 0x24D7,
+ 0x24D8,
+ 0x24D9,
+ 0x24DA,
+ 0x24DB,
+ 0x24DC,
+ 0x24DD,
+ 0x24DE,
+ 0x24DF,
+ 0x24E0,
+ 0x24E1,
+ 0x24E2,
+ 0x24E3,
+ 0x24E4,
+ 0x24E5,
+ 0x24E6,
+ 0x24E7,
+ 0x24E8,
+ 0x24E9,
+ 0x0020,
+ 0x0068,
+ 0x0070,
+ 0x0061,
+ 0x0061,
+ 0x0075,
+ 0x006F,
+ 0x0076,
+ 0x006E,
+ 0x0061,
+ 0x03BC,
+ 0x0061,
+ 0x006D,
+ 0x0061,
+ 0x006B,
+ 0x0061,
+ 0x006B,
+ 0x0062,
+ 0x006D,
+ 0x0062,
+ 0x0067,
+ 0x0062,
+ 0x0070,
+ 0x0066,
+ 0x006E,
+ 0x0066,
+ 0x03BC,
+ 0x0066,
+ 0x0068,
+ 0x007A,
+ 0x006B,
+ 0x0068,
+ 0x007A,
+ 0x006D,
+ 0x0068,
+ 0x007A,
+ 0x0067,
+ 0x0068,
+ 0x007A,
+ 0x0074,
+ 0x0068,
+ 0x007A,
+ 0x006B,
+ 0x0070,
+ 0x0061,
+ 0x006D,
+ 0x0070,
+ 0x0061,
+ 0x0067,
+ 0x0070,
+ 0x0061,
+ 0x0070,
+ 0x0076,
+ 0x006E,
+ 0x0076,
+ 0x03BC,
+ 0x0076,
+ 0x006D,
+ 0x0076,
+ 0x006B,
+ 0x0076,
+ 0x0070,
+ 0x0077,
+ 0x006E,
+ 0x0077,
+ 0x03BC,
+ 0x0077,
+ 0x006D,
+ 0x0077,
+ 0x006B,
+ 0x0077,
+ 0x006B,
+ 0x03C9,
+ 0x006D,
+ 0x03C9,
+ 0x0062,
+ 0x0071,
+ 0x0063,
+ 0x2215,
+ 0x006B,
+ 0x0067,
+ 0x0063,
+ 0x006F,
+ 0x002E,
+ 0x0064,
+ 0x0062,
+ 0x0067,
+ 0x0079,
+ 0x006B,
+ 0x006B,
+ 0x006B,
+ 0x006D,
+ 0x0070,
+ 0x0068,
+ 0x0070,
+ 0x0070,
+ 0x006D,
+ 0x0070,
+ 0x0072,
+ 0x0073,
+ 0x0076,
+ 0x0077,
+ 0x0062,
+ 0x0066,
+ 0x0066,
+ 0x0066,
+ 0x0069,
+ 0x0066,
+ 0x006C,
+ 0x0066,
+ 0x0066,
+ 0x006C,
+ 0x0574,
+ 0x0576,
+ 0x0574,
+ 0x0565,
+ 0x0574,
+ 0x056B,
+ 0x057E,
+ 0x0576,
+ 0x0574,
+ 0x056D,
+ 0xFF41,
+ 0xFF42,
+ 0xFF43,
+ 0xFF44,
+ 0xFF45,
+ 0xFF46,
+ 0xFF47,
+ 0xFF48,
+ 0xFF49,
+ 0xFF4A,
+ 0xFF4B,
+ 0xFF4C,
+ 0xFF4D,
+ 0xFF4E,
+ 0xFF4F,
+ 0xFF50,
+ 0xFF51,
+ 0xFF52,
+ 0xFF53,
+ 0xFF54,
+ 0xFF55,
+ 0xFF56,
+ 0xFF57,
+ 0xFF58,
+ 0xFF59,
+ 0xFF5A,
+ 0x10428,
+ 0x10429,
+ 0x1042A,
+ 0x1042B,
+ 0x1042C,
+ 0x1042D,
+ 0x1042E,
+ 0x1042F,
+ 0x10430,
+ 0x10431,
+ 0x10432,
+ 0x10433,
+ 0x10434,
+ 0x10435,
+ 0x10436,
+ 0x10437,
+ 0x10438,
+ 0x10439,
+ 0x1043A,
+ 0x1043B,
+ 0x1043C,
+ 0x1043D,
+ 0x1043E,
+ 0x1043F,
+ 0x10440,
+ 0x10441,
+ 0x10442,
+ 0x10443,
+ 0x10444,
+ 0x10445,
+ 0x10446,
+ 0x10447,
+ 0x10448,
+ 0x10449,
+ 0x1044A,
+ 0x1044B,
+ 0x1044C,
+ 0x1044D,
+};
+
diff --git a/source4/heimdal/lib/wind/map_table.h b/source4/heimdal/lib/wind/map_table.h
new file mode 100644
index 0000000000..4b4565472d
--- /dev/null
+++ b/source4/heimdal/lib/wind/map_table.h
@@ -0,0 +1,22 @@
+/* map_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.353625 */
+
+#ifndef MAP_TABLE_H
+#define MAP_TABLE_H 1
+
+#include "windlocl.h"
+
+struct translation {
+ uint32_t key;
+ unsigned short val_len;
+ unsigned short val_offset;
+ wind_profile_flags flags;
+};
+
+extern const struct translation _wind_map_table[];
+
+extern const size_t _wind_map_table_size;
+
+extern const uint32_t _wind_map_table_val[];
+
+#endif /* MAP_TABLE_H */
diff --git a/source4/heimdal/lib/wind/normalize.c b/source4/heimdal/lib/wind/normalize.c
new file mode 100644
index 0000000000..d1b440513a
--- /dev/null
+++ b/source4/heimdal/lib/wind/normalize.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "normalize_table.h"
+
+RCSID("$Id: normalize.c 22581 2008-02-11 20:42:25Z lha $");
+
+static int
+translation_cmp(const void *key, const void *data)
+{
+ const struct translation *t1 = (const struct translation *)key;
+ const struct translation *t2 = (const struct translation *)data;
+
+ return t1->key - t2->key;
+}
+
+enum { s_base = 0xAC00};
+enum { s_count = 11172};
+enum { l_base = 0x1100};
+enum { l_count = 19};
+enum { v_base = 0x1161};
+enum { v_count = 21};
+enum { t_base = 0x11A7};
+enum { t_count = 28};
+enum { n_count = v_count * t_count};
+
+static int
+hangul_decomp(const uint32_t *in, size_t in_len,
+ uint32_t *out, size_t *out_len)
+{
+ uint32_t u = *in;
+ unsigned s_index;
+ unsigned l, v, t;
+ unsigned o;
+
+ if (u < s_base || u >= s_base + s_count)
+ return 0;
+ s_index = u - s_base;
+ l = l_base + s_index / n_count;
+ v = v_base + (s_index % n_count) / t_count;
+ t = t_base + s_index % t_count;
+ o = 2;
+ if (t != t_base)
+ ++o;
+ if (*out_len < o)
+ return WIND_ERR_OVERRUN;
+ out[0] = l;
+ out[1] = v;
+ if (t != t_base)
+ out[2] = t;
+ *out_len = o;
+ return 1;
+}
+
+static uint32_t
+hangul_composition(const uint32_t *in, size_t in_len)
+{
+ if (in_len < 2)
+ return 0;
+ if (in[0] >= l_base && in[0] < l_base + l_count) {
+ unsigned l_index = in[0] - l_base;
+ unsigned v_index;
+
+ if (in[1] < v_base || in[1] >= v_base + v_count)
+ return 0;
+ v_index = in[1] - v_base;
+ return (l_index * v_count + v_index) * t_count + s_base;
+ } else if (in[0] >= s_base && in[0] < s_base + s_count) {
+ unsigned s_index = in[0] - s_base;
+ unsigned t_index;
+
+ if (s_index % t_count != 0)
+ return 0;
+ if (in[1] < t_base || in[1] >= t_base + t_count)
+ return 0;
+ t_index = in[1] - t_base;
+ return in[0] + t_index;
+ }
+ return 0;
+}
+
+static int
+compat_decomp(const uint32_t *in, size_t in_len,
+ uint32_t *out, size_t *out_len)
+{
+ unsigned i;
+ unsigned o = 0;
+
+ for (i = 0; i < in_len; ++i) {
+ struct translation ts = {in[i]};
+ size_t sub_len = *out_len - o;
+ int ret;
+
+ ret = hangul_decomp(in + i, in_len - i,
+ out + o, &sub_len);
+ if (ret) {
+ if (ret == WIND_ERR_OVERRUN)
+ return ret;
+ o += sub_len;
+ } else {
+ void *s = bsearch(&ts,
+ _wind_normalize_table,
+ _wind_normalize_table_size,
+ sizeof(_wind_normalize_table[0]),
+ translation_cmp);
+ if (s != NULL) {
+ const struct translation *t = (const struct translation *)s;
+
+ ret = compat_decomp(_wind_normalize_val_table + t->val_offset,
+ t->val_len,
+ out + o, &sub_len);
+ if (ret)
+ return ret;
+ o += sub_len;
+ } else {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ out[o++] = in[i];
+
+ }
+ }
+ }
+ *out_len = o;
+ return 0;
+}
+
+static int
+cc_cmp(const void *a, const void *b)
+{
+ const uint32_t *ua = (const uint32_t *)a;
+ const uint32_t *ub = (const uint32_t *)b;
+
+ return _wind_combining_class(*ua) - _wind_combining_class(*ub);
+}
+
+static void
+canonical_reorder(uint32_t *tmp, size_t tmp_len)
+{
+ unsigned i;
+
+ for (i = 0; i < tmp_len; ++i) {
+ int cc = _wind_combining_class(tmp[i]);
+ if (cc) {
+ size_t j;
+ for (j = i + 1;
+ j < tmp_len && _wind_combining_class(tmp[j]);
+ ++j)
+ ;
+ qsort(&tmp[i], j - i, sizeof(unsigned),
+ cc_cmp);
+ i = j;
+ }
+ }
+}
+
+static uint32_t
+find_composition(const uint32_t *in, unsigned in_len)
+{
+ unsigned short canon_index = 0;
+ uint32_t cur;
+ unsigned n = 0;
+
+ cur = hangul_composition(in, in_len);
+ if (cur)
+ return cur;
+
+ do {
+ const struct canon_node *c = &_wind_canon_table[canon_index];
+ unsigned i;
+
+ if (n % 5 == 0) {
+ cur = *in++;
+ if (in_len-- == 0)
+ return c->val;
+ }
+
+ i = cur >> 16;
+ if (i < c->next_start || i >= c->next_end)
+ canon_index = 0;
+ else
+ canon_index =
+ _wind_canon_next_table[c->next_offset + i - c->next_start];
+ if (canon_index != 0) {
+ cur = (cur << 4) & 0xFFFFF;
+ ++n;
+ }
+ } while (canon_index != 0);
+ return 0;
+}
+
+static int
+combine(const uint32_t *in, size_t in_len,
+ uint32_t *out, size_t *out_len)
+{
+ unsigned i;
+ int ostarter;
+ unsigned o = 0;
+ int old_cc;
+ int cc;
+
+ for (i = 0; i < in_len;) {
+ while (i < in_len && (cc = _wind_combining_class(in[i])) != 0) {
+ out[o++] = in[i++];
+ }
+ if (i < in_len) {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ ostarter = o;
+ out[o++] = in[i++];
+ old_cc = -1;
+
+ while (i < in_len) {
+ uint32_t comb;
+ uint32_t v[2];
+
+ v[0] = out[ostarter];
+ v[1] = in[i];
+
+ cc = _wind_combining_class(in[i]);
+ if (old_cc != cc && (comb = find_composition(v, 2))) {
+ out[ostarter] = comb;
+ } else if (cc == 0) {
+ break;
+ } else {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ out[o++] = in[i];
+ old_cc = cc;
+ }
+ ++i;
+ }
+ }
+ }
+ *out_len = o;
+ return 0;
+}
+
+int
+_wind_stringprep_normalize(const uint32_t *in, size_t in_len,
+ uint32_t *out, size_t *out_len)
+{
+ size_t tmp_len;
+ uint32_t *tmp;
+ int ret;
+
+ tmp_len = in_len * 4;
+ if (tmp_len < MAX_LENGTH_CANON)
+ tmp_len = MAX_LENGTH_CANON;
+ tmp = malloc(tmp_len * sizeof(uint32_t));
+ if (tmp == NULL)
+ return ENOMEM;
+
+ ret = compat_decomp(in, in_len, tmp, &tmp_len);
+ if (ret) {
+ free(tmp);
+ return ret;
+ }
+ canonical_reorder(tmp, tmp_len);
+ ret = combine(tmp, tmp_len, out, out_len);
+ free(tmp);
+ return ret;
+}
diff --git a/source4/heimdal/lib/wind/normalize_table.c b/source4/heimdal/lib/wind/normalize_table.c
new file mode 100644
index 0000000000..c8893193a7
--- /dev/null
+++ b/source4/heimdal/lib/wind/normalize_table.c
@@ -0,0 +1,22976 @@
+/* normalize_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.923861 */
+
+
+#include "normalize_table.h"
+
+const struct translation _wind_normalize_table[] = {
+ {0xa0, 1, 0}, /* NO-BREAK SPACE */
+ {0xa8, 2, 1}, /* DIAERESIS */
+ {0xaa, 1, 3}, /* FEMININE ORDINAL INDICATOR */
+ {0xaf, 2, 4}, /* MACRON */
+ {0xb2, 1, 6}, /* SUPERSCRIPT TWO */
+ {0xb3, 1, 7}, /* SUPERSCRIPT THREE */
+ {0xb4, 2, 8}, /* ACUTE ACCENT */
+ {0xb5, 1, 10}, /* MICRO SIGN */
+ {0xb8, 2, 11}, /* CEDILLA */
+ {0xb9, 1, 13}, /* SUPERSCRIPT ONE */
+ {0xba, 1, 14}, /* MASCULINE ORDINAL INDICATOR */
+ {0xbc, 3, 15}, /* VULGAR FRACTION ONE QUARTER */
+ {0xbd, 3, 18}, /* VULGAR FRACTION ONE HALF */
+ {0xbe, 3, 21}, /* VULGAR FRACTION THREE QUARTERS */
+ {0xc0, 2, 24}, /* LATIN CAPITAL LETTER A WITH GRAVE */
+ {0xc1, 2, 26}, /* LATIN CAPITAL LETTER A WITH ACUTE */
+ {0xc2, 2, 28}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+ {0xc3, 2, 30}, /* LATIN CAPITAL LETTER A WITH TILDE */
+ {0xc4, 2, 32}, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+ {0xc5, 2, 34}, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+ {0xc7, 2, 36}, /* LATIN CAPITAL LETTER C WITH CEDILLA */
+ {0xc8, 2, 38}, /* LATIN CAPITAL LETTER E WITH GRAVE */
+ {0xc9, 2, 40}, /* LATIN CAPITAL LETTER E WITH ACUTE */
+ {0xca, 2, 42}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+ {0xcb, 2, 44}, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+ {0xcc, 2, 46}, /* LATIN CAPITAL LETTER I WITH GRAVE */
+ {0xcd, 2, 48}, /* LATIN CAPITAL LETTER I WITH ACUTE */
+ {0xce, 2, 50}, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+ {0xcf, 2, 52}, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+ {0xd1, 2, 54}, /* LATIN CAPITAL LETTER N WITH TILDE */
+ {0xd2, 2, 56}, /* LATIN CAPITAL LETTER O WITH GRAVE */
+ {0xd3, 2, 58}, /* LATIN CAPITAL LETTER O WITH ACUTE */
+ {0xd4, 2, 60}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+ {0xd5, 2, 62}, /* LATIN CAPITAL LETTER O WITH TILDE */
+ {0xd6, 2, 64}, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+ {0xd9, 2, 66}, /* LATIN CAPITAL LETTER U WITH GRAVE */
+ {0xda, 2, 68}, /* LATIN CAPITAL LETTER U WITH ACUTE */
+ {0xdb, 2, 70}, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+ {0xdc, 2, 72}, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+ {0xdd, 2, 74}, /* LATIN CAPITAL LETTER Y WITH ACUTE */
+ {0xe0, 2, 76}, /* LATIN SMALL LETTER A WITH GRAVE */
+ {0xe1, 2, 78}, /* LATIN SMALL LETTER A WITH ACUTE */
+ {0xe2, 2, 80}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+ {0xe3, 2, 82}, /* LATIN SMALL LETTER A WITH TILDE */
+ {0xe4, 2, 84}, /* LATIN SMALL LETTER A WITH DIAERESIS */
+ {0xe5, 2, 86}, /* LATIN SMALL LETTER A WITH RING ABOVE */
+ {0xe7, 2, 88}, /* LATIN SMALL LETTER C WITH CEDILLA */
+ {0xe8, 2, 90}, /* LATIN SMALL LETTER E WITH GRAVE */
+ {0xe9, 2, 92}, /* LATIN SMALL LETTER E WITH ACUTE */
+ {0xea, 2, 94}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+ {0xeb, 2, 96}, /* LATIN SMALL LETTER E WITH DIAERESIS */
+ {0xec, 2, 98}, /* LATIN SMALL LETTER I WITH GRAVE */
+ {0xed, 2, 100}, /* LATIN SMALL LETTER I WITH ACUTE */
+ {0xee, 2, 102}, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+ {0xef, 2, 104}, /* LATIN SMALL LETTER I WITH DIAERESIS */
+ {0xf1, 2, 106}, /* LATIN SMALL LETTER N WITH TILDE */
+ {0xf2, 2, 108}, /* LATIN SMALL LETTER O WITH GRAVE */
+ {0xf3, 2, 110}, /* LATIN SMALL LETTER O WITH ACUTE */
+ {0xf4, 2, 112}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+ {0xf5, 2, 114}, /* LATIN SMALL LETTER O WITH TILDE */
+ {0xf6, 2, 116}, /* LATIN SMALL LETTER O WITH DIAERESIS */
+ {0xf9, 2, 118}, /* LATIN SMALL LETTER U WITH GRAVE */
+ {0xfa, 2, 120}, /* LATIN SMALL LETTER U WITH ACUTE */
+ {0xfb, 2, 122}, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+ {0xfc, 2, 124}, /* LATIN SMALL LETTER U WITH DIAERESIS */
+ {0xfd, 2, 126}, /* LATIN SMALL LETTER Y WITH ACUTE */
+ {0xff, 2, 128}, /* LATIN SMALL LETTER Y WITH DIAERESIS */
+ {0x100, 2, 130}, /* LATIN CAPITAL LETTER A WITH MACRON */
+ {0x101, 2, 132}, /* LATIN SMALL LETTER A WITH MACRON */
+ {0x102, 2, 134}, /* LATIN CAPITAL LETTER A WITH BREVE */
+ {0x103, 2, 136}, /* LATIN SMALL LETTER A WITH BREVE */
+ {0x104, 2, 138}, /* LATIN CAPITAL LETTER A WITH OGONEK */
+ {0x105, 2, 140}, /* LATIN SMALL LETTER A WITH OGONEK */
+ {0x106, 2, 142}, /* LATIN CAPITAL LETTER C WITH ACUTE */
+ {0x107, 2, 144}, /* LATIN SMALL LETTER C WITH ACUTE */
+ {0x108, 2, 146}, /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ {0x109, 2, 148}, /* LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ {0x10a, 2, 150}, /* LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ {0x10b, 2, 152}, /* LATIN SMALL LETTER C WITH DOT ABOVE */
+ {0x10c, 2, 154}, /* LATIN CAPITAL LETTER C WITH CARON */
+ {0x10d, 2, 156}, /* LATIN SMALL LETTER C WITH CARON */
+ {0x10e, 2, 158}, /* LATIN CAPITAL LETTER D WITH CARON */
+ {0x10f, 2, 160}, /* LATIN SMALL LETTER D WITH CARON */
+ {0x112, 2, 162}, /* LATIN CAPITAL LETTER E WITH MACRON */
+ {0x113, 2, 164}, /* LATIN SMALL LETTER E WITH MACRON */
+ {0x114, 2, 166}, /* LATIN CAPITAL LETTER E WITH BREVE */
+ {0x115, 2, 168}, /* LATIN SMALL LETTER E WITH BREVE */
+ {0x116, 2, 170}, /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ {0x117, 2, 172}, /* LATIN SMALL LETTER E WITH DOT ABOVE */
+ {0x118, 2, 174}, /* LATIN CAPITAL LETTER E WITH OGONEK */
+ {0x119, 2, 176}, /* LATIN SMALL LETTER E WITH OGONEK */
+ {0x11a, 2, 178}, /* LATIN CAPITAL LETTER E WITH CARON */
+ {0x11b, 2, 180}, /* LATIN SMALL LETTER E WITH CARON */
+ {0x11c, 2, 182}, /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ {0x11d, 2, 184}, /* LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ {0x11e, 2, 186}, /* LATIN CAPITAL LETTER G WITH BREVE */
+ {0x11f, 2, 188}, /* LATIN SMALL LETTER G WITH BREVE */
+ {0x120, 2, 190}, /* LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ {0x121, 2, 192}, /* LATIN SMALL LETTER G WITH DOT ABOVE */
+ {0x122, 2, 194}, /* LATIN CAPITAL LETTER G WITH CEDILLA */
+ {0x123, 2, 196}, /* LATIN SMALL LETTER G WITH CEDILLA */
+ {0x124, 2, 198}, /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ {0x125, 2, 200}, /* LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ {0x128, 2, 202}, /* LATIN CAPITAL LETTER I WITH TILDE */
+ {0x129, 2, 204}, /* LATIN SMALL LETTER I WITH TILDE */
+ {0x12a, 2, 206}, /* LATIN CAPITAL LETTER I WITH MACRON */
+ {0x12b, 2, 208}, /* LATIN SMALL LETTER I WITH MACRON */
+ {0x12c, 2, 210}, /* LATIN CAPITAL LETTER I WITH BREVE */
+ {0x12d, 2, 212}, /* LATIN SMALL LETTER I WITH BREVE */
+ {0x12e, 2, 214}, /* LATIN CAPITAL LETTER I WITH OGONEK */
+ {0x12f, 2, 216}, /* LATIN SMALL LETTER I WITH OGONEK */
+ {0x130, 2, 218}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ {0x132, 2, 220}, /* LATIN CAPITAL LIGATURE IJ */
+ {0x133, 2, 222}, /* LATIN SMALL LIGATURE IJ */
+ {0x134, 2, 224}, /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ {0x135, 2, 226}, /* LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ {0x136, 2, 228}, /* LATIN CAPITAL LETTER K WITH CEDILLA */
+ {0x137, 2, 230}, /* LATIN SMALL LETTER K WITH CEDILLA */
+ {0x139, 2, 232}, /* LATIN CAPITAL LETTER L WITH ACUTE */
+ {0x13a, 2, 234}, /* LATIN SMALL LETTER L WITH ACUTE */
+ {0x13b, 2, 236}, /* LATIN CAPITAL LETTER L WITH CEDILLA */
+ {0x13c, 2, 238}, /* LATIN SMALL LETTER L WITH CEDILLA */
+ {0x13d, 2, 240}, /* LATIN CAPITAL LETTER L WITH CARON */
+ {0x13e, 2, 242}, /* LATIN SMALL LETTER L WITH CARON */
+ {0x13f, 2, 244}, /* LATIN CAPITAL LETTER L WITH MIDDLE DOT */
+ {0x140, 2, 246}, /* LATIN SMALL LETTER L WITH MIDDLE DOT */
+ {0x143, 2, 248}, /* LATIN CAPITAL LETTER N WITH ACUTE */
+ {0x144, 2, 250}, /* LATIN SMALL LETTER N WITH ACUTE */
+ {0x145, 2, 252}, /* LATIN CAPITAL LETTER N WITH CEDILLA */
+ {0x146, 2, 254}, /* LATIN SMALL LETTER N WITH CEDILLA */
+ {0x147, 2, 256}, /* LATIN CAPITAL LETTER N WITH CARON */
+ {0x148, 2, 258}, /* LATIN SMALL LETTER N WITH CARON */
+ {0x149, 2, 260}, /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */
+ {0x14c, 2, 262}, /* LATIN CAPITAL LETTER O WITH MACRON */
+ {0x14d, 2, 264}, /* LATIN SMALL LETTER O WITH MACRON */
+ {0x14e, 2, 266}, /* LATIN CAPITAL LETTER O WITH BREVE */
+ {0x14f, 2, 268}, /* LATIN SMALL LETTER O WITH BREVE */
+ {0x150, 2, 270}, /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ {0x151, 2, 272}, /* LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ {0x154, 2, 274}, /* LATIN CAPITAL LETTER R WITH ACUTE */
+ {0x155, 2, 276}, /* LATIN SMALL LETTER R WITH ACUTE */
+ {0x156, 2, 278}, /* LATIN CAPITAL LETTER R WITH CEDILLA */
+ {0x157, 2, 280}, /* LATIN SMALL LETTER R WITH CEDILLA */
+ {0x158, 2, 282}, /* LATIN CAPITAL LETTER R WITH CARON */
+ {0x159, 2, 284}, /* LATIN SMALL LETTER R WITH CARON */
+ {0x15a, 2, 286}, /* LATIN CAPITAL LETTER S WITH ACUTE */
+ {0x15b, 2, 288}, /* LATIN SMALL LETTER S WITH ACUTE */
+ {0x15c, 2, 290}, /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ {0x15d, 2, 292}, /* LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ {0x15e, 2, 294}, /* LATIN CAPITAL LETTER S WITH CEDILLA */
+ {0x15f, 2, 296}, /* LATIN SMALL LETTER S WITH CEDILLA */
+ {0x160, 2, 298}, /* LATIN CAPITAL LETTER S WITH CARON */
+ {0x161, 2, 300}, /* LATIN SMALL LETTER S WITH CARON */
+ {0x162, 2, 302}, /* LATIN CAPITAL LETTER T WITH CEDILLA */
+ {0x163, 2, 304}, /* LATIN SMALL LETTER T WITH CEDILLA */
+ {0x164, 2, 306}, /* LATIN CAPITAL LETTER T WITH CARON */
+ {0x165, 2, 308}, /* LATIN SMALL LETTER T WITH CARON */
+ {0x168, 2, 310}, /* LATIN CAPITAL LETTER U WITH TILDE */
+ {0x169, 2, 312}, /* LATIN SMALL LETTER U WITH TILDE */
+ {0x16a, 2, 314}, /* LATIN CAPITAL LETTER U WITH MACRON */
+ {0x16b, 2, 316}, /* LATIN SMALL LETTER U WITH MACRON */
+ {0x16c, 2, 318}, /* LATIN CAPITAL LETTER U WITH BREVE */
+ {0x16d, 2, 320}, /* LATIN SMALL LETTER U WITH BREVE */
+ {0x16e, 2, 322}, /* LATIN CAPITAL LETTER U WITH RING ABOVE */
+ {0x16f, 2, 324}, /* LATIN SMALL LETTER U WITH RING ABOVE */
+ {0x170, 2, 326}, /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ {0x171, 2, 328}, /* LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ {0x172, 2, 330}, /* LATIN CAPITAL LETTER U WITH OGONEK */
+ {0x173, 2, 332}, /* LATIN SMALL LETTER U WITH OGONEK */
+ {0x174, 2, 334}, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+ {0x175, 2, 336}, /* LATIN SMALL LETTER W WITH CIRCUMFLEX */
+ {0x176, 2, 338}, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+ {0x177, 2, 340}, /* LATIN SMALL LETTER Y WITH CIRCUMFLEX */
+ {0x178, 2, 342}, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ {0x179, 2, 344}, /* LATIN CAPITAL LETTER Z WITH ACUTE */
+ {0x17a, 2, 346}, /* LATIN SMALL LETTER Z WITH ACUTE */
+ {0x17b, 2, 348}, /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ {0x17c, 2, 350}, /* LATIN SMALL LETTER Z WITH DOT ABOVE */
+ {0x17d, 2, 352}, /* LATIN CAPITAL LETTER Z WITH CARON */
+ {0x17e, 2, 354}, /* LATIN SMALL LETTER Z WITH CARON */
+ {0x17f, 1, 288}, /* LATIN SMALL LETTER LONG S */
+ {0x1a0, 2, 356}, /* LATIN CAPITAL LETTER O WITH HORN */
+ {0x1a1, 2, 358}, /* LATIN SMALL LETTER O WITH HORN */
+ {0x1af, 2, 360}, /* LATIN CAPITAL LETTER U WITH HORN */
+ {0x1b0, 2, 362}, /* LATIN SMALL LETTER U WITH HORN */
+ {0x1c4, 2, 364}, /* LATIN CAPITAL LETTER DZ WITH CARON */
+ {0x1c5, 2, 366}, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON */
+ {0x1c6, 2, 368}, /* LATIN SMALL LETTER DZ WITH CARON */
+ {0x1c7, 2, 370}, /* LATIN CAPITAL LETTER LJ */
+ {0x1c8, 2, 372}, /* LATIN CAPITAL LETTER L WITH SMALL LETTER J */
+ {0x1c9, 2, 374}, /* LATIN SMALL LETTER LJ */
+ {0x1ca, 2, 376}, /* LATIN CAPITAL LETTER NJ */
+ {0x1cb, 2, 378}, /* LATIN CAPITAL LETTER N WITH SMALL LETTER J */
+ {0x1cc, 2, 380}, /* LATIN SMALL LETTER NJ */
+ {0x1cd, 2, 382}, /* LATIN CAPITAL LETTER A WITH CARON */
+ {0x1ce, 2, 384}, /* LATIN SMALL LETTER A WITH CARON */
+ {0x1cf, 2, 386}, /* LATIN CAPITAL LETTER I WITH CARON */
+ {0x1d0, 2, 388}, /* LATIN SMALL LETTER I WITH CARON */
+ {0x1d1, 2, 390}, /* LATIN CAPITAL LETTER O WITH CARON */
+ {0x1d2, 2, 392}, /* LATIN SMALL LETTER O WITH CARON */
+ {0x1d3, 2, 394}, /* LATIN CAPITAL LETTER U WITH CARON */
+ {0x1d4, 2, 396}, /* LATIN SMALL LETTER U WITH CARON */
+ {0x1d5, 2, 398}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON */
+ {0x1d6, 2, 400}, /* LATIN SMALL LETTER U WITH DIAERESIS AND MACRON */
+ {0x1d7, 2, 402}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE */
+ {0x1d8, 2, 404}, /* LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE */
+ {0x1d9, 2, 406}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON */
+ {0x1da, 2, 408}, /* LATIN SMALL LETTER U WITH DIAERESIS AND CARON */
+ {0x1db, 2, 410}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE */
+ {0x1dc, 2, 412}, /* LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE */
+ {0x1de, 2, 414}, /* LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON */
+ {0x1df, 2, 416}, /* LATIN SMALL LETTER A WITH DIAERESIS AND MACRON */
+ {0x1e0, 2, 418}, /* LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON */
+ {0x1e1, 2, 420}, /* LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON */
+ {0x1e2, 2, 422}, /* LATIN CAPITAL LETTER AE WITH MACRON */
+ {0x1e3, 2, 424}, /* LATIN SMALL LETTER AE WITH MACRON */
+ {0x1e6, 2, 426}, /* LATIN CAPITAL LETTER G WITH CARON */
+ {0x1e7, 2, 428}, /* LATIN SMALL LETTER G WITH CARON */
+ {0x1e8, 2, 430}, /* LATIN CAPITAL LETTER K WITH CARON */
+ {0x1e9, 2, 432}, /* LATIN SMALL LETTER K WITH CARON */
+ {0x1ea, 2, 434}, /* LATIN CAPITAL LETTER O WITH OGONEK */
+ {0x1eb, 2, 436}, /* LATIN SMALL LETTER O WITH OGONEK */
+ {0x1ec, 2, 438}, /* LATIN CAPITAL LETTER O WITH OGONEK AND MACRON */
+ {0x1ed, 2, 440}, /* LATIN SMALL LETTER O WITH OGONEK AND MACRON */
+ {0x1ee, 2, 442}, /* LATIN CAPITAL LETTER EZH WITH CARON */
+ {0x1ef, 2, 444}, /* LATIN SMALL LETTER EZH WITH CARON */
+ {0x1f0, 2, 446}, /* LATIN SMALL LETTER J WITH CARON */
+ {0x1f1, 2, 448}, /* LATIN CAPITAL LETTER DZ */
+ {0x1f2, 2, 450}, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z */
+ {0x1f3, 2, 452}, /* LATIN SMALL LETTER DZ */
+ {0x1f4, 2, 454}, /* LATIN CAPITAL LETTER G WITH ACUTE */
+ {0x1f5, 2, 456}, /* LATIN SMALL LETTER G WITH ACUTE */
+ {0x1f8, 2, 458}, /* LATIN CAPITAL LETTER N WITH GRAVE */
+ {0x1f9, 2, 460}, /* LATIN SMALL LETTER N WITH GRAVE */
+ {0x1fa, 2, 462}, /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE */
+ {0x1fb, 2, 464}, /* LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE */
+ {0x1fc, 2, 466}, /* LATIN CAPITAL LETTER AE WITH ACUTE */
+ {0x1fd, 2, 468}, /* LATIN SMALL LETTER AE WITH ACUTE */
+ {0x1fe, 2, 470}, /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE */
+ {0x1ff, 2, 472}, /* LATIN SMALL LETTER O WITH STROKE AND ACUTE */
+ {0x200, 2, 474}, /* LATIN CAPITAL LETTER A WITH DOUBLE GRAVE */
+ {0x201, 2, 476}, /* LATIN SMALL LETTER A WITH DOUBLE GRAVE */
+ {0x202, 2, 478}, /* LATIN CAPITAL LETTER A WITH INVERTED BREVE */
+ {0x203, 2, 480}, /* LATIN SMALL LETTER A WITH INVERTED BREVE */
+ {0x204, 2, 482}, /* LATIN CAPITAL LETTER E WITH DOUBLE GRAVE */
+ {0x205, 2, 484}, /* LATIN SMALL LETTER E WITH DOUBLE GRAVE */
+ {0x206, 2, 486}, /* LATIN CAPITAL LETTER E WITH INVERTED BREVE */
+ {0x207, 2, 488}, /* LATIN SMALL LETTER E WITH INVERTED BREVE */
+ {0x208, 2, 490}, /* LATIN CAPITAL LETTER I WITH DOUBLE GRAVE */
+ {0x209, 2, 492}, /* LATIN SMALL LETTER I WITH DOUBLE GRAVE */
+ {0x20a, 2, 494}, /* LATIN CAPITAL LETTER I WITH INVERTED BREVE */
+ {0x20b, 2, 496}, /* LATIN SMALL LETTER I WITH INVERTED BREVE */
+ {0x20c, 2, 498}, /* LATIN CAPITAL LETTER O WITH DOUBLE GRAVE */
+ {0x20d, 2, 500}, /* LATIN SMALL LETTER O WITH DOUBLE GRAVE */
+ {0x20e, 2, 502}, /* LATIN CAPITAL LETTER O WITH INVERTED BREVE */
+ {0x20f, 2, 504}, /* LATIN SMALL LETTER O WITH INVERTED BREVE */
+ {0x210, 2, 506}, /* LATIN CAPITAL LETTER R WITH DOUBLE GRAVE */
+ {0x211, 2, 508}, /* LATIN SMALL LETTER R WITH DOUBLE GRAVE */
+ {0x212, 2, 510}, /* LATIN CAPITAL LETTER R WITH INVERTED BREVE */
+ {0x213, 2, 512}, /* LATIN SMALL LETTER R WITH INVERTED BREVE */
+ {0x214, 2, 514}, /* LATIN CAPITAL LETTER U WITH DOUBLE GRAVE */
+ {0x215, 2, 516}, /* LATIN SMALL LETTER U WITH DOUBLE GRAVE */
+ {0x216, 2, 518}, /* LATIN CAPITAL LETTER U WITH INVERTED BREVE */
+ {0x217, 2, 520}, /* LATIN SMALL LETTER U WITH INVERTED BREVE */
+ {0x218, 2, 522}, /* LATIN CAPITAL LETTER S WITH COMMA BELOW */
+ {0x219, 2, 524}, /* LATIN SMALL LETTER S WITH COMMA BELOW */
+ {0x21a, 2, 526}, /* LATIN CAPITAL LETTER T WITH COMMA BELOW */
+ {0x21b, 2, 528}, /* LATIN SMALL LETTER T WITH COMMA BELOW */
+ {0x21e, 2, 530}, /* LATIN CAPITAL LETTER H WITH CARON */
+ {0x21f, 2, 532}, /* LATIN SMALL LETTER H WITH CARON */
+ {0x226, 2, 534}, /* LATIN CAPITAL LETTER A WITH DOT ABOVE */
+ {0x227, 2, 536}, /* LATIN SMALL LETTER A WITH DOT ABOVE */
+ {0x228, 2, 538}, /* LATIN CAPITAL LETTER E WITH CEDILLA */
+ {0x229, 2, 540}, /* LATIN SMALL LETTER E WITH CEDILLA */
+ {0x22a, 2, 542}, /* LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON */
+ {0x22b, 2, 544}, /* LATIN SMALL LETTER O WITH DIAERESIS AND MACRON */
+ {0x22c, 2, 546}, /* LATIN CAPITAL LETTER O WITH TILDE AND MACRON */
+ {0x22d, 2, 548}, /* LATIN SMALL LETTER O WITH TILDE AND MACRON */
+ {0x22e, 2, 550}, /* LATIN CAPITAL LETTER O WITH DOT ABOVE */
+ {0x22f, 2, 552}, /* LATIN SMALL LETTER O WITH DOT ABOVE */
+ {0x230, 2, 554}, /* LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON */
+ {0x231, 2, 556}, /* LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON */
+ {0x232, 2, 558}, /* LATIN CAPITAL LETTER Y WITH MACRON */
+ {0x233, 2, 560}, /* LATIN SMALL LETTER Y WITH MACRON */
+ {0x2b0, 1, 200}, /* MODIFIER LETTER SMALL H */
+ {0x2b1, 1, 562}, /* MODIFIER LETTER SMALL H WITH HOOK */
+ {0x2b2, 1, 223}, /* MODIFIER LETTER SMALL J */
+ {0x2b3, 1, 276}, /* MODIFIER LETTER SMALL R */
+ {0x2b4, 1, 563}, /* MODIFIER LETTER SMALL TURNED R */
+ {0x2b5, 1, 564}, /* MODIFIER LETTER SMALL TURNED R WITH HOOK */
+ {0x2b6, 1, 565}, /* MODIFIER LETTER SMALL CAPITAL INVERTED R */
+ {0x2b7, 1, 336}, /* MODIFIER LETTER SMALL W */
+ {0x2b8, 1, 126}, /* MODIFIER LETTER SMALL Y */
+ {0x2d8, 2, 566}, /* BREVE */
+ {0x2d9, 2, 568}, /* DOT ABOVE */
+ {0x2da, 2, 570}, /* RING ABOVE */
+ {0x2db, 2, 572}, /* OGONEK */
+ {0x2dc, 2, 574}, /* SMALL TILDE */
+ {0x2dd, 2, 576}, /* DOUBLE ACUTE ACCENT */
+ {0x2e0, 1, 578}, /* MODIFIER LETTER SMALL GAMMA */
+ {0x2e1, 1, 234}, /* MODIFIER LETTER SMALL L */
+ {0x2e2, 1, 288}, /* MODIFIER LETTER SMALL S */
+ {0x2e3, 1, 579}, /* MODIFIER LETTER SMALL X */
+ {0x2e4, 1, 580}, /* MODIFIER LETTER SMALL REVERSED GLOTTAL STOP */
+ {0x340, 1, 25}, /* COMBINING GRAVE TONE MARK */
+ {0x341, 1, 9}, /* COMBINING ACUTE TONE MARK */
+ {0x343, 1, 581}, /* COMBINING GREEK KORONIS */
+ {0x344, 2, 582}, /* COMBINING GREEK DIALYTIKA TONOS */
+ {0x374, 1, 584}, /* GREEK NUMERAL SIGN */
+ {0x37a, 2, 585}, /* GREEK YPOGEGRAMMENI */
+ {0x37e, 1, 587}, /* GREEK QUESTION MARK */
+ {0x384, 2, 8}, /* GREEK TONOS */
+ {0x385, 2, 588}, /* GREEK DIALYTIKA TONOS */
+ {0x386, 2, 590}, /* GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ {0x387, 1, 245}, /* GREEK ANO TELEIA */
+ {0x388, 2, 592}, /* GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ {0x389, 2, 594}, /* GREEK CAPITAL LETTER ETA WITH TONOS */
+ {0x38a, 2, 596}, /* GREEK CAPITAL LETTER IOTA WITH TONOS */
+ {0x38c, 2, 598}, /* GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ {0x38e, 2, 600}, /* GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ {0x38f, 2, 602}, /* GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ {0x390, 2, 604}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ {0x3aa, 2, 606}, /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ {0x3ab, 2, 608}, /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ {0x3ac, 2, 610}, /* GREEK SMALL LETTER ALPHA WITH TONOS */
+ {0x3ad, 2, 612}, /* GREEK SMALL LETTER EPSILON WITH TONOS */
+ {0x3ae, 2, 614}, /* GREEK SMALL LETTER ETA WITH TONOS */
+ {0x3af, 2, 616}, /* GREEK SMALL LETTER IOTA WITH TONOS */
+ {0x3b0, 2, 618}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ {0x3ca, 2, 620}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ {0x3cb, 2, 622}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ {0x3cc, 2, 624}, /* GREEK SMALL LETTER OMICRON WITH TONOS */
+ {0x3cd, 2, 626}, /* GREEK SMALL LETTER UPSILON WITH TONOS */
+ {0x3ce, 2, 628}, /* GREEK SMALL LETTER OMEGA WITH TONOS */
+ {0x3d0, 1, 630}, /* GREEK BETA SYMBOL */
+ {0x3d1, 1, 631}, /* GREEK THETA SYMBOL */
+ {0x3d2, 1, 600}, /* GREEK UPSILON WITH HOOK SYMBOL */
+ {0x3d3, 2, 632}, /* GREEK UPSILON WITH ACUTE AND HOOK SYMBOL */
+ {0x3d4, 2, 634}, /* GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL */
+ {0x3d5, 1, 636}, /* GREEK PHI SYMBOL */
+ {0x3d6, 1, 637}, /* GREEK PI SYMBOL */
+ {0x3f0, 1, 638}, /* GREEK KAPPA SYMBOL */
+ {0x3f1, 1, 639}, /* GREEK RHO SYMBOL */
+ {0x3f2, 1, 640}, /* GREEK LUNATE SIGMA SYMBOL */
+ {0x3f4, 1, 641}, /* GREEK CAPITAL THETA SYMBOL */
+ {0x3f5, 1, 612}, /* GREEK LUNATE EPSILON SYMBOL */
+ {0x3f9, 1, 642}, /* GREEK CAPITAL LUNATE SIGMA SYMBOL */
+ {0x400, 2, 643}, /* CYRILLIC CAPITAL LETTER IE WITH GRAVE */
+ {0x401, 2, 645}, /* CYRILLIC CAPITAL LETTER IO */
+ {0x403, 2, 647}, /* CYRILLIC CAPITAL LETTER GJE */
+ {0x407, 2, 649}, /* CYRILLIC CAPITAL LETTER YI */
+ {0x40c, 2, 651}, /* CYRILLIC CAPITAL LETTER KJE */
+ {0x40d, 2, 653}, /* CYRILLIC CAPITAL LETTER I WITH GRAVE */
+ {0x40e, 2, 655}, /* CYRILLIC CAPITAL LETTER SHORT U */
+ {0x419, 2, 657}, /* CYRILLIC CAPITAL LETTER SHORT I */
+ {0x439, 2, 659}, /* CYRILLIC SMALL LETTER SHORT I */
+ {0x450, 2, 661}, /* CYRILLIC SMALL LETTER IE WITH GRAVE */
+ {0x451, 2, 663}, /* CYRILLIC SMALL LETTER IO */
+ {0x453, 2, 665}, /* CYRILLIC SMALL LETTER GJE */
+ {0x457, 2, 667}, /* CYRILLIC SMALL LETTER YI */
+ {0x45c, 2, 669}, /* CYRILLIC SMALL LETTER KJE */
+ {0x45d, 2, 671}, /* CYRILLIC SMALL LETTER I WITH GRAVE */
+ {0x45e, 2, 673}, /* CYRILLIC SMALL LETTER SHORT U */
+ {0x476, 2, 675}, /* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
+ {0x477, 2, 677}, /* CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
+ {0x4c1, 2, 679}, /* CYRILLIC CAPITAL LETTER ZHE WITH BREVE */
+ {0x4c2, 2, 681}, /* CYRILLIC SMALL LETTER ZHE WITH BREVE */
+ {0x4d0, 2, 683}, /* CYRILLIC CAPITAL LETTER A WITH BREVE */
+ {0x4d1, 2, 685}, /* CYRILLIC SMALL LETTER A WITH BREVE */
+ {0x4d2, 2, 687}, /* CYRILLIC CAPITAL LETTER A WITH DIAERESIS */
+ {0x4d3, 2, 689}, /* CYRILLIC SMALL LETTER A WITH DIAERESIS */
+ {0x4d6, 2, 691}, /* CYRILLIC CAPITAL LETTER IE WITH BREVE */
+ {0x4d7, 2, 693}, /* CYRILLIC SMALL LETTER IE WITH BREVE */
+ {0x4da, 2, 695}, /* CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS */
+ {0x4db, 2, 697}, /* CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS */
+ {0x4dc, 2, 699}, /* CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS */
+ {0x4dd, 2, 701}, /* CYRILLIC SMALL LETTER ZHE WITH DIAERESIS */
+ {0x4de, 2, 703}, /* CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS */
+ {0x4df, 2, 705}, /* CYRILLIC SMALL LETTER ZE WITH DIAERESIS */
+ {0x4e2, 2, 707}, /* CYRILLIC CAPITAL LETTER I WITH MACRON */
+ {0x4e3, 2, 709}, /* CYRILLIC SMALL LETTER I WITH MACRON */
+ {0x4e4, 2, 711}, /* CYRILLIC CAPITAL LETTER I WITH DIAERESIS */
+ {0x4e5, 2, 713}, /* CYRILLIC SMALL LETTER I WITH DIAERESIS */
+ {0x4e6, 2, 715}, /* CYRILLIC CAPITAL LETTER O WITH DIAERESIS */
+ {0x4e7, 2, 717}, /* CYRILLIC SMALL LETTER O WITH DIAERESIS */
+ {0x4ea, 2, 719}, /* CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS */
+ {0x4eb, 2, 721}, /* CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS */
+ {0x4ec, 2, 723}, /* CYRILLIC CAPITAL LETTER E WITH DIAERESIS */
+ {0x4ed, 2, 725}, /* CYRILLIC SMALL LETTER E WITH DIAERESIS */
+ {0x4ee, 2, 727}, /* CYRILLIC CAPITAL LETTER U WITH MACRON */
+ {0x4ef, 2, 729}, /* CYRILLIC SMALL LETTER U WITH MACRON */
+ {0x4f0, 2, 731}, /* CYRILLIC CAPITAL LETTER U WITH DIAERESIS */
+ {0x4f1, 2, 733}, /* CYRILLIC SMALL LETTER U WITH DIAERESIS */
+ {0x4f2, 2, 735}, /* CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE */
+ {0x4f3, 2, 737}, /* CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE */
+ {0x4f4, 2, 739}, /* CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS */
+ {0x4f5, 2, 741}, /* CYRILLIC SMALL LETTER CHE WITH DIAERESIS */
+ {0x4f8, 2, 743}, /* CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS */
+ {0x4f9, 2, 745}, /* CYRILLIC SMALL LETTER YERU WITH DIAERESIS */
+ {0x587, 2, 747}, /* ARMENIAN SMALL LIGATURE ECH YIWN */
+ {0x622, 2, 749}, /* ARABIC LETTER ALEF WITH MADDA ABOVE */
+ {0x623, 2, 751}, /* ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ {0x624, 2, 753}, /* ARABIC LETTER WAW WITH HAMZA ABOVE */
+ {0x625, 2, 755}, /* ARABIC LETTER ALEF WITH HAMZA BELOW */
+ {0x626, 2, 757}, /* ARABIC LETTER YEH WITH HAMZA ABOVE */
+ {0x675, 2, 759}, /* ARABIC LETTER HIGH HAMZA ALEF */
+ {0x676, 2, 761}, /* ARABIC LETTER HIGH HAMZA WAW */
+ {0x677, 2, 763}, /* ARABIC LETTER U WITH HAMZA ABOVE */
+ {0x678, 2, 765}, /* ARABIC LETTER HIGH HAMZA YEH */
+ {0x6c0, 2, 767}, /* ARABIC LETTER HEH WITH YEH ABOVE */
+ {0x6c2, 2, 769}, /* ARABIC LETTER HEH GOAL WITH HAMZA ABOVE */
+ {0x6d3, 2, 771}, /* ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */
+ {0x929, 2, 773}, /* DEVANAGARI LETTER NNNA */
+ {0x931, 2, 775}, /* DEVANAGARI LETTER RRA */
+ {0x934, 2, 777}, /* DEVANAGARI LETTER LLLA */
+ {0x958, 2, 779}, /* DEVANAGARI LETTER QA */
+ {0x959, 2, 781}, /* DEVANAGARI LETTER KHHA */
+ {0x95a, 2, 783}, /* DEVANAGARI LETTER GHHA */
+ {0x95b, 2, 785}, /* DEVANAGARI LETTER ZA */
+ {0x95c, 2, 787}, /* DEVANAGARI LETTER DDDHA */
+ {0x95d, 2, 789}, /* DEVANAGARI LETTER RHA */
+ {0x95e, 2, 791}, /* DEVANAGARI LETTER FA */
+ {0x95f, 2, 793}, /* DEVANAGARI LETTER YYA */
+ {0x9cb, 2, 795}, /* BENGALI VOWEL SIGN O */
+ {0x9cc, 2, 797}, /* BENGALI VOWEL SIGN AU */
+ {0x9dc, 2, 799}, /* BENGALI LETTER RRA */
+ {0x9dd, 2, 801}, /* BENGALI LETTER RHA */
+ {0x9df, 2, 803}, /* BENGALI LETTER YYA */
+ {0xa33, 2, 805}, /* GURMUKHI LETTER LLA */
+ {0xa36, 2, 807}, /* GURMUKHI LETTER SHA */
+ {0xa59, 2, 809}, /* GURMUKHI LETTER KHHA */
+ {0xa5a, 2, 811}, /* GURMUKHI LETTER GHHA */
+ {0xa5b, 2, 813}, /* GURMUKHI LETTER ZA */
+ {0xa5e, 2, 815}, /* GURMUKHI LETTER FA */
+ {0xb48, 2, 817}, /* ORIYA VOWEL SIGN AI */
+ {0xb4b, 2, 819}, /* ORIYA VOWEL SIGN O */
+ {0xb4c, 2, 821}, /* ORIYA VOWEL SIGN AU */
+ {0xb5c, 2, 823}, /* ORIYA LETTER RRA */
+ {0xb5d, 2, 825}, /* ORIYA LETTER RHA */
+ {0xb94, 2, 827}, /* TAMIL LETTER AU */
+ {0xbca, 2, 829}, /* TAMIL VOWEL SIGN O */
+ {0xbcb, 2, 831}, /* TAMIL VOWEL SIGN OO */
+ {0xbcc, 2, 833}, /* TAMIL VOWEL SIGN AU */
+ {0xc48, 2, 835}, /* TELUGU VOWEL SIGN AI */
+ {0xcc0, 2, 837}, /* KANNADA VOWEL SIGN II */
+ {0xcc7, 2, 839}, /* KANNADA VOWEL SIGN EE */
+ {0xcc8, 2, 841}, /* KANNADA VOWEL SIGN AI */
+ {0xcca, 2, 843}, /* KANNADA VOWEL SIGN O */
+ {0xccb, 2, 845}, /* KANNADA VOWEL SIGN OO */
+ {0xd4a, 2, 847}, /* MALAYALAM VOWEL SIGN O */
+ {0xd4b, 2, 849}, /* MALAYALAM VOWEL SIGN OO */
+ {0xd4c, 2, 851}, /* MALAYALAM VOWEL SIGN AU */
+ {0xdda, 2, 853}, /* SINHALA VOWEL SIGN DIGA KOMBUVA */
+ {0xddc, 2, 855}, /* SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA */
+ {0xddd, 2, 857}, /* SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA */
+ {0xdde, 2, 859}, /* SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA */
+ {0xe33, 2, 861}, /* THAI CHARACTER SARA AM */
+ {0xeb3, 2, 863}, /* LAO VOWEL SIGN AM */
+ {0xedc, 2, 865}, /* LAO HO NO */
+ {0xedd, 2, 867}, /* LAO HO MO */
+ {0xf0c, 1, 869}, /* TIBETAN MARK DELIMITER TSHEG BSTAR */
+ {0xf43, 2, 870}, /* TIBETAN LETTER GHA */
+ {0xf4d, 2, 872}, /* TIBETAN LETTER DDHA */
+ {0xf52, 2, 874}, /* TIBETAN LETTER DHA */
+ {0xf57, 2, 876}, /* TIBETAN LETTER BHA */
+ {0xf5c, 2, 878}, /* TIBETAN LETTER DZHA */
+ {0xf69, 2, 880}, /* TIBETAN LETTER KSSA */
+ {0xf73, 2, 882}, /* TIBETAN VOWEL SIGN II */
+ {0xf75, 2, 884}, /* TIBETAN VOWEL SIGN UU */
+ {0xf76, 2, 886}, /* TIBETAN VOWEL SIGN VOCALIC R */
+ {0xf77, 2, 888}, /* TIBETAN VOWEL SIGN VOCALIC RR */
+ {0xf78, 2, 890}, /* TIBETAN VOWEL SIGN VOCALIC L */
+ {0xf79, 2, 892}, /* TIBETAN VOWEL SIGN VOCALIC LL */
+ {0xf81, 2, 894}, /* TIBETAN VOWEL SIGN REVERSED II */
+ {0xf93, 2, 896}, /* TIBETAN SUBJOINED LETTER GHA */
+ {0xf9d, 2, 898}, /* TIBETAN SUBJOINED LETTER DDHA */
+ {0xfa2, 2, 900}, /* TIBETAN SUBJOINED LETTER DHA */
+ {0xfa7, 2, 902}, /* TIBETAN SUBJOINED LETTER BHA */
+ {0xfac, 2, 904}, /* TIBETAN SUBJOINED LETTER DZHA */
+ {0xfb9, 2, 906}, /* TIBETAN SUBJOINED LETTER KSSA */
+ {0x1026, 2, 908}, /* MYANMAR LETTER UU */
+ {0x1d2c, 1, 24}, /* MODIFIER LETTER CAPITAL A */
+ {0x1d2d, 1, 422}, /* MODIFIER LETTER CAPITAL AE */
+ {0x1d2e, 1, 910}, /* MODIFIER LETTER CAPITAL B */
+ {0x1d30, 1, 158}, /* MODIFIER LETTER CAPITAL D */
+ {0x1d31, 1, 38}, /* MODIFIER LETTER CAPITAL E */
+ {0x1d32, 1, 911}, /* MODIFIER LETTER CAPITAL REVERSED E */
+ {0x1d33, 1, 182}, /* MODIFIER LETTER CAPITAL G */
+ {0x1d34, 1, 198}, /* MODIFIER LETTER CAPITAL H */
+ {0x1d35, 1, 46}, /* MODIFIER LETTER CAPITAL I */
+ {0x1d36, 1, 221}, /* MODIFIER LETTER CAPITAL J */
+ {0x1d37, 1, 228}, /* MODIFIER LETTER CAPITAL K */
+ {0x1d38, 1, 232}, /* MODIFIER LETTER CAPITAL L */
+ {0x1d39, 1, 912}, /* MODIFIER LETTER CAPITAL M */
+ {0x1d3a, 1, 54}, /* MODIFIER LETTER CAPITAL N */
+ {0x1d3c, 1, 56}, /* MODIFIER LETTER CAPITAL O */
+ {0x1d3d, 1, 913}, /* MODIFIER LETTER CAPITAL OU */
+ {0x1d3e, 1, 914}, /* MODIFIER LETTER CAPITAL P */
+ {0x1d3f, 1, 274}, /* MODIFIER LETTER CAPITAL R */
+ {0x1d40, 1, 302}, /* MODIFIER LETTER CAPITAL T */
+ {0x1d41, 1, 66}, /* MODIFIER LETTER CAPITAL U */
+ {0x1d42, 1, 334}, /* MODIFIER LETTER CAPITAL W */
+ {0x1d43, 1, 3}, /* MODIFIER LETTER SMALL A */
+ {0x1d44, 1, 915}, /* MODIFIER LETTER SMALL TURNED A */
+ {0x1d45, 1, 916}, /* MODIFIER LETTER SMALL ALPHA */
+ {0x1d46, 1, 917}, /* MODIFIER LETTER SMALL TURNED AE */
+ {0x1d47, 1, 918}, /* MODIFIER LETTER SMALL B */
+ {0x1d48, 1, 160}, /* MODIFIER LETTER SMALL D */
+ {0x1d49, 1, 90}, /* MODIFIER LETTER SMALL E */
+ {0x1d4a, 1, 919}, /* MODIFIER LETTER SMALL SCHWA */
+ {0x1d4b, 1, 920}, /* MODIFIER LETTER SMALL OPEN E */
+ {0x1d4c, 1, 921}, /* MODIFIER LETTER SMALL TURNED OPEN E */
+ {0x1d4d, 1, 184}, /* MODIFIER LETTER SMALL G */
+ {0x1d4f, 1, 230}, /* MODIFIER LETTER SMALL K */
+ {0x1d50, 1, 922}, /* MODIFIER LETTER SMALL M */
+ {0x1d51, 1, 923}, /* MODIFIER LETTER SMALL ENG */
+ {0x1d52, 1, 14}, /* MODIFIER LETTER SMALL O */
+ {0x1d53, 1, 924}, /* MODIFIER LETTER SMALL OPEN O */
+ {0x1d54, 1, 925}, /* MODIFIER LETTER SMALL TOP HALF O */
+ {0x1d55, 1, 926}, /* MODIFIER LETTER SMALL BOTTOM HALF O */
+ {0x1d56, 1, 927}, /* MODIFIER LETTER SMALL P */
+ {0x1d57, 1, 304}, /* MODIFIER LETTER SMALL T */
+ {0x1d58, 1, 118}, /* MODIFIER LETTER SMALL U */
+ {0x1d59, 1, 928}, /* MODIFIER LETTER SMALL SIDEWAYS U */
+ {0x1d5a, 1, 929}, /* MODIFIER LETTER SMALL TURNED M */
+ {0x1d5b, 1, 930}, /* MODIFIER LETTER SMALL V */
+ {0x1d5c, 1, 931}, /* MODIFIER LETTER SMALL AIN */
+ {0x1d5d, 1, 630}, /* MODIFIER LETTER SMALL BETA */
+ {0x1d5e, 1, 932}, /* MODIFIER LETTER SMALL GREEK GAMMA */
+ {0x1d5f, 1, 933}, /* MODIFIER LETTER SMALL DELTA */
+ {0x1d60, 1, 636}, /* MODIFIER LETTER SMALL GREEK PHI */
+ {0x1d61, 1, 934}, /* MODIFIER LETTER SMALL CHI */
+ {0x1d62, 1, 98}, /* LATIN SUBSCRIPT SMALL LETTER I */
+ {0x1d63, 1, 276}, /* LATIN SUBSCRIPT SMALL LETTER R */
+ {0x1d64, 1, 118}, /* LATIN SUBSCRIPT SMALL LETTER U */
+ {0x1d65, 1, 930}, /* LATIN SUBSCRIPT SMALL LETTER V */
+ {0x1d66, 1, 630}, /* GREEK SUBSCRIPT SMALL LETTER BETA */
+ {0x1d67, 1, 932}, /* GREEK SUBSCRIPT SMALL LETTER GAMMA */
+ {0x1d68, 1, 639}, /* GREEK SUBSCRIPT SMALL LETTER RHO */
+ {0x1d69, 1, 636}, /* GREEK SUBSCRIPT SMALL LETTER PHI */
+ {0x1d6a, 1, 934}, /* GREEK SUBSCRIPT SMALL LETTER CHI */
+ {0x1e00, 2, 935}, /* LATIN CAPITAL LETTER A WITH RING BELOW */
+ {0x1e01, 2, 937}, /* LATIN SMALL LETTER A WITH RING BELOW */
+ {0x1e02, 2, 939}, /* LATIN CAPITAL LETTER B WITH DOT ABOVE */
+ {0x1e03, 2, 941}, /* LATIN SMALL LETTER B WITH DOT ABOVE */
+ {0x1e04, 2, 943}, /* LATIN CAPITAL LETTER B WITH DOT BELOW */
+ {0x1e05, 2, 945}, /* LATIN SMALL LETTER B WITH DOT BELOW */
+ {0x1e06, 2, 947}, /* LATIN CAPITAL LETTER B WITH LINE BELOW */
+ {0x1e07, 2, 949}, /* LATIN SMALL LETTER B WITH LINE BELOW */
+ {0x1e08, 2, 951}, /* LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE */
+ {0x1e09, 2, 953}, /* LATIN SMALL LETTER C WITH CEDILLA AND ACUTE */
+ {0x1e0a, 2, 955}, /* LATIN CAPITAL LETTER D WITH DOT ABOVE */
+ {0x1e0b, 2, 957}, /* LATIN SMALL LETTER D WITH DOT ABOVE */
+ {0x1e0c, 2, 959}, /* LATIN CAPITAL LETTER D WITH DOT BELOW */
+ {0x1e0d, 2, 961}, /* LATIN SMALL LETTER D WITH DOT BELOW */
+ {0x1e0e, 2, 963}, /* LATIN CAPITAL LETTER D WITH LINE BELOW */
+ {0x1e0f, 2, 965}, /* LATIN SMALL LETTER D WITH LINE BELOW */
+ {0x1e10, 2, 967}, /* LATIN CAPITAL LETTER D WITH CEDILLA */
+ {0x1e11, 2, 969}, /* LATIN SMALL LETTER D WITH CEDILLA */
+ {0x1e12, 2, 971}, /* LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW */
+ {0x1e13, 2, 973}, /* LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW */
+ {0x1e14, 2, 975}, /* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE */
+ {0x1e15, 2, 977}, /* LATIN SMALL LETTER E WITH MACRON AND GRAVE */
+ {0x1e16, 2, 979}, /* LATIN CAPITAL LETTER E WITH MACRON AND ACUTE */
+ {0x1e17, 2, 981}, /* LATIN SMALL LETTER E WITH MACRON AND ACUTE */
+ {0x1e18, 2, 983}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW */
+ {0x1e19, 2, 985}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW */
+ {0x1e1a, 2, 987}, /* LATIN CAPITAL LETTER E WITH TILDE BELOW */
+ {0x1e1b, 2, 989}, /* LATIN SMALL LETTER E WITH TILDE BELOW */
+ {0x1e1c, 2, 991}, /* LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE */
+ {0x1e1d, 2, 993}, /* LATIN SMALL LETTER E WITH CEDILLA AND BREVE */
+ {0x1e1e, 2, 995}, /* LATIN CAPITAL LETTER F WITH DOT ABOVE */
+ {0x1e1f, 2, 997}, /* LATIN SMALL LETTER F WITH DOT ABOVE */
+ {0x1e20, 2, 999}, /* LATIN CAPITAL LETTER G WITH MACRON */
+ {0x1e21, 2, 1001}, /* LATIN SMALL LETTER G WITH MACRON */
+ {0x1e22, 2, 1003}, /* LATIN CAPITAL LETTER H WITH DOT ABOVE */
+ {0x1e23, 2, 1005}, /* LATIN SMALL LETTER H WITH DOT ABOVE */
+ {0x1e24, 2, 1007}, /* LATIN CAPITAL LETTER H WITH DOT BELOW */
+ {0x1e25, 2, 1009}, /* LATIN SMALL LETTER H WITH DOT BELOW */
+ {0x1e26, 2, 1011}, /* LATIN CAPITAL LETTER H WITH DIAERESIS */
+ {0x1e27, 2, 1013}, /* LATIN SMALL LETTER H WITH DIAERESIS */
+ {0x1e28, 2, 1015}, /* LATIN CAPITAL LETTER H WITH CEDILLA */
+ {0x1e29, 2, 1017}, /* LATIN SMALL LETTER H WITH CEDILLA */
+ {0x1e2a, 2, 1019}, /* LATIN CAPITAL LETTER H WITH BREVE BELOW */
+ {0x1e2b, 2, 1021}, /* LATIN SMALL LETTER H WITH BREVE BELOW */
+ {0x1e2c, 2, 1023}, /* LATIN CAPITAL LETTER I WITH TILDE BELOW */
+ {0x1e2d, 2, 1025}, /* LATIN SMALL LETTER I WITH TILDE BELOW */
+ {0x1e2e, 2, 1027}, /* LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE */
+ {0x1e2f, 2, 1029}, /* LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE */
+ {0x1e30, 2, 1031}, /* LATIN CAPITAL LETTER K WITH ACUTE */
+ {0x1e31, 2, 1033}, /* LATIN SMALL LETTER K WITH ACUTE */
+ {0x1e32, 2, 1035}, /* LATIN CAPITAL LETTER K WITH DOT BELOW */
+ {0x1e33, 2, 1037}, /* LATIN SMALL LETTER K WITH DOT BELOW */
+ {0x1e34, 2, 1039}, /* LATIN CAPITAL LETTER K WITH LINE BELOW */
+ {0x1e35, 2, 1041}, /* LATIN SMALL LETTER K WITH LINE BELOW */
+ {0x1e36, 2, 1043}, /* LATIN CAPITAL LETTER L WITH DOT BELOW */
+ {0x1e37, 2, 1045}, /* LATIN SMALL LETTER L WITH DOT BELOW */
+ {0x1e38, 2, 1047}, /* LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON */
+ {0x1e39, 2, 1049}, /* LATIN SMALL LETTER L WITH DOT BELOW AND MACRON */
+ {0x1e3a, 2, 1051}, /* LATIN CAPITAL LETTER L WITH LINE BELOW */
+ {0x1e3b, 2, 1053}, /* LATIN SMALL LETTER L WITH LINE BELOW */
+ {0x1e3c, 2, 1055}, /* LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW */
+ {0x1e3d, 2, 1057}, /* LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW */
+ {0x1e3e, 2, 1059}, /* LATIN CAPITAL LETTER M WITH ACUTE */
+ {0x1e3f, 2, 1061}, /* LATIN SMALL LETTER M WITH ACUTE */
+ {0x1e40, 2, 1063}, /* LATIN CAPITAL LETTER M WITH DOT ABOVE */
+ {0x1e41, 2, 1065}, /* LATIN SMALL LETTER M WITH DOT ABOVE */
+ {0x1e42, 2, 1067}, /* LATIN CAPITAL LETTER M WITH DOT BELOW */
+ {0x1e43, 2, 1069}, /* LATIN SMALL LETTER M WITH DOT BELOW */
+ {0x1e44, 2, 1071}, /* LATIN CAPITAL LETTER N WITH DOT ABOVE */
+ {0x1e45, 2, 1073}, /* LATIN SMALL LETTER N WITH DOT ABOVE */
+ {0x1e46, 2, 1075}, /* LATIN CAPITAL LETTER N WITH DOT BELOW */
+ {0x1e47, 2, 1077}, /* LATIN SMALL LETTER N WITH DOT BELOW */
+ {0x1e48, 2, 1079}, /* LATIN CAPITAL LETTER N WITH LINE BELOW */
+ {0x1e49, 2, 1081}, /* LATIN SMALL LETTER N WITH LINE BELOW */
+ {0x1e4a, 2, 1083}, /* LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW */
+ {0x1e4b, 2, 1085}, /* LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW */
+ {0x1e4c, 2, 1087}, /* LATIN CAPITAL LETTER O WITH TILDE AND ACUTE */
+ {0x1e4d, 2, 1089}, /* LATIN SMALL LETTER O WITH TILDE AND ACUTE */
+ {0x1e4e, 2, 1091}, /* LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS */
+ {0x1e4f, 2, 1093}, /* LATIN SMALL LETTER O WITH TILDE AND DIAERESIS */
+ {0x1e50, 2, 1095}, /* LATIN CAPITAL LETTER O WITH MACRON AND GRAVE */
+ {0x1e51, 2, 1097}, /* LATIN SMALL LETTER O WITH MACRON AND GRAVE */
+ {0x1e52, 2, 1099}, /* LATIN CAPITAL LETTER O WITH MACRON AND ACUTE */
+ {0x1e53, 2, 1101}, /* LATIN SMALL LETTER O WITH MACRON AND ACUTE */
+ {0x1e54, 2, 1103}, /* LATIN CAPITAL LETTER P WITH ACUTE */
+ {0x1e55, 2, 1105}, /* LATIN SMALL LETTER P WITH ACUTE */
+ {0x1e56, 2, 1107}, /* LATIN CAPITAL LETTER P WITH DOT ABOVE */
+ {0x1e57, 2, 1109}, /* LATIN SMALL LETTER P WITH DOT ABOVE */
+ {0x1e58, 2, 1111}, /* LATIN CAPITAL LETTER R WITH DOT ABOVE */
+ {0x1e59, 2, 1113}, /* LATIN SMALL LETTER R WITH DOT ABOVE */
+ {0x1e5a, 2, 1115}, /* LATIN CAPITAL LETTER R WITH DOT BELOW */
+ {0x1e5b, 2, 1117}, /* LATIN SMALL LETTER R WITH DOT BELOW */
+ {0x1e5c, 2, 1119}, /* LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON */
+ {0x1e5d, 2, 1121}, /* LATIN SMALL LETTER R WITH DOT BELOW AND MACRON */
+ {0x1e5e, 2, 1123}, /* LATIN CAPITAL LETTER R WITH LINE BELOW */
+ {0x1e5f, 2, 1125}, /* LATIN SMALL LETTER R WITH LINE BELOW */
+ {0x1e60, 2, 1127}, /* LATIN CAPITAL LETTER S WITH DOT ABOVE */
+ {0x1e61, 2, 1129}, /* LATIN SMALL LETTER S WITH DOT ABOVE */
+ {0x1e62, 2, 1131}, /* LATIN CAPITAL LETTER S WITH DOT BELOW */
+ {0x1e63, 2, 1133}, /* LATIN SMALL LETTER S WITH DOT BELOW */
+ {0x1e64, 2, 1135}, /* LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE */
+ {0x1e65, 2, 1137}, /* LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE */
+ {0x1e66, 2, 1139}, /* LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE */
+ {0x1e67, 2, 1141}, /* LATIN SMALL LETTER S WITH CARON AND DOT ABOVE */
+ {0x1e68, 2, 1143}, /* LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE */
+ {0x1e69, 2, 1145}, /* LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE */
+ {0x1e6a, 2, 1147}, /* LATIN CAPITAL LETTER T WITH DOT ABOVE */
+ {0x1e6b, 2, 1149}, /* LATIN SMALL LETTER T WITH DOT ABOVE */
+ {0x1e6c, 2, 1151}, /* LATIN CAPITAL LETTER T WITH DOT BELOW */
+ {0x1e6d, 2, 1153}, /* LATIN SMALL LETTER T WITH DOT BELOW */
+ {0x1e6e, 2, 1155}, /* LATIN CAPITAL LETTER T WITH LINE BELOW */
+ {0x1e6f, 2, 1157}, /* LATIN SMALL LETTER T WITH LINE BELOW */
+ {0x1e70, 2, 1159}, /* LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW */
+ {0x1e71, 2, 1161}, /* LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW */
+ {0x1e72, 2, 1163}, /* LATIN CAPITAL LETTER U WITH DIAERESIS BELOW */
+ {0x1e73, 2, 1165}, /* LATIN SMALL LETTER U WITH DIAERESIS BELOW */
+ {0x1e74, 2, 1167}, /* LATIN CAPITAL LETTER U WITH TILDE BELOW */
+ {0x1e75, 2, 1169}, /* LATIN SMALL LETTER U WITH TILDE BELOW */
+ {0x1e76, 2, 1171}, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW */
+ {0x1e77, 2, 1173}, /* LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW */
+ {0x1e78, 2, 1175}, /* LATIN CAPITAL LETTER U WITH TILDE AND ACUTE */
+ {0x1e79, 2, 1177}, /* LATIN SMALL LETTER U WITH TILDE AND ACUTE */
+ {0x1e7a, 2, 1179}, /* LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS */
+ {0x1e7b, 2, 1181}, /* LATIN SMALL LETTER U WITH MACRON AND DIAERESIS */
+ {0x1e7c, 2, 1183}, /* LATIN CAPITAL LETTER V WITH TILDE */
+ {0x1e7d, 2, 1185}, /* LATIN SMALL LETTER V WITH TILDE */
+ {0x1e7e, 2, 1187}, /* LATIN CAPITAL LETTER V WITH DOT BELOW */
+ {0x1e7f, 2, 1189}, /* LATIN SMALL LETTER V WITH DOT BELOW */
+ {0x1e80, 2, 1191}, /* LATIN CAPITAL LETTER W WITH GRAVE */
+ {0x1e81, 2, 1193}, /* LATIN SMALL LETTER W WITH GRAVE */
+ {0x1e82, 2, 1195}, /* LATIN CAPITAL LETTER W WITH ACUTE */
+ {0x1e83, 2, 1197}, /* LATIN SMALL LETTER W WITH ACUTE */
+ {0x1e84, 2, 1199}, /* LATIN CAPITAL LETTER W WITH DIAERESIS */
+ {0x1e85, 2, 1201}, /* LATIN SMALL LETTER W WITH DIAERESIS */
+ {0x1e86, 2, 1203}, /* LATIN CAPITAL LETTER W WITH DOT ABOVE */
+ {0x1e87, 2, 1205}, /* LATIN SMALL LETTER W WITH DOT ABOVE */
+ {0x1e88, 2, 1207}, /* LATIN CAPITAL LETTER W WITH DOT BELOW */
+ {0x1e89, 2, 1209}, /* LATIN SMALL LETTER W WITH DOT BELOW */
+ {0x1e8a, 2, 1211}, /* LATIN CAPITAL LETTER X WITH DOT ABOVE */
+ {0x1e8b, 2, 1213}, /* LATIN SMALL LETTER X WITH DOT ABOVE */
+ {0x1e8c, 2, 1215}, /* LATIN CAPITAL LETTER X WITH DIAERESIS */
+ {0x1e8d, 2, 1217}, /* LATIN SMALL LETTER X WITH DIAERESIS */
+ {0x1e8e, 2, 1219}, /* LATIN CAPITAL LETTER Y WITH DOT ABOVE */
+ {0x1e8f, 2, 1221}, /* LATIN SMALL LETTER Y WITH DOT ABOVE */
+ {0x1e90, 2, 1223}, /* LATIN CAPITAL LETTER Z WITH CIRCUMFLEX */
+ {0x1e91, 2, 1225}, /* LATIN SMALL LETTER Z WITH CIRCUMFLEX */
+ {0x1e92, 2, 1227}, /* LATIN CAPITAL LETTER Z WITH DOT BELOW */
+ {0x1e93, 2, 1229}, /* LATIN SMALL LETTER Z WITH DOT BELOW */
+ {0x1e94, 2, 1231}, /* LATIN CAPITAL LETTER Z WITH LINE BELOW */
+ {0x1e95, 2, 1233}, /* LATIN SMALL LETTER Z WITH LINE BELOW */
+ {0x1e96, 2, 1235}, /* LATIN SMALL LETTER H WITH LINE BELOW */
+ {0x1e97, 2, 1237}, /* LATIN SMALL LETTER T WITH DIAERESIS */
+ {0x1e98, 2, 1239}, /* LATIN SMALL LETTER W WITH RING ABOVE */
+ {0x1e99, 2, 1241}, /* LATIN SMALL LETTER Y WITH RING ABOVE */
+ {0x1e9a, 2, 1243}, /* LATIN SMALL LETTER A WITH RIGHT HALF RING */
+ {0x1e9b, 2, 1245}, /* LATIN SMALL LETTER LONG S WITH DOT ABOVE */
+ {0x1ea0, 2, 1247}, /* LATIN CAPITAL LETTER A WITH DOT BELOW */
+ {0x1ea1, 2, 1249}, /* LATIN SMALL LETTER A WITH DOT BELOW */
+ {0x1ea2, 2, 1251}, /* LATIN CAPITAL LETTER A WITH HOOK ABOVE */
+ {0x1ea3, 2, 1253}, /* LATIN SMALL LETTER A WITH HOOK ABOVE */
+ {0x1ea4, 2, 1255}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
+ {0x1ea5, 2, 1257}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
+ {0x1ea6, 2, 1259}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
+ {0x1ea7, 2, 1261}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
+ {0x1ea8, 2, 1263}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+ {0x1ea9, 2, 1265}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+ {0x1eaa, 2, 1267}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
+ {0x1eab, 2, 1269}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
+ {0x1eac, 2, 1271}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+ {0x1ead, 2, 1273}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+ {0x1eae, 2, 1275}, /* LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
+ {0x1eaf, 2, 1277}, /* LATIN SMALL LETTER A WITH BREVE AND ACUTE */
+ {0x1eb0, 2, 1279}, /* LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
+ {0x1eb1, 2, 1281}, /* LATIN SMALL LETTER A WITH BREVE AND GRAVE */
+ {0x1eb2, 2, 1283}, /* LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
+ {0x1eb3, 2, 1285}, /* LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
+ {0x1eb4, 2, 1287}, /* LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
+ {0x1eb5, 2, 1289}, /* LATIN SMALL LETTER A WITH BREVE AND TILDE */
+ {0x1eb6, 2, 1291}, /* LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
+ {0x1eb7, 2, 1293}, /* LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
+ {0x1eb8, 2, 1295}, /* LATIN CAPITAL LETTER E WITH DOT BELOW */
+ {0x1eb9, 2, 1297}, /* LATIN SMALL LETTER E WITH DOT BELOW */
+ {0x1eba, 2, 1299}, /* LATIN CAPITAL LETTER E WITH HOOK ABOVE */
+ {0x1ebb, 2, 1301}, /* LATIN SMALL LETTER E WITH HOOK ABOVE */
+ {0x1ebc, 2, 1303}, /* LATIN CAPITAL LETTER E WITH TILDE */
+ {0x1ebd, 2, 1305}, /* LATIN SMALL LETTER E WITH TILDE */
+ {0x1ebe, 2, 1307}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
+ {0x1ebf, 2, 1309}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
+ {0x1ec0, 2, 1311}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
+ {0x1ec1, 2, 1313}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
+ {0x1ec2, 2, 1315}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+ {0x1ec3, 2, 1317}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+ {0x1ec4, 2, 1319}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
+ {0x1ec5, 2, 1321}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
+ {0x1ec6, 2, 1323}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+ {0x1ec7, 2, 1325}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+ {0x1ec8, 2, 1327}, /* LATIN CAPITAL LETTER I WITH HOOK ABOVE */
+ {0x1ec9, 2, 1329}, /* LATIN SMALL LETTER I WITH HOOK ABOVE */
+ {0x1eca, 2, 1331}, /* LATIN CAPITAL LETTER I WITH DOT BELOW */
+ {0x1ecb, 2, 1333}, /* LATIN SMALL LETTER I WITH DOT BELOW */
+ {0x1ecc, 2, 1335}, /* LATIN CAPITAL LETTER O WITH DOT BELOW */
+ {0x1ecd, 2, 1337}, /* LATIN SMALL LETTER O WITH DOT BELOW */
+ {0x1ece, 2, 1339}, /* LATIN CAPITAL LETTER O WITH HOOK ABOVE */
+ {0x1ecf, 2, 1341}, /* LATIN SMALL LETTER O WITH HOOK ABOVE */
+ {0x1ed0, 2, 1343}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
+ {0x1ed1, 2, 1345}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
+ {0x1ed2, 2, 1347}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
+ {0x1ed3, 2, 1349}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
+ {0x1ed4, 2, 1351}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+ {0x1ed5, 2, 1353}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+ {0x1ed6, 2, 1355}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
+ {0x1ed7, 2, 1357}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
+ {0x1ed8, 2, 1359}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+ {0x1ed9, 2, 1361}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+ {0x1eda, 2, 1363}, /* LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
+ {0x1edb, 2, 1365}, /* LATIN SMALL LETTER O WITH HORN AND ACUTE */
+ {0x1edc, 2, 1367}, /* LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
+ {0x1edd, 2, 1369}, /* LATIN SMALL LETTER O WITH HORN AND GRAVE */
+ {0x1ede, 2, 1371}, /* LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
+ {0x1edf, 2, 1373}, /* LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
+ {0x1ee0, 2, 1375}, /* LATIN CAPITAL LETTER O WITH HORN AND TILDE */
+ {0x1ee1, 2, 1377}, /* LATIN SMALL LETTER O WITH HORN AND TILDE */
+ {0x1ee2, 2, 1379}, /* LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
+ {0x1ee3, 2, 1381}, /* LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
+ {0x1ee4, 2, 1383}, /* LATIN CAPITAL LETTER U WITH DOT BELOW */
+ {0x1ee5, 2, 1385}, /* LATIN SMALL LETTER U WITH DOT BELOW */
+ {0x1ee6, 2, 1387}, /* LATIN CAPITAL LETTER U WITH HOOK ABOVE */
+ {0x1ee7, 2, 1389}, /* LATIN SMALL LETTER U WITH HOOK ABOVE */
+ {0x1ee8, 2, 1391}, /* LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
+ {0x1ee9, 2, 1393}, /* LATIN SMALL LETTER U WITH HORN AND ACUTE */
+ {0x1eea, 2, 1395}, /* LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
+ {0x1eeb, 2, 1397}, /* LATIN SMALL LETTER U WITH HORN AND GRAVE */
+ {0x1eec, 2, 1399}, /* LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
+ {0x1eed, 2, 1401}, /* LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
+ {0x1eee, 2, 1403}, /* LATIN CAPITAL LETTER U WITH HORN AND TILDE */
+ {0x1eef, 2, 1405}, /* LATIN SMALL LETTER U WITH HORN AND TILDE */
+ {0x1ef0, 2, 1407}, /* LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
+ {0x1ef1, 2, 1409}, /* LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
+ {0x1ef2, 2, 1411}, /* LATIN CAPITAL LETTER Y WITH GRAVE */
+ {0x1ef3, 2, 1413}, /* LATIN SMALL LETTER Y WITH GRAVE */
+ {0x1ef4, 2, 1415}, /* LATIN CAPITAL LETTER Y WITH DOT BELOW */
+ {0x1ef5, 2, 1417}, /* LATIN SMALL LETTER Y WITH DOT BELOW */
+ {0x1ef6, 2, 1419}, /* LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
+ {0x1ef7, 2, 1421}, /* LATIN SMALL LETTER Y WITH HOOK ABOVE */
+ {0x1ef8, 2, 1423}, /* LATIN CAPITAL LETTER Y WITH TILDE */
+ {0x1ef9, 2, 1425}, /* LATIN SMALL LETTER Y WITH TILDE */
+ {0x1f00, 2, 1427}, /* GREEK SMALL LETTER ALPHA WITH PSILI */
+ {0x1f01, 2, 1429}, /* GREEK SMALL LETTER ALPHA WITH DASIA */
+ {0x1f02, 2, 1431}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA */
+ {0x1f03, 2, 1433}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA */
+ {0x1f04, 2, 1435}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA */
+ {0x1f05, 2, 1437}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA */
+ {0x1f06, 2, 1439}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI */
+ {0x1f07, 2, 1441}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI */
+ {0x1f08, 2, 1443}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI */
+ {0x1f09, 2, 1445}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA */
+ {0x1f0a, 2, 1447}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA */
+ {0x1f0b, 2, 1449}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA */
+ {0x1f0c, 2, 1451}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA */
+ {0x1f0d, 2, 1453}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA */
+ {0x1f0e, 2, 1455}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI */
+ {0x1f0f, 2, 1457}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI */
+ {0x1f10, 2, 1459}, /* GREEK SMALL LETTER EPSILON WITH PSILI */
+ {0x1f11, 2, 1461}, /* GREEK SMALL LETTER EPSILON WITH DASIA */
+ {0x1f12, 2, 1463}, /* GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA */
+ {0x1f13, 2, 1465}, /* GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA */
+ {0x1f14, 2, 1467}, /* GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA */
+ {0x1f15, 2, 1469}, /* GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA */
+ {0x1f18, 2, 1471}, /* GREEK CAPITAL LETTER EPSILON WITH PSILI */
+ {0x1f19, 2, 1473}, /* GREEK CAPITAL LETTER EPSILON WITH DASIA */
+ {0x1f1a, 2, 1475}, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA */
+ {0x1f1b, 2, 1477}, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA */
+ {0x1f1c, 2, 1479}, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA */
+ {0x1f1d, 2, 1481}, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA */
+ {0x1f20, 2, 1483}, /* GREEK SMALL LETTER ETA WITH PSILI */
+ {0x1f21, 2, 1485}, /* GREEK SMALL LETTER ETA WITH DASIA */
+ {0x1f22, 2, 1487}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA */
+ {0x1f23, 2, 1489}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA */
+ {0x1f24, 2, 1491}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA */
+ {0x1f25, 2, 1493}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA */
+ {0x1f26, 2, 1495}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI */
+ {0x1f27, 2, 1497}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI */
+ {0x1f28, 2, 1499}, /* GREEK CAPITAL LETTER ETA WITH PSILI */
+ {0x1f29, 2, 1501}, /* GREEK CAPITAL LETTER ETA WITH DASIA */
+ {0x1f2a, 2, 1503}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA */
+ {0x1f2b, 2, 1505}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA */
+ {0x1f2c, 2, 1507}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA */
+ {0x1f2d, 2, 1509}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA */
+ {0x1f2e, 2, 1511}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI */
+ {0x1f2f, 2, 1513}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI */
+ {0x1f30, 2, 1515}, /* GREEK SMALL LETTER IOTA WITH PSILI */
+ {0x1f31, 2, 1517}, /* GREEK SMALL LETTER IOTA WITH DASIA */
+ {0x1f32, 2, 1519}, /* GREEK SMALL LETTER IOTA WITH PSILI AND VARIA */
+ {0x1f33, 2, 1521}, /* GREEK SMALL LETTER IOTA WITH DASIA AND VARIA */
+ {0x1f34, 2, 1523}, /* GREEK SMALL LETTER IOTA WITH PSILI AND OXIA */
+ {0x1f35, 2, 1525}, /* GREEK SMALL LETTER IOTA WITH DASIA AND OXIA */
+ {0x1f36, 2, 1527}, /* GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI */
+ {0x1f37, 2, 1529}, /* GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI */
+ {0x1f38, 2, 1531}, /* GREEK CAPITAL LETTER IOTA WITH PSILI */
+ {0x1f39, 2, 1533}, /* GREEK CAPITAL LETTER IOTA WITH DASIA */
+ {0x1f3a, 2, 1535}, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA */
+ {0x1f3b, 2, 1537}, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA */
+ {0x1f3c, 2, 1539}, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA */
+ {0x1f3d, 2, 1541}, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA */
+ {0x1f3e, 2, 1543}, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI */
+ {0x1f3f, 2, 1545}, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI */
+ {0x1f40, 2, 1547}, /* GREEK SMALL LETTER OMICRON WITH PSILI */
+ {0x1f41, 2, 1549}, /* GREEK SMALL LETTER OMICRON WITH DASIA */
+ {0x1f42, 2, 1551}, /* GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA */
+ {0x1f43, 2, 1553}, /* GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA */
+ {0x1f44, 2, 1555}, /* GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA */
+ {0x1f45, 2, 1557}, /* GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA */
+ {0x1f48, 2, 1559}, /* GREEK CAPITAL LETTER OMICRON WITH PSILI */
+ {0x1f49, 2, 1561}, /* GREEK CAPITAL LETTER OMICRON WITH DASIA */
+ {0x1f4a, 2, 1563}, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA */
+ {0x1f4b, 2, 1565}, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA */
+ {0x1f4c, 2, 1567}, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA */
+ {0x1f4d, 2, 1569}, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA */
+ {0x1f50, 2, 1571}, /* GREEK SMALL LETTER UPSILON WITH PSILI */
+ {0x1f51, 2, 1573}, /* GREEK SMALL LETTER UPSILON WITH DASIA */
+ {0x1f52, 2, 1575}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */
+ {0x1f53, 2, 1577}, /* GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA */
+ {0x1f54, 2, 1579}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */
+ {0x1f55, 2, 1581}, /* GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA */
+ {0x1f56, 2, 1583}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */
+ {0x1f57, 2, 1585}, /* GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI */
+ {0x1f59, 2, 1587}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA */
+ {0x1f5b, 2, 1589}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA */
+ {0x1f5d, 2, 1591}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA */
+ {0x1f5f, 2, 1593}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI */
+ {0x1f60, 2, 1595}, /* GREEK SMALL LETTER OMEGA WITH PSILI */
+ {0x1f61, 2, 1597}, /* GREEK SMALL LETTER OMEGA WITH DASIA */
+ {0x1f62, 2, 1599}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA */
+ {0x1f63, 2, 1601}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA */
+ {0x1f64, 2, 1603}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA */
+ {0x1f65, 2, 1605}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA */
+ {0x1f66, 2, 1607}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI */
+ {0x1f67, 2, 1609}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI */
+ {0x1f68, 2, 1611}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI */
+ {0x1f69, 2, 1613}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA */
+ {0x1f6a, 2, 1615}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA */
+ {0x1f6b, 2, 1617}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA */
+ {0x1f6c, 2, 1619}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA */
+ {0x1f6d, 2, 1621}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA */
+ {0x1f6e, 2, 1623}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI */
+ {0x1f6f, 2, 1625}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI */
+ {0x1f70, 2, 1627}, /* GREEK SMALL LETTER ALPHA WITH VARIA */
+ {0x1f71, 1, 1629}, /* GREEK SMALL LETTER ALPHA WITH OXIA */
+ {0x1f72, 2, 1630}, /* GREEK SMALL LETTER EPSILON WITH VARIA */
+ {0x1f73, 1, 1632}, /* GREEK SMALL LETTER EPSILON WITH OXIA */
+ {0x1f74, 2, 1633}, /* GREEK SMALL LETTER ETA WITH VARIA */
+ {0x1f75, 1, 1635}, /* GREEK SMALL LETTER ETA WITH OXIA */
+ {0x1f76, 2, 1636}, /* GREEK SMALL LETTER IOTA WITH VARIA */
+ {0x1f77, 1, 1638}, /* GREEK SMALL LETTER IOTA WITH OXIA */
+ {0x1f78, 2, 1639}, /* GREEK SMALL LETTER OMICRON WITH VARIA */
+ {0x1f79, 1, 1641}, /* GREEK SMALL LETTER OMICRON WITH OXIA */
+ {0x1f7a, 2, 1642}, /* GREEK SMALL LETTER UPSILON WITH VARIA */
+ {0x1f7b, 1, 1644}, /* GREEK SMALL LETTER UPSILON WITH OXIA */
+ {0x1f7c, 2, 1645}, /* GREEK SMALL LETTER OMEGA WITH VARIA */
+ {0x1f7d, 1, 1647}, /* GREEK SMALL LETTER OMEGA WITH OXIA */
+ {0x1f80, 2, 1648}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */
+ {0x1f81, 2, 1650}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */
+ {0x1f82, 2, 1652}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+ {0x1f83, 2, 1654}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+ {0x1f84, 2, 1656}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+ {0x1f85, 2, 1658}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+ {0x1f86, 2, 1660}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1f87, 2, 1662}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1f88, 2, 1664}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
+ {0x1f89, 2, 1666}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
+ {0x1f8a, 2, 1668}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+ {0x1f8b, 2, 1670}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+ {0x1f8c, 2, 1672}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+ {0x1f8d, 2, 1674}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+ {0x1f8e, 2, 1676}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+ {0x1f8f, 2, 1678}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+ {0x1f90, 2, 1680}, /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */
+ {0x1f91, 2, 1682}, /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */
+ {0x1f92, 2, 1684}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+ {0x1f93, 2, 1686}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+ {0x1f94, 2, 1688}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+ {0x1f95, 2, 1690}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+ {0x1f96, 2, 1692}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1f97, 2, 1694}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1f98, 2, 1696}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */
+ {0x1f99, 2, 1698}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */
+ {0x1f9a, 2, 1700}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+ {0x1f9b, 2, 1702}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+ {0x1f9c, 2, 1704}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+ {0x1f9d, 2, 1706}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+ {0x1f9e, 2, 1708}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+ {0x1f9f, 2, 1710}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+ {0x1fa0, 2, 1712}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI */
+ {0x1fa1, 2, 1714}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI */
+ {0x1fa2, 2, 1716}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+ {0x1fa3, 2, 1718}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+ {0x1fa4, 2, 1720}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+ {0x1fa5, 2, 1722}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+ {0x1fa6, 2, 1724}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1fa7, 2, 1726}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1fa8, 2, 1728}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
+ {0x1fa9, 2, 1730}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
+ {0x1faa, 2, 1732}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+ {0x1fab, 2, 1734}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+ {0x1fac, 2, 1736}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+ {0x1fad, 2, 1738}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+ {0x1fae, 2, 1740}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+ {0x1faf, 2, 1742}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+ {0x1fb0, 2, 1744}, /* GREEK SMALL LETTER ALPHA WITH VRACHY */
+ {0x1fb1, 2, 1746}, /* GREEK SMALL LETTER ALPHA WITH MACRON */
+ {0x1fb2, 2, 1748}, /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */
+ {0x1fb3, 2, 1750}, /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */
+ {0x1fb4, 2, 1752}, /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */
+ {0x1fb6, 2, 1754}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */
+ {0x1fb7, 2, 1756}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1fb8, 2, 1758}, /* GREEK CAPITAL LETTER ALPHA WITH VRACHY */
+ {0x1fb9, 2, 1760}, /* GREEK CAPITAL LETTER ALPHA WITH MACRON */
+ {0x1fba, 2, 1762}, /* GREEK CAPITAL LETTER ALPHA WITH VARIA */
+ {0x1fbb, 1, 1764}, /* GREEK CAPITAL LETTER ALPHA WITH OXIA */
+ {0x1fbc, 2, 1765}, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
+ {0x1fbd, 2, 1767}, /* GREEK KORONIS */
+ {0x1fbe, 1, 616}, /* GREEK PROSGEGRAMMENI */
+ {0x1fbf, 2, 1767}, /* GREEK PSILI */
+ {0x1fc0, 2, 1769}, /* GREEK PERISPOMENI */
+ {0x1fc1, 2, 1771}, /* GREEK DIALYTIKA AND PERISPOMENI */
+ {0x1fc2, 2, 1773}, /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */
+ {0x1fc3, 2, 1775}, /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */
+ {0x1fc4, 2, 1777}, /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */
+ {0x1fc6, 2, 1779}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI */
+ {0x1fc7, 2, 1781}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1fc8, 2, 1783}, /* GREEK CAPITAL LETTER EPSILON WITH VARIA */
+ {0x1fc9, 1, 1785}, /* GREEK CAPITAL LETTER EPSILON WITH OXIA */
+ {0x1fca, 2, 1786}, /* GREEK CAPITAL LETTER ETA WITH VARIA */
+ {0x1fcb, 1, 1788}, /* GREEK CAPITAL LETTER ETA WITH OXIA */
+ {0x1fcc, 2, 1789}, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
+ {0x1fcd, 2, 1791}, /* GREEK PSILI AND VARIA */
+ {0x1fce, 2, 1793}, /* GREEK PSILI AND OXIA */
+ {0x1fcf, 2, 1795}, /* GREEK PSILI AND PERISPOMENI */
+ {0x1fd0, 2, 1797}, /* GREEK SMALL LETTER IOTA WITH VRACHY */
+ {0x1fd1, 2, 1799}, /* GREEK SMALL LETTER IOTA WITH MACRON */
+ {0x1fd2, 2, 1801}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */
+ {0x1fd3, 1, 1803}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */
+ {0x1fd6, 2, 1804}, /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */
+ {0x1fd7, 2, 1806}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */
+ {0x1fd8, 2, 1808}, /* GREEK CAPITAL LETTER IOTA WITH VRACHY */
+ {0x1fd9, 2, 1810}, /* GREEK CAPITAL LETTER IOTA WITH MACRON */
+ {0x1fda, 2, 1812}, /* GREEK CAPITAL LETTER IOTA WITH VARIA */
+ {0x1fdb, 1, 1814}, /* GREEK CAPITAL LETTER IOTA WITH OXIA */
+ {0x1fdd, 2, 1815}, /* GREEK DASIA AND VARIA */
+ {0x1fde, 2, 1817}, /* GREEK DASIA AND OXIA */
+ {0x1fdf, 2, 1819}, /* GREEK DASIA AND PERISPOMENI */
+ {0x1fe0, 2, 1821}, /* GREEK SMALL LETTER UPSILON WITH VRACHY */
+ {0x1fe1, 2, 1823}, /* GREEK SMALL LETTER UPSILON WITH MACRON */
+ {0x1fe2, 2, 1825}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */
+ {0x1fe3, 1, 1827}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */
+ {0x1fe4, 2, 1828}, /* GREEK SMALL LETTER RHO WITH PSILI */
+ {0x1fe5, 2, 1830}, /* GREEK SMALL LETTER RHO WITH DASIA */
+ {0x1fe6, 2, 1832}, /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */
+ {0x1fe7, 2, 1834}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */
+ {0x1fe8, 2, 1836}, /* GREEK CAPITAL LETTER UPSILON WITH VRACHY */
+ {0x1fe9, 2, 1838}, /* GREEK CAPITAL LETTER UPSILON WITH MACRON */
+ {0x1fea, 2, 1840}, /* GREEK CAPITAL LETTER UPSILON WITH VARIA */
+ {0x1feb, 1, 1842}, /* GREEK CAPITAL LETTER UPSILON WITH OXIA */
+ {0x1fec, 2, 1843}, /* GREEK CAPITAL LETTER RHO WITH DASIA */
+ {0x1fed, 2, 1845}, /* GREEK DIALYTIKA AND VARIA */
+ {0x1fee, 1, 1847}, /* GREEK DIALYTIKA AND OXIA */
+ {0x1fef, 1, 1848}, /* GREEK VARIA */
+ {0x1ff2, 2, 1849}, /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */
+ {0x1ff3, 2, 1851}, /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */
+ {0x1ff4, 2, 1853}, /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */
+ {0x1ff6, 2, 1855}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */
+ {0x1ff7, 2, 1857}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */
+ {0x1ff8, 2, 1859}, /* GREEK CAPITAL LETTER OMICRON WITH VARIA */
+ {0x1ff9, 1, 1861}, /* GREEK CAPITAL LETTER OMICRON WITH OXIA */
+ {0x1ffa, 2, 1862}, /* GREEK CAPITAL LETTER OMEGA WITH VARIA */
+ {0x1ffb, 1, 1864}, /* GREEK CAPITAL LETTER OMEGA WITH OXIA */
+ {0x1ffc, 2, 1865}, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
+ {0x1ffd, 1, 1867}, /* GREEK OXIA */
+ {0x1ffe, 2, 1868}, /* GREEK DASIA */
+ {0x2000, 1, 1870}, /* EN QUAD */
+ {0x2001, 1, 1871}, /* EM QUAD */
+ {0x2002, 1, 1872}, /* EN SPACE */
+ {0x2003, 1, 1873}, /* EM SPACE */
+ {0x2004, 1, 1874}, /* THREE-PER-EM SPACE */
+ {0x2005, 1, 1875}, /* FOUR-PER-EM SPACE */
+ {0x2006, 1, 1876}, /* SIX-PER-EM SPACE */
+ {0x2007, 1, 1877}, /* FIGURE SPACE */
+ {0x2008, 1, 1878}, /* PUNCTUATION SPACE */
+ {0x2009, 1, 1879}, /* THIN SPACE */
+ {0x200a, 1, 1880}, /* HAIR SPACE */
+ {0x2011, 1, 1881}, /* NON-BREAKING HYPHEN */
+ {0x2017, 2, 1882}, /* DOUBLE LOW LINE */
+ {0x2024, 1, 1884}, /* ONE DOT LEADER */
+ {0x2025, 2, 1885}, /* TWO DOT LEADER */
+ {0x2026, 3, 1884}, /* HORIZONTAL ELLIPSIS */
+ {0x202f, 1, 1887}, /* NARROW NO-BREAK SPACE */
+ {0x2033, 2, 1888}, /* DOUBLE PRIME */
+ {0x2034, 3, 1890}, /* TRIPLE PRIME */
+ {0x2036, 2, 1893}, /* REVERSED DOUBLE PRIME */
+ {0x2037, 3, 1895}, /* REVERSED TRIPLE PRIME */
+ {0x203c, 2, 1898}, /* DOUBLE EXCLAMATION MARK */
+ {0x203e, 2, 1900}, /* OVERLINE */
+ {0x2047, 2, 1902}, /* DOUBLE QUESTION MARK */
+ {0x2048, 2, 1904}, /* QUESTION EXCLAMATION MARK */
+ {0x2049, 2, 1906}, /* EXCLAMATION QUESTION MARK */
+ {0x2057, 4, 1888}, /* QUADRUPLE PRIME */
+ {0x205f, 1, 1908}, /* MEDIUM MATHEMATICAL SPACE */
+ {0x2070, 1, 1909}, /* SUPERSCRIPT ZERO */
+ {0x2071, 1, 98}, /* SUPERSCRIPT LATIN SMALL LETTER I */
+ {0x2074, 1, 17}, /* SUPERSCRIPT FOUR */
+ {0x2075, 1, 1910}, /* SUPERSCRIPT FIVE */
+ {0x2076, 1, 1911}, /* SUPERSCRIPT SIX */
+ {0x2077, 1, 1912}, /* SUPERSCRIPT SEVEN */
+ {0x2078, 1, 1913}, /* SUPERSCRIPT EIGHT */
+ {0x2079, 1, 1914}, /* SUPERSCRIPT NINE */
+ {0x207a, 1, 1915}, /* SUPERSCRIPT PLUS SIGN */
+ {0x207b, 1, 1916}, /* SUPERSCRIPT MINUS */
+ {0x207c, 1, 1917}, /* SUPERSCRIPT EQUALS SIGN */
+ {0x207d, 1, 1918}, /* SUPERSCRIPT LEFT PARENTHESIS */
+ {0x207e, 1, 1919}, /* SUPERSCRIPT RIGHT PARENTHESIS */
+ {0x207f, 1, 106}, /* SUPERSCRIPT LATIN SMALL LETTER N */
+ {0x2080, 1, 1909}, /* SUBSCRIPT ZERO */
+ {0x2081, 1, 13}, /* SUBSCRIPT ONE */
+ {0x2082, 1, 6}, /* SUBSCRIPT TWO */
+ {0x2083, 1, 7}, /* SUBSCRIPT THREE */
+ {0x2084, 1, 17}, /* SUBSCRIPT FOUR */
+ {0x2085, 1, 1910}, /* SUBSCRIPT FIVE */
+ {0x2086, 1, 1911}, /* SUBSCRIPT SIX */
+ {0x2087, 1, 1912}, /* SUBSCRIPT SEVEN */
+ {0x2088, 1, 1913}, /* SUBSCRIPT EIGHT */
+ {0x2089, 1, 1914}, /* SUBSCRIPT NINE */
+ {0x208a, 1, 1915}, /* SUBSCRIPT PLUS SIGN */
+ {0x208b, 1, 1916}, /* SUBSCRIPT MINUS */
+ {0x208c, 1, 1917}, /* SUBSCRIPT EQUALS SIGN */
+ {0x208d, 1, 1918}, /* SUBSCRIPT LEFT PARENTHESIS */
+ {0x208e, 1, 1919}, /* SUBSCRIPT RIGHT PARENTHESIS */
+ {0x20a8, 2, 1920}, /* RUPEE SIGN */
+ {0x2100, 3, 1922}, /* ACCOUNT OF */
+ {0x2101, 3, 1925}, /* ADDRESSED TO THE SUBJECT */
+ {0x2102, 1, 36}, /* DOUBLE-STRUCK CAPITAL C */
+ {0x2103, 2, 1928}, /* DEGREE CELSIUS */
+ {0x2105, 3, 1930}, /* CARE OF */
+ {0x2106, 3, 1933}, /* CADA UNA */
+ {0x2107, 1, 1936}, /* EULER CONSTANT */
+ {0x2109, 2, 1937}, /* DEGREE FAHRENHEIT */
+ {0x210a, 1, 184}, /* SCRIPT SMALL G */
+ {0x210b, 1, 198}, /* SCRIPT CAPITAL H */
+ {0x210c, 1, 198}, /* BLACK-LETTER CAPITAL H */
+ {0x210d, 1, 198}, /* DOUBLE-STRUCK CAPITAL H */
+ {0x210e, 1, 200}, /* PLANCK CONSTANT */
+ {0x210f, 1, 1939}, /* PLANCK CONSTANT OVER TWO PI */
+ {0x2110, 1, 46}, /* SCRIPT CAPITAL I */
+ {0x2111, 1, 46}, /* BLACK-LETTER CAPITAL I */
+ {0x2112, 1, 232}, /* SCRIPT CAPITAL L */
+ {0x2113, 1, 234}, /* SCRIPT SMALL L */
+ {0x2115, 1, 54}, /* DOUBLE-STRUCK CAPITAL N */
+ {0x2116, 2, 1940}, /* NUMERO SIGN */
+ {0x2119, 1, 914}, /* DOUBLE-STRUCK CAPITAL P */
+ {0x211a, 1, 1942}, /* DOUBLE-STRUCK CAPITAL Q */
+ {0x211b, 1, 274}, /* SCRIPT CAPITAL R */
+ {0x211c, 1, 274}, /* BLACK-LETTER CAPITAL R */
+ {0x211d, 1, 274}, /* DOUBLE-STRUCK CAPITAL R */
+ {0x2120, 2, 1943}, /* SERVICE MARK */
+ {0x2121, 3, 1945}, /* TELEPHONE SIGN */
+ {0x2122, 2, 1948}, /* TRADE MARK SIGN */
+ {0x2124, 1, 344}, /* DOUBLE-STRUCK CAPITAL Z */
+ {0x2126, 1, 602}, /* OHM SIGN */
+ {0x2128, 1, 344}, /* BLACK-LETTER CAPITAL Z */
+ {0x212a, 1, 228}, /* KELVIN SIGN */
+ {0x212b, 1, 462}, /* ANGSTROM SIGN */
+ {0x212c, 1, 910}, /* SCRIPT CAPITAL B */
+ {0x212d, 1, 36}, /* BLACK-LETTER CAPITAL C */
+ {0x212f, 1, 90}, /* SCRIPT SMALL E */
+ {0x2130, 1, 38}, /* SCRIPT CAPITAL E */
+ {0x2131, 1, 995}, /* SCRIPT CAPITAL F */
+ {0x2133, 1, 912}, /* SCRIPT CAPITAL M */
+ {0x2134, 1, 14}, /* SCRIPT SMALL O */
+ {0x2135, 1, 1950}, /* ALEF SYMBOL */
+ {0x2136, 1, 1951}, /* BET SYMBOL */
+ {0x2137, 1, 1952}, /* GIMEL SYMBOL */
+ {0x2138, 1, 1953}, /* DALET SYMBOL */
+ {0x2139, 1, 98}, /* INFORMATION SOURCE */
+ {0x213b, 3, 1954}, /* FACSIMILE SIGN */
+ {0x213d, 1, 932}, /* DOUBLE-STRUCK SMALL GAMMA */
+ {0x213e, 1, 1957}, /* DOUBLE-STRUCK CAPITAL GAMMA */
+ {0x213f, 1, 1958}, /* DOUBLE-STRUCK CAPITAL PI */
+ {0x2140, 1, 1959}, /* DOUBLE-STRUCK N-ARY SUMMATION */
+ {0x2145, 1, 158}, /* DOUBLE-STRUCK ITALIC CAPITAL D */
+ {0x2146, 1, 160}, /* DOUBLE-STRUCK ITALIC SMALL D */
+ {0x2147, 1, 90}, /* DOUBLE-STRUCK ITALIC SMALL E */
+ {0x2148, 1, 98}, /* DOUBLE-STRUCK ITALIC SMALL I */
+ {0x2149, 1, 223}, /* DOUBLE-STRUCK ITALIC SMALL J */
+ {0x2153, 3, 1960}, /* VULGAR FRACTION ONE THIRD */
+ {0x2154, 3, 1963}, /* VULGAR FRACTION TWO THIRDS */
+ {0x2155, 3, 1966}, /* VULGAR FRACTION ONE FIFTH */
+ {0x2156, 3, 1969}, /* VULGAR FRACTION TWO FIFTHS */
+ {0x2157, 3, 1972}, /* VULGAR FRACTION THREE FIFTHS */
+ {0x2158, 3, 1975}, /* VULGAR FRACTION FOUR FIFTHS */
+ {0x2159, 3, 1978}, /* VULGAR FRACTION ONE SIXTH */
+ {0x215a, 3, 1981}, /* VULGAR FRACTION FIVE SIXTHS */
+ {0x215b, 3, 1984}, /* VULGAR FRACTION ONE EIGHTH */
+ {0x215c, 3, 1987}, /* VULGAR FRACTION THREE EIGHTHS */
+ {0x215d, 3, 1990}, /* VULGAR FRACTION FIVE EIGHTHS */
+ {0x215e, 3, 1993}, /* VULGAR FRACTION SEVEN EIGHTHS */
+ {0x215f, 2, 15}, /* FRACTION NUMERATOR ONE */
+ {0x2160, 1, 46}, /* ROMAN NUMERAL ONE */
+ {0x2161, 2, 1996}, /* ROMAN NUMERAL TWO */
+ {0x2162, 3, 1998}, /* ROMAN NUMERAL THREE */
+ {0x2163, 2, 2001}, /* ROMAN NUMERAL FOUR */
+ {0x2164, 1, 1183}, /* ROMAN NUMERAL FIVE */
+ {0x2165, 2, 2003}, /* ROMAN NUMERAL SIX */
+ {0x2166, 3, 2005}, /* ROMAN NUMERAL SEVEN */
+ {0x2167, 4, 2008}, /* ROMAN NUMERAL EIGHT */
+ {0x2168, 2, 2012}, /* ROMAN NUMERAL NINE */
+ {0x2169, 1, 1211}, /* ROMAN NUMERAL TEN */
+ {0x216a, 2, 2014}, /* ROMAN NUMERAL ELEVEN */
+ {0x216b, 3, 2016}, /* ROMAN NUMERAL TWELVE */
+ {0x216c, 1, 232}, /* ROMAN NUMERAL FIFTY */
+ {0x216d, 1, 36}, /* ROMAN NUMERAL ONE HUNDRED */
+ {0x216e, 1, 158}, /* ROMAN NUMERAL FIVE HUNDRED */
+ {0x216f, 1, 912}, /* ROMAN NUMERAL ONE THOUSAND */
+ {0x2170, 1, 98}, /* SMALL ROMAN NUMERAL ONE */
+ {0x2171, 2, 2019}, /* SMALL ROMAN NUMERAL TWO */
+ {0x2172, 3, 2021}, /* SMALL ROMAN NUMERAL THREE */
+ {0x2173, 2, 2024}, /* SMALL ROMAN NUMERAL FOUR */
+ {0x2174, 1, 930}, /* SMALL ROMAN NUMERAL FIVE */
+ {0x2175, 2, 2026}, /* SMALL ROMAN NUMERAL SIX */
+ {0x2176, 3, 2028}, /* SMALL ROMAN NUMERAL SEVEN */
+ {0x2177, 4, 2031}, /* SMALL ROMAN NUMERAL EIGHT */
+ {0x2178, 2, 2035}, /* SMALL ROMAN NUMERAL NINE */
+ {0x2179, 1, 579}, /* SMALL ROMAN NUMERAL TEN */
+ {0x217a, 2, 2037}, /* SMALL ROMAN NUMERAL ELEVEN */
+ {0x217b, 3, 2039}, /* SMALL ROMAN NUMERAL TWELVE */
+ {0x217c, 1, 234}, /* SMALL ROMAN NUMERAL FIFTY */
+ {0x217d, 1, 88}, /* SMALL ROMAN NUMERAL ONE HUNDRED */
+ {0x217e, 1, 160}, /* SMALL ROMAN NUMERAL FIVE HUNDRED */
+ {0x217f, 1, 922}, /* SMALL ROMAN NUMERAL ONE THOUSAND */
+ {0x219a, 2, 2042}, /* LEFTWARDS ARROW WITH STROKE */
+ {0x219b, 2, 2044}, /* RIGHTWARDS ARROW WITH STROKE */
+ {0x21ae, 2, 2046}, /* LEFT RIGHT ARROW WITH STROKE */
+ {0x21cd, 2, 2048}, /* LEFTWARDS DOUBLE ARROW WITH STROKE */
+ {0x21ce, 2, 2050}, /* LEFT RIGHT DOUBLE ARROW WITH STROKE */
+ {0x21cf, 2, 2052}, /* RIGHTWARDS DOUBLE ARROW WITH STROKE */
+ {0x2204, 2, 2054}, /* THERE DOES NOT EXIST */
+ {0x2209, 2, 2056}, /* NOT AN ELEMENT OF */
+ {0x220c, 2, 2058}, /* DOES NOT CONTAIN AS MEMBER */
+ {0x2224, 2, 2060}, /* DOES NOT DIVIDE */
+ {0x2226, 2, 2062}, /* NOT PARALLEL TO */
+ {0x222c, 2, 2064}, /* DOUBLE INTEGRAL */
+ {0x222d, 3, 2066}, /* TRIPLE INTEGRAL */
+ {0x222f, 2, 2069}, /* SURFACE INTEGRAL */
+ {0x2230, 3, 2071}, /* VOLUME INTEGRAL */
+ {0x2241, 2, 2074}, /* NOT TILDE */
+ {0x2244, 2, 2076}, /* NOT ASYMPTOTICALLY EQUAL TO */
+ {0x2247, 2, 2078}, /* NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO */
+ {0x2249, 2, 2080}, /* NOT ALMOST EQUAL TO */
+ {0x2260, 2, 2082}, /* NOT EQUAL TO */
+ {0x2262, 2, 2084}, /* NOT IDENTICAL TO */
+ {0x226d, 2, 2086}, /* NOT EQUIVALENT TO */
+ {0x226e, 2, 2088}, /* NOT LESS-THAN */
+ {0x226f, 2, 2090}, /* NOT GREATER-THAN */
+ {0x2270, 2, 2092}, /* NEITHER LESS-THAN NOR EQUAL TO */
+ {0x2271, 2, 2094}, /* NEITHER GREATER-THAN NOR EQUAL TO */
+ {0x2274, 2, 2096}, /* NEITHER LESS-THAN NOR EQUIVALENT TO */
+ {0x2275, 2, 2098}, /* NEITHER GREATER-THAN NOR EQUIVALENT TO */
+ {0x2278, 2, 2100}, /* NEITHER LESS-THAN NOR GREATER-THAN */
+ {0x2279, 2, 2102}, /* NEITHER GREATER-THAN NOR LESS-THAN */
+ {0x2280, 2, 2104}, /* DOES NOT PRECEDE */
+ {0x2281, 2, 2106}, /* DOES NOT SUCCEED */
+ {0x2284, 2, 2108}, /* NOT A SUBSET OF */
+ {0x2285, 2, 2110}, /* NOT A SUPERSET OF */
+ {0x2288, 2, 2112}, /* NEITHER A SUBSET OF NOR EQUAL TO */
+ {0x2289, 2, 2114}, /* NEITHER A SUPERSET OF NOR EQUAL TO */
+ {0x22ac, 2, 2116}, /* DOES NOT PROVE */
+ {0x22ad, 2, 2118}, /* NOT TRUE */
+ {0x22ae, 2, 2120}, /* DOES NOT FORCE */
+ {0x22af, 2, 2122}, /* NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE */
+ {0x22e0, 2, 2124}, /* DOES NOT PRECEDE OR EQUAL */
+ {0x22e1, 2, 2126}, /* DOES NOT SUCCEED OR EQUAL */
+ {0x22e2, 2, 2128}, /* NOT SQUARE IMAGE OF OR EQUAL TO */
+ {0x22e3, 2, 2130}, /* NOT SQUARE ORIGINAL OF OR EQUAL TO */
+ {0x22ea, 2, 2132}, /* NOT NORMAL SUBGROUP OF */
+ {0x22eb, 2, 2134}, /* DOES NOT CONTAIN AS NORMAL SUBGROUP */
+ {0x22ec, 2, 2136}, /* NOT NORMAL SUBGROUP OF OR EQUAL TO */
+ {0x22ed, 2, 2138}, /* DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL */
+ {0x2329, 1, 2140}, /* LEFT-POINTING ANGLE BRACKET */
+ {0x232a, 1, 2141}, /* RIGHT-POINTING ANGLE BRACKET */
+ {0x2460, 1, 13}, /* CIRCLED DIGIT ONE */
+ {0x2461, 1, 6}, /* CIRCLED DIGIT TWO */
+ {0x2462, 1, 7}, /* CIRCLED DIGIT THREE */
+ {0x2463, 1, 17}, /* CIRCLED DIGIT FOUR */
+ {0x2464, 1, 1910}, /* CIRCLED DIGIT FIVE */
+ {0x2465, 1, 1911}, /* CIRCLED DIGIT SIX */
+ {0x2466, 1, 1912}, /* CIRCLED DIGIT SEVEN */
+ {0x2467, 1, 1913}, /* CIRCLED DIGIT EIGHT */
+ {0x2468, 1, 1914}, /* CIRCLED DIGIT NINE */
+ {0x2469, 2, 2142}, /* CIRCLED NUMBER TEN */
+ {0x246a, 2, 2144}, /* CIRCLED NUMBER ELEVEN */
+ {0x246b, 2, 2146}, /* CIRCLED NUMBER TWELVE */
+ {0x246c, 2, 2148}, /* CIRCLED NUMBER THIRTEEN */
+ {0x246d, 2, 2150}, /* CIRCLED NUMBER FOURTEEN */
+ {0x246e, 2, 2152}, /* CIRCLED NUMBER FIFTEEN */
+ {0x246f, 2, 2154}, /* CIRCLED NUMBER SIXTEEN */
+ {0x2470, 2, 2156}, /* CIRCLED NUMBER SEVENTEEN */
+ {0x2471, 2, 2158}, /* CIRCLED NUMBER EIGHTEEN */
+ {0x2472, 2, 2160}, /* CIRCLED NUMBER NINETEEN */
+ {0x2473, 2, 2162}, /* CIRCLED NUMBER TWENTY */
+ {0x2474, 3, 2164}, /* PARENTHESIZED DIGIT ONE */
+ {0x2475, 3, 2167}, /* PARENTHESIZED DIGIT TWO */
+ {0x2476, 3, 2170}, /* PARENTHESIZED DIGIT THREE */
+ {0x2477, 3, 2173}, /* PARENTHESIZED DIGIT FOUR */
+ {0x2478, 3, 2176}, /* PARENTHESIZED DIGIT FIVE */
+ {0x2479, 3, 2179}, /* PARENTHESIZED DIGIT SIX */
+ {0x247a, 3, 2182}, /* PARENTHESIZED DIGIT SEVEN */
+ {0x247b, 3, 2185}, /* PARENTHESIZED DIGIT EIGHT */
+ {0x247c, 3, 2188}, /* PARENTHESIZED DIGIT NINE */
+ {0x247d, 4, 2191}, /* PARENTHESIZED NUMBER TEN */
+ {0x247e, 4, 2195}, /* PARENTHESIZED NUMBER ELEVEN */
+ {0x247f, 4, 2199}, /* PARENTHESIZED NUMBER TWELVE */
+ {0x2480, 4, 2203}, /* PARENTHESIZED NUMBER THIRTEEN */
+ {0x2481, 4, 2207}, /* PARENTHESIZED NUMBER FOURTEEN */
+ {0x2482, 4, 2211}, /* PARENTHESIZED NUMBER FIFTEEN */
+ {0x2483, 4, 2215}, /* PARENTHESIZED NUMBER SIXTEEN */
+ {0x2484, 4, 2219}, /* PARENTHESIZED NUMBER SEVENTEEN */
+ {0x2485, 4, 2223}, /* PARENTHESIZED NUMBER EIGHTEEN */
+ {0x2486, 4, 2227}, /* PARENTHESIZED NUMBER NINETEEN */
+ {0x2487, 4, 2231}, /* PARENTHESIZED NUMBER TWENTY */
+ {0x2488, 2, 2235}, /* DIGIT ONE FULL STOP */
+ {0x2489, 2, 2237}, /* DIGIT TWO FULL STOP */
+ {0x248a, 2, 2239}, /* DIGIT THREE FULL STOP */
+ {0x248b, 2, 2241}, /* DIGIT FOUR FULL STOP */
+ {0x248c, 2, 2243}, /* DIGIT FIVE FULL STOP */
+ {0x248d, 2, 2245}, /* DIGIT SIX FULL STOP */
+ {0x248e, 2, 2247}, /* DIGIT SEVEN FULL STOP */
+ {0x248f, 2, 2249}, /* DIGIT EIGHT FULL STOP */
+ {0x2490, 2, 2251}, /* DIGIT NINE FULL STOP */
+ {0x2491, 3, 2253}, /* NUMBER TEN FULL STOP */
+ {0x2492, 3, 2256}, /* NUMBER ELEVEN FULL STOP */
+ {0x2493, 3, 2259}, /* NUMBER TWELVE FULL STOP */
+ {0x2494, 3, 2262}, /* NUMBER THIRTEEN FULL STOP */
+ {0x2495, 3, 2265}, /* NUMBER FOURTEEN FULL STOP */
+ {0x2496, 3, 2268}, /* NUMBER FIFTEEN FULL STOP */
+ {0x2497, 3, 2271}, /* NUMBER SIXTEEN FULL STOP */
+ {0x2498, 3, 2274}, /* NUMBER SEVENTEEN FULL STOP */
+ {0x2499, 3, 2277}, /* NUMBER EIGHTEEN FULL STOP */
+ {0x249a, 3, 2280}, /* NUMBER NINETEEN FULL STOP */
+ {0x249b, 3, 2283}, /* NUMBER TWENTY FULL STOP */
+ {0x249c, 3, 2286}, /* PARENTHESIZED LATIN SMALL LETTER A */
+ {0x249d, 3, 2289}, /* PARENTHESIZED LATIN SMALL LETTER B */
+ {0x249e, 3, 2292}, /* PARENTHESIZED LATIN SMALL LETTER C */
+ {0x249f, 3, 2295}, /* PARENTHESIZED LATIN SMALL LETTER D */
+ {0x24a0, 3, 2298}, /* PARENTHESIZED LATIN SMALL LETTER E */
+ {0x24a1, 3, 2301}, /* PARENTHESIZED LATIN SMALL LETTER F */
+ {0x24a2, 3, 2304}, /* PARENTHESIZED LATIN SMALL LETTER G */
+ {0x24a3, 3, 2307}, /* PARENTHESIZED LATIN SMALL LETTER H */
+ {0x24a4, 3, 2310}, /* PARENTHESIZED LATIN SMALL LETTER I */
+ {0x24a5, 3, 2313}, /* PARENTHESIZED LATIN SMALL LETTER J */
+ {0x24a6, 3, 2316}, /* PARENTHESIZED LATIN SMALL LETTER K */
+ {0x24a7, 3, 2319}, /* PARENTHESIZED LATIN SMALL LETTER L */
+ {0x24a8, 3, 2322}, /* PARENTHESIZED LATIN SMALL LETTER M */
+ {0x24a9, 3, 2325}, /* PARENTHESIZED LATIN SMALL LETTER N */
+ {0x24aa, 3, 2328}, /* PARENTHESIZED LATIN SMALL LETTER O */
+ {0x24ab, 3, 2331}, /* PARENTHESIZED LATIN SMALL LETTER P */
+ {0x24ac, 3, 2334}, /* PARENTHESIZED LATIN SMALL LETTER Q */
+ {0x24ad, 3, 2337}, /* PARENTHESIZED LATIN SMALL LETTER R */
+ {0x24ae, 3, 2340}, /* PARENTHESIZED LATIN SMALL LETTER S */
+ {0x24af, 3, 2343}, /* PARENTHESIZED LATIN SMALL LETTER T */
+ {0x24b0, 3, 2346}, /* PARENTHESIZED LATIN SMALL LETTER U */
+ {0x24b1, 3, 2349}, /* PARENTHESIZED LATIN SMALL LETTER V */
+ {0x24b2, 3, 2352}, /* PARENTHESIZED LATIN SMALL LETTER W */
+ {0x24b3, 3, 2355}, /* PARENTHESIZED LATIN SMALL LETTER X */
+ {0x24b4, 3, 2358}, /* PARENTHESIZED LATIN SMALL LETTER Y */
+ {0x24b5, 3, 2361}, /* PARENTHESIZED LATIN SMALL LETTER Z */
+ {0x24b6, 1, 24}, /* CIRCLED LATIN CAPITAL LETTER A */
+ {0x24b7, 1, 910}, /* CIRCLED LATIN CAPITAL LETTER B */
+ {0x24b8, 1, 36}, /* CIRCLED LATIN CAPITAL LETTER C */
+ {0x24b9, 1, 158}, /* CIRCLED LATIN CAPITAL LETTER D */
+ {0x24ba, 1, 38}, /* CIRCLED LATIN CAPITAL LETTER E */
+ {0x24bb, 1, 995}, /* CIRCLED LATIN CAPITAL LETTER F */
+ {0x24bc, 1, 182}, /* CIRCLED LATIN CAPITAL LETTER G */
+ {0x24bd, 1, 198}, /* CIRCLED LATIN CAPITAL LETTER H */
+ {0x24be, 1, 46}, /* CIRCLED LATIN CAPITAL LETTER I */
+ {0x24bf, 1, 221}, /* CIRCLED LATIN CAPITAL LETTER J */
+ {0x24c0, 1, 228}, /* CIRCLED LATIN CAPITAL LETTER K */
+ {0x24c1, 1, 232}, /* CIRCLED LATIN CAPITAL LETTER L */
+ {0x24c2, 1, 912}, /* CIRCLED LATIN CAPITAL LETTER M */
+ {0x24c3, 1, 54}, /* CIRCLED LATIN CAPITAL LETTER N */
+ {0x24c4, 1, 56}, /* CIRCLED LATIN CAPITAL LETTER O */
+ {0x24c5, 1, 914}, /* CIRCLED LATIN CAPITAL LETTER P */
+ {0x24c6, 1, 1942}, /* CIRCLED LATIN CAPITAL LETTER Q */
+ {0x24c7, 1, 274}, /* CIRCLED LATIN CAPITAL LETTER R */
+ {0x24c8, 1, 286}, /* CIRCLED LATIN CAPITAL LETTER S */
+ {0x24c9, 1, 302}, /* CIRCLED LATIN CAPITAL LETTER T */
+ {0x24ca, 1, 66}, /* CIRCLED LATIN CAPITAL LETTER U */
+ {0x24cb, 1, 1183}, /* CIRCLED LATIN CAPITAL LETTER V */
+ {0x24cc, 1, 334}, /* CIRCLED LATIN CAPITAL LETTER W */
+ {0x24cd, 1, 1211}, /* CIRCLED LATIN CAPITAL LETTER X */
+ {0x24ce, 1, 74}, /* CIRCLED LATIN CAPITAL LETTER Y */
+ {0x24cf, 1, 344}, /* CIRCLED LATIN CAPITAL LETTER Z */
+ {0x24d0, 1, 3}, /* CIRCLED LATIN SMALL LETTER A */
+ {0x24d1, 1, 918}, /* CIRCLED LATIN SMALL LETTER B */
+ {0x24d2, 1, 88}, /* CIRCLED LATIN SMALL LETTER C */
+ {0x24d3, 1, 160}, /* CIRCLED LATIN SMALL LETTER D */
+ {0x24d4, 1, 90}, /* CIRCLED LATIN SMALL LETTER E */
+ {0x24d5, 1, 997}, /* CIRCLED LATIN SMALL LETTER F */
+ {0x24d6, 1, 184}, /* CIRCLED LATIN SMALL LETTER G */
+ {0x24d7, 1, 200}, /* CIRCLED LATIN SMALL LETTER H */
+ {0x24d8, 1, 98}, /* CIRCLED LATIN SMALL LETTER I */
+ {0x24d9, 1, 223}, /* CIRCLED LATIN SMALL LETTER J */
+ {0x24da, 1, 230}, /* CIRCLED LATIN SMALL LETTER K */
+ {0x24db, 1, 234}, /* CIRCLED LATIN SMALL LETTER L */
+ {0x24dc, 1, 922}, /* CIRCLED LATIN SMALL LETTER M */
+ {0x24dd, 1, 106}, /* CIRCLED LATIN SMALL LETTER N */
+ {0x24de, 1, 14}, /* CIRCLED LATIN SMALL LETTER O */
+ {0x24df, 1, 927}, /* CIRCLED LATIN SMALL LETTER P */
+ {0x24e0, 1, 2335}, /* CIRCLED LATIN SMALL LETTER Q */
+ {0x24e1, 1, 276}, /* CIRCLED LATIN SMALL LETTER R */
+ {0x24e2, 1, 288}, /* CIRCLED LATIN SMALL LETTER S */
+ {0x24e3, 1, 304}, /* CIRCLED LATIN SMALL LETTER T */
+ {0x24e4, 1, 118}, /* CIRCLED LATIN SMALL LETTER U */
+ {0x24e5, 1, 930}, /* CIRCLED LATIN SMALL LETTER V */
+ {0x24e6, 1, 336}, /* CIRCLED LATIN SMALL LETTER W */
+ {0x24e7, 1, 579}, /* CIRCLED LATIN SMALL LETTER X */
+ {0x24e8, 1, 126}, /* CIRCLED LATIN SMALL LETTER Y */
+ {0x24e9, 1, 346}, /* CIRCLED LATIN SMALL LETTER Z */
+ {0x24ea, 1, 1909}, /* CIRCLED DIGIT ZERO */
+ {0x2a0c, 4, 2064}, /* QUADRUPLE INTEGRAL OPERATOR */
+ {0x2a74, 3, 2364}, /* DOUBLE COLON EQUAL */
+ {0x2a75, 2, 2367}, /* TWO CONSECUTIVE EQUALS SIGNS */
+ {0x2a76, 3, 2366}, /* THREE CONSECUTIVE EQUALS SIGNS */
+ {0x2adc, 2, 2369}, /* FORKING */
+ {0x2e9f, 1, 2371}, /* CJK RADICAL MOTHER */
+ {0x2ef3, 1, 2372}, /* CJK RADICAL C-SIMPLIFIED TURTLE */
+ {0x2f00, 1, 2373}, /* KANGXI RADICAL ONE */
+ {0x2f01, 1, 2374}, /* KANGXI RADICAL LINE */
+ {0x2f02, 1, 2375}, /* KANGXI RADICAL DOT */
+ {0x2f03, 1, 2376}, /* KANGXI RADICAL SLASH */
+ {0x2f04, 1, 2377}, /* KANGXI RADICAL SECOND */
+ {0x2f05, 1, 2378}, /* KANGXI RADICAL HOOK */
+ {0x2f06, 1, 2379}, /* KANGXI RADICAL TWO */
+ {0x2f07, 1, 2380}, /* KANGXI RADICAL LID */
+ {0x2f08, 1, 2381}, /* KANGXI RADICAL MAN */
+ {0x2f09, 1, 2382}, /* KANGXI RADICAL LEGS */
+ {0x2f0a, 1, 2383}, /* KANGXI RADICAL ENTER */
+ {0x2f0b, 1, 2384}, /* KANGXI RADICAL EIGHT */
+ {0x2f0c, 1, 2385}, /* KANGXI RADICAL DOWN BOX */
+ {0x2f0d, 1, 2386}, /* KANGXI RADICAL COVER */
+ {0x2f0e, 1, 2387}, /* KANGXI RADICAL ICE */
+ {0x2f0f, 1, 2388}, /* KANGXI RADICAL TABLE */
+ {0x2f10, 1, 2389}, /* KANGXI RADICAL OPEN BOX */
+ {0x2f11, 1, 2390}, /* KANGXI RADICAL KNIFE */
+ {0x2f12, 1, 2391}, /* KANGXI RADICAL POWER */
+ {0x2f13, 1, 2392}, /* KANGXI RADICAL WRAP */
+ {0x2f14, 1, 2393}, /* KANGXI RADICAL SPOON */
+ {0x2f15, 1, 2394}, /* KANGXI RADICAL RIGHT OPEN BOX */
+ {0x2f16, 1, 2395}, /* KANGXI RADICAL HIDING ENCLOSURE */
+ {0x2f17, 1, 2396}, /* KANGXI RADICAL TEN */
+ {0x2f18, 1, 2397}, /* KANGXI RADICAL DIVINATION */
+ {0x2f19, 1, 2398}, /* KANGXI RADICAL SEAL */
+ {0x2f1a, 1, 2399}, /* KANGXI RADICAL CLIFF */
+ {0x2f1b, 1, 2400}, /* KANGXI RADICAL PRIVATE */
+ {0x2f1c, 1, 2401}, /* KANGXI RADICAL AGAIN */
+ {0x2f1d, 1, 2402}, /* KANGXI RADICAL MOUTH */
+ {0x2f1e, 1, 2403}, /* KANGXI RADICAL ENCLOSURE */
+ {0x2f1f, 1, 2404}, /* KANGXI RADICAL EARTH */
+ {0x2f20, 1, 2405}, /* KANGXI RADICAL SCHOLAR */
+ {0x2f21, 1, 2406}, /* KANGXI RADICAL GO */
+ {0x2f22, 1, 2407}, /* KANGXI RADICAL GO SLOWLY */
+ {0x2f23, 1, 2408}, /* KANGXI RADICAL EVENING */
+ {0x2f24, 1, 2409}, /* KANGXI RADICAL BIG */
+ {0x2f25, 1, 2410}, /* KANGXI RADICAL WOMAN */
+ {0x2f26, 1, 2411}, /* KANGXI RADICAL CHILD */
+ {0x2f27, 1, 2412}, /* KANGXI RADICAL ROOF */
+ {0x2f28, 1, 2413}, /* KANGXI RADICAL INCH */
+ {0x2f29, 1, 2414}, /* KANGXI RADICAL SMALL */
+ {0x2f2a, 1, 2415}, /* KANGXI RADICAL LAME */
+ {0x2f2b, 1, 2416}, /* KANGXI RADICAL CORPSE */
+ {0x2f2c, 1, 2417}, /* KANGXI RADICAL SPROUT */
+ {0x2f2d, 1, 2418}, /* KANGXI RADICAL MOUNTAIN */
+ {0x2f2e, 1, 2419}, /* KANGXI RADICAL RIVER */
+ {0x2f2f, 1, 2420}, /* KANGXI RADICAL WORK */
+ {0x2f30, 1, 2421}, /* KANGXI RADICAL ONESELF */
+ {0x2f31, 1, 2422}, /* KANGXI RADICAL TURBAN */
+ {0x2f32, 1, 2423}, /* KANGXI RADICAL DRY */
+ {0x2f33, 1, 2424}, /* KANGXI RADICAL SHORT THREAD */
+ {0x2f34, 1, 2425}, /* KANGXI RADICAL DOTTED CLIFF */
+ {0x2f35, 1, 2426}, /* KANGXI RADICAL LONG STRIDE */
+ {0x2f36, 1, 2427}, /* KANGXI RADICAL TWO HANDS */
+ {0x2f37, 1, 2428}, /* KANGXI RADICAL SHOOT */
+ {0x2f38, 1, 2429}, /* KANGXI RADICAL BOW */
+ {0x2f39, 1, 2430}, /* KANGXI RADICAL SNOUT */
+ {0x2f3a, 1, 2431}, /* KANGXI RADICAL BRISTLE */
+ {0x2f3b, 1, 2432}, /* KANGXI RADICAL STEP */
+ {0x2f3c, 1, 2433}, /* KANGXI RADICAL HEART */
+ {0x2f3d, 1, 2434}, /* KANGXI RADICAL HALBERD */
+ {0x2f3e, 1, 2435}, /* KANGXI RADICAL DOOR */
+ {0x2f3f, 1, 2436}, /* KANGXI RADICAL HAND */
+ {0x2f40, 1, 2437}, /* KANGXI RADICAL BRANCH */
+ {0x2f41, 1, 2438}, /* KANGXI RADICAL RAP */
+ {0x2f42, 1, 2439}, /* KANGXI RADICAL SCRIPT */
+ {0x2f43, 1, 2440}, /* KANGXI RADICAL DIPPER */
+ {0x2f44, 1, 2441}, /* KANGXI RADICAL AXE */
+ {0x2f45, 1, 2442}, /* KANGXI RADICAL SQUARE */
+ {0x2f46, 1, 2443}, /* KANGXI RADICAL NOT */
+ {0x2f47, 1, 2444}, /* KANGXI RADICAL SUN */
+ {0x2f48, 1, 2445}, /* KANGXI RADICAL SAY */
+ {0x2f49, 1, 2446}, /* KANGXI RADICAL MOON */
+ {0x2f4a, 1, 2447}, /* KANGXI RADICAL TREE */
+ {0x2f4b, 1, 2448}, /* KANGXI RADICAL LACK */
+ {0x2f4c, 1, 2449}, /* KANGXI RADICAL STOP */
+ {0x2f4d, 1, 2450}, /* KANGXI RADICAL DEATH */
+ {0x2f4e, 1, 2451}, /* KANGXI RADICAL WEAPON */
+ {0x2f4f, 1, 2452}, /* KANGXI RADICAL DO NOT */
+ {0x2f50, 1, 2453}, /* KANGXI RADICAL COMPARE */
+ {0x2f51, 1, 2454}, /* KANGXI RADICAL FUR */
+ {0x2f52, 1, 2455}, /* KANGXI RADICAL CLAN */
+ {0x2f53, 1, 2456}, /* KANGXI RADICAL STEAM */
+ {0x2f54, 1, 2457}, /* KANGXI RADICAL WATER */
+ {0x2f55, 1, 2458}, /* KANGXI RADICAL FIRE */
+ {0x2f56, 1, 2459}, /* KANGXI RADICAL CLAW */
+ {0x2f57, 1, 2460}, /* KANGXI RADICAL FATHER */
+ {0x2f58, 1, 2461}, /* KANGXI RADICAL DOUBLE X */
+ {0x2f59, 1, 2462}, /* KANGXI RADICAL HALF TREE TRUNK */
+ {0x2f5a, 1, 2463}, /* KANGXI RADICAL SLICE */
+ {0x2f5b, 1, 2464}, /* KANGXI RADICAL FANG */
+ {0x2f5c, 1, 2465}, /* KANGXI RADICAL COW */
+ {0x2f5d, 1, 2466}, /* KANGXI RADICAL DOG */
+ {0x2f5e, 1, 2467}, /* KANGXI RADICAL PROFOUND */
+ {0x2f5f, 1, 2468}, /* KANGXI RADICAL JADE */
+ {0x2f60, 1, 2469}, /* KANGXI RADICAL MELON */
+ {0x2f61, 1, 2470}, /* KANGXI RADICAL TILE */
+ {0x2f62, 1, 2471}, /* KANGXI RADICAL SWEET */
+ {0x2f63, 1, 2472}, /* KANGXI RADICAL LIFE */
+ {0x2f64, 1, 2473}, /* KANGXI RADICAL USE */
+ {0x2f65, 1, 2474}, /* KANGXI RADICAL FIELD */
+ {0x2f66, 1, 2475}, /* KANGXI RADICAL BOLT OF CLOTH */
+ {0x2f67, 1, 2476}, /* KANGXI RADICAL SICKNESS */
+ {0x2f68, 1, 2477}, /* KANGXI RADICAL DOTTED TENT */
+ {0x2f69, 1, 2478}, /* KANGXI RADICAL WHITE */
+ {0x2f6a, 1, 2479}, /* KANGXI RADICAL SKIN */
+ {0x2f6b, 1, 2480}, /* KANGXI RADICAL DISH */
+ {0x2f6c, 1, 2481}, /* KANGXI RADICAL EYE */
+ {0x2f6d, 1, 2482}, /* KANGXI RADICAL SPEAR */
+ {0x2f6e, 1, 2483}, /* KANGXI RADICAL ARROW */
+ {0x2f6f, 1, 2484}, /* KANGXI RADICAL STONE */
+ {0x2f70, 1, 2485}, /* KANGXI RADICAL SPIRIT */
+ {0x2f71, 1, 2486}, /* KANGXI RADICAL TRACK */
+ {0x2f72, 1, 2487}, /* KANGXI RADICAL GRAIN */
+ {0x2f73, 1, 2488}, /* KANGXI RADICAL CAVE */
+ {0x2f74, 1, 2489}, /* KANGXI RADICAL STAND */
+ {0x2f75, 1, 2490}, /* KANGXI RADICAL BAMBOO */
+ {0x2f76, 1, 2491}, /* KANGXI RADICAL RICE */
+ {0x2f77, 1, 2492}, /* KANGXI RADICAL SILK */
+ {0x2f78, 1, 2493}, /* KANGXI RADICAL JAR */
+ {0x2f79, 1, 2494}, /* KANGXI RADICAL NET */
+ {0x2f7a, 1, 2495}, /* KANGXI RADICAL SHEEP */
+ {0x2f7b, 1, 2496}, /* KANGXI RADICAL FEATHER */
+ {0x2f7c, 1, 2497}, /* KANGXI RADICAL OLD */
+ {0x2f7d, 1, 2498}, /* KANGXI RADICAL AND */
+ {0x2f7e, 1, 2499}, /* KANGXI RADICAL PLOW */
+ {0x2f7f, 1, 2500}, /* KANGXI RADICAL EAR */
+ {0x2f80, 1, 2501}, /* KANGXI RADICAL BRUSH */
+ {0x2f81, 1, 2502}, /* KANGXI RADICAL MEAT */
+ {0x2f82, 1, 2503}, /* KANGXI RADICAL MINISTER */
+ {0x2f83, 1, 2504}, /* KANGXI RADICAL SELF */
+ {0x2f84, 1, 2505}, /* KANGXI RADICAL ARRIVE */
+ {0x2f85, 1, 2506}, /* KANGXI RADICAL MORTAR */
+ {0x2f86, 1, 2507}, /* KANGXI RADICAL TONGUE */
+ {0x2f87, 1, 2508}, /* KANGXI RADICAL OPPOSE */
+ {0x2f88, 1, 2509}, /* KANGXI RADICAL BOAT */
+ {0x2f89, 1, 2510}, /* KANGXI RADICAL STOPPING */
+ {0x2f8a, 1, 2511}, /* KANGXI RADICAL COLOR */
+ {0x2f8b, 1, 2512}, /* KANGXI RADICAL GRASS */
+ {0x2f8c, 1, 2513}, /* KANGXI RADICAL TIGER */
+ {0x2f8d, 1, 2514}, /* KANGXI RADICAL INSECT */
+ {0x2f8e, 1, 2515}, /* KANGXI RADICAL BLOOD */
+ {0x2f8f, 1, 2516}, /* KANGXI RADICAL WALK ENCLOSURE */
+ {0x2f90, 1, 2517}, /* KANGXI RADICAL CLOTHES */
+ {0x2f91, 1, 2518}, /* KANGXI RADICAL WEST */
+ {0x2f92, 1, 2519}, /* KANGXI RADICAL SEE */
+ {0x2f93, 1, 2520}, /* KANGXI RADICAL HORN */
+ {0x2f94, 1, 2521}, /* KANGXI RADICAL SPEECH */
+ {0x2f95, 1, 2522}, /* KANGXI RADICAL VALLEY */
+ {0x2f96, 1, 2523}, /* KANGXI RADICAL BEAN */
+ {0x2f97, 1, 2524}, /* KANGXI RADICAL PIG */
+ {0x2f98, 1, 2525}, /* KANGXI RADICAL BADGER */
+ {0x2f99, 1, 2526}, /* KANGXI RADICAL SHELL */
+ {0x2f9a, 1, 2527}, /* KANGXI RADICAL RED */
+ {0x2f9b, 1, 2528}, /* KANGXI RADICAL RUN */
+ {0x2f9c, 1, 2529}, /* KANGXI RADICAL FOOT */
+ {0x2f9d, 1, 2530}, /* KANGXI RADICAL BODY */
+ {0x2f9e, 1, 2531}, /* KANGXI RADICAL CART */
+ {0x2f9f, 1, 2532}, /* KANGXI RADICAL BITTER */
+ {0x2fa0, 1, 2533}, /* KANGXI RADICAL MORNING */
+ {0x2fa1, 1, 2534}, /* KANGXI RADICAL WALK */
+ {0x2fa2, 1, 2535}, /* KANGXI RADICAL CITY */
+ {0x2fa3, 1, 2536}, /* KANGXI RADICAL WINE */
+ {0x2fa4, 1, 2537}, /* KANGXI RADICAL DISTINGUISH */
+ {0x2fa5, 1, 2538}, /* KANGXI RADICAL VILLAGE */
+ {0x2fa6, 1, 2539}, /* KANGXI RADICAL GOLD */
+ {0x2fa7, 1, 2540}, /* KANGXI RADICAL LONG */
+ {0x2fa8, 1, 2541}, /* KANGXI RADICAL GATE */
+ {0x2fa9, 1, 2542}, /* KANGXI RADICAL MOUND */
+ {0x2faa, 1, 2543}, /* KANGXI RADICAL SLAVE */
+ {0x2fab, 1, 2544}, /* KANGXI RADICAL SHORT TAILED BIRD */
+ {0x2fac, 1, 2545}, /* KANGXI RADICAL RAIN */
+ {0x2fad, 1, 2546}, /* KANGXI RADICAL BLUE */
+ {0x2fae, 1, 2547}, /* KANGXI RADICAL WRONG */
+ {0x2faf, 1, 2548}, /* KANGXI RADICAL FACE */
+ {0x2fb0, 1, 2549}, /* KANGXI RADICAL LEATHER */
+ {0x2fb1, 1, 2550}, /* KANGXI RADICAL TANNED LEATHER */
+ {0x2fb2, 1, 2551}, /* KANGXI RADICAL LEEK */
+ {0x2fb3, 1, 2552}, /* KANGXI RADICAL SOUND */
+ {0x2fb4, 1, 2553}, /* KANGXI RADICAL LEAF */
+ {0x2fb5, 1, 2554}, /* KANGXI RADICAL WIND */
+ {0x2fb6, 1, 2555}, /* KANGXI RADICAL FLY */
+ {0x2fb7, 1, 2556}, /* KANGXI RADICAL EAT */
+ {0x2fb8, 1, 2557}, /* KANGXI RADICAL HEAD */
+ {0x2fb9, 1, 2558}, /* KANGXI RADICAL FRAGRANT */
+ {0x2fba, 1, 2559}, /* KANGXI RADICAL HORSE */
+ {0x2fbb, 1, 2560}, /* KANGXI RADICAL BONE */
+ {0x2fbc, 1, 2561}, /* KANGXI RADICAL TALL */
+ {0x2fbd, 1, 2562}, /* KANGXI RADICAL HAIR */
+ {0x2fbe, 1, 2563}, /* KANGXI RADICAL FIGHT */
+ {0x2fbf, 1, 2564}, /* KANGXI RADICAL SACRIFICIAL WINE */
+ {0x2fc0, 1, 2565}, /* KANGXI RADICAL CAULDRON */
+ {0x2fc1, 1, 2566}, /* KANGXI RADICAL GHOST */
+ {0x2fc2, 1, 2567}, /* KANGXI RADICAL FISH */
+ {0x2fc3, 1, 2568}, /* KANGXI RADICAL BIRD */
+ {0x2fc4, 1, 2569}, /* KANGXI RADICAL SALT */
+ {0x2fc5, 1, 2570}, /* KANGXI RADICAL DEER */
+ {0x2fc6, 1, 2571}, /* KANGXI RADICAL WHEAT */
+ {0x2fc7, 1, 2572}, /* KANGXI RADICAL HEMP */
+ {0x2fc8, 1, 2573}, /* KANGXI RADICAL YELLOW */
+ {0x2fc9, 1, 2574}, /* KANGXI RADICAL MILLET */
+ {0x2fca, 1, 2575}, /* KANGXI RADICAL BLACK */
+ {0x2fcb, 1, 2576}, /* KANGXI RADICAL EMBROIDERY */
+ {0x2fcc, 1, 2577}, /* KANGXI RADICAL FROG */
+ {0x2fcd, 1, 2578}, /* KANGXI RADICAL TRIPOD */
+ {0x2fce, 1, 2579}, /* KANGXI RADICAL DRUM */
+ {0x2fcf, 1, 2580}, /* KANGXI RADICAL RAT */
+ {0x2fd0, 1, 2581}, /* KANGXI RADICAL NOSE */
+ {0x2fd1, 1, 2582}, /* KANGXI RADICAL EVEN */
+ {0x2fd2, 1, 2583}, /* KANGXI RADICAL TOOTH */
+ {0x2fd3, 1, 2584}, /* KANGXI RADICAL DRAGON */
+ {0x2fd4, 1, 2585}, /* KANGXI RADICAL TURTLE */
+ {0x2fd5, 1, 2586}, /* KANGXI RADICAL FLUTE */
+ {0x3000, 1, 2587}, /* IDEOGRAPHIC SPACE */
+ {0x3036, 1, 2588}, /* CIRCLED POSTAL MARK */
+ {0x3038, 1, 2396}, /* HANGZHOU NUMERAL TEN */
+ {0x3039, 1, 2589}, /* HANGZHOU NUMERAL TWENTY */
+ {0x303a, 1, 2590}, /* HANGZHOU NUMERAL THIRTY */
+ {0x304c, 2, 2591}, /* HIRAGANA LETTER GA */
+ {0x304e, 2, 2593}, /* HIRAGANA LETTER GI */
+ {0x3050, 2, 2595}, /* HIRAGANA LETTER GU */
+ {0x3052, 2, 2597}, /* HIRAGANA LETTER GE */
+ {0x3054, 2, 2599}, /* HIRAGANA LETTER GO */
+ {0x3056, 2, 2601}, /* HIRAGANA LETTER ZA */
+ {0x3058, 2, 2603}, /* HIRAGANA LETTER ZI */
+ {0x305a, 2, 2605}, /* HIRAGANA LETTER ZU */
+ {0x305c, 2, 2607}, /* HIRAGANA LETTER ZE */
+ {0x305e, 2, 2609}, /* HIRAGANA LETTER ZO */
+ {0x3060, 2, 2611}, /* HIRAGANA LETTER DA */
+ {0x3062, 2, 2613}, /* HIRAGANA LETTER DI */
+ {0x3065, 2, 2615}, /* HIRAGANA LETTER DU */
+ {0x3067, 2, 2617}, /* HIRAGANA LETTER DE */
+ {0x3069, 2, 2619}, /* HIRAGANA LETTER DO */
+ {0x3070, 2, 2621}, /* HIRAGANA LETTER BA */
+ {0x3071, 2, 2623}, /* HIRAGANA LETTER PA */
+ {0x3073, 2, 2625}, /* HIRAGANA LETTER BI */
+ {0x3074, 2, 2627}, /* HIRAGANA LETTER PI */
+ {0x3076, 2, 2629}, /* HIRAGANA LETTER BU */
+ {0x3077, 2, 2631}, /* HIRAGANA LETTER PU */
+ {0x3079, 2, 2633}, /* HIRAGANA LETTER BE */
+ {0x307a, 2, 2635}, /* HIRAGANA LETTER PE */
+ {0x307c, 2, 2637}, /* HIRAGANA LETTER BO */
+ {0x307d, 2, 2639}, /* HIRAGANA LETTER PO */
+ {0x3094, 2, 2641}, /* HIRAGANA LETTER VU */
+ {0x309b, 2, 2643}, /* KATAKANA-HIRAGANA VOICED SOUND MARK */
+ {0x309c, 2, 2645}, /* KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+ {0x309e, 2, 2647}, /* HIRAGANA VOICED ITERATION MARK */
+ {0x309f, 2, 2649}, /* HIRAGANA DIGRAPH YORI */
+ {0x30ac, 2, 2651}, /* KATAKANA LETTER GA */
+ {0x30ae, 2, 2653}, /* KATAKANA LETTER GI */
+ {0x30b0, 2, 2655}, /* KATAKANA LETTER GU */
+ {0x30b2, 2, 2657}, /* KATAKANA LETTER GE */
+ {0x30b4, 2, 2659}, /* KATAKANA LETTER GO */
+ {0x30b6, 2, 2661}, /* KATAKANA LETTER ZA */
+ {0x30b8, 2, 2663}, /* KATAKANA LETTER ZI */
+ {0x30ba, 2, 2665}, /* KATAKANA LETTER ZU */
+ {0x30bc, 2, 2667}, /* KATAKANA LETTER ZE */
+ {0x30be, 2, 2669}, /* KATAKANA LETTER ZO */
+ {0x30c0, 2, 2671}, /* KATAKANA LETTER DA */
+ {0x30c2, 2, 2673}, /* KATAKANA LETTER DI */
+ {0x30c5, 2, 2675}, /* KATAKANA LETTER DU */
+ {0x30c7, 2, 2677}, /* KATAKANA LETTER DE */
+ {0x30c9, 2, 2679}, /* KATAKANA LETTER DO */
+ {0x30d0, 2, 2681}, /* KATAKANA LETTER BA */
+ {0x30d1, 2, 2683}, /* KATAKANA LETTER PA */
+ {0x30d3, 2, 2685}, /* KATAKANA LETTER BI */
+ {0x30d4, 2, 2687}, /* KATAKANA LETTER PI */
+ {0x30d6, 2, 2689}, /* KATAKANA LETTER BU */
+ {0x30d7, 2, 2691}, /* KATAKANA LETTER PU */
+ {0x30d9, 2, 2693}, /* KATAKANA LETTER BE */
+ {0x30da, 2, 2695}, /* KATAKANA LETTER PE */
+ {0x30dc, 2, 2697}, /* KATAKANA LETTER BO */
+ {0x30dd, 2, 2699}, /* KATAKANA LETTER PO */
+ {0x30f4, 2, 2701}, /* KATAKANA LETTER VU */
+ {0x30f7, 2, 2703}, /* KATAKANA LETTER VA */
+ {0x30f8, 2, 2705}, /* KATAKANA LETTER VI */
+ {0x30f9, 2, 2707}, /* KATAKANA LETTER VE */
+ {0x30fa, 2, 2709}, /* KATAKANA LETTER VO */
+ {0x30fe, 2, 2711}, /* KATAKANA VOICED ITERATION MARK */
+ {0x30ff, 2, 2713}, /* KATAKANA DIGRAPH KOTO */
+ {0x3131, 1, 2715}, /* HANGUL LETTER KIYEOK */
+ {0x3132, 1, 2716}, /* HANGUL LETTER SSANGKIYEOK */
+ {0x3133, 1, 2717}, /* HANGUL LETTER KIYEOK-SIOS */
+ {0x3134, 1, 2718}, /* HANGUL LETTER NIEUN */
+ {0x3135, 1, 2719}, /* HANGUL LETTER NIEUN-CIEUC */
+ {0x3136, 1, 2720}, /* HANGUL LETTER NIEUN-HIEUH */
+ {0x3137, 1, 2721}, /* HANGUL LETTER TIKEUT */
+ {0x3138, 1, 2722}, /* HANGUL LETTER SSANGTIKEUT */
+ {0x3139, 1, 2723}, /* HANGUL LETTER RIEUL */
+ {0x313a, 1, 2724}, /* HANGUL LETTER RIEUL-KIYEOK */
+ {0x313b, 1, 2725}, /* HANGUL LETTER RIEUL-MIEUM */
+ {0x313c, 1, 2726}, /* HANGUL LETTER RIEUL-PIEUP */
+ {0x313d, 1, 2727}, /* HANGUL LETTER RIEUL-SIOS */
+ {0x313e, 1, 2728}, /* HANGUL LETTER RIEUL-THIEUTH */
+ {0x313f, 1, 2729}, /* HANGUL LETTER RIEUL-PHIEUPH */
+ {0x3140, 1, 2730}, /* HANGUL LETTER RIEUL-HIEUH */
+ {0x3141, 1, 2731}, /* HANGUL LETTER MIEUM */
+ {0x3142, 1, 2732}, /* HANGUL LETTER PIEUP */
+ {0x3143, 1, 2733}, /* HANGUL LETTER SSANGPIEUP */
+ {0x3144, 1, 2734}, /* HANGUL LETTER PIEUP-SIOS */
+ {0x3145, 1, 2735}, /* HANGUL LETTER SIOS */
+ {0x3146, 1, 2736}, /* HANGUL LETTER SSANGSIOS */
+ {0x3147, 1, 2737}, /* HANGUL LETTER IEUNG */
+ {0x3148, 1, 2738}, /* HANGUL LETTER CIEUC */
+ {0x3149, 1, 2739}, /* HANGUL LETTER SSANGCIEUC */
+ {0x314a, 1, 2740}, /* HANGUL LETTER CHIEUCH */
+ {0x314b, 1, 2741}, /* HANGUL LETTER KHIEUKH */
+ {0x314c, 1, 2742}, /* HANGUL LETTER THIEUTH */
+ {0x314d, 1, 2743}, /* HANGUL LETTER PHIEUPH */
+ {0x314e, 1, 2744}, /* HANGUL LETTER HIEUH */
+ {0x314f, 1, 2745}, /* HANGUL LETTER A */
+ {0x3150, 1, 2746}, /* HANGUL LETTER AE */
+ {0x3151, 1, 2747}, /* HANGUL LETTER YA */
+ {0x3152, 1, 2748}, /* HANGUL LETTER YAE */
+ {0x3153, 1, 2749}, /* HANGUL LETTER EO */
+ {0x3154, 1, 2750}, /* HANGUL LETTER E */
+ {0x3155, 1, 2751}, /* HANGUL LETTER YEO */
+ {0x3156, 1, 2752}, /* HANGUL LETTER YE */
+ {0x3157, 1, 2753}, /* HANGUL LETTER O */
+ {0x3158, 1, 2754}, /* HANGUL LETTER WA */
+ {0x3159, 1, 2755}, /* HANGUL LETTER WAE */
+ {0x315a, 1, 2756}, /* HANGUL LETTER OE */
+ {0x315b, 1, 2757}, /* HANGUL LETTER YO */
+ {0x315c, 1, 2758}, /* HANGUL LETTER U */
+ {0x315d, 1, 2759}, /* HANGUL LETTER WEO */
+ {0x315e, 1, 2760}, /* HANGUL LETTER WE */
+ {0x315f, 1, 2761}, /* HANGUL LETTER WI */
+ {0x3160, 1, 2762}, /* HANGUL LETTER YU */
+ {0x3161, 1, 2763}, /* HANGUL LETTER EU */
+ {0x3162, 1, 2764}, /* HANGUL LETTER YI */
+ {0x3163, 1, 2765}, /* HANGUL LETTER I */
+ {0x3164, 1, 2766}, /* HANGUL FILLER */
+ {0x3165, 1, 2767}, /* HANGUL LETTER SSANGNIEUN */
+ {0x3166, 1, 2768}, /* HANGUL LETTER NIEUN-TIKEUT */
+ {0x3167, 1, 2769}, /* HANGUL LETTER NIEUN-SIOS */
+ {0x3168, 1, 2770}, /* HANGUL LETTER NIEUN-PANSIOS */
+ {0x3169, 1, 2771}, /* HANGUL LETTER RIEUL-KIYEOK-SIOS */
+ {0x316a, 1, 2772}, /* HANGUL LETTER RIEUL-TIKEUT */
+ {0x316b, 1, 2773}, /* HANGUL LETTER RIEUL-PIEUP-SIOS */
+ {0x316c, 1, 2774}, /* HANGUL LETTER RIEUL-PANSIOS */
+ {0x316d, 1, 2775}, /* HANGUL LETTER RIEUL-YEORINHIEUH */
+ {0x316e, 1, 2776}, /* HANGUL LETTER MIEUM-PIEUP */
+ {0x316f, 1, 2777}, /* HANGUL LETTER MIEUM-SIOS */
+ {0x3170, 1, 2778}, /* HANGUL LETTER MIEUM-PANSIOS */
+ {0x3171, 1, 2779}, /* HANGUL LETTER KAPYEOUNMIEUM */
+ {0x3172, 1, 2780}, /* HANGUL LETTER PIEUP-KIYEOK */
+ {0x3173, 1, 2781}, /* HANGUL LETTER PIEUP-TIKEUT */
+ {0x3174, 1, 2782}, /* HANGUL LETTER PIEUP-SIOS-KIYEOK */
+ {0x3175, 1, 2783}, /* HANGUL LETTER PIEUP-SIOS-TIKEUT */
+ {0x3176, 1, 2784}, /* HANGUL LETTER PIEUP-CIEUC */
+ {0x3177, 1, 2785}, /* HANGUL LETTER PIEUP-THIEUTH */
+ {0x3178, 1, 2786}, /* HANGUL LETTER KAPYEOUNPIEUP */
+ {0x3179, 1, 2787}, /* HANGUL LETTER KAPYEOUNSSANGPIEUP */
+ {0x317a, 1, 2788}, /* HANGUL LETTER SIOS-KIYEOK */
+ {0x317b, 1, 2789}, /* HANGUL LETTER SIOS-NIEUN */
+ {0x317c, 1, 2790}, /* HANGUL LETTER SIOS-TIKEUT */
+ {0x317d, 1, 2791}, /* HANGUL LETTER SIOS-PIEUP */
+ {0x317e, 1, 2792}, /* HANGUL LETTER SIOS-CIEUC */
+ {0x317f, 1, 2793}, /* HANGUL LETTER PANSIOS */
+ {0x3180, 1, 2794}, /* HANGUL LETTER SSANGIEUNG */
+ {0x3181, 1, 2795}, /* HANGUL LETTER YESIEUNG */
+ {0x3182, 1, 2796}, /* HANGUL LETTER YESIEUNG-SIOS */
+ {0x3183, 1, 2797}, /* HANGUL LETTER YESIEUNG-PANSIOS */
+ {0x3184, 1, 2798}, /* HANGUL LETTER KAPYEOUNPHIEUPH */
+ {0x3185, 1, 2799}, /* HANGUL LETTER SSANGHIEUH */
+ {0x3186, 1, 2800}, /* HANGUL LETTER YEORINHIEUH */
+ {0x3187, 1, 2801}, /* HANGUL LETTER YO-YA */
+ {0x3188, 1, 2802}, /* HANGUL LETTER YO-YAE */
+ {0x3189, 1, 2803}, /* HANGUL LETTER YO-I */
+ {0x318a, 1, 2804}, /* HANGUL LETTER YU-YEO */
+ {0x318b, 1, 2805}, /* HANGUL LETTER YU-YE */
+ {0x318c, 1, 2806}, /* HANGUL LETTER YU-I */
+ {0x318d, 1, 2807}, /* HANGUL LETTER ARAEA */
+ {0x318e, 1, 2808}, /* HANGUL LETTER ARAEAE */
+ {0x3192, 1, 2373}, /* IDEOGRAPHIC ANNOTATION ONE MARK */
+ {0x3193, 1, 2379}, /* IDEOGRAPHIC ANNOTATION TWO MARK */
+ {0x3194, 1, 2809}, /* IDEOGRAPHIC ANNOTATION THREE MARK */
+ {0x3195, 1, 2810}, /* IDEOGRAPHIC ANNOTATION FOUR MARK */
+ {0x3196, 1, 2811}, /* IDEOGRAPHIC ANNOTATION TOP MARK */
+ {0x3197, 1, 2812}, /* IDEOGRAPHIC ANNOTATION MIDDLE MARK */
+ {0x3198, 1, 2813}, /* IDEOGRAPHIC ANNOTATION BOTTOM MARK */
+ {0x3199, 1, 2814}, /* IDEOGRAPHIC ANNOTATION FIRST MARK */
+ {0x319a, 1, 2377}, /* IDEOGRAPHIC ANNOTATION SECOND MARK */
+ {0x319b, 1, 2815}, /* IDEOGRAPHIC ANNOTATION THIRD MARK */
+ {0x319c, 1, 2816}, /* IDEOGRAPHIC ANNOTATION FOURTH MARK */
+ {0x319d, 1, 2817}, /* IDEOGRAPHIC ANNOTATION HEAVEN MARK */
+ {0x319e, 1, 2818}, /* IDEOGRAPHIC ANNOTATION EARTH MARK */
+ {0x319f, 1, 2381}, /* IDEOGRAPHIC ANNOTATION MAN MARK */
+ {0x3200, 3, 2819}, /* PARENTHESIZED HANGUL KIYEOK */
+ {0x3201, 3, 2822}, /* PARENTHESIZED HANGUL NIEUN */
+ {0x3202, 3, 2825}, /* PARENTHESIZED HANGUL TIKEUT */
+ {0x3203, 3, 2828}, /* PARENTHESIZED HANGUL RIEUL */
+ {0x3204, 3, 2831}, /* PARENTHESIZED HANGUL MIEUM */
+ {0x3205, 3, 2834}, /* PARENTHESIZED HANGUL PIEUP */
+ {0x3206, 3, 2837}, /* PARENTHESIZED HANGUL SIOS */
+ {0x3207, 3, 2840}, /* PARENTHESIZED HANGUL IEUNG */
+ {0x3208, 3, 2843}, /* PARENTHESIZED HANGUL CIEUC */
+ {0x3209, 3, 2846}, /* PARENTHESIZED HANGUL CHIEUCH */
+ {0x320a, 3, 2849}, /* PARENTHESIZED HANGUL KHIEUKH */
+ {0x320b, 3, 2852}, /* PARENTHESIZED HANGUL THIEUTH */
+ {0x320c, 3, 2855}, /* PARENTHESIZED HANGUL PHIEUPH */
+ {0x320d, 3, 2858}, /* PARENTHESIZED HANGUL HIEUH */
+ {0x320e, 4, 2861}, /* PARENTHESIZED HANGUL KIYEOK A */
+ {0x320f, 4, 2865}, /* PARENTHESIZED HANGUL NIEUN A */
+ {0x3210, 4, 2869}, /* PARENTHESIZED HANGUL TIKEUT A */
+ {0x3211, 4, 2873}, /* PARENTHESIZED HANGUL RIEUL A */
+ {0x3212, 4, 2877}, /* PARENTHESIZED HANGUL MIEUM A */
+ {0x3213, 4, 2881}, /* PARENTHESIZED HANGUL PIEUP A */
+ {0x3214, 4, 2885}, /* PARENTHESIZED HANGUL SIOS A */
+ {0x3215, 4, 2889}, /* PARENTHESIZED HANGUL IEUNG A */
+ {0x3216, 4, 2893}, /* PARENTHESIZED HANGUL CIEUC A */
+ {0x3217, 4, 2897}, /* PARENTHESIZED HANGUL CHIEUCH A */
+ {0x3218, 4, 2901}, /* PARENTHESIZED HANGUL KHIEUKH A */
+ {0x3219, 4, 2905}, /* PARENTHESIZED HANGUL THIEUTH A */
+ {0x321a, 4, 2909}, /* PARENTHESIZED HANGUL PHIEUPH A */
+ {0x321b, 4, 2913}, /* PARENTHESIZED HANGUL HIEUH A */
+ {0x321c, 4, 2917}, /* PARENTHESIZED HANGUL CIEUC U */
+ {0x321d, 7, 2921}, /* PARENTHESIZED KOREAN CHARACTER OJEON */
+ {0x321e, 6, 2928}, /* PARENTHESIZED KOREAN CHARACTER O HU */
+ {0x3220, 3, 2934}, /* PARENTHESIZED IDEOGRAPH ONE */
+ {0x3221, 3, 2937}, /* PARENTHESIZED IDEOGRAPH TWO */
+ {0x3222, 3, 2940}, /* PARENTHESIZED IDEOGRAPH THREE */
+ {0x3223, 3, 2943}, /* PARENTHESIZED IDEOGRAPH FOUR */
+ {0x3224, 3, 2946}, /* PARENTHESIZED IDEOGRAPH FIVE */
+ {0x3225, 3, 2949}, /* PARENTHESIZED IDEOGRAPH SIX */
+ {0x3226, 3, 2952}, /* PARENTHESIZED IDEOGRAPH SEVEN */
+ {0x3227, 3, 2955}, /* PARENTHESIZED IDEOGRAPH EIGHT */
+ {0x3228, 3, 2958}, /* PARENTHESIZED IDEOGRAPH NINE */
+ {0x3229, 3, 2961}, /* PARENTHESIZED IDEOGRAPH TEN */
+ {0x322a, 3, 2964}, /* PARENTHESIZED IDEOGRAPH MOON */
+ {0x322b, 3, 2967}, /* PARENTHESIZED IDEOGRAPH FIRE */
+ {0x322c, 3, 2970}, /* PARENTHESIZED IDEOGRAPH WATER */
+ {0x322d, 3, 2973}, /* PARENTHESIZED IDEOGRAPH WOOD */
+ {0x322e, 3, 2976}, /* PARENTHESIZED IDEOGRAPH METAL */
+ {0x322f, 3, 2979}, /* PARENTHESIZED IDEOGRAPH EARTH */
+ {0x3230, 3, 2982}, /* PARENTHESIZED IDEOGRAPH SUN */
+ {0x3231, 3, 2985}, /* PARENTHESIZED IDEOGRAPH STOCK */
+ {0x3232, 3, 2988}, /* PARENTHESIZED IDEOGRAPH HAVE */
+ {0x3233, 3, 2991}, /* PARENTHESIZED IDEOGRAPH SOCIETY */
+ {0x3234, 3, 2994}, /* PARENTHESIZED IDEOGRAPH NAME */
+ {0x3235, 3, 2997}, /* PARENTHESIZED IDEOGRAPH SPECIAL */
+ {0x3236, 3, 3000}, /* PARENTHESIZED IDEOGRAPH FINANCIAL */
+ {0x3237, 3, 3003}, /* PARENTHESIZED IDEOGRAPH CONGRATULATION */
+ {0x3238, 3, 3006}, /* PARENTHESIZED IDEOGRAPH LABOR */
+ {0x3239, 3, 3009}, /* PARENTHESIZED IDEOGRAPH REPRESENT */
+ {0x323a, 3, 3012}, /* PARENTHESIZED IDEOGRAPH CALL */
+ {0x323b, 3, 3015}, /* PARENTHESIZED IDEOGRAPH STUDY */
+ {0x323c, 3, 3018}, /* PARENTHESIZED IDEOGRAPH SUPERVISE */
+ {0x323d, 3, 3021}, /* PARENTHESIZED IDEOGRAPH ENTERPRISE */
+ {0x323e, 3, 3024}, /* PARENTHESIZED IDEOGRAPH RESOURCE */
+ {0x323f, 3, 3027}, /* PARENTHESIZED IDEOGRAPH ALLIANCE */
+ {0x3240, 3, 3030}, /* PARENTHESIZED IDEOGRAPH FESTIVAL */
+ {0x3241, 3, 3033}, /* PARENTHESIZED IDEOGRAPH REST */
+ {0x3242, 3, 3036}, /* PARENTHESIZED IDEOGRAPH SELF */
+ {0x3243, 3, 3039}, /* PARENTHESIZED IDEOGRAPH REACH */
+ {0x3250, 3, 3042}, /* PARTNERSHIP SIGN */
+ {0x3251, 2, 2147}, /* CIRCLED NUMBER TWENTY ONE */
+ {0x3252, 2, 3045}, /* CIRCLED NUMBER TWENTY TWO */
+ {0x3253, 2, 6}, /* CIRCLED NUMBER TWENTY THREE */
+ {0x3254, 2, 3047}, /* CIRCLED NUMBER TWENTY FOUR */
+ {0x3255, 2, 3049}, /* CIRCLED NUMBER TWENTY FIVE */
+ {0x3256, 2, 3051}, /* CIRCLED NUMBER TWENTY SIX */
+ {0x3257, 2, 3053}, /* CIRCLED NUMBER TWENTY SEVEN */
+ {0x3258, 2, 3055}, /* CIRCLED NUMBER TWENTY EIGHT */
+ {0x3259, 2, 3057}, /* CIRCLED NUMBER TWENTY NINE */
+ {0x325a, 2, 3059}, /* CIRCLED NUMBER THIRTY */
+ {0x325b, 2, 1965}, /* CIRCLED NUMBER THIRTY ONE */
+ {0x325c, 2, 1962}, /* CIRCLED NUMBER THIRTY TWO */
+ {0x325d, 2, 3061}, /* CIRCLED NUMBER THIRTY THREE */
+ {0x325e, 2, 3063}, /* CIRCLED NUMBER THIRTY FOUR */
+ {0x325f, 2, 3065}, /* CIRCLED NUMBER THIRTY FIVE */
+ {0x3260, 1, 2715}, /* CIRCLED HANGUL KIYEOK */
+ {0x3261, 1, 2718}, /* CIRCLED HANGUL NIEUN */
+ {0x3262, 1, 2721}, /* CIRCLED HANGUL TIKEUT */
+ {0x3263, 1, 2723}, /* CIRCLED HANGUL RIEUL */
+ {0x3264, 1, 2731}, /* CIRCLED HANGUL MIEUM */
+ {0x3265, 1, 2732}, /* CIRCLED HANGUL PIEUP */
+ {0x3266, 1, 2735}, /* CIRCLED HANGUL SIOS */
+ {0x3267, 1, 2737}, /* CIRCLED HANGUL IEUNG */
+ {0x3268, 1, 2738}, /* CIRCLED HANGUL CIEUC */
+ {0x3269, 1, 2740}, /* CIRCLED HANGUL CHIEUCH */
+ {0x326a, 1, 2741}, /* CIRCLED HANGUL KHIEUKH */
+ {0x326b, 1, 2742}, /* CIRCLED HANGUL THIEUTH */
+ {0x326c, 1, 2743}, /* CIRCLED HANGUL PHIEUPH */
+ {0x326d, 1, 2744}, /* CIRCLED HANGUL HIEUH */
+ {0x326e, 2, 2862}, /* CIRCLED HANGUL KIYEOK A */
+ {0x326f, 2, 2866}, /* CIRCLED HANGUL NIEUN A */
+ {0x3270, 2, 2870}, /* CIRCLED HANGUL TIKEUT A */
+ {0x3271, 2, 2874}, /* CIRCLED HANGUL RIEUL A */
+ {0x3272, 2, 2878}, /* CIRCLED HANGUL MIEUM A */
+ {0x3273, 2, 2882}, /* CIRCLED HANGUL PIEUP A */
+ {0x3274, 2, 2886}, /* CIRCLED HANGUL SIOS A */
+ {0x3275, 2, 2890}, /* CIRCLED HANGUL IEUNG A */
+ {0x3276, 2, 2894}, /* CIRCLED HANGUL CIEUC A */
+ {0x3277, 2, 2898}, /* CIRCLED HANGUL CHIEUCH A */
+ {0x3278, 2, 2902}, /* CIRCLED HANGUL KHIEUKH A */
+ {0x3279, 2, 2906}, /* CIRCLED HANGUL THIEUTH A */
+ {0x327a, 2, 2910}, /* CIRCLED HANGUL PHIEUPH A */
+ {0x327b, 2, 2744}, /* CIRCLED HANGUL HIEUH A */
+ {0x327c, 5, 3067}, /* CIRCLED KOREAN CHARACTER CHAMKO */
+ {0x327d, 4, 3072}, /* CIRCLED KOREAN CHARACTER JUEUI */
+ {0x3280, 1, 2373}, /* CIRCLED IDEOGRAPH ONE */
+ {0x3281, 1, 2379}, /* CIRCLED IDEOGRAPH TWO */
+ {0x3282, 1, 2809}, /* CIRCLED IDEOGRAPH THREE */
+ {0x3283, 1, 2810}, /* CIRCLED IDEOGRAPH FOUR */
+ {0x3284, 1, 2947}, /* CIRCLED IDEOGRAPH FIVE */
+ {0x3285, 1, 2950}, /* CIRCLED IDEOGRAPH SIX */
+ {0x3286, 1, 2953}, /* CIRCLED IDEOGRAPH SEVEN */
+ {0x3287, 1, 2384}, /* CIRCLED IDEOGRAPH EIGHT */
+ {0x3288, 1, 2959}, /* CIRCLED IDEOGRAPH NINE */
+ {0x3289, 1, 2396}, /* CIRCLED IDEOGRAPH TEN */
+ {0x328a, 1, 2446}, /* CIRCLED IDEOGRAPH MOON */
+ {0x328b, 1, 2458}, /* CIRCLED IDEOGRAPH FIRE */
+ {0x328c, 1, 2457}, /* CIRCLED IDEOGRAPH WATER */
+ {0x328d, 1, 2447}, /* CIRCLED IDEOGRAPH WOOD */
+ {0x328e, 1, 2539}, /* CIRCLED IDEOGRAPH METAL */
+ {0x328f, 1, 2404}, /* CIRCLED IDEOGRAPH EARTH */
+ {0x3290, 1, 2444}, /* CIRCLED IDEOGRAPH SUN */
+ {0x3291, 1, 2986}, /* CIRCLED IDEOGRAPH STOCK */
+ {0x3292, 1, 2989}, /* CIRCLED IDEOGRAPH HAVE */
+ {0x3293, 1, 2992}, /* CIRCLED IDEOGRAPH SOCIETY */
+ {0x3294, 1, 2995}, /* CIRCLED IDEOGRAPH NAME */
+ {0x3295, 1, 2998}, /* CIRCLED IDEOGRAPH SPECIAL */
+ {0x3296, 1, 3001}, /* CIRCLED IDEOGRAPH FINANCIAL */
+ {0x3297, 1, 3004}, /* CIRCLED IDEOGRAPH CONGRATULATION */
+ {0x3298, 1, 3007}, /* CIRCLED IDEOGRAPH LABOR */
+ {0x3299, 1, 3076}, /* CIRCLED IDEOGRAPH SECRET */
+ {0x329a, 1, 3077}, /* CIRCLED IDEOGRAPH MALE */
+ {0x329b, 1, 2410}, /* CIRCLED IDEOGRAPH FEMALE */
+ {0x329c, 1, 3078}, /* CIRCLED IDEOGRAPH SUITABLE */
+ {0x329d, 1, 3079}, /* CIRCLED IDEOGRAPH EXCELLENT */
+ {0x329e, 1, 3080}, /* CIRCLED IDEOGRAPH PRINT */
+ {0x329f, 1, 3081}, /* CIRCLED IDEOGRAPH ATTENTION */
+ {0x32a0, 1, 3082}, /* CIRCLED IDEOGRAPH ITEM */
+ {0x32a1, 1, 3034}, /* CIRCLED IDEOGRAPH REST */
+ {0x32a2, 1, 3083}, /* CIRCLED IDEOGRAPH COPY */
+ {0x32a3, 1, 3084}, /* CIRCLED IDEOGRAPH CORRECT */
+ {0x32a4, 1, 2811}, /* CIRCLED IDEOGRAPH HIGH */
+ {0x32a5, 1, 2812}, /* CIRCLED IDEOGRAPH CENTRE */
+ {0x32a6, 1, 2813}, /* CIRCLED IDEOGRAPH LOW */
+ {0x32a7, 1, 3085}, /* CIRCLED IDEOGRAPH LEFT */
+ {0x32a8, 1, 3086}, /* CIRCLED IDEOGRAPH RIGHT */
+ {0x32a9, 1, 3087}, /* CIRCLED IDEOGRAPH MEDICINE */
+ {0x32aa, 1, 3088}, /* CIRCLED IDEOGRAPH RELIGION */
+ {0x32ab, 1, 3016}, /* CIRCLED IDEOGRAPH STUDY */
+ {0x32ac, 1, 3019}, /* CIRCLED IDEOGRAPH SUPERVISE */
+ {0x32ad, 1, 3022}, /* CIRCLED IDEOGRAPH ENTERPRISE */
+ {0x32ae, 1, 3025}, /* CIRCLED IDEOGRAPH RESOURCE */
+ {0x32af, 1, 3028}, /* CIRCLED IDEOGRAPH ALLIANCE */
+ {0x32b0, 1, 3089}, /* CIRCLED IDEOGRAPH NIGHT */
+ {0x32b1, 2, 3090}, /* CIRCLED NUMBER THIRTY SIX */
+ {0x32b2, 2, 3092}, /* CIRCLED NUMBER THIRTY SEVEN */
+ {0x32b3, 2, 3094}, /* CIRCLED NUMBER THIRTY EIGHT */
+ {0x32b4, 2, 3096}, /* CIRCLED NUMBER THIRTY NINE */
+ {0x32b5, 2, 3098}, /* CIRCLED NUMBER FORTY */
+ {0x32b6, 2, 17}, /* CIRCLED NUMBER FORTY ONE */
+ {0x32b7, 2, 3048}, /* CIRCLED NUMBER FORTY TWO */
+ {0x32b8, 2, 3064}, /* CIRCLED NUMBER FORTY THREE */
+ {0x32b9, 2, 3100}, /* CIRCLED NUMBER FORTY FOUR */
+ {0x32ba, 2, 3102}, /* CIRCLED NUMBER FORTY FIVE */
+ {0x32bb, 2, 3104}, /* CIRCLED NUMBER FORTY SIX */
+ {0x32bc, 2, 3106}, /* CIRCLED NUMBER FORTY SEVEN */
+ {0x32bd, 2, 3108}, /* CIRCLED NUMBER FORTY EIGHT */
+ {0x32be, 2, 3110}, /* CIRCLED NUMBER FORTY NINE */
+ {0x32bf, 2, 3112}, /* CIRCLED NUMBER FIFTY */
+ {0x32c0, 2, 3114}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY */
+ {0x32c1, 2, 3116}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY */
+ {0x32c2, 2, 3118}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH */
+ {0x32c3, 2, 3120}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL */
+ {0x32c4, 2, 3122}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY */
+ {0x32c5, 2, 3124}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE */
+ {0x32c6, 2, 3126}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY */
+ {0x32c7, 2, 3128}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST */
+ {0x32c8, 2, 3130}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER */
+ {0x32c9, 3, 3132}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER */
+ {0x32ca, 3, 3135}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER */
+ {0x32cb, 3, 3138}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER */
+ {0x32cc, 2, 3141}, /* SQUARE HG */
+ {0x32cd, 3, 3143}, /* SQUARE ERG */
+ {0x32ce, 2, 3146}, /* SQUARE EV */
+ {0x32cf, 3, 3148}, /* LIMITED LIABILITY SIGN */
+ {0x32d0, 1, 3151}, /* CIRCLED KATAKANA A */
+ {0x32d1, 1, 3152}, /* CIRCLED KATAKANA I */
+ {0x32d2, 1, 2701}, /* CIRCLED KATAKANA U */
+ {0x32d3, 1, 3153}, /* CIRCLED KATAKANA E */
+ {0x32d4, 1, 3154}, /* CIRCLED KATAKANA O */
+ {0x32d5, 1, 2651}, /* CIRCLED KATAKANA KA */
+ {0x32d6, 1, 2653}, /* CIRCLED KATAKANA KI */
+ {0x32d7, 1, 2655}, /* CIRCLED KATAKANA KU */
+ {0x32d8, 1, 2657}, /* CIRCLED KATAKANA KE */
+ {0x32d9, 1, 2659}, /* CIRCLED KATAKANA KO */
+ {0x32da, 1, 2661}, /* CIRCLED KATAKANA SA */
+ {0x32db, 1, 2663}, /* CIRCLED KATAKANA SI */
+ {0x32dc, 1, 2665}, /* CIRCLED KATAKANA SU */
+ {0x32dd, 1, 2667}, /* CIRCLED KATAKANA SE */
+ {0x32de, 1, 2669}, /* CIRCLED KATAKANA SO */
+ {0x32df, 1, 2671}, /* CIRCLED KATAKANA TA */
+ {0x32e0, 1, 2673}, /* CIRCLED KATAKANA TI */
+ {0x32e1, 1, 2675}, /* CIRCLED KATAKANA TU */
+ {0x32e2, 1, 2677}, /* CIRCLED KATAKANA TE */
+ {0x32e3, 1, 2679}, /* CIRCLED KATAKANA TO */
+ {0x32e4, 1, 3155}, /* CIRCLED KATAKANA NA */
+ {0x32e5, 1, 3156}, /* CIRCLED KATAKANA NI */
+ {0x32e6, 1, 3157}, /* CIRCLED KATAKANA NU */
+ {0x32e7, 1, 3158}, /* CIRCLED KATAKANA NE */
+ {0x32e8, 1, 3159}, /* CIRCLED KATAKANA NO */
+ {0x32e9, 1, 2681}, /* CIRCLED KATAKANA HA */
+ {0x32ea, 1, 2685}, /* CIRCLED KATAKANA HI */
+ {0x32eb, 1, 2689}, /* CIRCLED KATAKANA HU */
+ {0x32ec, 1, 2693}, /* CIRCLED KATAKANA HE */
+ {0x32ed, 1, 2697}, /* CIRCLED KATAKANA HO */
+ {0x32ee, 1, 3160}, /* CIRCLED KATAKANA MA */
+ {0x32ef, 1, 3161}, /* CIRCLED KATAKANA MI */
+ {0x32f0, 1, 3162}, /* CIRCLED KATAKANA MU */
+ {0x32f1, 1, 3163}, /* CIRCLED KATAKANA ME */
+ {0x32f2, 1, 3164}, /* CIRCLED KATAKANA MO */
+ {0x32f3, 1, 3165}, /* CIRCLED KATAKANA YA */
+ {0x32f4, 1, 3166}, /* CIRCLED KATAKANA YU */
+ {0x32f5, 1, 3167}, /* CIRCLED KATAKANA YO */
+ {0x32f6, 1, 3168}, /* CIRCLED KATAKANA RA */
+ {0x32f7, 1, 3169}, /* CIRCLED KATAKANA RI */
+ {0x32f8, 1, 3170}, /* CIRCLED KATAKANA RU */
+ {0x32f9, 1, 3171}, /* CIRCLED KATAKANA RE */
+ {0x32fa, 1, 3172}, /* CIRCLED KATAKANA RO */
+ {0x32fb, 1, 2703}, /* CIRCLED KATAKANA WA */
+ {0x32fc, 1, 2705}, /* CIRCLED KATAKANA WI */
+ {0x32fd, 1, 2707}, /* CIRCLED KATAKANA WE */
+ {0x32fe, 1, 2709}, /* CIRCLED KATAKANA WO */
+ {0x3300, 4, 3173}, /* SQUARE APAATO */
+ {0x3301, 4, 3177}, /* SQUARE ARUHUA */
+ {0x3302, 4, 3181}, /* SQUARE ANPEA */
+ {0x3303, 3, 3185}, /* SQUARE AARU */
+ {0x3304, 4, 3188}, /* SQUARE ININGU */
+ {0x3305, 3, 3192}, /* SQUARE INTI */
+ {0x3306, 3, 3195}, /* SQUARE UON */
+ {0x3307, 5, 3198}, /* SQUARE ESUKUUDO */
+ {0x3308, 4, 3203}, /* SQUARE EEKAA */
+ {0x3309, 3, 3207}, /* SQUARE ONSU */
+ {0x330a, 3, 3210}, /* SQUARE OOMU */
+ {0x330b, 3, 3213}, /* SQUARE KAIRI */
+ {0x330c, 4, 3216}, /* SQUARE KARATTO */
+ {0x330d, 4, 3220}, /* SQUARE KARORII */
+ {0x330e, 3, 3224}, /* SQUARE GARON */
+ {0x330f, 3, 3227}, /* SQUARE GANMA */
+ {0x3310, 2, 3230}, /* SQUARE GIGA */
+ {0x3311, 3, 3232}, /* SQUARE GINII */
+ {0x3312, 4, 3235}, /* SQUARE KYURII */
+ {0x3313, 4, 3239}, /* SQUARE GIRUDAA */
+ {0x3314, 2, 3243}, /* SQUARE KIRO */
+ {0x3315, 5, 3245}, /* SQUARE KIROGURAMU */
+ {0x3316, 6, 3250}, /* SQUARE KIROMEETORU */
+ {0x3317, 5, 3256}, /* SQUARE KIROWATTO */
+ {0x3318, 3, 3247}, /* SQUARE GURAMU */
+ {0x3319, 5, 3261}, /* SQUARE GURAMUTON */
+ {0x331a, 5, 3266}, /* SQUARE KURUZEIRO */
+ {0x331b, 4, 3271}, /* SQUARE KUROONE */
+ {0x331c, 3, 3275}, /* SQUARE KEESU */
+ {0x331d, 3, 3278}, /* SQUARE KORUNA */
+ {0x331e, 3, 3281}, /* SQUARE KOOPO */
+ {0x331f, 4, 3284}, /* SQUARE SAIKURU */
+ {0x3320, 5, 3288}, /* SQUARE SANTIIMU */
+ {0x3321, 4, 3293}, /* SQUARE SIRINGU */
+ {0x3322, 3, 3297}, /* SQUARE SENTI */
+ {0x3323, 3, 3300}, /* SQUARE SENTO */
+ {0x3324, 3, 3303}, /* SQUARE DAASU */
+ {0x3325, 2, 3306}, /* SQUARE DESI */
+ {0x3326, 2, 3308}, /* SQUARE DORU */
+ {0x3327, 2, 3264}, /* SQUARE TON */
+ {0x3328, 2, 3310}, /* SQUARE NANO */
+ {0x3329, 3, 3312}, /* SQUARE NOTTO */
+ {0x332a, 3, 3315}, /* SQUARE HAITU */
+ {0x332b, 5, 3318}, /* SQUARE PAASENTO */
+ {0x332c, 3, 3323}, /* SQUARE PAATU */
+ {0x332d, 4, 3326}, /* SQUARE BAARERU */
+ {0x332e, 5, 3330}, /* SQUARE PIASUTORU */
+ {0x332f, 3, 3335}, /* SQUARE PIKURU */
+ {0x3330, 2, 3338}, /* SQUARE PIKO */
+ {0x3331, 2, 3340}, /* SQUARE BIRU */
+ {0x3332, 5, 3342}, /* SQUARE HUARADDO */
+ {0x3333, 4, 3347}, /* SQUARE HUIITO */
+ {0x3334, 5, 3351}, /* SQUARE BUSSYERU */
+ {0x3335, 3, 3356}, /* SQUARE HURAN */
+ {0x3336, 5, 3359}, /* SQUARE HEKUTAARU */
+ {0x3337, 2, 3364}, /* SQUARE PESO */
+ {0x3338, 3, 3366}, /* SQUARE PENIHI */
+ {0x3339, 3, 3369}, /* SQUARE HERUTU */
+ {0x333a, 3, 3372}, /* SQUARE PENSU */
+ {0x333b, 3, 3375}, /* SQUARE PEEZI */
+ {0x333c, 3, 3378}, /* SQUARE BEETA */
+ {0x333d, 4, 3381}, /* SQUARE POINTO */
+ {0x333e, 3, 3385}, /* SQUARE BORUTO */
+ {0x333f, 2, 3388}, /* SQUARE HON */
+ {0x3340, 3, 3390}, /* SQUARE PONDO */
+ {0x3341, 3, 3393}, /* SQUARE HOORU */
+ {0x3342, 3, 3396}, /* SQUARE HOON */
+ {0x3343, 4, 3399}, /* SQUARE MAIKURO */
+ {0x3344, 3, 3403}, /* SQUARE MAIRU */
+ {0x3345, 3, 3406}, /* SQUARE MAHHA */
+ {0x3346, 3, 3409}, /* SQUARE MARUKU */
+ {0x3347, 5, 3412}, /* SQUARE MANSYON */
+ {0x3348, 4, 3417}, /* SQUARE MIKURON */
+ {0x3349, 2, 3421}, /* SQUARE MIRI */
+ {0x334a, 5, 3423}, /* SQUARE MIRIBAARU */
+ {0x334b, 2, 3428}, /* SQUARE MEGA */
+ {0x334c, 4, 3430}, /* SQUARE MEGATON */
+ {0x334d, 4, 3252}, /* SQUARE MEETORU */
+ {0x334e, 3, 3434}, /* SQUARE YAADO */
+ {0x334f, 3, 3437}, /* SQUARE YAARU */
+ {0x3350, 3, 3440}, /* SQUARE YUAN */
+ {0x3351, 4, 3443}, /* SQUARE RITTORU */
+ {0x3352, 2, 3447}, /* SQUARE RIRA */
+ {0x3353, 3, 3449}, /* SQUARE RUPII */
+ {0x3354, 4, 3452}, /* SQUARE RUUBURU */
+ {0x3355, 2, 3456}, /* SQUARE REMU */
+ {0x3356, 5, 3458}, /* SQUARE RENTOGEN */
+ {0x3357, 3, 3258}, /* SQUARE WATTO */
+ {0x3358, 2, 3463}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO */
+ {0x3359, 2, 3465}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE */
+ {0x335a, 2, 3467}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO */
+ {0x335b, 2, 3469}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE */
+ {0x335c, 2, 3471}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR */
+ {0x335d, 2, 3473}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE */
+ {0x335e, 2, 3475}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX */
+ {0x335f, 2, 3477}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN */
+ {0x3360, 2, 3479}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT */
+ {0x3361, 2, 3481}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE */
+ {0x3362, 3, 3483}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN */
+ {0x3363, 3, 3486}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN */
+ {0x3364, 3, 3489}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE */
+ {0x3365, 3, 3492}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN */
+ {0x3366, 3, 3495}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN */
+ {0x3367, 3, 3498}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN */
+ {0x3368, 3, 3501}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN */
+ {0x3369, 3, 3504}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN */
+ {0x336a, 3, 3507}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN */
+ {0x336b, 3, 3510}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN */
+ {0x336c, 3, 3513}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY */
+ {0x336d, 3, 3516}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE */
+ {0x336e, 3, 3519}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO */
+ {0x336f, 3, 3522}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE */
+ {0x3370, 3, 3525}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR */
+ {0x3371, 3, 3528}, /* SQUARE HPA */
+ {0x3372, 2, 3531}, /* SQUARE DA */
+ {0x3373, 2, 3533}, /* SQUARE AU */
+ {0x3374, 3, 3535}, /* SQUARE BAR */
+ {0x3375, 2, 3538}, /* SQUARE OV */
+ {0x3376, 2, 3540}, /* SQUARE PC */
+ {0x3377, 2, 3542}, /* SQUARE DM */
+ {0x3378, 3, 3544}, /* SQUARE DM SQUARED */
+ {0x3379, 3, 3547}, /* SQUARE DM CUBED */
+ {0x337a, 2, 3550}, /* SQUARE IU */
+ {0x337b, 2, 3552}, /* SQUARE ERA NAME HEISEI */
+ {0x337c, 2, 3554}, /* SQUARE ERA NAME SYOUWA */
+ {0x337d, 2, 3556}, /* SQUARE ERA NAME TAISYOU */
+ {0x337e, 2, 3558}, /* SQUARE ERA NAME MEIZI */
+ {0x337f, 4, 3560}, /* SQUARE CORPORATION */
+ {0x3380, 2, 3564}, /* SQUARE PA AMPS */
+ {0x3381, 2, 3566}, /* SQUARE NA */
+ {0x3382, 2, 3568}, /* SQUARE MU A */
+ {0x3383, 2, 3570}, /* SQUARE MA */
+ {0x3384, 2, 3572}, /* SQUARE KA */
+ {0x3385, 2, 3574}, /* SQUARE KB */
+ {0x3386, 2, 3576}, /* SQUARE MB */
+ {0x3387, 2, 3578}, /* SQUARE GB */
+ {0x3388, 3, 3580}, /* SQUARE CAL */
+ {0x3389, 4, 3583}, /* SQUARE KCAL */
+ {0x338a, 2, 3587}, /* SQUARE PF */
+ {0x338b, 2, 3589}, /* SQUARE NF */
+ {0x338c, 2, 3591}, /* SQUARE MU F */
+ {0x338d, 2, 3593}, /* SQUARE MU G */
+ {0x338e, 2, 3595}, /* SQUARE MG */
+ {0x338f, 2, 3597}, /* SQUARE KG */
+ {0x3390, 2, 3599}, /* SQUARE HZ */
+ {0x3391, 3, 3601}, /* SQUARE KHZ */
+ {0x3392, 3, 3604}, /* SQUARE MHZ */
+ {0x3393, 3, 3607}, /* SQUARE GHZ */
+ {0x3394, 3, 3610}, /* SQUARE THZ */
+ {0x3395, 2, 3613}, /* SQUARE MU L */
+ {0x3396, 2, 3615}, /* SQUARE ML */
+ {0x3397, 2, 3617}, /* SQUARE DL */
+ {0x3398, 2, 3619}, /* SQUARE KL */
+ {0x3399, 2, 3621}, /* SQUARE FM */
+ {0x339a, 2, 3623}, /* SQUARE NM */
+ {0x339b, 2, 3625}, /* SQUARE MU M */
+ {0x339c, 2, 3627}, /* SQUARE MM */
+ {0x339d, 2, 3629}, /* SQUARE CM */
+ {0x339e, 2, 3631}, /* SQUARE KM */
+ {0x339f, 3, 3633}, /* SQUARE MM SQUARED */
+ {0x33a0, 3, 3636}, /* SQUARE CM SQUARED */
+ {0x33a1, 2, 3545}, /* SQUARE M SQUARED */
+ {0x33a2, 3, 3639}, /* SQUARE KM SQUARED */
+ {0x33a3, 3, 3642}, /* SQUARE MM CUBED */
+ {0x33a4, 3, 3645}, /* SQUARE CM CUBED */
+ {0x33a5, 2, 3548}, /* SQUARE M CUBED */
+ {0x33a6, 3, 3648}, /* SQUARE KM CUBED */
+ {0x33a7, 3, 3651}, /* SQUARE M OVER S */
+ {0x33a8, 4, 3654}, /* SQUARE M OVER S SQUARED */
+ {0x33a9, 2, 3529}, /* SQUARE PA */
+ {0x33aa, 3, 3658}, /* SQUARE KPA */
+ {0x33ab, 3, 3661}, /* SQUARE MPA */
+ {0x33ac, 3, 3664}, /* SQUARE GPA */
+ {0x33ad, 3, 3667}, /* SQUARE RAD */
+ {0x33ae, 5, 3670}, /* SQUARE RAD OVER S */
+ {0x33af, 6, 3675}, /* SQUARE RAD OVER S SQUARED */
+ {0x33b0, 2, 3681}, /* SQUARE PS */
+ {0x33b1, 2, 3683}, /* SQUARE NS */
+ {0x33b2, 2, 3685}, /* SQUARE MU S */
+ {0x33b3, 2, 3687}, /* SQUARE MS */
+ {0x33b4, 2, 3689}, /* SQUARE PV */
+ {0x33b5, 2, 3691}, /* SQUARE NV */
+ {0x33b6, 2, 3693}, /* SQUARE MU V */
+ {0x33b7, 2, 3695}, /* SQUARE MV */
+ {0x33b8, 2, 3697}, /* SQUARE KV */
+ {0x33b9, 2, 3699}, /* SQUARE MV MEGA */
+ {0x33ba, 2, 3701}, /* SQUARE PW */
+ {0x33bb, 2, 3703}, /* SQUARE NW */
+ {0x33bc, 2, 3705}, /* SQUARE MU W */
+ {0x33bd, 2, 3707}, /* SQUARE MW */
+ {0x33be, 2, 3709}, /* SQUARE KW */
+ {0x33bf, 2, 3711}, /* SQUARE MW MEGA */
+ {0x33c0, 2, 3713}, /* SQUARE K OHM */
+ {0x33c1, 2, 3715}, /* SQUARE M OHM */
+ {0x33c2, 4, 3717}, /* SQUARE AM */
+ {0x33c3, 2, 3721}, /* SQUARE BQ */
+ {0x33c4, 2, 3723}, /* SQUARE CC */
+ {0x33c5, 2, 3541}, /* SQUARE CD */
+ {0x33c6, 4, 3725}, /* SQUARE C OVER KG */
+ {0x33c7, 3, 3729}, /* SQUARE CO */
+ {0x33c8, 2, 3732}, /* SQUARE DB */
+ {0x33c9, 2, 3734}, /* SQUARE GY */
+ {0x33ca, 2, 3736}, /* SQUARE HA */
+ {0x33cb, 2, 3738}, /* SQUARE HP */
+ {0x33cc, 2, 3740}, /* SQUARE IN */
+ {0x33cd, 2, 3742}, /* SQUARE KK */
+ {0x33ce, 2, 3744}, /* SQUARE KM CAPITAL */
+ {0x33cf, 2, 3746}, /* SQUARE KT */
+ {0x33d0, 2, 3748}, /* SQUARE LM */
+ {0x33d1, 2, 3750}, /* SQUARE LN */
+ {0x33d2, 3, 3752}, /* SQUARE LOG */
+ {0x33d3, 2, 3755}, /* SQUARE LX */
+ {0x33d4, 2, 3757}, /* SQUARE MB SMALL */
+ {0x33d5, 3, 3759}, /* SQUARE MIL */
+ {0x33d6, 3, 3762}, /* SQUARE MOL */
+ {0x33d7, 2, 3765}, /* SQUARE PH */
+ {0x33d8, 4, 3767}, /* SQUARE PM */
+ {0x33d9, 3, 3771}, /* SQUARE PPM */
+ {0x33da, 2, 3774}, /* SQUARE PR */
+ {0x33db, 2, 3674}, /* SQUARE SR */
+ {0x33dc, 2, 3776}, /* SQUARE SV */
+ {0x33dd, 2, 3778}, /* SQUARE WB */
+ {0x33de, 3, 3780}, /* SQUARE V OVER M */
+ {0x33df, 3, 3783}, /* SQUARE A OVER M */
+ {0x33e0, 2, 3786}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE */
+ {0x33e1, 2, 3788}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO */
+ {0x33e2, 2, 3790}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE */
+ {0x33e3, 2, 3792}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR */
+ {0x33e4, 2, 3794}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE */
+ {0x33e5, 2, 3796}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX */
+ {0x33e6, 2, 3798}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN */
+ {0x33e7, 2, 3800}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT */
+ {0x33e8, 2, 3802}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE */
+ {0x33e9, 3, 3804}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN */
+ {0x33ea, 3, 3807}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN */
+ {0x33eb, 3, 3810}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE */
+ {0x33ec, 3, 3813}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN */
+ {0x33ed, 3, 3816}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN */
+ {0x33ee, 3, 3819}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN */
+ {0x33ef, 3, 3822}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN */
+ {0x33f0, 3, 3825}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN */
+ {0x33f1, 3, 3828}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN */
+ {0x33f2, 3, 3831}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN */
+ {0x33f3, 3, 3834}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY */
+ {0x33f4, 3, 3837}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE */
+ {0x33f5, 3, 3840}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO */
+ {0x33f6, 3, 3843}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE */
+ {0x33f7, 3, 3846}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR */
+ {0x33f8, 3, 3849}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE */
+ {0x33f9, 3, 3852}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX */
+ {0x33fa, 3, 3855}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN */
+ {0x33fb, 3, 3858}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT */
+ {0x33fc, 3, 3861}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE */
+ {0x33fd, 3, 3864}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY */
+ {0x33fe, 3, 3867}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE */
+ {0x33ff, 3, 3870}, /* SQUARE GAL */
+ {0xf900, 1, 3873}, /* CJK COMPATIBILITY IDEOGRAPH-F900 */
+ {0xf901, 1, 3874}, /* CJK COMPATIBILITY IDEOGRAPH-F901 */
+ {0xf902, 1, 2531}, /* CJK COMPATIBILITY IDEOGRAPH-F902 */
+ {0xf903, 1, 3875}, /* CJK COMPATIBILITY IDEOGRAPH-F903 */
+ {0xf904, 1, 3876}, /* CJK COMPATIBILITY IDEOGRAPH-F904 */
+ {0xf905, 1, 3877}, /* CJK COMPATIBILITY IDEOGRAPH-F905 */
+ {0xf906, 1, 3878}, /* CJK COMPATIBILITY IDEOGRAPH-F906 */
+ {0xf907, 1, 2585}, /* CJK COMPATIBILITY IDEOGRAPH-F907 */
+ {0xf908, 1, 2585}, /* CJK COMPATIBILITY IDEOGRAPH-F908 */
+ {0xf909, 1, 3879}, /* CJK COMPATIBILITY IDEOGRAPH-F909 */
+ {0xf90a, 1, 2539}, /* CJK COMPATIBILITY IDEOGRAPH-F90A */
+ {0xf90b, 1, 3880}, /* CJK COMPATIBILITY IDEOGRAPH-F90B */
+ {0xf90c, 1, 3881}, /* CJK COMPATIBILITY IDEOGRAPH-F90C */
+ {0xf90d, 1, 3882}, /* CJK COMPATIBILITY IDEOGRAPH-F90D */
+ {0xf90e, 1, 3883}, /* CJK COMPATIBILITY IDEOGRAPH-F90E */
+ {0xf90f, 1, 3884}, /* CJK COMPATIBILITY IDEOGRAPH-F90F */
+ {0xf910, 1, 3885}, /* CJK COMPATIBILITY IDEOGRAPH-F910 */
+ {0xf911, 1, 3886}, /* CJK COMPATIBILITY IDEOGRAPH-F911 */
+ {0xf912, 1, 3887}, /* CJK COMPATIBILITY IDEOGRAPH-F912 */
+ {0xf913, 1, 3888}, /* CJK COMPATIBILITY IDEOGRAPH-F913 */
+ {0xf914, 1, 3889}, /* CJK COMPATIBILITY IDEOGRAPH-F914 */
+ {0xf915, 1, 3890}, /* CJK COMPATIBILITY IDEOGRAPH-F915 */
+ {0xf916, 1, 3891}, /* CJK COMPATIBILITY IDEOGRAPH-F916 */
+ {0xf917, 1, 3892}, /* CJK COMPATIBILITY IDEOGRAPH-F917 */
+ {0xf918, 1, 3893}, /* CJK COMPATIBILITY IDEOGRAPH-F918 */
+ {0xf919, 1, 3894}, /* CJK COMPATIBILITY IDEOGRAPH-F919 */
+ {0xf91a, 1, 3895}, /* CJK COMPATIBILITY IDEOGRAPH-F91A */
+ {0xf91b, 1, 3896}, /* CJK COMPATIBILITY IDEOGRAPH-F91B */
+ {0xf91c, 1, 3897}, /* CJK COMPATIBILITY IDEOGRAPH-F91C */
+ {0xf91d, 1, 3898}, /* CJK COMPATIBILITY IDEOGRAPH-F91D */
+ {0xf91e, 1, 3899}, /* CJK COMPATIBILITY IDEOGRAPH-F91E */
+ {0xf91f, 1, 3900}, /* CJK COMPATIBILITY IDEOGRAPH-F91F */
+ {0xf920, 1, 3901}, /* CJK COMPATIBILITY IDEOGRAPH-F920 */
+ {0xf921, 1, 3902}, /* CJK COMPATIBILITY IDEOGRAPH-F921 */
+ {0xf922, 1, 3903}, /* CJK COMPATIBILITY IDEOGRAPH-F922 */
+ {0xf923, 1, 3904}, /* CJK COMPATIBILITY IDEOGRAPH-F923 */
+ {0xf924, 1, 3905}, /* CJK COMPATIBILITY IDEOGRAPH-F924 */
+ {0xf925, 1, 3906}, /* CJK COMPATIBILITY IDEOGRAPH-F925 */
+ {0xf926, 1, 3907}, /* CJK COMPATIBILITY IDEOGRAPH-F926 */
+ {0xf927, 1, 3908}, /* CJK COMPATIBILITY IDEOGRAPH-F927 */
+ {0xf928, 1, 3909}, /* CJK COMPATIBILITY IDEOGRAPH-F928 */
+ {0xf929, 1, 3910}, /* CJK COMPATIBILITY IDEOGRAPH-F929 */
+ {0xf92a, 1, 3911}, /* CJK COMPATIBILITY IDEOGRAPH-F92A */
+ {0xf92b, 1, 3912}, /* CJK COMPATIBILITY IDEOGRAPH-F92B */
+ {0xf92c, 1, 3913}, /* CJK COMPATIBILITY IDEOGRAPH-F92C */
+ {0xf92d, 1, 3914}, /* CJK COMPATIBILITY IDEOGRAPH-F92D */
+ {0xf92e, 1, 3915}, /* CJK COMPATIBILITY IDEOGRAPH-F92E */
+ {0xf92f, 1, 3916}, /* CJK COMPATIBILITY IDEOGRAPH-F92F */
+ {0xf930, 1, 3917}, /* CJK COMPATIBILITY IDEOGRAPH-F930 */
+ {0xf931, 1, 3918}, /* CJK COMPATIBILITY IDEOGRAPH-F931 */
+ {0xf932, 1, 3919}, /* CJK COMPATIBILITY IDEOGRAPH-F932 */
+ {0xf933, 1, 3920}, /* CJK COMPATIBILITY IDEOGRAPH-F933 */
+ {0xf934, 1, 2497}, /* CJK COMPATIBILITY IDEOGRAPH-F934 */
+ {0xf935, 1, 3921}, /* CJK COMPATIBILITY IDEOGRAPH-F935 */
+ {0xf936, 1, 3922}, /* CJK COMPATIBILITY IDEOGRAPH-F936 */
+ {0xf937, 1, 3923}, /* CJK COMPATIBILITY IDEOGRAPH-F937 */
+ {0xf938, 1, 3924}, /* CJK COMPATIBILITY IDEOGRAPH-F938 */
+ {0xf939, 1, 3925}, /* CJK COMPATIBILITY IDEOGRAPH-F939 */
+ {0xf93a, 1, 3926}, /* CJK COMPATIBILITY IDEOGRAPH-F93A */
+ {0xf93b, 1, 3927}, /* CJK COMPATIBILITY IDEOGRAPH-F93B */
+ {0xf93c, 1, 3928}, /* CJK COMPATIBILITY IDEOGRAPH-F93C */
+ {0xf93d, 1, 3929}, /* CJK COMPATIBILITY IDEOGRAPH-F93D */
+ {0xf93e, 1, 3930}, /* CJK COMPATIBILITY IDEOGRAPH-F93E */
+ {0xf93f, 1, 3931}, /* CJK COMPATIBILITY IDEOGRAPH-F93F */
+ {0xf940, 1, 2570}, /* CJK COMPATIBILITY IDEOGRAPH-F940 */
+ {0xf941, 1, 3932}, /* CJK COMPATIBILITY IDEOGRAPH-F941 */
+ {0xf942, 1, 3933}, /* CJK COMPATIBILITY IDEOGRAPH-F942 */
+ {0xf943, 1, 3934}, /* CJK COMPATIBILITY IDEOGRAPH-F943 */
+ {0xf944, 1, 3935}, /* CJK COMPATIBILITY IDEOGRAPH-F944 */
+ {0xf945, 1, 3936}, /* CJK COMPATIBILITY IDEOGRAPH-F945 */
+ {0xf946, 1, 3937}, /* CJK COMPATIBILITY IDEOGRAPH-F946 */
+ {0xf947, 1, 3938}, /* CJK COMPATIBILITY IDEOGRAPH-F947 */
+ {0xf948, 1, 3939}, /* CJK COMPATIBILITY IDEOGRAPH-F948 */
+ {0xf949, 1, 3940}, /* CJK COMPATIBILITY IDEOGRAPH-F949 */
+ {0xf94a, 1, 3941}, /* CJK COMPATIBILITY IDEOGRAPH-F94A */
+ {0xf94b, 1, 3942}, /* CJK COMPATIBILITY IDEOGRAPH-F94B */
+ {0xf94c, 1, 3943}, /* CJK COMPATIBILITY IDEOGRAPH-F94C */
+ {0xf94d, 1, 3944}, /* CJK COMPATIBILITY IDEOGRAPH-F94D */
+ {0xf94e, 1, 3945}, /* CJK COMPATIBILITY IDEOGRAPH-F94E */
+ {0xf94f, 1, 3946}, /* CJK COMPATIBILITY IDEOGRAPH-F94F */
+ {0xf950, 1, 3947}, /* CJK COMPATIBILITY IDEOGRAPH-F950 */
+ {0xf951, 1, 3948}, /* CJK COMPATIBILITY IDEOGRAPH-F951 */
+ {0xf952, 1, 3949}, /* CJK COMPATIBILITY IDEOGRAPH-F952 */
+ {0xf953, 1, 3950}, /* CJK COMPATIBILITY IDEOGRAPH-F953 */
+ {0xf954, 1, 3951}, /* CJK COMPATIBILITY IDEOGRAPH-F954 */
+ {0xf955, 1, 3952}, /* CJK COMPATIBILITY IDEOGRAPH-F955 */
+ {0xf956, 1, 3953}, /* CJK COMPATIBILITY IDEOGRAPH-F956 */
+ {0xf957, 1, 3954}, /* CJK COMPATIBILITY IDEOGRAPH-F957 */
+ {0xf958, 1, 3955}, /* CJK COMPATIBILITY IDEOGRAPH-F958 */
+ {0xf959, 1, 3956}, /* CJK COMPATIBILITY IDEOGRAPH-F959 */
+ {0xf95a, 1, 3957}, /* CJK COMPATIBILITY IDEOGRAPH-F95A */
+ {0xf95b, 1, 3958}, /* CJK COMPATIBILITY IDEOGRAPH-F95B */
+ {0xf95c, 1, 3889}, /* CJK COMPATIBILITY IDEOGRAPH-F95C */
+ {0xf95d, 1, 3959}, /* CJK COMPATIBILITY IDEOGRAPH-F95D */
+ {0xf95e, 1, 3960}, /* CJK COMPATIBILITY IDEOGRAPH-F95E */
+ {0xf95f, 1, 3961}, /* CJK COMPATIBILITY IDEOGRAPH-F95F */
+ {0xf960, 1, 3962}, /* CJK COMPATIBILITY IDEOGRAPH-F960 */
+ {0xf961, 1, 3963}, /* CJK COMPATIBILITY IDEOGRAPH-F961 */
+ {0xf962, 1, 3964}, /* CJK COMPATIBILITY IDEOGRAPH-F962 */
+ {0xf963, 1, 3965}, /* CJK COMPATIBILITY IDEOGRAPH-F963 */
+ {0xf964, 1, 3966}, /* CJK COMPATIBILITY IDEOGRAPH-F964 */
+ {0xf965, 1, 3967}, /* CJK COMPATIBILITY IDEOGRAPH-F965 */
+ {0xf966, 1, 3968}, /* CJK COMPATIBILITY IDEOGRAPH-F966 */
+ {0xf967, 1, 3969}, /* CJK COMPATIBILITY IDEOGRAPH-F967 */
+ {0xf968, 1, 3970}, /* CJK COMPATIBILITY IDEOGRAPH-F968 */
+ {0xf969, 1, 3971}, /* CJK COMPATIBILITY IDEOGRAPH-F969 */
+ {0xf96a, 1, 3972}, /* CJK COMPATIBILITY IDEOGRAPH-F96A */
+ {0xf96b, 1, 3973}, /* CJK COMPATIBILITY IDEOGRAPH-F96B */
+ {0xf96c, 1, 3974}, /* CJK COMPATIBILITY IDEOGRAPH-F96C */
+ {0xf96d, 1, 3975}, /* CJK COMPATIBILITY IDEOGRAPH-F96D */
+ {0xf96e, 1, 3976}, /* CJK COMPATIBILITY IDEOGRAPH-F96E */
+ {0xf96f, 1, 3977}, /* CJK COMPATIBILITY IDEOGRAPH-F96F */
+ {0xf970, 1, 3978}, /* CJK COMPATIBILITY IDEOGRAPH-F970 */
+ {0xf971, 1, 2533}, /* CJK COMPATIBILITY IDEOGRAPH-F971 */
+ {0xf972, 1, 3979}, /* CJK COMPATIBILITY IDEOGRAPH-F972 */
+ {0xf973, 1, 3980}, /* CJK COMPATIBILITY IDEOGRAPH-F973 */
+ {0xf974, 1, 3981}, /* CJK COMPATIBILITY IDEOGRAPH-F974 */
+ {0xf975, 1, 3982}, /* CJK COMPATIBILITY IDEOGRAPH-F975 */
+ {0xf976, 1, 3983}, /* CJK COMPATIBILITY IDEOGRAPH-F976 */
+ {0xf977, 1, 3984}, /* CJK COMPATIBILITY IDEOGRAPH-F977 */
+ {0xf978, 1, 3985}, /* CJK COMPATIBILITY IDEOGRAPH-F978 */
+ {0xf979, 1, 3986}, /* CJK COMPATIBILITY IDEOGRAPH-F979 */
+ {0xf97a, 1, 3987}, /* CJK COMPATIBILITY IDEOGRAPH-F97A */
+ {0xf97b, 1, 3988}, /* CJK COMPATIBILITY IDEOGRAPH-F97B */
+ {0xf97c, 1, 3989}, /* CJK COMPATIBILITY IDEOGRAPH-F97C */
+ {0xf97d, 1, 3990}, /* CJK COMPATIBILITY IDEOGRAPH-F97D */
+ {0xf97e, 1, 3991}, /* CJK COMPATIBILITY IDEOGRAPH-F97E */
+ {0xf97f, 1, 3992}, /* CJK COMPATIBILITY IDEOGRAPH-F97F */
+ {0xf980, 1, 3993}, /* CJK COMPATIBILITY IDEOGRAPH-F980 */
+ {0xf981, 1, 2410}, /* CJK COMPATIBILITY IDEOGRAPH-F981 */
+ {0xf982, 1, 3994}, /* CJK COMPATIBILITY IDEOGRAPH-F982 */
+ {0xf983, 1, 3995}, /* CJK COMPATIBILITY IDEOGRAPH-F983 */
+ {0xf984, 1, 3996}, /* CJK COMPATIBILITY IDEOGRAPH-F984 */
+ {0xf985, 1, 3997}, /* CJK COMPATIBILITY IDEOGRAPH-F985 */
+ {0xf986, 1, 3998}, /* CJK COMPATIBILITY IDEOGRAPH-F986 */
+ {0xf987, 1, 3999}, /* CJK COMPATIBILITY IDEOGRAPH-F987 */
+ {0xf988, 1, 4000}, /* CJK COMPATIBILITY IDEOGRAPH-F988 */
+ {0xf989, 1, 4001}, /* CJK COMPATIBILITY IDEOGRAPH-F989 */
+ {0xf98a, 1, 2391}, /* CJK COMPATIBILITY IDEOGRAPH-F98A */
+ {0xf98b, 1, 4002}, /* CJK COMPATIBILITY IDEOGRAPH-F98B */
+ {0xf98c, 1, 4003}, /* CJK COMPATIBILITY IDEOGRAPH-F98C */
+ {0xf98d, 1, 4004}, /* CJK COMPATIBILITY IDEOGRAPH-F98D */
+ {0xf98e, 1, 4005}, /* CJK COMPATIBILITY IDEOGRAPH-F98E */
+ {0xf98f, 1, 4006}, /* CJK COMPATIBILITY IDEOGRAPH-F98F */
+ {0xf990, 1, 4007}, /* CJK COMPATIBILITY IDEOGRAPH-F990 */
+ {0xf991, 1, 4008}, /* CJK COMPATIBILITY IDEOGRAPH-F991 */
+ {0xf992, 1, 4009}, /* CJK COMPATIBILITY IDEOGRAPH-F992 */
+ {0xf993, 1, 4010}, /* CJK COMPATIBILITY IDEOGRAPH-F993 */
+ {0xf994, 1, 4011}, /* CJK COMPATIBILITY IDEOGRAPH-F994 */
+ {0xf995, 1, 4012}, /* CJK COMPATIBILITY IDEOGRAPH-F995 */
+ {0xf996, 1, 4013}, /* CJK COMPATIBILITY IDEOGRAPH-F996 */
+ {0xf997, 1, 4014}, /* CJK COMPATIBILITY IDEOGRAPH-F997 */
+ {0xf998, 1, 4015}, /* CJK COMPATIBILITY IDEOGRAPH-F998 */
+ {0xf999, 1, 4016}, /* CJK COMPATIBILITY IDEOGRAPH-F999 */
+ {0xf99a, 1, 4017}, /* CJK COMPATIBILITY IDEOGRAPH-F99A */
+ {0xf99b, 1, 4018}, /* CJK COMPATIBILITY IDEOGRAPH-F99B */
+ {0xf99c, 1, 4019}, /* CJK COMPATIBILITY IDEOGRAPH-F99C */
+ {0xf99d, 1, 4020}, /* CJK COMPATIBILITY IDEOGRAPH-F99D */
+ {0xf99e, 1, 4021}, /* CJK COMPATIBILITY IDEOGRAPH-F99E */
+ {0xf99f, 1, 4022}, /* CJK COMPATIBILITY IDEOGRAPH-F99F */
+ {0xf9a0, 1, 4023}, /* CJK COMPATIBILITY IDEOGRAPH-F9A0 */
+ {0xf9a1, 1, 3977}, /* CJK COMPATIBILITY IDEOGRAPH-F9A1 */
+ {0xf9a2, 1, 4024}, /* CJK COMPATIBILITY IDEOGRAPH-F9A2 */
+ {0xf9a3, 1, 4025}, /* CJK COMPATIBILITY IDEOGRAPH-F9A3 */
+ {0xf9a4, 1, 4026}, /* CJK COMPATIBILITY IDEOGRAPH-F9A4 */
+ {0xf9a5, 1, 4027}, /* CJK COMPATIBILITY IDEOGRAPH-F9A5 */
+ {0xf9a6, 1, 4028}, /* CJK COMPATIBILITY IDEOGRAPH-F9A6 */
+ {0xf9a7, 1, 4029}, /* CJK COMPATIBILITY IDEOGRAPH-F9A7 */
+ {0xf9a8, 1, 4030}, /* CJK COMPATIBILITY IDEOGRAPH-F9A8 */
+ {0xf9a9, 1, 4031}, /* CJK COMPATIBILITY IDEOGRAPH-F9A9 */
+ {0xf9aa, 1, 3961}, /* CJK COMPATIBILITY IDEOGRAPH-F9AA */
+ {0xf9ab, 1, 4032}, /* CJK COMPATIBILITY IDEOGRAPH-F9AB */
+ {0xf9ac, 1, 4033}, /* CJK COMPATIBILITY IDEOGRAPH-F9AC */
+ {0xf9ad, 1, 4034}, /* CJK COMPATIBILITY IDEOGRAPH-F9AD */
+ {0xf9ae, 1, 4035}, /* CJK COMPATIBILITY IDEOGRAPH-F9AE */
+ {0xf9af, 1, 4036}, /* CJK COMPATIBILITY IDEOGRAPH-F9AF */
+ {0xf9b0, 1, 4037}, /* CJK COMPATIBILITY IDEOGRAPH-F9B0 */
+ {0xf9b1, 1, 4038}, /* CJK COMPATIBILITY IDEOGRAPH-F9B1 */
+ {0xf9b2, 1, 4039}, /* CJK COMPATIBILITY IDEOGRAPH-F9B2 */
+ {0xf9b3, 1, 4040}, /* CJK COMPATIBILITY IDEOGRAPH-F9B3 */
+ {0xf9b4, 1, 4041}, /* CJK COMPATIBILITY IDEOGRAPH-F9B4 */
+ {0xf9b5, 1, 4042}, /* CJK COMPATIBILITY IDEOGRAPH-F9B5 */
+ {0xf9b6, 1, 4043}, /* CJK COMPATIBILITY IDEOGRAPH-F9B6 */
+ {0xf9b7, 1, 4044}, /* CJK COMPATIBILITY IDEOGRAPH-F9B7 */
+ {0xf9b8, 1, 4045}, /* CJK COMPATIBILITY IDEOGRAPH-F9B8 */
+ {0xf9b9, 1, 4046}, /* CJK COMPATIBILITY IDEOGRAPH-F9B9 */
+ {0xf9ba, 1, 4047}, /* CJK COMPATIBILITY IDEOGRAPH-F9BA */
+ {0xf9bb, 1, 4048}, /* CJK COMPATIBILITY IDEOGRAPH-F9BB */
+ {0xf9bc, 1, 4049}, /* CJK COMPATIBILITY IDEOGRAPH-F9BC */
+ {0xf9bd, 1, 4050}, /* CJK COMPATIBILITY IDEOGRAPH-F9BD */
+ {0xf9be, 1, 4051}, /* CJK COMPATIBILITY IDEOGRAPH-F9BE */
+ {0xf9bf, 1, 3889}, /* CJK COMPATIBILITY IDEOGRAPH-F9BF */
+ {0xf9c0, 1, 4052}, /* CJK COMPATIBILITY IDEOGRAPH-F9C0 */
+ {0xf9c1, 1, 4053}, /* CJK COMPATIBILITY IDEOGRAPH-F9C1 */
+ {0xf9c2, 1, 4054}, /* CJK COMPATIBILITY IDEOGRAPH-F9C2 */
+ {0xf9c3, 1, 4055}, /* CJK COMPATIBILITY IDEOGRAPH-F9C3 */
+ {0xf9c4, 1, 2584}, /* CJK COMPATIBILITY IDEOGRAPH-F9C4 */
+ {0xf9c5, 1, 4056}, /* CJK COMPATIBILITY IDEOGRAPH-F9C5 */
+ {0xf9c6, 1, 4057}, /* CJK COMPATIBILITY IDEOGRAPH-F9C6 */
+ {0xf9c7, 1, 4058}, /* CJK COMPATIBILITY IDEOGRAPH-F9C7 */
+ {0xf9c8, 1, 4059}, /* CJK COMPATIBILITY IDEOGRAPH-F9C8 */
+ {0xf9c9, 1, 4060}, /* CJK COMPATIBILITY IDEOGRAPH-F9C9 */
+ {0xf9ca, 1, 4061}, /* CJK COMPATIBILITY IDEOGRAPH-F9CA */
+ {0xf9cb, 1, 4062}, /* CJK COMPATIBILITY IDEOGRAPH-F9CB */
+ {0xf9cc, 1, 4063}, /* CJK COMPATIBILITY IDEOGRAPH-F9CC */
+ {0xf9cd, 1, 4064}, /* CJK COMPATIBILITY IDEOGRAPH-F9CD */
+ {0xf9ce, 1, 4065}, /* CJK COMPATIBILITY IDEOGRAPH-F9CE */
+ {0xf9cf, 1, 4066}, /* CJK COMPATIBILITY IDEOGRAPH-F9CF */
+ {0xf9d0, 1, 4067}, /* CJK COMPATIBILITY IDEOGRAPH-F9D0 */
+ {0xf9d1, 1, 2950}, /* CJK COMPATIBILITY IDEOGRAPH-F9D1 */
+ {0xf9d2, 1, 4068}, /* CJK COMPATIBILITY IDEOGRAPH-F9D2 */
+ {0xf9d3, 1, 4069}, /* CJK COMPATIBILITY IDEOGRAPH-F9D3 */
+ {0xf9d4, 1, 4070}, /* CJK COMPATIBILITY IDEOGRAPH-F9D4 */
+ {0xf9d5, 1, 4071}, /* CJK COMPATIBILITY IDEOGRAPH-F9D5 */
+ {0xf9d6, 1, 4072}, /* CJK COMPATIBILITY IDEOGRAPH-F9D6 */
+ {0xf9d7, 1, 4073}, /* CJK COMPATIBILITY IDEOGRAPH-F9D7 */
+ {0xf9d8, 1, 4074}, /* CJK COMPATIBILITY IDEOGRAPH-F9D8 */
+ {0xf9d9, 1, 4075}, /* CJK COMPATIBILITY IDEOGRAPH-F9D9 */
+ {0xf9da, 1, 4076}, /* CJK COMPATIBILITY IDEOGRAPH-F9DA */
+ {0xf9db, 1, 3963}, /* CJK COMPATIBILITY IDEOGRAPH-F9DB */
+ {0xf9dc, 1, 4077}, /* CJK COMPATIBILITY IDEOGRAPH-F9DC */
+ {0xf9dd, 1, 4078}, /* CJK COMPATIBILITY IDEOGRAPH-F9DD */
+ {0xf9de, 1, 4079}, /* CJK COMPATIBILITY IDEOGRAPH-F9DE */
+ {0xf9df, 1, 4080}, /* CJK COMPATIBILITY IDEOGRAPH-F9DF */
+ {0xf9e0, 1, 4081}, /* CJK COMPATIBILITY IDEOGRAPH-F9E0 */
+ {0xf9e1, 1, 4082}, /* CJK COMPATIBILITY IDEOGRAPH-F9E1 */
+ {0xf9e2, 1, 4083}, /* CJK COMPATIBILITY IDEOGRAPH-F9E2 */
+ {0xf9e3, 1, 4084}, /* CJK COMPATIBILITY IDEOGRAPH-F9E3 */
+ {0xf9e4, 1, 4085}, /* CJK COMPATIBILITY IDEOGRAPH-F9E4 */
+ {0xf9e5, 1, 4086}, /* CJK COMPATIBILITY IDEOGRAPH-F9E5 */
+ {0xf9e6, 1, 4087}, /* CJK COMPATIBILITY IDEOGRAPH-F9E6 */
+ {0xf9e7, 1, 4088}, /* CJK COMPATIBILITY IDEOGRAPH-F9E7 */
+ {0xf9e8, 1, 4089}, /* CJK COMPATIBILITY IDEOGRAPH-F9E8 */
+ {0xf9e9, 1, 2538}, /* CJK COMPATIBILITY IDEOGRAPH-F9E9 */
+ {0xf9ea, 1, 4090}, /* CJK COMPATIBILITY IDEOGRAPH-F9EA */
+ {0xf9eb, 1, 4091}, /* CJK COMPATIBILITY IDEOGRAPH-F9EB */
+ {0xf9ec, 1, 4092}, /* CJK COMPATIBILITY IDEOGRAPH-F9EC */
+ {0xf9ed, 1, 4093}, /* CJK COMPATIBILITY IDEOGRAPH-F9ED */
+ {0xf9ee, 1, 4094}, /* CJK COMPATIBILITY IDEOGRAPH-F9EE */
+ {0xf9ef, 1, 4095}, /* CJK COMPATIBILITY IDEOGRAPH-F9EF */
+ {0xf9f0, 1, 4096}, /* CJK COMPATIBILITY IDEOGRAPH-F9F0 */
+ {0xf9f1, 1, 4097}, /* CJK COMPATIBILITY IDEOGRAPH-F9F1 */
+ {0xf9f2, 1, 4098}, /* CJK COMPATIBILITY IDEOGRAPH-F9F2 */
+ {0xf9f3, 1, 4099}, /* CJK COMPATIBILITY IDEOGRAPH-F9F3 */
+ {0xf9f4, 1, 4100}, /* CJK COMPATIBILITY IDEOGRAPH-F9F4 */
+ {0xf9f5, 1, 4101}, /* CJK COMPATIBILITY IDEOGRAPH-F9F5 */
+ {0xf9f6, 1, 4102}, /* CJK COMPATIBILITY IDEOGRAPH-F9F6 */
+ {0xf9f7, 1, 2489}, /* CJK COMPATIBILITY IDEOGRAPH-F9F7 */
+ {0xf9f8, 1, 4103}, /* CJK COMPATIBILITY IDEOGRAPH-F9F8 */
+ {0xf9f9, 1, 4104}, /* CJK COMPATIBILITY IDEOGRAPH-F9F9 */
+ {0xf9fa, 1, 4105}, /* CJK COMPATIBILITY IDEOGRAPH-F9FA */
+ {0xf9fb, 1, 4106}, /* CJK COMPATIBILITY IDEOGRAPH-F9FB */
+ {0xf9fc, 1, 4107}, /* CJK COMPATIBILITY IDEOGRAPH-F9FC */
+ {0xf9fd, 1, 4108}, /* CJK COMPATIBILITY IDEOGRAPH-F9FD */
+ {0xf9fe, 1, 4109}, /* CJK COMPATIBILITY IDEOGRAPH-F9FE */
+ {0xf9ff, 1, 4110}, /* CJK COMPATIBILITY IDEOGRAPH-F9FF */
+ {0xfa00, 1, 4111}, /* CJK COMPATIBILITY IDEOGRAPH-FA00 */
+ {0xfa01, 1, 4112}, /* CJK COMPATIBILITY IDEOGRAPH-FA01 */
+ {0xfa02, 1, 4113}, /* CJK COMPATIBILITY IDEOGRAPH-FA02 */
+ {0xfa03, 1, 4114}, /* CJK COMPATIBILITY IDEOGRAPH-FA03 */
+ {0xfa04, 1, 4115}, /* CJK COMPATIBILITY IDEOGRAPH-FA04 */
+ {0xfa05, 1, 4116}, /* CJK COMPATIBILITY IDEOGRAPH-FA05 */
+ {0xfa06, 1, 4117}, /* CJK COMPATIBILITY IDEOGRAPH-FA06 */
+ {0xfa07, 1, 4118}, /* CJK COMPATIBILITY IDEOGRAPH-FA07 */
+ {0xfa08, 1, 2516}, /* CJK COMPATIBILITY IDEOGRAPH-FA08 */
+ {0xfa09, 1, 4119}, /* CJK COMPATIBILITY IDEOGRAPH-FA09 */
+ {0xfa0a, 1, 2519}, /* CJK COMPATIBILITY IDEOGRAPH-FA0A */
+ {0xfa0b, 1, 4120}, /* CJK COMPATIBILITY IDEOGRAPH-FA0B */
+ {0xfa0c, 1, 4121}, /* CJK COMPATIBILITY IDEOGRAPH-FA0C */
+ {0xfa0d, 1, 4122}, /* CJK COMPATIBILITY IDEOGRAPH-FA0D */
+ {0xfa10, 1, 4123}, /* CJK COMPATIBILITY IDEOGRAPH-FA10 */
+ {0xfa12, 1, 4124}, /* CJK COMPATIBILITY IDEOGRAPH-FA12 */
+ {0xfa15, 1, 4125}, /* CJK COMPATIBILITY IDEOGRAPH-FA15 */
+ {0xfa16, 1, 4126}, /* CJK COMPATIBILITY IDEOGRAPH-FA16 */
+ {0xfa17, 1, 4127}, /* CJK COMPATIBILITY IDEOGRAPH-FA17 */
+ {0xfa18, 1, 4128}, /* CJK COMPATIBILITY IDEOGRAPH-FA18 */
+ {0xfa19, 1, 4129}, /* CJK COMPATIBILITY IDEOGRAPH-FA19 */
+ {0xfa1a, 1, 4130}, /* CJK COMPATIBILITY IDEOGRAPH-FA1A */
+ {0xfa1b, 1, 4131}, /* CJK COMPATIBILITY IDEOGRAPH-FA1B */
+ {0xfa1c, 1, 4132}, /* CJK COMPATIBILITY IDEOGRAPH-FA1C */
+ {0xfa1d, 1, 4133}, /* CJK COMPATIBILITY IDEOGRAPH-FA1D */
+ {0xfa1e, 1, 2496}, /* CJK COMPATIBILITY IDEOGRAPH-FA1E */
+ {0xfa20, 1, 4134}, /* CJK COMPATIBILITY IDEOGRAPH-FA20 */
+ {0xfa22, 1, 4135}, /* CJK COMPATIBILITY IDEOGRAPH-FA22 */
+ {0xfa25, 1, 4136}, /* CJK COMPATIBILITY IDEOGRAPH-FA25 */
+ {0xfa26, 1, 4137}, /* CJK COMPATIBILITY IDEOGRAPH-FA26 */
+ {0xfa2a, 1, 4138}, /* CJK COMPATIBILITY IDEOGRAPH-FA2A */
+ {0xfa2b, 1, 4139}, /* CJK COMPATIBILITY IDEOGRAPH-FA2B */
+ {0xfa2c, 1, 4140}, /* CJK COMPATIBILITY IDEOGRAPH-FA2C */
+ {0xfa2d, 1, 4141}, /* CJK COMPATIBILITY IDEOGRAPH-FA2D */
+ {0xfa30, 1, 4142}, /* CJK COMPATIBILITY IDEOGRAPH-FA30 */
+ {0xfa31, 1, 4143}, /* CJK COMPATIBILITY IDEOGRAPH-FA31 */
+ {0xfa32, 1, 4144}, /* CJK COMPATIBILITY IDEOGRAPH-FA32 */
+ {0xfa33, 1, 4145}, /* CJK COMPATIBILITY IDEOGRAPH-FA33 */
+ {0xfa34, 1, 4146}, /* CJK COMPATIBILITY IDEOGRAPH-FA34 */
+ {0xfa35, 1, 4147}, /* CJK COMPATIBILITY IDEOGRAPH-FA35 */
+ {0xfa36, 1, 4148}, /* CJK COMPATIBILITY IDEOGRAPH-FA36 */
+ {0xfa37, 1, 4149}, /* CJK COMPATIBILITY IDEOGRAPH-FA37 */
+ {0xfa38, 1, 4150}, /* CJK COMPATIBILITY IDEOGRAPH-FA38 */
+ {0xfa39, 1, 4151}, /* CJK COMPATIBILITY IDEOGRAPH-FA39 */
+ {0xfa3a, 1, 4152}, /* CJK COMPATIBILITY IDEOGRAPH-FA3A */
+ {0xfa3b, 1, 4153}, /* CJK COMPATIBILITY IDEOGRAPH-FA3B */
+ {0xfa3c, 1, 2417}, /* CJK COMPATIBILITY IDEOGRAPH-FA3C */
+ {0xfa3d, 1, 4154}, /* CJK COMPATIBILITY IDEOGRAPH-FA3D */
+ {0xfa3e, 1, 4155}, /* CJK COMPATIBILITY IDEOGRAPH-FA3E */
+ {0xfa3f, 1, 4156}, /* CJK COMPATIBILITY IDEOGRAPH-FA3F */
+ {0xfa40, 1, 4157}, /* CJK COMPATIBILITY IDEOGRAPH-FA40 */
+ {0xfa41, 1, 4158}, /* CJK COMPATIBILITY IDEOGRAPH-FA41 */
+ {0xfa42, 1, 4159}, /* CJK COMPATIBILITY IDEOGRAPH-FA42 */
+ {0xfa43, 1, 4160}, /* CJK COMPATIBILITY IDEOGRAPH-FA43 */
+ {0xfa44, 1, 4161}, /* CJK COMPATIBILITY IDEOGRAPH-FA44 */
+ {0xfa45, 1, 4162}, /* CJK COMPATIBILITY IDEOGRAPH-FA45 */
+ {0xfa46, 1, 4163}, /* CJK COMPATIBILITY IDEOGRAPH-FA46 */
+ {0xfa47, 1, 4164}, /* CJK COMPATIBILITY IDEOGRAPH-FA47 */
+ {0xfa48, 1, 4165}, /* CJK COMPATIBILITY IDEOGRAPH-FA48 */
+ {0xfa49, 1, 4166}, /* CJK COMPATIBILITY IDEOGRAPH-FA49 */
+ {0xfa4a, 1, 4167}, /* CJK COMPATIBILITY IDEOGRAPH-FA4A */
+ {0xfa4b, 1, 4168}, /* CJK COMPATIBILITY IDEOGRAPH-FA4B */
+ {0xfa4c, 1, 2992}, /* CJK COMPATIBILITY IDEOGRAPH-FA4C */
+ {0xfa4d, 1, 4169}, /* CJK COMPATIBILITY IDEOGRAPH-FA4D */
+ {0xfa4e, 1, 4170}, /* CJK COMPATIBILITY IDEOGRAPH-FA4E */
+ {0xfa4f, 1, 4171}, /* CJK COMPATIBILITY IDEOGRAPH-FA4F */
+ {0xfa50, 1, 4172}, /* CJK COMPATIBILITY IDEOGRAPH-FA50 */
+ {0xfa51, 1, 3004}, /* CJK COMPATIBILITY IDEOGRAPH-FA51 */
+ {0xfa52, 1, 4173}, /* CJK COMPATIBILITY IDEOGRAPH-FA52 */
+ {0xfa53, 1, 4174}, /* CJK COMPATIBILITY IDEOGRAPH-FA53 */
+ {0xfa54, 1, 4175}, /* CJK COMPATIBILITY IDEOGRAPH-FA54 */
+ {0xfa55, 1, 4176}, /* CJK COMPATIBILITY IDEOGRAPH-FA55 */
+ {0xfa56, 1, 4177}, /* CJK COMPATIBILITY IDEOGRAPH-FA56 */
+ {0xfa57, 1, 4013}, /* CJK COMPATIBILITY IDEOGRAPH-FA57 */
+ {0xfa58, 1, 4178}, /* CJK COMPATIBILITY IDEOGRAPH-FA58 */
+ {0xfa59, 1, 4179}, /* CJK COMPATIBILITY IDEOGRAPH-FA59 */
+ {0xfa5a, 1, 4180}, /* CJK COMPATIBILITY IDEOGRAPH-FA5A */
+ {0xfa5b, 1, 4181}, /* CJK COMPATIBILITY IDEOGRAPH-FA5B */
+ {0xfa5c, 1, 4182}, /* CJK COMPATIBILITY IDEOGRAPH-FA5C */
+ {0xfa5d, 1, 4183}, /* CJK COMPATIBILITY IDEOGRAPH-FA5D */
+ {0xfa5e, 1, 4183}, /* CJK COMPATIBILITY IDEOGRAPH-FA5E */
+ {0xfa5f, 1, 4184}, /* CJK COMPATIBILITY IDEOGRAPH-FA5F */
+ {0xfa60, 1, 4185}, /* CJK COMPATIBILITY IDEOGRAPH-FA60 */
+ {0xfa61, 1, 4186}, /* CJK COMPATIBILITY IDEOGRAPH-FA61 */
+ {0xfa62, 1, 4187}, /* CJK COMPATIBILITY IDEOGRAPH-FA62 */
+ {0xfa63, 1, 4188}, /* CJK COMPATIBILITY IDEOGRAPH-FA63 */
+ {0xfa64, 1, 4189}, /* CJK COMPATIBILITY IDEOGRAPH-FA64 */
+ {0xfa65, 1, 4190}, /* CJK COMPATIBILITY IDEOGRAPH-FA65 */
+ {0xfa66, 1, 4191}, /* CJK COMPATIBILITY IDEOGRAPH-FA66 */
+ {0xfa67, 1, 4136}, /* CJK COMPATIBILITY IDEOGRAPH-FA67 */
+ {0xfa68, 1, 4192}, /* CJK COMPATIBILITY IDEOGRAPH-FA68 */
+ {0xfa69, 1, 4193}, /* CJK COMPATIBILITY IDEOGRAPH-FA69 */
+ {0xfa6a, 1, 4194}, /* CJK COMPATIBILITY IDEOGRAPH-FA6A */
+ {0xfb00, 2, 4195}, /* LATIN SMALL LIGATURE FF */
+ {0xfb01, 2, 4197}, /* LATIN SMALL LIGATURE FI */
+ {0xfb02, 2, 4199}, /* LATIN SMALL LIGATURE FL */
+ {0xfb03, 3, 4196}, /* LATIN SMALL LIGATURE FFI */
+ {0xfb04, 3, 4201}, /* LATIN SMALL LIGATURE FFL */
+ {0xfb05, 2, 4204}, /* LATIN SMALL LIGATURE LONG S T */
+ {0xfb06, 2, 4206}, /* LATIN SMALL LIGATURE ST */
+ {0xfb13, 2, 4208}, /* ARMENIAN SMALL LIGATURE MEN NOW */
+ {0xfb14, 2, 4210}, /* ARMENIAN SMALL LIGATURE MEN ECH */
+ {0xfb15, 2, 4212}, /* ARMENIAN SMALL LIGATURE MEN INI */
+ {0xfb16, 2, 4214}, /* ARMENIAN SMALL LIGATURE VEW NOW */
+ {0xfb17, 2, 4216}, /* ARMENIAN SMALL LIGATURE MEN XEH */
+ {0xfb1d, 2, 4218}, /* HEBREW LETTER YOD WITH HIRIQ */
+ {0xfb1f, 2, 4220}, /* HEBREW LIGATURE YIDDISH YOD YOD PATAH */
+ {0xfb20, 1, 4222}, /* HEBREW LETTER ALTERNATIVE AYIN */
+ {0xfb21, 1, 1950}, /* HEBREW LETTER WIDE ALEF */
+ {0xfb22, 1, 1953}, /* HEBREW LETTER WIDE DALET */
+ {0xfb23, 1, 4223}, /* HEBREW LETTER WIDE HE */
+ {0xfb24, 1, 4224}, /* HEBREW LETTER WIDE KAF */
+ {0xfb25, 1, 4225}, /* HEBREW LETTER WIDE LAMED */
+ {0xfb26, 1, 4226}, /* HEBREW LETTER WIDE FINAL MEM */
+ {0xfb27, 1, 4227}, /* HEBREW LETTER WIDE RESH */
+ {0xfb28, 1, 4228}, /* HEBREW LETTER WIDE TAV */
+ {0xfb29, 1, 1915}, /* HEBREW LETTER ALTERNATIVE PLUS SIGN */
+ {0xfb2a, 2, 4229}, /* HEBREW LETTER SHIN WITH SHIN DOT */
+ {0xfb2b, 2, 4231}, /* HEBREW LETTER SHIN WITH SIN DOT */
+ {0xfb2c, 2, 4233}, /* HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT */
+ {0xfb2d, 2, 4235}, /* HEBREW LETTER SHIN WITH DAGESH AND SIN DOT */
+ {0xfb2e, 2, 4237}, /* HEBREW LETTER ALEF WITH PATAH */
+ {0xfb2f, 2, 4239}, /* HEBREW LETTER ALEF WITH QAMATS */
+ {0xfb30, 2, 4241}, /* HEBREW LETTER ALEF WITH MAPIQ */
+ {0xfb31, 2, 4243}, /* HEBREW LETTER BET WITH DAGESH */
+ {0xfb32, 2, 4245}, /* HEBREW LETTER GIMEL WITH DAGESH */
+ {0xfb33, 2, 4247}, /* HEBREW LETTER DALET WITH DAGESH */
+ {0xfb34, 2, 4249}, /* HEBREW LETTER HE WITH MAPIQ */
+ {0xfb35, 2, 4251}, /* HEBREW LETTER VAV WITH DAGESH */
+ {0xfb36, 2, 4253}, /* HEBREW LETTER ZAYIN WITH DAGESH */
+ {0xfb38, 2, 4255}, /* HEBREW LETTER TET WITH DAGESH */
+ {0xfb39, 2, 4257}, /* HEBREW LETTER YOD WITH DAGESH */
+ {0xfb3a, 2, 4259}, /* HEBREW LETTER FINAL KAF WITH DAGESH */
+ {0xfb3b, 2, 4261}, /* HEBREW LETTER KAF WITH DAGESH */
+ {0xfb3c, 2, 4263}, /* HEBREW LETTER LAMED WITH DAGESH */
+ {0xfb3e, 2, 4265}, /* HEBREW LETTER MEM WITH DAGESH */
+ {0xfb40, 2, 4267}, /* HEBREW LETTER NUN WITH DAGESH */
+ {0xfb41, 2, 4269}, /* HEBREW LETTER SAMEKH WITH DAGESH */
+ {0xfb43, 2, 4271}, /* HEBREW LETTER FINAL PE WITH DAGESH */
+ {0xfb44, 2, 4273}, /* HEBREW LETTER PE WITH DAGESH */
+ {0xfb46, 2, 4275}, /* HEBREW LETTER TSADI WITH DAGESH */
+ {0xfb47, 2, 4277}, /* HEBREW LETTER QOF WITH DAGESH */
+ {0xfb48, 2, 4279}, /* HEBREW LETTER RESH WITH DAGESH */
+ {0xfb49, 2, 4281}, /* HEBREW LETTER SHIN WITH DAGESH */
+ {0xfb4a, 2, 4283}, /* HEBREW LETTER TAV WITH DAGESH */
+ {0xfb4b, 2, 4285}, /* HEBREW LETTER VAV WITH HOLAM */
+ {0xfb4c, 2, 4287}, /* HEBREW LETTER BET WITH RAFE */
+ {0xfb4d, 2, 4289}, /* HEBREW LETTER KAF WITH RAFE */
+ {0xfb4e, 2, 4291}, /* HEBREW LETTER PE WITH RAFE */
+ {0xfb4f, 2, 4293}, /* HEBREW LIGATURE ALEF LAMED */
+ {0xfb50, 1, 4295}, /* ARABIC LETTER ALEF WASLA ISOLATED FORM */
+ {0xfb51, 1, 4295}, /* ARABIC LETTER ALEF WASLA FINAL FORM */
+ {0xfb52, 1, 4296}, /* ARABIC LETTER BEEH ISOLATED FORM */
+ {0xfb53, 1, 4296}, /* ARABIC LETTER BEEH FINAL FORM */
+ {0xfb54, 1, 4296}, /* ARABIC LETTER BEEH INITIAL FORM */
+ {0xfb55, 1, 4296}, /* ARABIC LETTER BEEH MEDIAL FORM */
+ {0xfb56, 1, 4297}, /* ARABIC LETTER PEH ISOLATED FORM */
+ {0xfb57, 1, 4297}, /* ARABIC LETTER PEH FINAL FORM */
+ {0xfb58, 1, 4297}, /* ARABIC LETTER PEH INITIAL FORM */
+ {0xfb59, 1, 4297}, /* ARABIC LETTER PEH MEDIAL FORM */
+ {0xfb5a, 1, 4298}, /* ARABIC LETTER BEHEH ISOLATED FORM */
+ {0xfb5b, 1, 4298}, /* ARABIC LETTER BEHEH FINAL FORM */
+ {0xfb5c, 1, 4298}, /* ARABIC LETTER BEHEH INITIAL FORM */
+ {0xfb5d, 1, 4298}, /* ARABIC LETTER BEHEH MEDIAL FORM */
+ {0xfb5e, 1, 4299}, /* ARABIC LETTER TTEHEH ISOLATED FORM */
+ {0xfb5f, 1, 4299}, /* ARABIC LETTER TTEHEH FINAL FORM */
+ {0xfb60, 1, 4299}, /* ARABIC LETTER TTEHEH INITIAL FORM */
+ {0xfb61, 1, 4299}, /* ARABIC LETTER TTEHEH MEDIAL FORM */
+ {0xfb62, 1, 4300}, /* ARABIC LETTER TEHEH ISOLATED FORM */
+ {0xfb63, 1, 4300}, /* ARABIC LETTER TEHEH FINAL FORM */
+ {0xfb64, 1, 4300}, /* ARABIC LETTER TEHEH INITIAL FORM */
+ {0xfb65, 1, 4300}, /* ARABIC LETTER TEHEH MEDIAL FORM */
+ {0xfb66, 1, 4301}, /* ARABIC LETTER TTEH ISOLATED FORM */
+ {0xfb67, 1, 4301}, /* ARABIC LETTER TTEH FINAL FORM */
+ {0xfb68, 1, 4301}, /* ARABIC LETTER TTEH INITIAL FORM */
+ {0xfb69, 1, 4301}, /* ARABIC LETTER TTEH MEDIAL FORM */
+ {0xfb6a, 1, 4302}, /* ARABIC LETTER VEH ISOLATED FORM */
+ {0xfb6b, 1, 4302}, /* ARABIC LETTER VEH FINAL FORM */
+ {0xfb6c, 1, 4302}, /* ARABIC LETTER VEH INITIAL FORM */
+ {0xfb6d, 1, 4302}, /* ARABIC LETTER VEH MEDIAL FORM */
+ {0xfb6e, 1, 4303}, /* ARABIC LETTER PEHEH ISOLATED FORM */
+ {0xfb6f, 1, 4303}, /* ARABIC LETTER PEHEH FINAL FORM */
+ {0xfb70, 1, 4303}, /* ARABIC LETTER PEHEH INITIAL FORM */
+ {0xfb71, 1, 4303}, /* ARABIC LETTER PEHEH MEDIAL FORM */
+ {0xfb72, 1, 4304}, /* ARABIC LETTER DYEH ISOLATED FORM */
+ {0xfb73, 1, 4304}, /* ARABIC LETTER DYEH FINAL FORM */
+ {0xfb74, 1, 4304}, /* ARABIC LETTER DYEH INITIAL FORM */
+ {0xfb75, 1, 4304}, /* ARABIC LETTER DYEH MEDIAL FORM */
+ {0xfb76, 1, 4305}, /* ARABIC LETTER NYEH ISOLATED FORM */
+ {0xfb77, 1, 4305}, /* ARABIC LETTER NYEH FINAL FORM */
+ {0xfb78, 1, 4305}, /* ARABIC LETTER NYEH INITIAL FORM */
+ {0xfb79, 1, 4305}, /* ARABIC LETTER NYEH MEDIAL FORM */
+ {0xfb7a, 1, 4306}, /* ARABIC LETTER TCHEH ISOLATED FORM */
+ {0xfb7b, 1, 4306}, /* ARABIC LETTER TCHEH FINAL FORM */
+ {0xfb7c, 1, 4306}, /* ARABIC LETTER TCHEH INITIAL FORM */
+ {0xfb7d, 1, 4306}, /* ARABIC LETTER TCHEH MEDIAL FORM */
+ {0xfb7e, 1, 4307}, /* ARABIC LETTER TCHEHEH ISOLATED FORM */
+ {0xfb7f, 1, 4307}, /* ARABIC LETTER TCHEHEH FINAL FORM */
+ {0xfb80, 1, 4307}, /* ARABIC LETTER TCHEHEH INITIAL FORM */
+ {0xfb81, 1, 4307}, /* ARABIC LETTER TCHEHEH MEDIAL FORM */
+ {0xfb82, 1, 4308}, /* ARABIC LETTER DDAHAL ISOLATED FORM */
+ {0xfb83, 1, 4308}, /* ARABIC LETTER DDAHAL FINAL FORM */
+ {0xfb84, 1, 4309}, /* ARABIC LETTER DAHAL ISOLATED FORM */
+ {0xfb85, 1, 4309}, /* ARABIC LETTER DAHAL FINAL FORM */
+ {0xfb86, 1, 4310}, /* ARABIC LETTER DUL ISOLATED FORM */
+ {0xfb87, 1, 4310}, /* ARABIC LETTER DUL FINAL FORM */
+ {0xfb88, 1, 4311}, /* ARABIC LETTER DDAL ISOLATED FORM */
+ {0xfb89, 1, 4311}, /* ARABIC LETTER DDAL FINAL FORM */
+ {0xfb8a, 1, 4312}, /* ARABIC LETTER JEH ISOLATED FORM */
+ {0xfb8b, 1, 4312}, /* ARABIC LETTER JEH FINAL FORM */
+ {0xfb8c, 1, 4313}, /* ARABIC LETTER RREH ISOLATED FORM */
+ {0xfb8d, 1, 4313}, /* ARABIC LETTER RREH FINAL FORM */
+ {0xfb8e, 1, 4314}, /* ARABIC LETTER KEHEH ISOLATED FORM */
+ {0xfb8f, 1, 4314}, /* ARABIC LETTER KEHEH FINAL FORM */
+ {0xfb90, 1, 4314}, /* ARABIC LETTER KEHEH INITIAL FORM */
+ {0xfb91, 1, 4314}, /* ARABIC LETTER KEHEH MEDIAL FORM */
+ {0xfb92, 1, 4315}, /* ARABIC LETTER GAF ISOLATED FORM */
+ {0xfb93, 1, 4315}, /* ARABIC LETTER GAF FINAL FORM */
+ {0xfb94, 1, 4315}, /* ARABIC LETTER GAF INITIAL FORM */
+ {0xfb95, 1, 4315}, /* ARABIC LETTER GAF MEDIAL FORM */
+ {0xfb96, 1, 4316}, /* ARABIC LETTER GUEH ISOLATED FORM */
+ {0xfb97, 1, 4316}, /* ARABIC LETTER GUEH FINAL FORM */
+ {0xfb98, 1, 4316}, /* ARABIC LETTER GUEH INITIAL FORM */
+ {0xfb99, 1, 4316}, /* ARABIC LETTER GUEH MEDIAL FORM */
+ {0xfb9a, 1, 4317}, /* ARABIC LETTER NGOEH ISOLATED FORM */
+ {0xfb9b, 1, 4317}, /* ARABIC LETTER NGOEH FINAL FORM */
+ {0xfb9c, 1, 4317}, /* ARABIC LETTER NGOEH INITIAL FORM */
+ {0xfb9d, 1, 4317}, /* ARABIC LETTER NGOEH MEDIAL FORM */
+ {0xfb9e, 1, 4318}, /* ARABIC LETTER NOON GHUNNA ISOLATED FORM */
+ {0xfb9f, 1, 4318}, /* ARABIC LETTER NOON GHUNNA FINAL FORM */
+ {0xfba0, 1, 4319}, /* ARABIC LETTER RNOON ISOLATED FORM */
+ {0xfba1, 1, 4319}, /* ARABIC LETTER RNOON FINAL FORM */
+ {0xfba2, 1, 4319}, /* ARABIC LETTER RNOON INITIAL FORM */
+ {0xfba3, 1, 4319}, /* ARABIC LETTER RNOON MEDIAL FORM */
+ {0xfba4, 1, 4320}, /* ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM */
+ {0xfba5, 1, 4320}, /* ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM */
+ {0xfba6, 1, 769}, /* ARABIC LETTER HEH GOAL ISOLATED FORM */
+ {0xfba7, 1, 769}, /* ARABIC LETTER HEH GOAL FINAL FORM */
+ {0xfba8, 1, 769}, /* ARABIC LETTER HEH GOAL INITIAL FORM */
+ {0xfba9, 1, 769}, /* ARABIC LETTER HEH GOAL MEDIAL FORM */
+ {0xfbaa, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM */
+ {0xfbab, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE FINAL FORM */
+ {0xfbac, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE INITIAL FORM */
+ {0xfbad, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM */
+ {0xfbae, 1, 771}, /* ARABIC LETTER YEH BARREE ISOLATED FORM */
+ {0xfbaf, 1, 771}, /* ARABIC LETTER YEH BARREE FINAL FORM */
+ {0xfbb0, 1, 4322}, /* ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM */
+ {0xfbb1, 1, 4322}, /* ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM */
+ {0xfbd3, 1, 4323}, /* ARABIC LETTER NG ISOLATED FORM */
+ {0xfbd4, 1, 4323}, /* ARABIC LETTER NG FINAL FORM */
+ {0xfbd5, 1, 4323}, /* ARABIC LETTER NG INITIAL FORM */
+ {0xfbd6, 1, 4323}, /* ARABIC LETTER NG MEDIAL FORM */
+ {0xfbd7, 1, 763}, /* ARABIC LETTER U ISOLATED FORM */
+ {0xfbd8, 1, 763}, /* ARABIC LETTER U FINAL FORM */
+ {0xfbd9, 1, 4324}, /* ARABIC LETTER OE ISOLATED FORM */
+ {0xfbda, 1, 4324}, /* ARABIC LETTER OE FINAL FORM */
+ {0xfbdb, 1, 4325}, /* ARABIC LETTER YU ISOLATED FORM */
+ {0xfbdc, 1, 4325}, /* ARABIC LETTER YU FINAL FORM */
+ {0xfbdd, 1, 4326}, /* ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */
+ {0xfbde, 1, 4327}, /* ARABIC LETTER VE ISOLATED FORM */
+ {0xfbdf, 1, 4327}, /* ARABIC LETTER VE FINAL FORM */
+ {0xfbe0, 1, 4328}, /* ARABIC LETTER KIRGHIZ OE ISOLATED FORM */
+ {0xfbe1, 1, 4328}, /* ARABIC LETTER KIRGHIZ OE FINAL FORM */
+ {0xfbe2, 1, 4329}, /* ARABIC LETTER KIRGHIZ YU ISOLATED FORM */
+ {0xfbe3, 1, 4329}, /* ARABIC LETTER KIRGHIZ YU FINAL FORM */
+ {0xfbe4, 1, 4330}, /* ARABIC LETTER E ISOLATED FORM */
+ {0xfbe5, 1, 4330}, /* ARABIC LETTER E FINAL FORM */
+ {0xfbe6, 1, 4330}, /* ARABIC LETTER E INITIAL FORM */
+ {0xfbe7, 1, 4330}, /* ARABIC LETTER E MEDIAL FORM */
+ {0xfbe8, 1, 4331}, /* ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM */
+ {0xfbe9, 1, 4331}, /* ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM */
+ {0xfbea, 2, 4332}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM */
+ {0xfbeb, 2, 4332}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM */
+ {0xfbec, 2, 4334}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM */
+ {0xfbed, 2, 4334}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM */
+ {0xfbee, 2, 4336}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM */
+ {0xfbef, 2, 4336}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM */
+ {0xfbf0, 2, 4338}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM */
+ {0xfbf1, 2, 4338}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM */
+ {0xfbf2, 2, 4340}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM */
+ {0xfbf3, 2, 4340}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM */
+ {0xfbf4, 2, 4342}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM */
+ {0xfbf5, 2, 4342}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM */
+ {0xfbf6, 2, 4344}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM */
+ {0xfbf7, 2, 4344}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM */
+ {0xfbf8, 2, 4344}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM */
+ {0xfbf9, 2, 4346}, /* ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfbfa, 2, 4346}, /* ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM */
+ {0xfbfb, 2, 4346}, /* ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM */
+ {0xfbfc, 1, 4348}, /* ARABIC LETTER FARSI YEH ISOLATED FORM */
+ {0xfbfd, 1, 4348}, /* ARABIC LETTER FARSI YEH FINAL FORM */
+ {0xfbfe, 1, 4348}, /* ARABIC LETTER FARSI YEH INITIAL FORM */
+ {0xfbff, 1, 4348}, /* ARABIC LETTER FARSI YEH MEDIAL FORM */
+ {0xfc00, 2, 4349}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM */
+ {0xfc01, 2, 4351}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM */
+ {0xfc02, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM */
+ {0xfc03, 2, 4346}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc04, 2, 4355}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM */
+ {0xfc05, 2, 4357}, /* ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM */
+ {0xfc06, 2, 4359}, /* ARABIC LIGATURE BEH WITH HAH ISOLATED FORM */
+ {0xfc07, 2, 4361}, /* ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM */
+ {0xfc08, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM */
+ {0xfc09, 2, 4365}, /* ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc0a, 2, 4367}, /* ARABIC LIGATURE BEH WITH YEH ISOLATED FORM */
+ {0xfc0b, 2, 4369}, /* ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM */
+ {0xfc0c, 2, 4371}, /* ARABIC LIGATURE TEH WITH HAH ISOLATED FORM */
+ {0xfc0d, 2, 4373}, /* ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM */
+ {0xfc0e, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM */
+ {0xfc0f, 2, 4377}, /* ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc10, 2, 4379}, /* ARABIC LIGATURE TEH WITH YEH ISOLATED FORM */
+ {0xfc11, 2, 4381}, /* ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM */
+ {0xfc12, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM */
+ {0xfc13, 2, 4385}, /* ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc14, 2, 4387}, /* ARABIC LIGATURE THEH WITH YEH ISOLATED FORM */
+ {0xfc15, 2, 4389}, /* ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM */
+ {0xfc16, 2, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM */
+ {0xfc17, 2, 4390}, /* ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM */
+ {0xfc18, 2, 4393}, /* ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM */
+ {0xfc19, 2, 4395}, /* ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM */
+ {0xfc1a, 2, 4397}, /* ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM */
+ {0xfc1b, 2, 4399}, /* ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM */
+ {0xfc1c, 2, 4401}, /* ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM */
+ {0xfc1d, 2, 4403}, /* ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM */
+ {0xfc1e, 2, 4405}, /* ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM */
+ {0xfc1f, 2, 4407}, /* ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM */
+ {0xfc20, 2, 4409}, /* ARABIC LIGATURE SAD WITH HAH ISOLATED FORM */
+ {0xfc21, 2, 4411}, /* ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM */
+ {0xfc22, 2, 4413}, /* ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM */
+ {0xfc23, 2, 4415}, /* ARABIC LIGATURE DAD WITH HAH ISOLATED FORM */
+ {0xfc24, 2, 4417}, /* ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM */
+ {0xfc25, 2, 4419}, /* ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM */
+ {0xfc26, 2, 4421}, /* ARABIC LIGATURE TAH WITH HAH ISOLATED FORM */
+ {0xfc27, 2, 4423}, /* ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM */
+ {0xfc28, 2, 4425}, /* ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM */
+ {0xfc29, 2, 4427}, /* ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM */
+ {0xfc2a, 2, 4429}, /* ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM */
+ {0xfc2b, 2, 4431}, /* ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM */
+ {0xfc2c, 2, 4433}, /* ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM */
+ {0xfc2d, 2, 4435}, /* ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM */
+ {0xfc2e, 2, 4437}, /* ARABIC LIGATURE FEH WITH HAH ISOLATED FORM */
+ {0xfc2f, 2, 4439}, /* ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM */
+ {0xfc30, 2, 4441}, /* ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM */
+ {0xfc31, 2, 4443}, /* ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc32, 2, 4445}, /* ARABIC LIGATURE FEH WITH YEH ISOLATED FORM */
+ {0xfc33, 2, 4447}, /* ARABIC LIGATURE QAF WITH HAH ISOLATED FORM */
+ {0xfc34, 2, 4449}, /* ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM */
+ {0xfc35, 2, 4451}, /* ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc36, 2, 4453}, /* ARABIC LIGATURE QAF WITH YEH ISOLATED FORM */
+ {0xfc37, 2, 4455}, /* ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM */
+ {0xfc38, 2, 4457}, /* ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM */
+ {0xfc39, 2, 4459}, /* ARABIC LIGATURE KAF WITH HAH ISOLATED FORM */
+ {0xfc3a, 2, 4461}, /* ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM */
+ {0xfc3b, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM ISOLATED FORM */
+ {0xfc3c, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM */
+ {0xfc3d, 2, 4467}, /* ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc3e, 2, 4469}, /* ARABIC LIGATURE KAF WITH YEH ISOLATED FORM */
+ {0xfc3f, 2, 4471}, /* ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM */
+ {0xfc40, 2, 4473}, /* ARABIC LIGATURE LAM WITH HAH ISOLATED FORM */
+ {0xfc41, 2, 4475}, /* ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM */
+ {0xfc42, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM */
+ {0xfc43, 2, 4479}, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc44, 2, 4481}, /* ARABIC LIGATURE LAM WITH YEH ISOLATED FORM */
+ {0xfc45, 2, 4483}, /* ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM */
+ {0xfc46, 2, 4392}, /* ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM */
+ {0xfc47, 2, 4394}, /* ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM */
+ {0xfc48, 2, 4485}, /* ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM */
+ {0xfc49, 2, 4487}, /* ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc4a, 2, 4489}, /* ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM */
+ {0xfc4b, 2, 4491}, /* ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM */
+ {0xfc4c, 2, 4493}, /* ARABIC LIGATURE NOON WITH HAH ISOLATED FORM */
+ {0xfc4d, 2, 4495}, /* ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM */
+ {0xfc4e, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM */
+ {0xfc4f, 2, 4499}, /* ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc50, 2, 4501}, /* ARABIC LIGATURE NOON WITH YEH ISOLATED FORM */
+ {0xfc51, 2, 4503}, /* ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM */
+ {0xfc52, 2, 4505}, /* ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM */
+ {0xfc53, 2, 4507}, /* ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc54, 2, 4509}, /* ARABIC LIGATURE HEH WITH YEH ISOLATED FORM */
+ {0xfc55, 2, 4388}, /* ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM */
+ {0xfc56, 2, 4511}, /* ARABIC LIGATURE YEH WITH HAH ISOLATED FORM */
+ {0xfc57, 2, 4513}, /* ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM */
+ {0xfc58, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM */
+ {0xfc59, 2, 4515}, /* ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfc5a, 2, 4510}, /* ARABIC LIGATURE YEH WITH YEH ISOLATED FORM */
+ {0xfc5b, 2, 4517}, /* ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM */
+ {0xfc5c, 2, 4519}, /* ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM */
+ {0xfc5d, 2, 4521}, /* ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM */
+ {0xfc5e, 3, 4523}, /* ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM */
+ {0xfc5f, 3, 4526}, /* ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM */
+ {0xfc60, 3, 4529}, /* ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM */
+ {0xfc61, 3, 4532}, /* ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM */
+ {0xfc62, 3, 4535}, /* ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM */
+ {0xfc63, 3, 4538}, /* ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM */
+ {0xfc64, 2, 4541}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM */
+ {0xfc65, 2, 4543}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM */
+ {0xfc66, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM */
+ {0xfc67, 2, 4545}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM */
+ {0xfc68, 2, 4346}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM */
+ {0xfc69, 2, 4355}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM */
+ {0xfc6a, 2, 4547}, /* ARABIC LIGATURE BEH WITH REH FINAL FORM */
+ {0xfc6b, 2, 4549}, /* ARABIC LIGATURE BEH WITH ZAIN FINAL FORM */
+ {0xfc6c, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM FINAL FORM */
+ {0xfc6d, 2, 4551}, /* ARABIC LIGATURE BEH WITH NOON FINAL FORM */
+ {0xfc6e, 2, 4365}, /* ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM */
+ {0xfc6f, 2, 4367}, /* ARABIC LIGATURE BEH WITH YEH FINAL FORM */
+ {0xfc70, 2, 4553}, /* ARABIC LIGATURE TEH WITH REH FINAL FORM */
+ {0xfc71, 2, 4555}, /* ARABIC LIGATURE TEH WITH ZAIN FINAL FORM */
+ {0xfc72, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM FINAL FORM */
+ {0xfc73, 2, 4557}, /* ARABIC LIGATURE TEH WITH NOON FINAL FORM */
+ {0xfc74, 2, 4377}, /* ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM */
+ {0xfc75, 2, 4379}, /* ARABIC LIGATURE TEH WITH YEH FINAL FORM */
+ {0xfc76, 2, 4559}, /* ARABIC LIGATURE THEH WITH REH FINAL FORM */
+ {0xfc77, 2, 4561}, /* ARABIC LIGATURE THEH WITH ZAIN FINAL FORM */
+ {0xfc78, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM FINAL FORM */
+ {0xfc79, 2, 4563}, /* ARABIC LIGATURE THEH WITH NOON FINAL FORM */
+ {0xfc7a, 2, 4385}, /* ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM */
+ {0xfc7b, 2, 4387}, /* ARABIC LIGATURE THEH WITH YEH FINAL FORM */
+ {0xfc7c, 2, 4443}, /* ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM */
+ {0xfc7d, 2, 4445}, /* ARABIC LIGATURE FEH WITH YEH FINAL FORM */
+ {0xfc7e, 2, 4451}, /* ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM */
+ {0xfc7f, 2, 4453}, /* ARABIC LIGATURE QAF WITH YEH FINAL FORM */
+ {0xfc80, 2, 4455}, /* ARABIC LIGATURE KAF WITH ALEF FINAL FORM */
+ {0xfc81, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM FINAL FORM */
+ {0xfc82, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM FINAL FORM */
+ {0xfc83, 2, 4467}, /* ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM */
+ {0xfc84, 2, 4469}, /* ARABIC LIGATURE KAF WITH YEH FINAL FORM */
+ {0xfc85, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM FINAL FORM */
+ {0xfc86, 2, 4479}, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM */
+ {0xfc87, 2, 4481}, /* ARABIC LIGATURE LAM WITH YEH FINAL FORM */
+ {0xfc88, 2, 4565}, /* ARABIC LIGATURE MEEM WITH ALEF FINAL FORM */
+ {0xfc89, 2, 4485}, /* ARABIC LIGATURE MEEM WITH MEEM FINAL FORM */
+ {0xfc8a, 2, 4567}, /* ARABIC LIGATURE NOON WITH REH FINAL FORM */
+ {0xfc8b, 2, 4569}, /* ARABIC LIGATURE NOON WITH ZAIN FINAL FORM */
+ {0xfc8c, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM FINAL FORM */
+ {0xfc8d, 2, 4571}, /* ARABIC LIGATURE NOON WITH NOON FINAL FORM */
+ {0xfc8e, 2, 4499}, /* ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM */
+ {0xfc8f, 2, 4501}, /* ARABIC LIGATURE NOON WITH YEH FINAL FORM */
+ {0xfc90, 2, 4521}, /* ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM */
+ {0xfc91, 2, 4573}, /* ARABIC LIGATURE YEH WITH REH FINAL FORM */
+ {0xfc92, 2, 4575}, /* ARABIC LIGATURE YEH WITH ZAIN FINAL FORM */
+ {0xfc93, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM FINAL FORM */
+ {0xfc94, 2, 4490}, /* ARABIC LIGATURE YEH WITH NOON FINAL FORM */
+ {0xfc95, 2, 4515}, /* ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM */
+ {0xfc96, 2, 4510}, /* ARABIC LIGATURE YEH WITH YEH FINAL FORM */
+ {0xfc97, 2, 4349}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM */
+ {0xfc98, 2, 4351}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM */
+ {0xfc99, 2, 4577}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM */
+ {0xfc9a, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM */
+ {0xfc9b, 2, 4579}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM */
+ {0xfc9c, 2, 4357}, /* ARABIC LIGATURE BEH WITH JEEM INITIAL FORM */
+ {0xfc9d, 2, 4359}, /* ARABIC LIGATURE BEH WITH HAH INITIAL FORM */
+ {0xfc9e, 2, 4361}, /* ARABIC LIGATURE BEH WITH KHAH INITIAL FORM */
+ {0xfc9f, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM INITIAL FORM */
+ {0xfca0, 2, 4581}, /* ARABIC LIGATURE BEH WITH HEH INITIAL FORM */
+ {0xfca1, 2, 4369}, /* ARABIC LIGATURE TEH WITH JEEM INITIAL FORM */
+ {0xfca2, 2, 4371}, /* ARABIC LIGATURE TEH WITH HAH INITIAL FORM */
+ {0xfca3, 2, 4373}, /* ARABIC LIGATURE TEH WITH KHAH INITIAL FORM */
+ {0xfca4, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM INITIAL FORM */
+ {0xfca5, 2, 4583}, /* ARABIC LIGATURE TEH WITH HEH INITIAL FORM */
+ {0xfca6, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM INITIAL FORM */
+ {0xfca7, 2, 4389}, /* ARABIC LIGATURE JEEM WITH HAH INITIAL FORM */
+ {0xfca8, 2, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM */
+ {0xfca9, 2, 4390}, /* ARABIC LIGATURE HAH WITH JEEM INITIAL FORM */
+ {0xfcaa, 2, 4393}, /* ARABIC LIGATURE HAH WITH MEEM INITIAL FORM */
+ {0xfcab, 2, 4395}, /* ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM */
+ {0xfcac, 2, 4399}, /* ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM */
+ {0xfcad, 2, 4401}, /* ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM */
+ {0xfcae, 2, 4403}, /* ARABIC LIGATURE SEEN WITH HAH INITIAL FORM */
+ {0xfcaf, 2, 4405}, /* ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM */
+ {0xfcb0, 2, 4407}, /* ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM */
+ {0xfcb1, 2, 4409}, /* ARABIC LIGATURE SAD WITH HAH INITIAL FORM */
+ {0xfcb2, 2, 4585}, /* ARABIC LIGATURE SAD WITH KHAH INITIAL FORM */
+ {0xfcb3, 2, 4411}, /* ARABIC LIGATURE SAD WITH MEEM INITIAL FORM */
+ {0xfcb4, 2, 4413}, /* ARABIC LIGATURE DAD WITH JEEM INITIAL FORM */
+ {0xfcb5, 2, 4415}, /* ARABIC LIGATURE DAD WITH HAH INITIAL FORM */
+ {0xfcb6, 2, 4417}, /* ARABIC LIGATURE DAD WITH KHAH INITIAL FORM */
+ {0xfcb7, 2, 4419}, /* ARABIC LIGATURE DAD WITH MEEM INITIAL FORM */
+ {0xfcb8, 2, 4421}, /* ARABIC LIGATURE TAH WITH HAH INITIAL FORM */
+ {0xfcb9, 2, 4425}, /* ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM */
+ {0xfcba, 2, 4427}, /* ARABIC LIGATURE AIN WITH JEEM INITIAL FORM */
+ {0xfcbb, 2, 4429}, /* ARABIC LIGATURE AIN WITH MEEM INITIAL FORM */
+ {0xfcbc, 2, 4431}, /* ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM */
+ {0xfcbd, 2, 4433}, /* ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM */
+ {0xfcbe, 2, 4435}, /* ARABIC LIGATURE FEH WITH JEEM INITIAL FORM */
+ {0xfcbf, 2, 4437}, /* ARABIC LIGATURE FEH WITH HAH INITIAL FORM */
+ {0xfcc0, 2, 4439}, /* ARABIC LIGATURE FEH WITH KHAH INITIAL FORM */
+ {0xfcc1, 2, 4441}, /* ARABIC LIGATURE FEH WITH MEEM INITIAL FORM */
+ {0xfcc2, 2, 4447}, /* ARABIC LIGATURE QAF WITH HAH INITIAL FORM */
+ {0xfcc3, 2, 4449}, /* ARABIC LIGATURE QAF WITH MEEM INITIAL FORM */
+ {0xfcc4, 2, 4457}, /* ARABIC LIGATURE KAF WITH JEEM INITIAL FORM */
+ {0xfcc5, 2, 4459}, /* ARABIC LIGATURE KAF WITH HAH INITIAL FORM */
+ {0xfcc6, 2, 4461}, /* ARABIC LIGATURE KAF WITH KHAH INITIAL FORM */
+ {0xfcc7, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM INITIAL FORM */
+ {0xfcc8, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM INITIAL FORM */
+ {0xfcc9, 2, 4471}, /* ARABIC LIGATURE LAM WITH JEEM INITIAL FORM */
+ {0xfcca, 2, 4473}, /* ARABIC LIGATURE LAM WITH HAH INITIAL FORM */
+ {0xfccb, 2, 4475}, /* ARABIC LIGATURE LAM WITH KHAH INITIAL FORM */
+ {0xfccc, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM INITIAL FORM */
+ {0xfccd, 2, 4587}, /* ARABIC LIGATURE LAM WITH HEH INITIAL FORM */
+ {0xfcce, 2, 4483}, /* ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM */
+ {0xfccf, 2, 4392}, /* ARABIC LIGATURE MEEM WITH HAH INITIAL FORM */
+ {0xfcd0, 2, 4394}, /* ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM */
+ {0xfcd1, 2, 4485}, /* ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM */
+ {0xfcd2, 2, 4491}, /* ARABIC LIGATURE NOON WITH JEEM INITIAL FORM */
+ {0xfcd3, 2, 4493}, /* ARABIC LIGATURE NOON WITH HAH INITIAL FORM */
+ {0xfcd4, 2, 4495}, /* ARABIC LIGATURE NOON WITH KHAH INITIAL FORM */
+ {0xfcd5, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM INITIAL FORM */
+ {0xfcd6, 2, 4589}, /* ARABIC LIGATURE NOON WITH HEH INITIAL FORM */
+ {0xfcd7, 2, 4503}, /* ARABIC LIGATURE HEH WITH JEEM INITIAL FORM */
+ {0xfcd8, 2, 4505}, /* ARABIC LIGATURE HEH WITH MEEM INITIAL FORM */
+ {0xfcd9, 2, 4591}, /* ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM */
+ {0xfcda, 2, 4388}, /* ARABIC LIGATURE YEH WITH JEEM INITIAL FORM */
+ {0xfcdb, 2, 4511}, /* ARABIC LIGATURE YEH WITH HAH INITIAL FORM */
+ {0xfcdc, 2, 4513}, /* ARABIC LIGATURE YEH WITH KHAH INITIAL FORM */
+ {0xfcdd, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM INITIAL FORM */
+ {0xfcde, 2, 4502}, /* ARABIC LIGATURE YEH WITH HEH INITIAL FORM */
+ {0xfcdf, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM */
+ {0xfce0, 2, 4579}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM */
+ {0xfce1, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM */
+ {0xfce2, 2, 4581}, /* ARABIC LIGATURE BEH WITH HEH MEDIAL FORM */
+ {0xfce3, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM */
+ {0xfce4, 2, 4583}, /* ARABIC LIGATURE TEH WITH HEH MEDIAL FORM */
+ {0xfce5, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM */
+ {0xfce6, 2, 4593}, /* ARABIC LIGATURE THEH WITH HEH MEDIAL FORM */
+ {0xfce7, 2, 4407}, /* ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM */
+ {0xfce8, 2, 4595}, /* ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM */
+ {0xfce9, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM */
+ {0xfcea, 2, 4599}, /* ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM */
+ {0xfceb, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM MEDIAL FORM */
+ {0xfcec, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM */
+ {0xfced, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM */
+ {0xfcee, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM */
+ {0xfcef, 2, 4589}, /* ARABIC LIGATURE NOON WITH HEH MEDIAL FORM */
+ {0xfcf0, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM */
+ {0xfcf1, 2, 4502}, /* ARABIC LIGATURE YEH WITH HEH MEDIAL FORM */
+ {0xfcf2, 3, 4601}, /* ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM */
+ {0xfcf3, 3, 4604}, /* ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM */
+ {0xfcf4, 3, 4607}, /* ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM */
+ {0xfcf5, 2, 4610}, /* ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfcf6, 2, 4612}, /* ARABIC LIGATURE TAH WITH YEH ISOLATED FORM */
+ {0xfcf7, 2, 4614}, /* ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfcf8, 2, 4616}, /* ARABIC LIGATURE AIN WITH YEH ISOLATED FORM */
+ {0xfcf9, 2, 4618}, /* ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfcfa, 2, 4620}, /* ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM */
+ {0xfcfb, 2, 4622}, /* ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfcfc, 2, 4624}, /* ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM */
+ {0xfcfd, 2, 4626}, /* ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfcfe, 2, 4628}, /* ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM */
+ {0xfcff, 2, 4630}, /* ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfd00, 2, 4512}, /* ARABIC LIGATURE HAH WITH YEH ISOLATED FORM */
+ {0xfd01, 2, 4632}, /* ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfd02, 2, 4634}, /* ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM */
+ {0xfd03, 2, 4636}, /* ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfd04, 2, 4514}, /* ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM */
+ {0xfd05, 2, 4638}, /* ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfd06, 2, 4640}, /* ARABIC LIGATURE SAD WITH YEH ISOLATED FORM */
+ {0xfd07, 2, 4642}, /* ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM */
+ {0xfd08, 2, 4644}, /* ARABIC LIGATURE DAD WITH YEH ISOLATED FORM */
+ {0xfd09, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM */
+ {0xfd0a, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM */
+ {0xfd0b, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM */
+ {0xfd0c, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM */
+ {0xfd0d, 2, 4652}, /* ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM */
+ {0xfd0e, 2, 4654}, /* ARABIC LIGATURE SEEN WITH REH ISOLATED FORM */
+ {0xfd0f, 2, 4656}, /* ARABIC LIGATURE SAD WITH REH ISOLATED FORM */
+ {0xfd10, 2, 4658}, /* ARABIC LIGATURE DAD WITH REH ISOLATED FORM */
+ {0xfd11, 2, 4610}, /* ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfd12, 2, 4612}, /* ARABIC LIGATURE TAH WITH YEH FINAL FORM */
+ {0xfd13, 2, 4614}, /* ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM */
+ {0xfd14, 2, 4616}, /* ARABIC LIGATURE AIN WITH YEH FINAL FORM */
+ {0xfd15, 2, 4618}, /* ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM */
+ {0xfd16, 2, 4620}, /* ARABIC LIGATURE GHAIN WITH YEH FINAL FORM */
+ {0xfd17, 2, 4622}, /* ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM */
+ {0xfd18, 2, 4624}, /* ARABIC LIGATURE SEEN WITH YEH FINAL FORM */
+ {0xfd19, 2, 4626}, /* ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM */
+ {0xfd1a, 2, 4628}, /* ARABIC LIGATURE SHEEN WITH YEH FINAL FORM */
+ {0xfd1b, 2, 4630}, /* ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfd1c, 2, 4512}, /* ARABIC LIGATURE HAH WITH YEH FINAL FORM */
+ {0xfd1d, 2, 4632}, /* ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd1e, 2, 4634}, /* ARABIC LIGATURE JEEM WITH YEH FINAL FORM */
+ {0xfd1f, 2, 4636}, /* ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfd20, 2, 4514}, /* ARABIC LIGATURE KHAH WITH YEH FINAL FORM */
+ {0xfd21, 2, 4638}, /* ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM */
+ {0xfd22, 2, 4640}, /* ARABIC LIGATURE SAD WITH YEH FINAL FORM */
+ {0xfd23, 2, 4642}, /* ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM */
+ {0xfd24, 2, 4644}, /* ARABIC LIGATURE DAD WITH YEH FINAL FORM */
+ {0xfd25, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM */
+ {0xfd26, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH FINAL FORM */
+ {0xfd27, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM */
+ {0xfd28, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM */
+ {0xfd29, 2, 4652}, /* ARABIC LIGATURE SHEEN WITH REH FINAL FORM */
+ {0xfd2a, 2, 4654}, /* ARABIC LIGATURE SEEN WITH REH FINAL FORM */
+ {0xfd2b, 2, 4656}, /* ARABIC LIGATURE SAD WITH REH FINAL FORM */
+ {0xfd2c, 2, 4658}, /* ARABIC LIGATURE DAD WITH REH FINAL FORM */
+ {0xfd2d, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM */
+ {0xfd2e, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM */
+ {0xfd2f, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM */
+ {0xfd30, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM */
+ {0xfd31, 2, 4595}, /* ARABIC LIGATURE SEEN WITH HEH INITIAL FORM */
+ {0xfd32, 2, 4599}, /* ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM */
+ {0xfd33, 2, 4423}, /* ARABIC LIGATURE TAH WITH MEEM INITIAL FORM */
+ {0xfd34, 2, 4401}, /* ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM */
+ {0xfd35, 2, 4403}, /* ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM */
+ {0xfd36, 2, 4405}, /* ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM */
+ {0xfd37, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM */
+ {0xfd38, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM */
+ {0xfd39, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM */
+ {0xfd3a, 2, 4423}, /* ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM */
+ {0xfd3b, 2, 4425}, /* ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM */
+ {0xfd3c, 2, 4660}, /* ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM */
+ {0xfd3d, 2, 4660}, /* ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM */
+ {0xfd50, 3, 4662}, /* ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM */
+ {0xfd51, 3, 4665}, /* ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM */
+ {0xfd52, 3, 4665}, /* ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM */
+ {0xfd53, 3, 4668}, /* ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM */
+ {0xfd54, 3, 4671}, /* ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM */
+ {0xfd55, 3, 4674}, /* ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM */
+ {0xfd56, 3, 4677}, /* ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM */
+ {0xfd57, 3, 4680}, /* ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM */
+ {0xfd58, 3, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM */
+ {0xfd59, 3, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM */
+ {0xfd5a, 3, 4683}, /* ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM */
+ {0xfd5b, 3, 4686}, /* ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd5c, 3, 4689}, /* ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM */
+ {0xfd5d, 3, 4692}, /* ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM */
+ {0xfd5e, 3, 4695}, /* ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd5f, 3, 4698}, /* ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM */
+ {0xfd60, 3, 4698}, /* ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM */
+ {0xfd61, 3, 4701}, /* ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM */
+ {0xfd62, 3, 4704}, /* ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd63, 3, 4704}, /* ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfd64, 3, 4707}, /* ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM */
+ {0xfd65, 3, 4707}, /* ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM */
+ {0xfd66, 3, 4710}, /* ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd67, 3, 4713}, /* ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM */
+ {0xfd68, 3, 4713}, /* ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM */
+ {0xfd69, 3, 4716}, /* ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM */
+ {0xfd6a, 3, 4719}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM */
+ {0xfd6b, 3, 4719}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM */
+ {0xfd6c, 3, 4722}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd6d, 3, 4722}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfd6e, 3, 4725}, /* ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfd6f, 3, 4728}, /* ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM */
+ {0xfd70, 3, 4728}, /* ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM */
+ {0xfd71, 3, 4731}, /* ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM */
+ {0xfd72, 3, 4731}, /* ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM */
+ {0xfd73, 3, 4734}, /* ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfd74, 3, 4737}, /* ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM */
+ {0xfd75, 3, 4740}, /* ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM */
+ {0xfd76, 3, 4743}, /* ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd77, 3, 4743}, /* ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfd78, 3, 4746}, /* ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd79, 3, 4749}, /* ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd7a, 3, 4752}, /* ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM */
+ {0xfd7b, 3, 4755}, /* ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd7c, 3, 4758}, /* ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM */
+ {0xfd7d, 3, 4758}, /* ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM */
+ {0xfd7e, 3, 4761}, /* ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM */
+ {0xfd7f, 3, 4764}, /* ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd80, 3, 4767}, /* ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM */
+ {0xfd81, 3, 4770}, /* ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM */
+ {0xfd82, 3, 4773}, /* ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfd83, 3, 4776}, /* ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM */
+ {0xfd84, 3, 4776}, /* ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM */
+ {0xfd85, 3, 4779}, /* ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM */
+ {0xfd86, 3, 4779}, /* ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM */
+ {0xfd87, 3, 4782}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM */
+ {0xfd88, 3, 4782}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM */
+ {0xfd89, 3, 4785}, /* ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM */
+ {0xfd8a, 3, 4392}, /* ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM */
+ {0xfd8b, 3, 4788}, /* ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM */
+ {0xfd8c, 3, 4791}, /* ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM */
+ {0xfd8d, 3, 4483}, /* ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM */
+ {0xfd8e, 3, 4394}, /* ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM */
+ {0xfd8f, 3, 4794}, /* ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM */
+ {0xfd92, 3, 4797}, /* ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM */
+ {0xfd93, 3, 4800}, /* ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM */
+ {0xfd94, 3, 4803}, /* ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfd95, 3, 4806}, /* ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM */
+ {0xfd96, 3, 4809}, /* ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfd97, 3, 4812}, /* ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM */
+ {0xfd98, 3, 4812}, /* ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM */
+ {0xfd99, 3, 4815}, /* ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd9a, 3, 4818}, /* ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM */
+ {0xfd9b, 3, 4821}, /* ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfd9c, 3, 4824}, /* ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM */
+ {0xfd9d, 3, 4824}, /* ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfd9e, 3, 4827}, /* ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM */
+ {0xfd9f, 3, 4830}, /* ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM */
+ {0xfda0, 3, 4833}, /* ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfda1, 3, 4836}, /* ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM */
+ {0xfda2, 3, 4839}, /* ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfda3, 3, 4842}, /* ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM */
+ {0xfda4, 3, 4845}, /* ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfda5, 3, 4848}, /* ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM */
+ {0xfda6, 3, 4851}, /* ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfda7, 3, 4854}, /* ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+ {0xfda8, 3, 4857}, /* ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM */
+ {0xfda9, 3, 4860}, /* ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM */
+ {0xfdaa, 3, 4863}, /* ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM */
+ {0xfdab, 3, 4866}, /* ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM */
+ {0xfdac, 3, 4869}, /* ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM */
+ {0xfdad, 3, 4872}, /* ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM */
+ {0xfdae, 3, 4511}, /* ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM */
+ {0xfdaf, 3, 4875}, /* ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM */
+ {0xfdb0, 3, 4878}, /* ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM */
+ {0xfdb1, 3, 4881}, /* ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM */
+ {0xfdb2, 3, 4884}, /* ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM */
+ {0xfdb3, 3, 4887}, /* ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM */
+ {0xfdb4, 3, 4761}, /* ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM */
+ {0xfdb5, 3, 4767}, /* ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM */
+ {0xfdb6, 3, 4890}, /* ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM */
+ {0xfdb7, 3, 4893}, /* ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM */
+ {0xfdb8, 3, 4896}, /* ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM */
+ {0xfdb9, 3, 4899}, /* ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM */
+ {0xfdba, 3, 4902}, /* ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM */
+ {0xfdbb, 3, 4905}, /* ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM */
+ {0xfdbc, 3, 4902}, /* ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM */
+ {0xfdbd, 3, 4896}, /* ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM */
+ {0xfdbe, 3, 4908}, /* ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM */
+ {0xfdbf, 3, 4911}, /* ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM */
+ {0xfdc0, 3, 4914}, /* ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM */
+ {0xfdc1, 3, 4917}, /* ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM */
+ {0xfdc2, 3, 4920}, /* ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM */
+ {0xfdc3, 3, 4905}, /* ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfdc4, 3, 4740}, /* ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM */
+ {0xfdc5, 3, 4710}, /* ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM */
+ {0xfdc6, 3, 4923}, /* ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM */
+ {0xfdc7, 3, 4926}, /* ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM */
+ {0xfdf0, 3, 4929}, /* ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM */
+ {0xfdf1, 3, 4932}, /* ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM */
+ {0xfdf2, 4, 4935}, /* ARABIC LIGATURE ALLAH ISOLATED FORM */
+ {0xfdf3, 4, 4939}, /* ARABIC LIGATURE AKBAR ISOLATED FORM */
+ {0xfdf4, 4, 4943}, /* ARABIC LIGATURE MOHAMMAD ISOLATED FORM */
+ {0xfdf5, 4, 4947}, /* ARABIC LIGATURE SALAM ISOLATED FORM */
+ {0xfdf6, 4, 4951}, /* ARABIC LIGATURE RASOUL ISOLATED FORM */
+ {0xfdf7, 4, 4955}, /* ARABIC LIGATURE ALAYHE ISOLATED FORM */
+ {0xfdf8, 4, 4959}, /* ARABIC LIGATURE WASALLAM ISOLATED FORM */
+ {0xfdf9, 3, 4963}, /* ARABIC LIGATURE SALLA ISOLATED FORM */
+ {0xfdfa, 18, 4966}, /* ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM */
+ {0xfdfb, 8, 4984}, /* ARABIC LIGATURE JALLAJALALOUHOU */
+ {0xfdfc, 4, 4992}, /* RIAL SIGN */
+ {0xfe30, 1, 4996}, /* PRESENTATION FORM FOR VERTICAL TWO DOT LEADER */
+ {0xfe31, 1, 4997}, /* PRESENTATION FORM FOR VERTICAL EM DASH */
+ {0xfe32, 1, 4998}, /* PRESENTATION FORM FOR VERTICAL EN DASH */
+ {0xfe33, 1, 4999}, /* PRESENTATION FORM FOR VERTICAL LOW LINE */
+ {0xfe34, 1, 4999}, /* PRESENTATION FORM FOR VERTICAL WAVY LOW LINE */
+ {0xfe35, 1, 1918}, /* PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS */
+ {0xfe36, 1, 1919}, /* PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS */
+ {0xfe37, 1, 5000}, /* PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET */
+ {0xfe38, 1, 5001}, /* PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET */
+ {0xfe39, 1, 5002}, /* PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET */
+ {0xfe3a, 1, 5003}, /* PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET */
+ {0xfe3b, 1, 5004}, /* PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET */
+ {0xfe3c, 1, 5005}, /* PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET */
+ {0xfe3d, 1, 5006}, /* PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET */
+ {0xfe3e, 1, 5007}, /* PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET */
+ {0xfe3f, 1, 2140}, /* PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET */
+ {0xfe40, 1, 2141}, /* PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET */
+ {0xfe41, 1, 5008}, /* PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET */
+ {0xfe42, 1, 5009}, /* PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET */
+ {0xfe43, 1, 5010}, /* PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET */
+ {0xfe44, 1, 5011}, /* PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET */
+ {0xfe47, 1, 5012}, /* PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET */
+ {0xfe48, 1, 5013}, /* PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET */
+ {0xfe49, 1, 5014}, /* DASHED OVERLINE */
+ {0xfe4a, 1, 5014}, /* CENTRELINE OVERLINE */
+ {0xfe4b, 1, 5014}, /* WAVY OVERLINE */
+ {0xfe4c, 1, 5014}, /* DOUBLE WAVY OVERLINE */
+ {0xfe4d, 1, 4999}, /* DASHED LOW LINE */
+ {0xfe4e, 1, 4999}, /* CENTRELINE LOW LINE */
+ {0xfe4f, 1, 4999}, /* WAVY LOW LINE */
+ {0xfe50, 1, 5015}, /* SMALL COMMA */
+ {0xfe51, 1, 5016}, /* SMALL IDEOGRAPHIC COMMA */
+ {0xfe52, 1, 1884}, /* SMALL FULL STOP */
+ {0xfe54, 1, 587}, /* SMALL SEMICOLON */
+ {0xfe55, 1, 2364}, /* SMALL COLON */
+ {0xfe56, 1, 1902}, /* SMALL QUESTION MARK */
+ {0xfe57, 1, 1898}, /* SMALL EXCLAMATION MARK */
+ {0xfe58, 1, 4997}, /* SMALL EM DASH */
+ {0xfe59, 1, 1918}, /* SMALL LEFT PARENTHESIS */
+ {0xfe5a, 1, 1919}, /* SMALL RIGHT PARENTHESIS */
+ {0xfe5b, 1, 5000}, /* SMALL LEFT CURLY BRACKET */
+ {0xfe5c, 1, 5001}, /* SMALL RIGHT CURLY BRACKET */
+ {0xfe5d, 1, 5002}, /* SMALL LEFT TORTOISE SHELL BRACKET */
+ {0xfe5e, 1, 5003}, /* SMALL RIGHT TORTOISE SHELL BRACKET */
+ {0xfe5f, 1, 5017}, /* SMALL NUMBER SIGN */
+ {0xfe60, 1, 5018}, /* SMALL AMPERSAND */
+ {0xfe61, 1, 5019}, /* SMALL ASTERISK */
+ {0xfe62, 1, 1915}, /* SMALL PLUS SIGN */
+ {0xfe63, 1, 5020}, /* SMALL HYPHEN-MINUS */
+ {0xfe64, 1, 2088}, /* SMALL LESS-THAN SIGN */
+ {0xfe65, 1, 2090}, /* SMALL GREATER-THAN SIGN */
+ {0xfe66, 1, 1917}, /* SMALL EQUALS SIGN */
+ {0xfe68, 1, 5021}, /* SMALL REVERSE SOLIDUS */
+ {0xfe69, 1, 5022}, /* SMALL DOLLAR SIGN */
+ {0xfe6a, 1, 5023}, /* SMALL PERCENT SIGN */
+ {0xfe6b, 1, 5024}, /* SMALL COMMERCIAL AT */
+ {0xfe70, 2, 5025}, /* ARABIC FATHATAN ISOLATED FORM */
+ {0xfe71, 2, 5027}, /* ARABIC TATWEEL WITH FATHATAN ABOVE */
+ {0xfe72, 2, 4523}, /* ARABIC DAMMATAN ISOLATED FORM */
+ {0xfe74, 2, 4526}, /* ARABIC KASRATAN ISOLATED FORM */
+ {0xfe76, 2, 4529}, /* ARABIC FATHA ISOLATED FORM */
+ {0xfe77, 2, 4601}, /* ARABIC FATHA MEDIAL FORM */
+ {0xfe78, 2, 4532}, /* ARABIC DAMMA ISOLATED FORM */
+ {0xfe79, 2, 4604}, /* ARABIC DAMMA MEDIAL FORM */
+ {0xfe7a, 2, 4535}, /* ARABIC KASRA ISOLATED FORM */
+ {0xfe7b, 2, 4607}, /* ARABIC KASRA MEDIAL FORM */
+ {0xfe7c, 2, 4538}, /* ARABIC SHADDA ISOLATED FORM */
+ {0xfe7d, 2, 5029}, /* ARABIC SHADDA MEDIAL FORM */
+ {0xfe7e, 2, 5031}, /* ARABIC SUKUN ISOLATED FORM */
+ {0xfe7f, 2, 5033}, /* ARABIC SUKUN MEDIAL FORM */
+ {0xfe80, 1, 5035}, /* ARABIC LETTER HAMZA ISOLATED FORM */
+ {0xfe81, 1, 5036}, /* ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM */
+ {0xfe82, 1, 5036}, /* ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM */
+ {0xfe83, 1, 5037}, /* ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM */
+ {0xfe84, 1, 5037}, /* ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM */
+ {0xfe85, 1, 5038}, /* ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM */
+ {0xfe86, 1, 5038}, /* ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM */
+ {0xfe87, 1, 5039}, /* ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM */
+ {0xfe88, 1, 5039}, /* ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM */
+ {0xfe89, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM */
+ {0xfe8a, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM */
+ {0xfe8b, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM */
+ {0xfe8c, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM */
+ {0xfe8d, 1, 749}, /* ARABIC LETTER ALEF ISOLATED FORM */
+ {0xfe8e, 1, 749}, /* ARABIC LETTER ALEF FINAL FORM */
+ {0xfe8f, 1, 4357}, /* ARABIC LETTER BEH ISOLATED FORM */
+ {0xfe90, 1, 4357}, /* ARABIC LETTER BEH FINAL FORM */
+ {0xfe91, 1, 4357}, /* ARABIC LETTER BEH INITIAL FORM */
+ {0xfe92, 1, 4357}, /* ARABIC LETTER BEH MEDIAL FORM */
+ {0xfe93, 1, 5040}, /* ARABIC LETTER TEH MARBUTA ISOLATED FORM */
+ {0xfe94, 1, 5040}, /* ARABIC LETTER TEH MARBUTA FINAL FORM */
+ {0xfe95, 1, 4369}, /* ARABIC LETTER TEH ISOLATED FORM */
+ {0xfe96, 1, 4369}, /* ARABIC LETTER TEH FINAL FORM */
+ {0xfe97, 1, 4369}, /* ARABIC LETTER TEH INITIAL FORM */
+ {0xfe98, 1, 4369}, /* ARABIC LETTER TEH MEDIAL FORM */
+ {0xfe99, 1, 4381}, /* ARABIC LETTER THEH ISOLATED FORM */
+ {0xfe9a, 1, 4381}, /* ARABIC LETTER THEH FINAL FORM */
+ {0xfe9b, 1, 4381}, /* ARABIC LETTER THEH INITIAL FORM */
+ {0xfe9c, 1, 4381}, /* ARABIC LETTER THEH MEDIAL FORM */
+ {0xfe9d, 1, 4350}, /* ARABIC LETTER JEEM ISOLATED FORM */
+ {0xfe9e, 1, 4350}, /* ARABIC LETTER JEEM FINAL FORM */
+ {0xfe9f, 1, 4350}, /* ARABIC LETTER JEEM INITIAL FORM */
+ {0xfea0, 1, 4350}, /* ARABIC LETTER JEEM MEDIAL FORM */
+ {0xfea1, 1, 4352}, /* ARABIC LETTER HAH ISOLATED FORM */
+ {0xfea2, 1, 4352}, /* ARABIC LETTER HAH FINAL FORM */
+ {0xfea3, 1, 4352}, /* ARABIC LETTER HAH INITIAL FORM */
+ {0xfea4, 1, 4352}, /* ARABIC LETTER HAH MEDIAL FORM */
+ {0xfea5, 1, 4362}, /* ARABIC LETTER KHAH ISOLATED FORM */
+ {0xfea6, 1, 4362}, /* ARABIC LETTER KHAH FINAL FORM */
+ {0xfea7, 1, 4362}, /* ARABIC LETTER KHAH INITIAL FORM */
+ {0xfea8, 1, 4362}, /* ARABIC LETTER KHAH MEDIAL FORM */
+ {0xfea9, 1, 4946}, /* ARABIC LETTER DAL ISOLATED FORM */
+ {0xfeaa, 1, 4946}, /* ARABIC LETTER DAL FINAL FORM */
+ {0xfeab, 1, 4517}, /* ARABIC LETTER THAL ISOLATED FORM */
+ {0xfeac, 1, 4517}, /* ARABIC LETTER THAL FINAL FORM */
+ {0xfead, 1, 4519}, /* ARABIC LETTER REH ISOLATED FORM */
+ {0xfeae, 1, 4519}, /* ARABIC LETTER REH FINAL FORM */
+ {0xfeaf, 1, 4544}, /* ARABIC LETTER ZAIN ISOLATED FORM */
+ {0xfeb0, 1, 4544}, /* ARABIC LETTER ZAIN FINAL FORM */
+ {0xfeb1, 1, 4401}, /* ARABIC LETTER SEEN ISOLATED FORM */
+ {0xfeb2, 1, 4401}, /* ARABIC LETTER SEEN FINAL FORM */
+ {0xfeb3, 1, 4401}, /* ARABIC LETTER SEEN INITIAL FORM */
+ {0xfeb4, 1, 4401}, /* ARABIC LETTER SEEN MEDIAL FORM */
+ {0xfeb5, 1, 4597}, /* ARABIC LETTER SHEEN ISOLATED FORM */
+ {0xfeb6, 1, 4597}, /* ARABIC LETTER SHEEN FINAL FORM */
+ {0xfeb7, 1, 4597}, /* ARABIC LETTER SHEEN INITIAL FORM */
+ {0xfeb8, 1, 4597}, /* ARABIC LETTER SHEEN MEDIAL FORM */
+ {0xfeb9, 1, 4409}, /* ARABIC LETTER SAD ISOLATED FORM */
+ {0xfeba, 1, 4409}, /* ARABIC LETTER SAD FINAL FORM */
+ {0xfebb, 1, 4409}, /* ARABIC LETTER SAD INITIAL FORM */
+ {0xfebc, 1, 4409}, /* ARABIC LETTER SAD MEDIAL FORM */
+ {0xfebd, 1, 4413}, /* ARABIC LETTER DAD ISOLATED FORM */
+ {0xfebe, 1, 4413}, /* ARABIC LETTER DAD FINAL FORM */
+ {0xfebf, 1, 4413}, /* ARABIC LETTER DAD INITIAL FORM */
+ {0xfec0, 1, 4413}, /* ARABIC LETTER DAD MEDIAL FORM */
+ {0xfec1, 1, 4421}, /* ARABIC LETTER TAH ISOLATED FORM */
+ {0xfec2, 1, 4421}, /* ARABIC LETTER TAH FINAL FORM */
+ {0xfec3, 1, 4421}, /* ARABIC LETTER TAH INITIAL FORM */
+ {0xfec4, 1, 4421}, /* ARABIC LETTER TAH MEDIAL FORM */
+ {0xfec5, 1, 4425}, /* ARABIC LETTER ZAH ISOLATED FORM */
+ {0xfec6, 1, 4425}, /* ARABIC LETTER ZAH FINAL FORM */
+ {0xfec7, 1, 4425}, /* ARABIC LETTER ZAH INITIAL FORM */
+ {0xfec8, 1, 4425}, /* ARABIC LETTER ZAH MEDIAL FORM */
+ {0xfec9, 1, 4427}, /* ARABIC LETTER AIN ISOLATED FORM */
+ {0xfeca, 1, 4427}, /* ARABIC LETTER AIN FINAL FORM */
+ {0xfecb, 1, 4427}, /* ARABIC LETTER AIN INITIAL FORM */
+ {0xfecc, 1, 4427}, /* ARABIC LETTER AIN MEDIAL FORM */
+ {0xfecd, 1, 4431}, /* ARABIC LETTER GHAIN ISOLATED FORM */
+ {0xfece, 1, 4431}, /* ARABIC LETTER GHAIN FINAL FORM */
+ {0xfecf, 1, 4431}, /* ARABIC LETTER GHAIN INITIAL FORM */
+ {0xfed0, 1, 4431}, /* ARABIC LETTER GHAIN MEDIAL FORM */
+ {0xfed1, 1, 4435}, /* ARABIC LETTER FEH ISOLATED FORM */
+ {0xfed2, 1, 4435}, /* ARABIC LETTER FEH FINAL FORM */
+ {0xfed3, 1, 4435}, /* ARABIC LETTER FEH INITIAL FORM */
+ {0xfed4, 1, 4435}, /* ARABIC LETTER FEH MEDIAL FORM */
+ {0xfed5, 1, 4447}, /* ARABIC LETTER QAF ISOLATED FORM */
+ {0xfed6, 1, 4447}, /* ARABIC LETTER QAF FINAL FORM */
+ {0xfed7, 1, 4447}, /* ARABIC LETTER QAF INITIAL FORM */
+ {0xfed8, 1, 4447}, /* ARABIC LETTER QAF MEDIAL FORM */
+ {0xfed9, 1, 4455}, /* ARABIC LETTER KAF ISOLATED FORM */
+ {0xfeda, 1, 4455}, /* ARABIC LETTER KAF FINAL FORM */
+ {0xfedb, 1, 4455}, /* ARABIC LETTER KAF INITIAL FORM */
+ {0xfedc, 1, 4455}, /* ARABIC LETTER KAF MEDIAL FORM */
+ {0xfedd, 1, 4464}, /* ARABIC LETTER LAM ISOLATED FORM */
+ {0xfede, 1, 4464}, /* ARABIC LETTER LAM FINAL FORM */
+ {0xfedf, 1, 4464}, /* ARABIC LETTER LAM INITIAL FORM */
+ {0xfee0, 1, 4464}, /* ARABIC LETTER LAM MEDIAL FORM */
+ {0xfee1, 1, 4354}, /* ARABIC LETTER MEEM ISOLATED FORM */
+ {0xfee2, 1, 4354}, /* ARABIC LETTER MEEM FINAL FORM */
+ {0xfee3, 1, 4354}, /* ARABIC LETTER MEEM INITIAL FORM */
+ {0xfee4, 1, 4354}, /* ARABIC LETTER MEEM MEDIAL FORM */
+ {0xfee5, 1, 4491}, /* ARABIC LETTER NOON ISOLATED FORM */
+ {0xfee6, 1, 4491}, /* ARABIC LETTER NOON FINAL FORM */
+ {0xfee7, 1, 4491}, /* ARABIC LETTER NOON INITIAL FORM */
+ {0xfee8, 1, 4491}, /* ARABIC LETTER NOON MEDIAL FORM */
+ {0xfee9, 1, 4503}, /* ARABIC LETTER HEH ISOLATED FORM */
+ {0xfeea, 1, 4503}, /* ARABIC LETTER HEH FINAL FORM */
+ {0xfeeb, 1, 4503}, /* ARABIC LETTER HEH INITIAL FORM */
+ {0xfeec, 1, 4503}, /* ARABIC LETTER HEH MEDIAL FORM */
+ {0xfeed, 1, 753}, /* ARABIC LETTER WAW ISOLATED FORM */
+ {0xfeee, 1, 753}, /* ARABIC LETTER WAW FINAL FORM */
+ {0xfeef, 1, 4331}, /* ARABIC LETTER ALEF MAKSURA ISOLATED FORM */
+ {0xfef0, 1, 4331}, /* ARABIC LETTER ALEF MAKSURA FINAL FORM */
+ {0xfef1, 1, 757}, /* ARABIC LETTER YEH ISOLATED FORM */
+ {0xfef2, 1, 757}, /* ARABIC LETTER YEH FINAL FORM */
+ {0xfef3, 1, 757}, /* ARABIC LETTER YEH INITIAL FORM */
+ {0xfef4, 1, 757}, /* ARABIC LETTER YEH MEDIAL FORM */
+ {0xfef5, 2, 5041}, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+ {0xfef6, 2, 5041}, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+ {0xfef7, 2, 5043}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
+ {0xfef8, 2, 5043}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
+ {0xfef9, 2, 5045}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+ {0xfefa, 2, 5045}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+ {0xfefb, 2, 4988}, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+ {0xfefc, 2, 4988}, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+ {0xff01, 1, 1898}, /* FULLWIDTH EXCLAMATION MARK */
+ {0xff02, 1, 5047}, /* FULLWIDTH QUOTATION MARK */
+ {0xff03, 1, 5017}, /* FULLWIDTH NUMBER SIGN */
+ {0xff04, 1, 5022}, /* FULLWIDTH DOLLAR SIGN */
+ {0xff05, 1, 5023}, /* FULLWIDTH PERCENT SIGN */
+ {0xff06, 1, 5018}, /* FULLWIDTH AMPERSAND */
+ {0xff07, 1, 5048}, /* FULLWIDTH APOSTROPHE */
+ {0xff08, 1, 1918}, /* FULLWIDTH LEFT PARENTHESIS */
+ {0xff09, 1, 1919}, /* FULLWIDTH RIGHT PARENTHESIS */
+ {0xff0a, 1, 5019}, /* FULLWIDTH ASTERISK */
+ {0xff0b, 1, 1915}, /* FULLWIDTH PLUS SIGN */
+ {0xff0c, 1, 5015}, /* FULLWIDTH COMMA */
+ {0xff0d, 1, 5020}, /* FULLWIDTH HYPHEN-MINUS */
+ {0xff0e, 1, 1884}, /* FULLWIDTH FULL STOP */
+ {0xff0f, 1, 1923}, /* FULLWIDTH SOLIDUS */
+ {0xff10, 1, 1909}, /* FULLWIDTH DIGIT ZERO */
+ {0xff11, 1, 13}, /* FULLWIDTH DIGIT ONE */
+ {0xff12, 1, 6}, /* FULLWIDTH DIGIT TWO */
+ {0xff13, 1, 7}, /* FULLWIDTH DIGIT THREE */
+ {0xff14, 1, 17}, /* FULLWIDTH DIGIT FOUR */
+ {0xff15, 1, 1910}, /* FULLWIDTH DIGIT FIVE */
+ {0xff16, 1, 1911}, /* FULLWIDTH DIGIT SIX */
+ {0xff17, 1, 1912}, /* FULLWIDTH DIGIT SEVEN */
+ {0xff18, 1, 1913}, /* FULLWIDTH DIGIT EIGHT */
+ {0xff19, 1, 1914}, /* FULLWIDTH DIGIT NINE */
+ {0xff1a, 1, 2364}, /* FULLWIDTH COLON */
+ {0xff1b, 1, 587}, /* FULLWIDTH SEMICOLON */
+ {0xff1c, 1, 2088}, /* FULLWIDTH LESS-THAN SIGN */
+ {0xff1d, 1, 1917}, /* FULLWIDTH EQUALS SIGN */
+ {0xff1e, 1, 2090}, /* FULLWIDTH GREATER-THAN SIGN */
+ {0xff1f, 1, 1902}, /* FULLWIDTH QUESTION MARK */
+ {0xff20, 1, 5024}, /* FULLWIDTH COMMERCIAL AT */
+ {0xff21, 1, 24}, /* FULLWIDTH LATIN CAPITAL LETTER A */
+ {0xff22, 1, 910}, /* FULLWIDTH LATIN CAPITAL LETTER B */
+ {0xff23, 1, 36}, /* FULLWIDTH LATIN CAPITAL LETTER C */
+ {0xff24, 1, 158}, /* FULLWIDTH LATIN CAPITAL LETTER D */
+ {0xff25, 1, 38}, /* FULLWIDTH LATIN CAPITAL LETTER E */
+ {0xff26, 1, 995}, /* FULLWIDTH LATIN CAPITAL LETTER F */
+ {0xff27, 1, 182}, /* FULLWIDTH LATIN CAPITAL LETTER G */
+ {0xff28, 1, 198}, /* FULLWIDTH LATIN CAPITAL LETTER H */
+ {0xff29, 1, 46}, /* FULLWIDTH LATIN CAPITAL LETTER I */
+ {0xff2a, 1, 221}, /* FULLWIDTH LATIN CAPITAL LETTER J */
+ {0xff2b, 1, 228}, /* FULLWIDTH LATIN CAPITAL LETTER K */
+ {0xff2c, 1, 232}, /* FULLWIDTH LATIN CAPITAL LETTER L */
+ {0xff2d, 1, 912}, /* FULLWIDTH LATIN CAPITAL LETTER M */
+ {0xff2e, 1, 54}, /* FULLWIDTH LATIN CAPITAL LETTER N */
+ {0xff2f, 1, 56}, /* FULLWIDTH LATIN CAPITAL LETTER O */
+ {0xff30, 1, 914}, /* FULLWIDTH LATIN CAPITAL LETTER P */
+ {0xff31, 1, 1942}, /* FULLWIDTH LATIN CAPITAL LETTER Q */
+ {0xff32, 1, 274}, /* FULLWIDTH LATIN CAPITAL LETTER R */
+ {0xff33, 1, 286}, /* FULLWIDTH LATIN CAPITAL LETTER S */
+ {0xff34, 1, 302}, /* FULLWIDTH LATIN CAPITAL LETTER T */
+ {0xff35, 1, 66}, /* FULLWIDTH LATIN CAPITAL LETTER U */
+ {0xff36, 1, 1183}, /* FULLWIDTH LATIN CAPITAL LETTER V */
+ {0xff37, 1, 334}, /* FULLWIDTH LATIN CAPITAL LETTER W */
+ {0xff38, 1, 1211}, /* FULLWIDTH LATIN CAPITAL LETTER X */
+ {0xff39, 1, 74}, /* FULLWIDTH LATIN CAPITAL LETTER Y */
+ {0xff3a, 1, 344}, /* FULLWIDTH LATIN CAPITAL LETTER Z */
+ {0xff3b, 1, 5012}, /* FULLWIDTH LEFT SQUARE BRACKET */
+ {0xff3c, 1, 5021}, /* FULLWIDTH REVERSE SOLIDUS */
+ {0xff3d, 1, 5013}, /* FULLWIDTH RIGHT SQUARE BRACKET */
+ {0xff3e, 1, 5049}, /* FULLWIDTH CIRCUMFLEX ACCENT */
+ {0xff3f, 1, 4999}, /* FULLWIDTH LOW LINE */
+ {0xff40, 1, 1848}, /* FULLWIDTH GRAVE ACCENT */
+ {0xff41, 1, 3}, /* FULLWIDTH LATIN SMALL LETTER A */
+ {0xff42, 1, 918}, /* FULLWIDTH LATIN SMALL LETTER B */
+ {0xff43, 1, 88}, /* FULLWIDTH LATIN SMALL LETTER C */
+ {0xff44, 1, 160}, /* FULLWIDTH LATIN SMALL LETTER D */
+ {0xff45, 1, 90}, /* FULLWIDTH LATIN SMALL LETTER E */
+ {0xff46, 1, 997}, /* FULLWIDTH LATIN SMALL LETTER F */
+ {0xff47, 1, 184}, /* FULLWIDTH LATIN SMALL LETTER G */
+ {0xff48, 1, 200}, /* FULLWIDTH LATIN SMALL LETTER H */
+ {0xff49, 1, 98}, /* FULLWIDTH LATIN SMALL LETTER I */
+ {0xff4a, 1, 223}, /* FULLWIDTH LATIN SMALL LETTER J */
+ {0xff4b, 1, 230}, /* FULLWIDTH LATIN SMALL LETTER K */
+ {0xff4c, 1, 234}, /* FULLWIDTH LATIN SMALL LETTER L */
+ {0xff4d, 1, 922}, /* FULLWIDTH LATIN SMALL LETTER M */
+ {0xff4e, 1, 106}, /* FULLWIDTH LATIN SMALL LETTER N */
+ {0xff4f, 1, 14}, /* FULLWIDTH LATIN SMALL LETTER O */
+ {0xff50, 1, 927}, /* FULLWIDTH LATIN SMALL LETTER P */
+ {0xff51, 1, 2335}, /* FULLWIDTH LATIN SMALL LETTER Q */
+ {0xff52, 1, 276}, /* FULLWIDTH LATIN SMALL LETTER R */
+ {0xff53, 1, 288}, /* FULLWIDTH LATIN SMALL LETTER S */
+ {0xff54, 1, 304}, /* FULLWIDTH LATIN SMALL LETTER T */
+ {0xff55, 1, 118}, /* FULLWIDTH LATIN SMALL LETTER U */
+ {0xff56, 1, 930}, /* FULLWIDTH LATIN SMALL LETTER V */
+ {0xff57, 1, 336}, /* FULLWIDTH LATIN SMALL LETTER W */
+ {0xff58, 1, 579}, /* FULLWIDTH LATIN SMALL LETTER X */
+ {0xff59, 1, 126}, /* FULLWIDTH LATIN SMALL LETTER Y */
+ {0xff5a, 1, 346}, /* FULLWIDTH LATIN SMALL LETTER Z */
+ {0xff5b, 1, 5000}, /* FULLWIDTH LEFT CURLY BRACKET */
+ {0xff5c, 1, 5050}, /* FULLWIDTH VERTICAL LINE */
+ {0xff5d, 1, 5001}, /* FULLWIDTH RIGHT CURLY BRACKET */
+ {0xff5e, 1, 5051}, /* FULLWIDTH TILDE */
+ {0xff5f, 1, 5052}, /* FULLWIDTH LEFT WHITE PARENTHESIS */
+ {0xff60, 1, 5053}, /* FULLWIDTH RIGHT WHITE PARENTHESIS */
+ {0xff61, 1, 5054}, /* HALFWIDTH IDEOGRAPHIC FULL STOP */
+ {0xff62, 1, 5008}, /* HALFWIDTH LEFT CORNER BRACKET */
+ {0xff63, 1, 5009}, /* HALFWIDTH RIGHT CORNER BRACKET */
+ {0xff64, 1, 5016}, /* HALFWIDTH IDEOGRAPHIC COMMA */
+ {0xff65, 1, 5055}, /* HALFWIDTH KATAKANA MIDDLE DOT */
+ {0xff66, 1, 2709}, /* HALFWIDTH KATAKANA LETTER WO */
+ {0xff67, 1, 3180}, /* HALFWIDTH KATAKANA LETTER SMALL A */
+ {0xff68, 1, 3348}, /* HALFWIDTH KATAKANA LETTER SMALL I */
+ {0xff69, 1, 5056}, /* HALFWIDTH KATAKANA LETTER SMALL U */
+ {0xff6a, 1, 3354}, /* HALFWIDTH KATAKANA LETTER SMALL E */
+ {0xff6b, 1, 3196}, /* HALFWIDTH KATAKANA LETTER SMALL O */
+ {0xff6c, 1, 5057}, /* HALFWIDTH KATAKANA LETTER SMALL YA */
+ {0xff6d, 1, 3236}, /* HALFWIDTH KATAKANA LETTER SMALL YU */
+ {0xff6e, 1, 3415}, /* HALFWIDTH KATAKANA LETTER SMALL YO */
+ {0xff6f, 1, 3218}, /* HALFWIDTH KATAKANA LETTER SMALL TU */
+ {0xff70, 1, 3175}, /* HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+ {0xff71, 1, 3151}, /* HALFWIDTH KATAKANA LETTER A */
+ {0xff72, 1, 3152}, /* HALFWIDTH KATAKANA LETTER I */
+ {0xff73, 1, 2701}, /* HALFWIDTH KATAKANA LETTER U */
+ {0xff74, 1, 3153}, /* HALFWIDTH KATAKANA LETTER E */
+ {0xff75, 1, 3154}, /* HALFWIDTH KATAKANA LETTER O */
+ {0xff76, 1, 2651}, /* HALFWIDTH KATAKANA LETTER KA */
+ {0xff77, 1, 2653}, /* HALFWIDTH KATAKANA LETTER KI */
+ {0xff78, 1, 2655}, /* HALFWIDTH KATAKANA LETTER KU */
+ {0xff79, 1, 2657}, /* HALFWIDTH KATAKANA LETTER KE */
+ {0xff7a, 1, 2659}, /* HALFWIDTH KATAKANA LETTER KO */
+ {0xff7b, 1, 2661}, /* HALFWIDTH KATAKANA LETTER SA */
+ {0xff7c, 1, 2663}, /* HALFWIDTH KATAKANA LETTER SI */
+ {0xff7d, 1, 2665}, /* HALFWIDTH KATAKANA LETTER SU */
+ {0xff7e, 1, 2667}, /* HALFWIDTH KATAKANA LETTER SE */
+ {0xff7f, 1, 2669}, /* HALFWIDTH KATAKANA LETTER SO */
+ {0xff80, 1, 2671}, /* HALFWIDTH KATAKANA LETTER TA */
+ {0xff81, 1, 2673}, /* HALFWIDTH KATAKANA LETTER TI */
+ {0xff82, 1, 2675}, /* HALFWIDTH KATAKANA LETTER TU */
+ {0xff83, 1, 2677}, /* HALFWIDTH KATAKANA LETTER TE */
+ {0xff84, 1, 2679}, /* HALFWIDTH KATAKANA LETTER TO */
+ {0xff85, 1, 3155}, /* HALFWIDTH KATAKANA LETTER NA */
+ {0xff86, 1, 3156}, /* HALFWIDTH KATAKANA LETTER NI */
+ {0xff87, 1, 3157}, /* HALFWIDTH KATAKANA LETTER NU */
+ {0xff88, 1, 3158}, /* HALFWIDTH KATAKANA LETTER NE */
+ {0xff89, 1, 3159}, /* HALFWIDTH KATAKANA LETTER NO */
+ {0xff8a, 1, 2681}, /* HALFWIDTH KATAKANA LETTER HA */
+ {0xff8b, 1, 2685}, /* HALFWIDTH KATAKANA LETTER HI */
+ {0xff8c, 1, 2689}, /* HALFWIDTH KATAKANA LETTER HU */
+ {0xff8d, 1, 2693}, /* HALFWIDTH KATAKANA LETTER HE */
+ {0xff8e, 1, 2697}, /* HALFWIDTH KATAKANA LETTER HO */
+ {0xff8f, 1, 3160}, /* HALFWIDTH KATAKANA LETTER MA */
+ {0xff90, 1, 3161}, /* HALFWIDTH KATAKANA LETTER MI */
+ {0xff91, 1, 3162}, /* HALFWIDTH KATAKANA LETTER MU */
+ {0xff92, 1, 3163}, /* HALFWIDTH KATAKANA LETTER ME */
+ {0xff93, 1, 3164}, /* HALFWIDTH KATAKANA LETTER MO */
+ {0xff94, 1, 3165}, /* HALFWIDTH KATAKANA LETTER YA */
+ {0xff95, 1, 3166}, /* HALFWIDTH KATAKANA LETTER YU */
+ {0xff96, 1, 3167}, /* HALFWIDTH KATAKANA LETTER YO */
+ {0xff97, 1, 3168}, /* HALFWIDTH KATAKANA LETTER RA */
+ {0xff98, 1, 3169}, /* HALFWIDTH KATAKANA LETTER RI */
+ {0xff99, 1, 3170}, /* HALFWIDTH KATAKANA LETTER RU */
+ {0xff9a, 1, 3171}, /* HALFWIDTH KATAKANA LETTER RE */
+ {0xff9b, 1, 3172}, /* HALFWIDTH KATAKANA LETTER RO */
+ {0xff9c, 1, 2703}, /* HALFWIDTH KATAKANA LETTER WA */
+ {0xff9d, 1, 3182}, /* HALFWIDTH KATAKANA LETTER N */
+ {0xff9e, 1, 2592}, /* HALFWIDTH KATAKANA VOICED SOUND MARK */
+ {0xff9f, 1, 2624}, /* HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK */
+ {0xffa0, 1, 5058}, /* HALFWIDTH HANGUL FILLER */
+ {0xffa1, 1, 5059}, /* HALFWIDTH HANGUL LETTER KIYEOK */
+ {0xffa2, 1, 5060}, /* HALFWIDTH HANGUL LETTER SSANGKIYEOK */
+ {0xffa3, 1, 5061}, /* HALFWIDTH HANGUL LETTER KIYEOK-SIOS */
+ {0xffa4, 1, 5062}, /* HALFWIDTH HANGUL LETTER NIEUN */
+ {0xffa5, 1, 5063}, /* HALFWIDTH HANGUL LETTER NIEUN-CIEUC */
+ {0xffa6, 1, 5064}, /* HALFWIDTH HANGUL LETTER NIEUN-HIEUH */
+ {0xffa7, 1, 5065}, /* HALFWIDTH HANGUL LETTER TIKEUT */
+ {0xffa8, 1, 5066}, /* HALFWIDTH HANGUL LETTER SSANGTIKEUT */
+ {0xffa9, 1, 5067}, /* HALFWIDTH HANGUL LETTER RIEUL */
+ {0xffaa, 1, 5068}, /* HALFWIDTH HANGUL LETTER RIEUL-KIYEOK */
+ {0xffab, 1, 5069}, /* HALFWIDTH HANGUL LETTER RIEUL-MIEUM */
+ {0xffac, 1, 5070}, /* HALFWIDTH HANGUL LETTER RIEUL-PIEUP */
+ {0xffad, 1, 5071}, /* HALFWIDTH HANGUL LETTER RIEUL-SIOS */
+ {0xffae, 1, 5072}, /* HALFWIDTH HANGUL LETTER RIEUL-THIEUTH */
+ {0xffaf, 1, 5073}, /* HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH */
+ {0xffb0, 1, 5074}, /* HALFWIDTH HANGUL LETTER RIEUL-HIEUH */
+ {0xffb1, 1, 5075}, /* HALFWIDTH HANGUL LETTER MIEUM */
+ {0xffb2, 1, 5076}, /* HALFWIDTH HANGUL LETTER PIEUP */
+ {0xffb3, 1, 5077}, /* HALFWIDTH HANGUL LETTER SSANGPIEUP */
+ {0xffb4, 1, 5078}, /* HALFWIDTH HANGUL LETTER PIEUP-SIOS */
+ {0xffb5, 1, 5079}, /* HALFWIDTH HANGUL LETTER SIOS */
+ {0xffb6, 1, 5080}, /* HALFWIDTH HANGUL LETTER SSANGSIOS */
+ {0xffb7, 1, 5081}, /* HALFWIDTH HANGUL LETTER IEUNG */
+ {0xffb8, 1, 5082}, /* HALFWIDTH HANGUL LETTER CIEUC */
+ {0xffb9, 1, 5083}, /* HALFWIDTH HANGUL LETTER SSANGCIEUC */
+ {0xffba, 1, 5084}, /* HALFWIDTH HANGUL LETTER CHIEUCH */
+ {0xffbb, 1, 5085}, /* HALFWIDTH HANGUL LETTER KHIEUKH */
+ {0xffbc, 1, 5086}, /* HALFWIDTH HANGUL LETTER THIEUTH */
+ {0xffbd, 1, 5087}, /* HALFWIDTH HANGUL LETTER PHIEUPH */
+ {0xffbe, 1, 5088}, /* HALFWIDTH HANGUL LETTER HIEUH */
+ {0xffc2, 1, 5089}, /* HALFWIDTH HANGUL LETTER A */
+ {0xffc3, 1, 5090}, /* HALFWIDTH HANGUL LETTER AE */
+ {0xffc4, 1, 5091}, /* HALFWIDTH HANGUL LETTER YA */
+ {0xffc5, 1, 5092}, /* HALFWIDTH HANGUL LETTER YAE */
+ {0xffc6, 1, 5093}, /* HALFWIDTH HANGUL LETTER EO */
+ {0xffc7, 1, 5094}, /* HALFWIDTH HANGUL LETTER E */
+ {0xffca, 1, 5095}, /* HALFWIDTH HANGUL LETTER YEO */
+ {0xffcb, 1, 5096}, /* HALFWIDTH HANGUL LETTER YE */
+ {0xffcc, 1, 5097}, /* HALFWIDTH HANGUL LETTER O */
+ {0xffcd, 1, 5098}, /* HALFWIDTH HANGUL LETTER WA */
+ {0xffce, 1, 5099}, /* HALFWIDTH HANGUL LETTER WAE */
+ {0xffcf, 1, 5100}, /* HALFWIDTH HANGUL LETTER OE */
+ {0xffd2, 1, 5101}, /* HALFWIDTH HANGUL LETTER YO */
+ {0xffd3, 1, 5102}, /* HALFWIDTH HANGUL LETTER U */
+ {0xffd4, 1, 5103}, /* HALFWIDTH HANGUL LETTER WEO */
+ {0xffd5, 1, 5104}, /* HALFWIDTH HANGUL LETTER WE */
+ {0xffd6, 1, 5105}, /* HALFWIDTH HANGUL LETTER WI */
+ {0xffd7, 1, 5106}, /* HALFWIDTH HANGUL LETTER YU */
+ {0xffda, 1, 5107}, /* HALFWIDTH HANGUL LETTER EU */
+ {0xffdb, 1, 5108}, /* HALFWIDTH HANGUL LETTER YI */
+ {0xffdc, 1, 5109}, /* HALFWIDTH HANGUL LETTER I */
+ {0xffe0, 1, 5110}, /* FULLWIDTH CENT SIGN */
+ {0xffe1, 1, 5111}, /* FULLWIDTH POUND SIGN */
+ {0xffe2, 1, 5112}, /* FULLWIDTH NOT SIGN */
+ {0xffe3, 1, 5113}, /* FULLWIDTH MACRON */
+ {0xffe4, 1, 5114}, /* FULLWIDTH BROKEN BAR */
+ {0xffe5, 1, 5115}, /* FULLWIDTH YEN SIGN */
+ {0xffe6, 1, 5116}, /* FULLWIDTH WON SIGN */
+ {0xffe8, 1, 5117}, /* HALFWIDTH FORMS LIGHT VERTICAL */
+ {0xffe9, 1, 2042}, /* HALFWIDTH LEFTWARDS ARROW */
+ {0xffea, 1, 5118}, /* HALFWIDTH UPWARDS ARROW */
+ {0xffeb, 1, 2044}, /* HALFWIDTH RIGHTWARDS ARROW */
+ {0xffec, 1, 5119}, /* HALFWIDTH DOWNWARDS ARROW */
+ {0xffed, 1, 5120}, /* HALFWIDTH BLACK SQUARE */
+ {0xffee, 1, 5121}, /* HALFWIDTH WHITE CIRCLE */
+ {0x1d15e, 2, 5122}, /* MUSICAL SYMBOL HALF NOTE */
+ {0x1d15f, 2, 5124}, /* MUSICAL SYMBOL QUARTER NOTE */
+ {0x1d160, 2, 5126}, /* MUSICAL SYMBOL EIGHTH NOTE */
+ {0x1d161, 2, 5128}, /* MUSICAL SYMBOL SIXTEENTH NOTE */
+ {0x1d162, 2, 5130}, /* MUSICAL SYMBOL THIRTY-SECOND NOTE */
+ {0x1d163, 2, 5132}, /* MUSICAL SYMBOL SIXTY-FOURTH NOTE */
+ {0x1d164, 2, 5134}, /* MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE */
+ {0x1d1bb, 2, 5136}, /* MUSICAL SYMBOL MINIMA */
+ {0x1d1bc, 2, 5138}, /* MUSICAL SYMBOL MINIMA BLACK */
+ {0x1d1bd, 2, 5140}, /* MUSICAL SYMBOL SEMIMINIMA WHITE */
+ {0x1d1be, 2, 5142}, /* MUSICAL SYMBOL SEMIMINIMA BLACK */
+ {0x1d1bf, 2, 5144}, /* MUSICAL SYMBOL FUSA WHITE */
+ {0x1d1c0, 2, 5146}, /* MUSICAL SYMBOL FUSA BLACK */
+ {0x1d400, 1, 24}, /* MATHEMATICAL BOLD CAPITAL A */
+ {0x1d401, 1, 910}, /* MATHEMATICAL BOLD CAPITAL B */
+ {0x1d402, 1, 36}, /* MATHEMATICAL BOLD CAPITAL C */
+ {0x1d403, 1, 158}, /* MATHEMATICAL BOLD CAPITAL D */
+ {0x1d404, 1, 38}, /* MATHEMATICAL BOLD CAPITAL E */
+ {0x1d405, 1, 995}, /* MATHEMATICAL BOLD CAPITAL F */
+ {0x1d406, 1, 182}, /* MATHEMATICAL BOLD CAPITAL G */
+ {0x1d407, 1, 198}, /* MATHEMATICAL BOLD CAPITAL H */
+ {0x1d408, 1, 46}, /* MATHEMATICAL BOLD CAPITAL I */
+ {0x1d409, 1, 221}, /* MATHEMATICAL BOLD CAPITAL J */
+ {0x1d40a, 1, 228}, /* MATHEMATICAL BOLD CAPITAL K */
+ {0x1d40b, 1, 232}, /* MATHEMATICAL BOLD CAPITAL L */
+ {0x1d40c, 1, 912}, /* MATHEMATICAL BOLD CAPITAL M */
+ {0x1d40d, 1, 54}, /* MATHEMATICAL BOLD CAPITAL N */
+ {0x1d40e, 1, 56}, /* MATHEMATICAL BOLD CAPITAL O */
+ {0x1d40f, 1, 914}, /* MATHEMATICAL BOLD CAPITAL P */
+ {0x1d410, 1, 1942}, /* MATHEMATICAL BOLD CAPITAL Q */
+ {0x1d411, 1, 274}, /* MATHEMATICAL BOLD CAPITAL R */
+ {0x1d412, 1, 286}, /* MATHEMATICAL BOLD CAPITAL S */
+ {0x1d413, 1, 302}, /* MATHEMATICAL BOLD CAPITAL T */
+ {0x1d414, 1, 66}, /* MATHEMATICAL BOLD CAPITAL U */
+ {0x1d415, 1, 1183}, /* MATHEMATICAL BOLD CAPITAL V */
+ {0x1d416, 1, 334}, /* MATHEMATICAL BOLD CAPITAL W */
+ {0x1d417, 1, 1211}, /* MATHEMATICAL BOLD CAPITAL X */
+ {0x1d418, 1, 74}, /* MATHEMATICAL BOLD CAPITAL Y */
+ {0x1d419, 1, 344}, /* MATHEMATICAL BOLD CAPITAL Z */
+ {0x1d41a, 1, 3}, /* MATHEMATICAL BOLD SMALL A */
+ {0x1d41b, 1, 918}, /* MATHEMATICAL BOLD SMALL B */
+ {0x1d41c, 1, 88}, /* MATHEMATICAL BOLD SMALL C */
+ {0x1d41d, 1, 160}, /* MATHEMATICAL BOLD SMALL D */
+ {0x1d41e, 1, 90}, /* MATHEMATICAL BOLD SMALL E */
+ {0x1d41f, 1, 997}, /* MATHEMATICAL BOLD SMALL F */
+ {0x1d420, 1, 184}, /* MATHEMATICAL BOLD SMALL G */
+ {0x1d421, 1, 200}, /* MATHEMATICAL BOLD SMALL H */
+ {0x1d422, 1, 98}, /* MATHEMATICAL BOLD SMALL I */
+ {0x1d423, 1, 223}, /* MATHEMATICAL BOLD SMALL J */
+ {0x1d424, 1, 230}, /* MATHEMATICAL BOLD SMALL K */
+ {0x1d425, 1, 234}, /* MATHEMATICAL BOLD SMALL L */
+ {0x1d426, 1, 922}, /* MATHEMATICAL BOLD SMALL M */
+ {0x1d427, 1, 106}, /* MATHEMATICAL BOLD SMALL N */
+ {0x1d428, 1, 14}, /* MATHEMATICAL BOLD SMALL O */
+ {0x1d429, 1, 927}, /* MATHEMATICAL BOLD SMALL P */
+ {0x1d42a, 1, 2335}, /* MATHEMATICAL BOLD SMALL Q */
+ {0x1d42b, 1, 276}, /* MATHEMATICAL BOLD SMALL R */
+ {0x1d42c, 1, 288}, /* MATHEMATICAL BOLD SMALL S */
+ {0x1d42d, 1, 304}, /* MATHEMATICAL BOLD SMALL T */
+ {0x1d42e, 1, 118}, /* MATHEMATICAL BOLD SMALL U */
+ {0x1d42f, 1, 930}, /* MATHEMATICAL BOLD SMALL V */
+ {0x1d430, 1, 336}, /* MATHEMATICAL BOLD SMALL W */
+ {0x1d431, 1, 579}, /* MATHEMATICAL BOLD SMALL X */
+ {0x1d432, 1, 126}, /* MATHEMATICAL BOLD SMALL Y */
+ {0x1d433, 1, 346}, /* MATHEMATICAL BOLD SMALL Z */
+ {0x1d434, 1, 24}, /* MATHEMATICAL ITALIC CAPITAL A */
+ {0x1d435, 1, 910}, /* MATHEMATICAL ITALIC CAPITAL B */
+ {0x1d436, 1, 36}, /* MATHEMATICAL ITALIC CAPITAL C */
+ {0x1d437, 1, 158}, /* MATHEMATICAL ITALIC CAPITAL D */
+ {0x1d438, 1, 38}, /* MATHEMATICAL ITALIC CAPITAL E */
+ {0x1d439, 1, 995}, /* MATHEMATICAL ITALIC CAPITAL F */
+ {0x1d43a, 1, 182}, /* MATHEMATICAL ITALIC CAPITAL G */
+ {0x1d43b, 1, 198}, /* MATHEMATICAL ITALIC CAPITAL H */
+ {0x1d43c, 1, 46}, /* MATHEMATICAL ITALIC CAPITAL I */
+ {0x1d43d, 1, 221}, /* MATHEMATICAL ITALIC CAPITAL J */
+ {0x1d43e, 1, 228}, /* MATHEMATICAL ITALIC CAPITAL K */
+ {0x1d43f, 1, 232}, /* MATHEMATICAL ITALIC CAPITAL L */
+ {0x1d440, 1, 912}, /* MATHEMATICAL ITALIC CAPITAL M */
+ {0x1d441, 1, 54}, /* MATHEMATICAL ITALIC CAPITAL N */
+ {0x1d442, 1, 56}, /* MATHEMATICAL ITALIC CAPITAL O */
+ {0x1d443, 1, 914}, /* MATHEMATICAL ITALIC CAPITAL P */
+ {0x1d444, 1, 1942}, /* MATHEMATICAL ITALIC CAPITAL Q */
+ {0x1d445, 1, 274}, /* MATHEMATICAL ITALIC CAPITAL R */
+ {0x1d446, 1, 286}, /* MATHEMATICAL ITALIC CAPITAL S */
+ {0x1d447, 1, 302}, /* MATHEMATICAL ITALIC CAPITAL T */
+ {0x1d448, 1, 66}, /* MATHEMATICAL ITALIC CAPITAL U */
+ {0x1d449, 1, 1183}, /* MATHEMATICAL ITALIC CAPITAL V */
+ {0x1d44a, 1, 334}, /* MATHEMATICAL ITALIC CAPITAL W */
+ {0x1d44b, 1, 1211}, /* MATHEMATICAL ITALIC CAPITAL X */
+ {0x1d44c, 1, 74}, /* MATHEMATICAL ITALIC CAPITAL Y */
+ {0x1d44d, 1, 344}, /* MATHEMATICAL ITALIC CAPITAL Z */
+ {0x1d44e, 1, 3}, /* MATHEMATICAL ITALIC SMALL A */
+ {0x1d44f, 1, 918}, /* MATHEMATICAL ITALIC SMALL B */
+ {0x1d450, 1, 88}, /* MATHEMATICAL ITALIC SMALL C */
+ {0x1d451, 1, 160}, /* MATHEMATICAL ITALIC SMALL D */
+ {0x1d452, 1, 90}, /* MATHEMATICAL ITALIC SMALL E */
+ {0x1d453, 1, 997}, /* MATHEMATICAL ITALIC SMALL F */
+ {0x1d454, 1, 184}, /* MATHEMATICAL ITALIC SMALL G */
+ {0x1d456, 1, 98}, /* MATHEMATICAL ITALIC SMALL I */
+ {0x1d457, 1, 223}, /* MATHEMATICAL ITALIC SMALL J */
+ {0x1d458, 1, 230}, /* MATHEMATICAL ITALIC SMALL K */
+ {0x1d459, 1, 234}, /* MATHEMATICAL ITALIC SMALL L */
+ {0x1d45a, 1, 922}, /* MATHEMATICAL ITALIC SMALL M */
+ {0x1d45b, 1, 106}, /* MATHEMATICAL ITALIC SMALL N */
+ {0x1d45c, 1, 14}, /* MATHEMATICAL ITALIC SMALL O */
+ {0x1d45d, 1, 927}, /* MATHEMATICAL ITALIC SMALL P */
+ {0x1d45e, 1, 2335}, /* MATHEMATICAL ITALIC SMALL Q */
+ {0x1d45f, 1, 276}, /* MATHEMATICAL ITALIC SMALL R */
+ {0x1d460, 1, 288}, /* MATHEMATICAL ITALIC SMALL S */
+ {0x1d461, 1, 304}, /* MATHEMATICAL ITALIC SMALL T */
+ {0x1d462, 1, 118}, /* MATHEMATICAL ITALIC SMALL U */
+ {0x1d463, 1, 930}, /* MATHEMATICAL ITALIC SMALL V */
+ {0x1d464, 1, 336}, /* MATHEMATICAL ITALIC SMALL W */
+ {0x1d465, 1, 579}, /* MATHEMATICAL ITALIC SMALL X */
+ {0x1d466, 1, 126}, /* MATHEMATICAL ITALIC SMALL Y */
+ {0x1d467, 1, 346}, /* MATHEMATICAL ITALIC SMALL Z */
+ {0x1d468, 1, 24}, /* MATHEMATICAL BOLD ITALIC CAPITAL A */
+ {0x1d469, 1, 910}, /* MATHEMATICAL BOLD ITALIC CAPITAL B */
+ {0x1d46a, 1, 36}, /* MATHEMATICAL BOLD ITALIC CAPITAL C */
+ {0x1d46b, 1, 158}, /* MATHEMATICAL BOLD ITALIC CAPITAL D */
+ {0x1d46c, 1, 38}, /* MATHEMATICAL BOLD ITALIC CAPITAL E */
+ {0x1d46d, 1, 995}, /* MATHEMATICAL BOLD ITALIC CAPITAL F */
+ {0x1d46e, 1, 182}, /* MATHEMATICAL BOLD ITALIC CAPITAL G */
+ {0x1d46f, 1, 198}, /* MATHEMATICAL BOLD ITALIC CAPITAL H */
+ {0x1d470, 1, 46}, /* MATHEMATICAL BOLD ITALIC CAPITAL I */
+ {0x1d471, 1, 221}, /* MATHEMATICAL BOLD ITALIC CAPITAL J */
+ {0x1d472, 1, 228}, /* MATHEMATICAL BOLD ITALIC CAPITAL K */
+ {0x1d473, 1, 232}, /* MATHEMATICAL BOLD ITALIC CAPITAL L */
+ {0x1d474, 1, 912}, /* MATHEMATICAL BOLD ITALIC CAPITAL M */
+ {0x1d475, 1, 54}, /* MATHEMATICAL BOLD ITALIC CAPITAL N */
+ {0x1d476, 1, 56}, /* MATHEMATICAL BOLD ITALIC CAPITAL O */
+ {0x1d477, 1, 914}, /* MATHEMATICAL BOLD ITALIC CAPITAL P */
+ {0x1d478, 1, 1942}, /* MATHEMATICAL BOLD ITALIC CAPITAL Q */
+ {0x1d479, 1, 274}, /* MATHEMATICAL BOLD ITALIC CAPITAL R */
+ {0x1d47a, 1, 286}, /* MATHEMATICAL BOLD ITALIC CAPITAL S */
+ {0x1d47b, 1, 302}, /* MATHEMATICAL BOLD ITALIC CAPITAL T */
+ {0x1d47c, 1, 66}, /* MATHEMATICAL BOLD ITALIC CAPITAL U */
+ {0x1d47d, 1, 1183}, /* MATHEMATICAL BOLD ITALIC CAPITAL V */
+ {0x1d47e, 1, 334}, /* MATHEMATICAL BOLD ITALIC CAPITAL W */
+ {0x1d47f, 1, 1211}, /* MATHEMATICAL BOLD ITALIC CAPITAL X */
+ {0x1d480, 1, 74}, /* MATHEMATICAL BOLD ITALIC CAPITAL Y */
+ {0x1d481, 1, 344}, /* MATHEMATICAL BOLD ITALIC CAPITAL Z */
+ {0x1d482, 1, 3}, /* MATHEMATICAL BOLD ITALIC SMALL A */
+ {0x1d483, 1, 918}, /* MATHEMATICAL BOLD ITALIC SMALL B */
+ {0x1d484, 1, 88}, /* MATHEMATICAL BOLD ITALIC SMALL C */
+ {0x1d485, 1, 160}, /* MATHEMATICAL BOLD ITALIC SMALL D */
+ {0x1d486, 1, 90}, /* MATHEMATICAL BOLD ITALIC SMALL E */
+ {0x1d487, 1, 997}, /* MATHEMATICAL BOLD ITALIC SMALL F */
+ {0x1d488, 1, 184}, /* MATHEMATICAL BOLD ITALIC SMALL G */
+ {0x1d489, 1, 200}, /* MATHEMATICAL BOLD ITALIC SMALL H */
+ {0x1d48a, 1, 98}, /* MATHEMATICAL BOLD ITALIC SMALL I */
+ {0x1d48b, 1, 223}, /* MATHEMATICAL BOLD ITALIC SMALL J */
+ {0x1d48c, 1, 230}, /* MATHEMATICAL BOLD ITALIC SMALL K */
+ {0x1d48d, 1, 234}, /* MATHEMATICAL BOLD ITALIC SMALL L */
+ {0x1d48e, 1, 922}, /* MATHEMATICAL BOLD ITALIC SMALL M */
+ {0x1d48f, 1, 106}, /* MATHEMATICAL BOLD ITALIC SMALL N */
+ {0x1d490, 1, 14}, /* MATHEMATICAL BOLD ITALIC SMALL O */
+ {0x1d491, 1, 927}, /* MATHEMATICAL BOLD ITALIC SMALL P */
+ {0x1d492, 1, 2335}, /* MATHEMATICAL BOLD ITALIC SMALL Q */
+ {0x1d493, 1, 276}, /* MATHEMATICAL BOLD ITALIC SMALL R */
+ {0x1d494, 1, 288}, /* MATHEMATICAL BOLD ITALIC SMALL S */
+ {0x1d495, 1, 304}, /* MATHEMATICAL BOLD ITALIC SMALL T */
+ {0x1d496, 1, 118}, /* MATHEMATICAL BOLD ITALIC SMALL U */
+ {0x1d497, 1, 930}, /* MATHEMATICAL BOLD ITALIC SMALL V */
+ {0x1d498, 1, 336}, /* MATHEMATICAL BOLD ITALIC SMALL W */
+ {0x1d499, 1, 579}, /* MATHEMATICAL BOLD ITALIC SMALL X */
+ {0x1d49a, 1, 126}, /* MATHEMATICAL BOLD ITALIC SMALL Y */
+ {0x1d49b, 1, 346}, /* MATHEMATICAL BOLD ITALIC SMALL Z */
+ {0x1d49c, 1, 24}, /* MATHEMATICAL SCRIPT CAPITAL A */
+ {0x1d49e, 1, 36}, /* MATHEMATICAL SCRIPT CAPITAL C */
+ {0x1d49f, 1, 158}, /* MATHEMATICAL SCRIPT CAPITAL D */
+ {0x1d4a2, 1, 182}, /* MATHEMATICAL SCRIPT CAPITAL G */
+ {0x1d4a5, 1, 221}, /* MATHEMATICAL SCRIPT CAPITAL J */
+ {0x1d4a6, 1, 228}, /* MATHEMATICAL SCRIPT CAPITAL K */
+ {0x1d4a9, 1, 54}, /* MATHEMATICAL SCRIPT CAPITAL N */
+ {0x1d4aa, 1, 56}, /* MATHEMATICAL SCRIPT CAPITAL O */
+ {0x1d4ab, 1, 914}, /* MATHEMATICAL SCRIPT CAPITAL P */
+ {0x1d4ac, 1, 1942}, /* MATHEMATICAL SCRIPT CAPITAL Q */
+ {0x1d4ae, 1, 286}, /* MATHEMATICAL SCRIPT CAPITAL S */
+ {0x1d4af, 1, 302}, /* MATHEMATICAL SCRIPT CAPITAL T */
+ {0x1d4b0, 1, 66}, /* MATHEMATICAL SCRIPT CAPITAL U */
+ {0x1d4b1, 1, 1183}, /* MATHEMATICAL SCRIPT CAPITAL V */
+ {0x1d4b2, 1, 334}, /* MATHEMATICAL SCRIPT CAPITAL W */
+ {0x1d4b3, 1, 1211}, /* MATHEMATICAL SCRIPT CAPITAL X */
+ {0x1d4b4, 1, 74}, /* MATHEMATICAL SCRIPT CAPITAL Y */
+ {0x1d4b5, 1, 344}, /* MATHEMATICAL SCRIPT CAPITAL Z */
+ {0x1d4b6, 1, 3}, /* MATHEMATICAL SCRIPT SMALL A */
+ {0x1d4b7, 1, 918}, /* MATHEMATICAL SCRIPT SMALL B */
+ {0x1d4b8, 1, 88}, /* MATHEMATICAL SCRIPT SMALL C */
+ {0x1d4b9, 1, 160}, /* MATHEMATICAL SCRIPT SMALL D */
+ {0x1d4bb, 1, 997}, /* MATHEMATICAL SCRIPT SMALL F */
+ {0x1d4bd, 1, 200}, /* MATHEMATICAL SCRIPT SMALL H */
+ {0x1d4be, 1, 98}, /* MATHEMATICAL SCRIPT SMALL I */
+ {0x1d4bf, 1, 223}, /* MATHEMATICAL SCRIPT SMALL J */
+ {0x1d4c0, 1, 230}, /* MATHEMATICAL SCRIPT SMALL K */
+ {0x1d4c1, 1, 234}, /* MATHEMATICAL SCRIPT SMALL L */
+ {0x1d4c2, 1, 922}, /* MATHEMATICAL SCRIPT SMALL M */
+ {0x1d4c3, 1, 106}, /* MATHEMATICAL SCRIPT SMALL N */
+ {0x1d4c5, 1, 927}, /* MATHEMATICAL SCRIPT SMALL P */
+ {0x1d4c6, 1, 2335}, /* MATHEMATICAL SCRIPT SMALL Q */
+ {0x1d4c7, 1, 276}, /* MATHEMATICAL SCRIPT SMALL R */
+ {0x1d4c8, 1, 288}, /* MATHEMATICAL SCRIPT SMALL S */
+ {0x1d4c9, 1, 304}, /* MATHEMATICAL SCRIPT SMALL T */
+ {0x1d4ca, 1, 118}, /* MATHEMATICAL SCRIPT SMALL U */
+ {0x1d4cb, 1, 930}, /* MATHEMATICAL SCRIPT SMALL V */
+ {0x1d4cc, 1, 336}, /* MATHEMATICAL SCRIPT SMALL W */
+ {0x1d4cd, 1, 579}, /* MATHEMATICAL SCRIPT SMALL X */
+ {0x1d4ce, 1, 126}, /* MATHEMATICAL SCRIPT SMALL Y */
+ {0x1d4cf, 1, 346}, /* MATHEMATICAL SCRIPT SMALL Z */
+ {0x1d4d0, 1, 24}, /* MATHEMATICAL BOLD SCRIPT CAPITAL A */
+ {0x1d4d1, 1, 910}, /* MATHEMATICAL BOLD SCRIPT CAPITAL B */
+ {0x1d4d2, 1, 36}, /* MATHEMATICAL BOLD SCRIPT CAPITAL C */
+ {0x1d4d3, 1, 158}, /* MATHEMATICAL BOLD SCRIPT CAPITAL D */
+ {0x1d4d4, 1, 38}, /* MATHEMATICAL BOLD SCRIPT CAPITAL E */
+ {0x1d4d5, 1, 995}, /* MATHEMATICAL BOLD SCRIPT CAPITAL F */
+ {0x1d4d6, 1, 182}, /* MATHEMATICAL BOLD SCRIPT CAPITAL G */
+ {0x1d4d7, 1, 198}, /* MATHEMATICAL BOLD SCRIPT CAPITAL H */
+ {0x1d4d8, 1, 46}, /* MATHEMATICAL BOLD SCRIPT CAPITAL I */
+ {0x1d4d9, 1, 221}, /* MATHEMATICAL BOLD SCRIPT CAPITAL J */
+ {0x1d4da, 1, 228}, /* MATHEMATICAL BOLD SCRIPT CAPITAL K */
+ {0x1d4db, 1, 232}, /* MATHEMATICAL BOLD SCRIPT CAPITAL L */
+ {0x1d4dc, 1, 912}, /* MATHEMATICAL BOLD SCRIPT CAPITAL M */
+ {0x1d4dd, 1, 54}, /* MATHEMATICAL BOLD SCRIPT CAPITAL N */
+ {0x1d4de, 1, 56}, /* MATHEMATICAL BOLD SCRIPT CAPITAL O */
+ {0x1d4df, 1, 914}, /* MATHEMATICAL BOLD SCRIPT CAPITAL P */
+ {0x1d4e0, 1, 1942}, /* MATHEMATICAL BOLD SCRIPT CAPITAL Q */
+ {0x1d4e1, 1, 274}, /* MATHEMATICAL BOLD SCRIPT CAPITAL R */
+ {0x1d4e2, 1, 286}, /* MATHEMATICAL BOLD SCRIPT CAPITAL S */
+ {0x1d4e3, 1, 302}, /* MATHEMATICAL BOLD SCRIPT CAPITAL T */
+ {0x1d4e4, 1, 66}, /* MATHEMATICAL BOLD SCRIPT CAPITAL U */
+ {0x1d4e5, 1, 1183}, /* MATHEMATICAL BOLD SCRIPT CAPITAL V */
+ {0x1d4e6, 1, 334}, /* MATHEMATICAL BOLD SCRIPT CAPITAL W */
+ {0x1d4e7, 1, 1211}, /* MATHEMATICAL BOLD SCRIPT CAPITAL X */
+ {0x1d4e8, 1, 74}, /* MATHEMATICAL BOLD SCRIPT CAPITAL Y */
+ {0x1d4e9, 1, 344}, /* MATHEMATICAL BOLD SCRIPT CAPITAL Z */
+ {0x1d4ea, 1, 3}, /* MATHEMATICAL BOLD SCRIPT SMALL A */
+ {0x1d4eb, 1, 918}, /* MATHEMATICAL BOLD SCRIPT SMALL B */
+ {0x1d4ec, 1, 88}, /* MATHEMATICAL BOLD SCRIPT SMALL C */
+ {0x1d4ed, 1, 160}, /* MATHEMATICAL BOLD SCRIPT SMALL D */
+ {0x1d4ee, 1, 90}, /* MATHEMATICAL BOLD SCRIPT SMALL E */
+ {0x1d4ef, 1, 997}, /* MATHEMATICAL BOLD SCRIPT SMALL F */
+ {0x1d4f0, 1, 184}, /* MATHEMATICAL BOLD SCRIPT SMALL G */
+ {0x1d4f1, 1, 200}, /* MATHEMATICAL BOLD SCRIPT SMALL H */
+ {0x1d4f2, 1, 98}, /* MATHEMATICAL BOLD SCRIPT SMALL I */
+ {0x1d4f3, 1, 223}, /* MATHEMATICAL BOLD SCRIPT SMALL J */
+ {0x1d4f4, 1, 230}, /* MATHEMATICAL BOLD SCRIPT SMALL K */
+ {0x1d4f5, 1, 234}, /* MATHEMATICAL BOLD SCRIPT SMALL L */
+ {0x1d4f6, 1, 922}, /* MATHEMATICAL BOLD SCRIPT SMALL M */
+ {0x1d4f7, 1, 106}, /* MATHEMATICAL BOLD SCRIPT SMALL N */
+ {0x1d4f8, 1, 14}, /* MATHEMATICAL BOLD SCRIPT SMALL O */
+ {0x1d4f9, 1, 927}, /* MATHEMATICAL BOLD SCRIPT SMALL P */
+ {0x1d4fa, 1, 2335}, /* MATHEMATICAL BOLD SCRIPT SMALL Q */
+ {0x1d4fb, 1, 276}, /* MATHEMATICAL BOLD SCRIPT SMALL R */
+ {0x1d4fc, 1, 288}, /* MATHEMATICAL BOLD SCRIPT SMALL S */
+ {0x1d4fd, 1, 304}, /* MATHEMATICAL BOLD SCRIPT SMALL T */
+ {0x1d4fe, 1, 118}, /* MATHEMATICAL BOLD SCRIPT SMALL U */
+ {0x1d4ff, 1, 930}, /* MATHEMATICAL BOLD SCRIPT SMALL V */
+ {0x1d500, 1, 336}, /* MATHEMATICAL BOLD SCRIPT SMALL W */
+ {0x1d501, 1, 579}, /* MATHEMATICAL BOLD SCRIPT SMALL X */
+ {0x1d502, 1, 126}, /* MATHEMATICAL BOLD SCRIPT SMALL Y */
+ {0x1d503, 1, 346}, /* MATHEMATICAL BOLD SCRIPT SMALL Z */
+ {0x1d504, 1, 24}, /* MATHEMATICAL FRAKTUR CAPITAL A */
+ {0x1d505, 1, 910}, /* MATHEMATICAL FRAKTUR CAPITAL B */
+ {0x1d507, 1, 158}, /* MATHEMATICAL FRAKTUR CAPITAL D */
+ {0x1d508, 1, 38}, /* MATHEMATICAL FRAKTUR CAPITAL E */
+ {0x1d509, 1, 995}, /* MATHEMATICAL FRAKTUR CAPITAL F */
+ {0x1d50a, 1, 182}, /* MATHEMATICAL FRAKTUR CAPITAL G */
+ {0x1d50d, 1, 221}, /* MATHEMATICAL FRAKTUR CAPITAL J */
+ {0x1d50e, 1, 228}, /* MATHEMATICAL FRAKTUR CAPITAL K */
+ {0x1d50f, 1, 232}, /* MATHEMATICAL FRAKTUR CAPITAL L */
+ {0x1d510, 1, 912}, /* MATHEMATICAL FRAKTUR CAPITAL M */
+ {0x1d511, 1, 54}, /* MATHEMATICAL FRAKTUR CAPITAL N */
+ {0x1d512, 1, 56}, /* MATHEMATICAL FRAKTUR CAPITAL O */
+ {0x1d513, 1, 914}, /* MATHEMATICAL FRAKTUR CAPITAL P */
+ {0x1d514, 1, 1942}, /* MATHEMATICAL FRAKTUR CAPITAL Q */
+ {0x1d516, 1, 286}, /* MATHEMATICAL FRAKTUR CAPITAL S */
+ {0x1d517, 1, 302}, /* MATHEMATICAL FRAKTUR CAPITAL T */
+ {0x1d518, 1, 66}, /* MATHEMATICAL FRAKTUR CAPITAL U */
+ {0x1d519, 1, 1183}, /* MATHEMATICAL FRAKTUR CAPITAL V */
+ {0x1d51a, 1, 334}, /* MATHEMATICAL FRAKTUR CAPITAL W */
+ {0x1d51b, 1, 1211}, /* MATHEMATICAL FRAKTUR CAPITAL X */
+ {0x1d51c, 1, 74}, /* MATHEMATICAL FRAKTUR CAPITAL Y */
+ {0x1d51e, 1, 3}, /* MATHEMATICAL FRAKTUR SMALL A */
+ {0x1d51f, 1, 918}, /* MATHEMATICAL FRAKTUR SMALL B */
+ {0x1d520, 1, 88}, /* MATHEMATICAL FRAKTUR SMALL C */
+ {0x1d521, 1, 160}, /* MATHEMATICAL FRAKTUR SMALL D */
+ {0x1d522, 1, 90}, /* MATHEMATICAL FRAKTUR SMALL E */
+ {0x1d523, 1, 997}, /* MATHEMATICAL FRAKTUR SMALL F */
+ {0x1d524, 1, 184}, /* MATHEMATICAL FRAKTUR SMALL G */
+ {0x1d525, 1, 200}, /* MATHEMATICAL FRAKTUR SMALL H */
+ {0x1d526, 1, 98}, /* MATHEMATICAL FRAKTUR SMALL I */
+ {0x1d527, 1, 223}, /* MATHEMATICAL FRAKTUR SMALL J */
+ {0x1d528, 1, 230}, /* MATHEMATICAL FRAKTUR SMALL K */
+ {0x1d529, 1, 234}, /* MATHEMATICAL FRAKTUR SMALL L */
+ {0x1d52a, 1, 922}, /* MATHEMATICAL FRAKTUR SMALL M */
+ {0x1d52b, 1, 106}, /* MATHEMATICAL FRAKTUR SMALL N */
+ {0x1d52c, 1, 14}, /* MATHEMATICAL FRAKTUR SMALL O */
+ {0x1d52d, 1, 927}, /* MATHEMATICAL FRAKTUR SMALL P */
+ {0x1d52e, 1, 2335}, /* MATHEMATICAL FRAKTUR SMALL Q */
+ {0x1d52f, 1, 276}, /* MATHEMATICAL FRAKTUR SMALL R */
+ {0x1d530, 1, 288}, /* MATHEMATICAL FRAKTUR SMALL S */
+ {0x1d531, 1, 304}, /* MATHEMATICAL FRAKTUR SMALL T */
+ {0x1d532, 1, 118}, /* MATHEMATICAL FRAKTUR SMALL U */
+ {0x1d533, 1, 930}, /* MATHEMATICAL FRAKTUR SMALL V */
+ {0x1d534, 1, 336}, /* MATHEMATICAL FRAKTUR SMALL W */
+ {0x1d535, 1, 579}, /* MATHEMATICAL FRAKTUR SMALL X */
+ {0x1d536, 1, 126}, /* MATHEMATICAL FRAKTUR SMALL Y */
+ {0x1d537, 1, 346}, /* MATHEMATICAL FRAKTUR SMALL Z */
+ {0x1d538, 1, 24}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL A */
+ {0x1d539, 1, 910}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL B */
+ {0x1d53b, 1, 158}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL D */
+ {0x1d53c, 1, 38}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL E */
+ {0x1d53d, 1, 995}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL F */
+ {0x1d53e, 1, 182}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL G */
+ {0x1d540, 1, 46}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL I */
+ {0x1d541, 1, 221}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL J */
+ {0x1d542, 1, 228}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL K */
+ {0x1d543, 1, 232}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL L */
+ {0x1d544, 1, 912}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL M */
+ {0x1d546, 1, 56}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL O */
+ {0x1d54a, 1, 286}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL S */
+ {0x1d54b, 1, 302}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL T */
+ {0x1d54c, 1, 66}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL U */
+ {0x1d54d, 1, 1183}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL V */
+ {0x1d54e, 1, 334}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL W */
+ {0x1d54f, 1, 1211}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL X */
+ {0x1d550, 1, 74}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL Y */
+ {0x1d552, 1, 3}, /* MATHEMATICAL DOUBLE-STRUCK SMALL A */
+ {0x1d553, 1, 918}, /* MATHEMATICAL DOUBLE-STRUCK SMALL B */
+ {0x1d554, 1, 88}, /* MATHEMATICAL DOUBLE-STRUCK SMALL C */
+ {0x1d555, 1, 160}, /* MATHEMATICAL DOUBLE-STRUCK SMALL D */
+ {0x1d556, 1, 90}, /* MATHEMATICAL DOUBLE-STRUCK SMALL E */
+ {0x1d557, 1, 997}, /* MATHEMATICAL DOUBLE-STRUCK SMALL F */
+ {0x1d558, 1, 184}, /* MATHEMATICAL DOUBLE-STRUCK SMALL G */
+ {0x1d559, 1, 200}, /* MATHEMATICAL DOUBLE-STRUCK SMALL H */
+ {0x1d55a, 1, 98}, /* MATHEMATICAL DOUBLE-STRUCK SMALL I */
+ {0x1d55b, 1, 223}, /* MATHEMATICAL DOUBLE-STRUCK SMALL J */
+ {0x1d55c, 1, 230}, /* MATHEMATICAL DOUBLE-STRUCK SMALL K */
+ {0x1d55d, 1, 234}, /* MATHEMATICAL DOUBLE-STRUCK SMALL L */
+ {0x1d55e, 1, 922}, /* MATHEMATICAL DOUBLE-STRUCK SMALL M */
+ {0x1d55f, 1, 106}, /* MATHEMATICAL DOUBLE-STRUCK SMALL N */
+ {0x1d560, 1, 14}, /* MATHEMATICAL DOUBLE-STRUCK SMALL O */
+ {0x1d561, 1, 927}, /* MATHEMATICAL DOUBLE-STRUCK SMALL P */
+ {0x1d562, 1, 2335}, /* MATHEMATICAL DOUBLE-STRUCK SMALL Q */
+ {0x1d563, 1, 276}, /* MATHEMATICAL DOUBLE-STRUCK SMALL R */
+ {0x1d564, 1, 288}, /* MATHEMATICAL DOUBLE-STRUCK SMALL S */
+ {0x1d565, 1, 304}, /* MATHEMATICAL DOUBLE-STRUCK SMALL T */
+ {0x1d566, 1, 118}, /* MATHEMATICAL DOUBLE-STRUCK SMALL U */
+ {0x1d567, 1, 930}, /* MATHEMATICAL DOUBLE-STRUCK SMALL V */
+ {0x1d568, 1, 336}, /* MATHEMATICAL DOUBLE-STRUCK SMALL W */
+ {0x1d569, 1, 579}, /* MATHEMATICAL DOUBLE-STRUCK SMALL X */
+ {0x1d56a, 1, 126}, /* MATHEMATICAL DOUBLE-STRUCK SMALL Y */
+ {0x1d56b, 1, 346}, /* MATHEMATICAL DOUBLE-STRUCK SMALL Z */
+ {0x1d56c, 1, 24}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL A */
+ {0x1d56d, 1, 910}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL B */
+ {0x1d56e, 1, 36}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL C */
+ {0x1d56f, 1, 158}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL D */
+ {0x1d570, 1, 38}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL E */
+ {0x1d571, 1, 995}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL F */
+ {0x1d572, 1, 182}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL G */
+ {0x1d573, 1, 198}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL H */
+ {0x1d574, 1, 46}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL I */
+ {0x1d575, 1, 221}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL J */
+ {0x1d576, 1, 228}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL K */
+ {0x1d577, 1, 232}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL L */
+ {0x1d578, 1, 912}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL M */
+ {0x1d579, 1, 54}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL N */
+ {0x1d57a, 1, 56}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL O */
+ {0x1d57b, 1, 914}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL P */
+ {0x1d57c, 1, 1942}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL Q */
+ {0x1d57d, 1, 274}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL R */
+ {0x1d57e, 1, 286}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL S */
+ {0x1d57f, 1, 302}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL T */
+ {0x1d580, 1, 66}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL U */
+ {0x1d581, 1, 1183}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL V */
+ {0x1d582, 1, 334}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL W */
+ {0x1d583, 1, 1211}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL X */
+ {0x1d584, 1, 74}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL Y */
+ {0x1d585, 1, 344}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL Z */
+ {0x1d586, 1, 3}, /* MATHEMATICAL BOLD FRAKTUR SMALL A */
+ {0x1d587, 1, 918}, /* MATHEMATICAL BOLD FRAKTUR SMALL B */
+ {0x1d588, 1, 88}, /* MATHEMATICAL BOLD FRAKTUR SMALL C */
+ {0x1d589, 1, 160}, /* MATHEMATICAL BOLD FRAKTUR SMALL D */
+ {0x1d58a, 1, 90}, /* MATHEMATICAL BOLD FRAKTUR SMALL E */
+ {0x1d58b, 1, 997}, /* MATHEMATICAL BOLD FRAKTUR SMALL F */
+ {0x1d58c, 1, 184}, /* MATHEMATICAL BOLD FRAKTUR SMALL G */
+ {0x1d58d, 1, 200}, /* MATHEMATICAL BOLD FRAKTUR SMALL H */
+ {0x1d58e, 1, 98}, /* MATHEMATICAL BOLD FRAKTUR SMALL I */
+ {0x1d58f, 1, 223}, /* MATHEMATICAL BOLD FRAKTUR SMALL J */
+ {0x1d590, 1, 230}, /* MATHEMATICAL BOLD FRAKTUR SMALL K */
+ {0x1d591, 1, 234}, /* MATHEMATICAL BOLD FRAKTUR SMALL L */
+ {0x1d592, 1, 922}, /* MATHEMATICAL BOLD FRAKTUR SMALL M */
+ {0x1d593, 1, 106}, /* MATHEMATICAL BOLD FRAKTUR SMALL N */
+ {0x1d594, 1, 14}, /* MATHEMATICAL BOLD FRAKTUR SMALL O */
+ {0x1d595, 1, 927}, /* MATHEMATICAL BOLD FRAKTUR SMALL P */
+ {0x1d596, 1, 2335}, /* MATHEMATICAL BOLD FRAKTUR SMALL Q */
+ {0x1d597, 1, 276}, /* MATHEMATICAL BOLD FRAKTUR SMALL R */
+ {0x1d598, 1, 288}, /* MATHEMATICAL BOLD FRAKTUR SMALL S */
+ {0x1d599, 1, 304}, /* MATHEMATICAL BOLD FRAKTUR SMALL T */
+ {0x1d59a, 1, 118}, /* MATHEMATICAL BOLD FRAKTUR SMALL U */
+ {0x1d59b, 1, 930}, /* MATHEMATICAL BOLD FRAKTUR SMALL V */
+ {0x1d59c, 1, 336}, /* MATHEMATICAL BOLD FRAKTUR SMALL W */
+ {0x1d59d, 1, 579}, /* MATHEMATICAL BOLD FRAKTUR SMALL X */
+ {0x1d59e, 1, 126}, /* MATHEMATICAL BOLD FRAKTUR SMALL Y */
+ {0x1d59f, 1, 346}, /* MATHEMATICAL BOLD FRAKTUR SMALL Z */
+ {0x1d5a0, 1, 24}, /* MATHEMATICAL SANS-SERIF CAPITAL A */
+ {0x1d5a1, 1, 910}, /* MATHEMATICAL SANS-SERIF CAPITAL B */
+ {0x1d5a2, 1, 36}, /* MATHEMATICAL SANS-SERIF CAPITAL C */
+ {0x1d5a3, 1, 158}, /* MATHEMATICAL SANS-SERIF CAPITAL D */
+ {0x1d5a4, 1, 38}, /* MATHEMATICAL SANS-SERIF CAPITAL E */
+ {0x1d5a5, 1, 995}, /* MATHEMATICAL SANS-SERIF CAPITAL F */
+ {0x1d5a6, 1, 182}, /* MATHEMATICAL SANS-SERIF CAPITAL G */
+ {0x1d5a7, 1, 198}, /* MATHEMATICAL SANS-SERIF CAPITAL H */
+ {0x1d5a8, 1, 46}, /* MATHEMATICAL SANS-SERIF CAPITAL I */
+ {0x1d5a9, 1, 221}, /* MATHEMATICAL SANS-SERIF CAPITAL J */
+ {0x1d5aa, 1, 228}, /* MATHEMATICAL SANS-SERIF CAPITAL K */
+ {0x1d5ab, 1, 232}, /* MATHEMATICAL SANS-SERIF CAPITAL L */
+ {0x1d5ac, 1, 912}, /* MATHEMATICAL SANS-SERIF CAPITAL M */
+ {0x1d5ad, 1, 54}, /* MATHEMATICAL SANS-SERIF CAPITAL N */
+ {0x1d5ae, 1, 56}, /* MATHEMATICAL SANS-SERIF CAPITAL O */
+ {0x1d5af, 1, 914}, /* MATHEMATICAL SANS-SERIF CAPITAL P */
+ {0x1d5b0, 1, 1942}, /* MATHEMATICAL SANS-SERIF CAPITAL Q */
+ {0x1d5b1, 1, 274}, /* MATHEMATICAL SANS-SERIF CAPITAL R */
+ {0x1d5b2, 1, 286}, /* MATHEMATICAL SANS-SERIF CAPITAL S */
+ {0x1d5b3, 1, 302}, /* MATHEMATICAL SANS-SERIF CAPITAL T */
+ {0x1d5b4, 1, 66}, /* MATHEMATICAL SANS-SERIF CAPITAL U */
+ {0x1d5b5, 1, 1183}, /* MATHEMATICAL SANS-SERIF CAPITAL V */
+ {0x1d5b6, 1, 334}, /* MATHEMATICAL SANS-SERIF CAPITAL W */
+ {0x1d5b7, 1, 1211}, /* MATHEMATICAL SANS-SERIF CAPITAL X */
+ {0x1d5b8, 1, 74}, /* MATHEMATICAL SANS-SERIF CAPITAL Y */
+ {0x1d5b9, 1, 344}, /* MATHEMATICAL SANS-SERIF CAPITAL Z */
+ {0x1d5ba, 1, 3}, /* MATHEMATICAL SANS-SERIF SMALL A */
+ {0x1d5bb, 1, 918}, /* MATHEMATICAL SANS-SERIF SMALL B */
+ {0x1d5bc, 1, 88}, /* MATHEMATICAL SANS-SERIF SMALL C */
+ {0x1d5bd, 1, 160}, /* MATHEMATICAL SANS-SERIF SMALL D */
+ {0x1d5be, 1, 90}, /* MATHEMATICAL SANS-SERIF SMALL E */
+ {0x1d5bf, 1, 997}, /* MATHEMATICAL SANS-SERIF SMALL F */
+ {0x1d5c0, 1, 184}, /* MATHEMATICAL SANS-SERIF SMALL G */
+ {0x1d5c1, 1, 200}, /* MATHEMATICAL SANS-SERIF SMALL H */
+ {0x1d5c2, 1, 98}, /* MATHEMATICAL SANS-SERIF SMALL I */
+ {0x1d5c3, 1, 223}, /* MATHEMATICAL SANS-SERIF SMALL J */
+ {0x1d5c4, 1, 230}, /* MATHEMATICAL SANS-SERIF SMALL K */
+ {0x1d5c5, 1, 234}, /* MATHEMATICAL SANS-SERIF SMALL L */
+ {0x1d5c6, 1, 922}, /* MATHEMATICAL SANS-SERIF SMALL M */
+ {0x1d5c7, 1, 106}, /* MATHEMATICAL SANS-SERIF SMALL N */
+ {0x1d5c8, 1, 14}, /* MATHEMATICAL SANS-SERIF SMALL O */
+ {0x1d5c9, 1, 927}, /* MATHEMATICAL SANS-SERIF SMALL P */
+ {0x1d5ca, 1, 2335}, /* MATHEMATICAL SANS-SERIF SMALL Q */
+ {0x1d5cb, 1, 276}, /* MATHEMATICAL SANS-SERIF SMALL R */
+ {0x1d5cc, 1, 288}, /* MATHEMATICAL SANS-SERIF SMALL S */
+ {0x1d5cd, 1, 304}, /* MATHEMATICAL SANS-SERIF SMALL T */
+ {0x1d5ce, 1, 118}, /* MATHEMATICAL SANS-SERIF SMALL U */
+ {0x1d5cf, 1, 930}, /* MATHEMATICAL SANS-SERIF SMALL V */
+ {0x1d5d0, 1, 336}, /* MATHEMATICAL SANS-SERIF SMALL W */
+ {0x1d5d1, 1, 579}, /* MATHEMATICAL SANS-SERIF SMALL X */
+ {0x1d5d2, 1, 126}, /* MATHEMATICAL SANS-SERIF SMALL Y */
+ {0x1d5d3, 1, 346}, /* MATHEMATICAL SANS-SERIF SMALL Z */
+ {0x1d5d4, 1, 24}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL A */
+ {0x1d5d5, 1, 910}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL B */
+ {0x1d5d6, 1, 36}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL C */
+ {0x1d5d7, 1, 158}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL D */
+ {0x1d5d8, 1, 38}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL E */
+ {0x1d5d9, 1, 995}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL F */
+ {0x1d5da, 1, 182}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL G */
+ {0x1d5db, 1, 198}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL H */
+ {0x1d5dc, 1, 46}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL I */
+ {0x1d5dd, 1, 221}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL J */
+ {0x1d5de, 1, 228}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL K */
+ {0x1d5df, 1, 232}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL L */
+ {0x1d5e0, 1, 912}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL M */
+ {0x1d5e1, 1, 54}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL N */
+ {0x1d5e2, 1, 56}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL O */
+ {0x1d5e3, 1, 914}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL P */
+ {0x1d5e4, 1, 1942}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL Q */
+ {0x1d5e5, 1, 274}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL R */
+ {0x1d5e6, 1, 286}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL S */
+ {0x1d5e7, 1, 302}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL T */
+ {0x1d5e8, 1, 66}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL U */
+ {0x1d5e9, 1, 1183}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL V */
+ {0x1d5ea, 1, 334}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL W */
+ {0x1d5eb, 1, 1211}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL X */
+ {0x1d5ec, 1, 74}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL Y */
+ {0x1d5ed, 1, 344}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL Z */
+ {0x1d5ee, 1, 3}, /* MATHEMATICAL SANS-SERIF BOLD SMALL A */
+ {0x1d5ef, 1, 918}, /* MATHEMATICAL SANS-SERIF BOLD SMALL B */
+ {0x1d5f0, 1, 88}, /* MATHEMATICAL SANS-SERIF BOLD SMALL C */
+ {0x1d5f1, 1, 160}, /* MATHEMATICAL SANS-SERIF BOLD SMALL D */
+ {0x1d5f2, 1, 90}, /* MATHEMATICAL SANS-SERIF BOLD SMALL E */
+ {0x1d5f3, 1, 997}, /* MATHEMATICAL SANS-SERIF BOLD SMALL F */
+ {0x1d5f4, 1, 184}, /* MATHEMATICAL SANS-SERIF BOLD SMALL G */
+ {0x1d5f5, 1, 200}, /* MATHEMATICAL SANS-SERIF BOLD SMALL H */
+ {0x1d5f6, 1, 98}, /* MATHEMATICAL SANS-SERIF BOLD SMALL I */
+ {0x1d5f7, 1, 223}, /* MATHEMATICAL SANS-SERIF BOLD SMALL J */
+ {0x1d5f8, 1, 230}, /* MATHEMATICAL SANS-SERIF BOLD SMALL K */
+ {0x1d5f9, 1, 234}, /* MATHEMATICAL SANS-SERIF BOLD SMALL L */
+ {0x1d5fa, 1, 922}, /* MATHEMATICAL SANS-SERIF BOLD SMALL M */
+ {0x1d5fb, 1, 106}, /* MATHEMATICAL SANS-SERIF BOLD SMALL N */
+ {0x1d5fc, 1, 14}, /* MATHEMATICAL SANS-SERIF BOLD SMALL O */
+ {0x1d5fd, 1, 927}, /* MATHEMATICAL SANS-SERIF BOLD SMALL P */
+ {0x1d5fe, 1, 2335}, /* MATHEMATICAL SANS-SERIF BOLD SMALL Q */
+ {0x1d5ff, 1, 276}, /* MATHEMATICAL SANS-SERIF BOLD SMALL R */
+ {0x1d600, 1, 288}, /* MATHEMATICAL SANS-SERIF BOLD SMALL S */
+ {0x1d601, 1, 304}, /* MATHEMATICAL SANS-SERIF BOLD SMALL T */
+ {0x1d602, 1, 118}, /* MATHEMATICAL SANS-SERIF BOLD SMALL U */
+ {0x1d603, 1, 930}, /* MATHEMATICAL SANS-SERIF BOLD SMALL V */
+ {0x1d604, 1, 336}, /* MATHEMATICAL SANS-SERIF BOLD SMALL W */
+ {0x1d605, 1, 579}, /* MATHEMATICAL SANS-SERIF BOLD SMALL X */
+ {0x1d606, 1, 126}, /* MATHEMATICAL SANS-SERIF BOLD SMALL Y */
+ {0x1d607, 1, 346}, /* MATHEMATICAL SANS-SERIF BOLD SMALL Z */
+ {0x1d608, 1, 24}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL A */
+ {0x1d609, 1, 910}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL B */
+ {0x1d60a, 1, 36}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL C */
+ {0x1d60b, 1, 158}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL D */
+ {0x1d60c, 1, 38}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL E */
+ {0x1d60d, 1, 995}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL F */
+ {0x1d60e, 1, 182}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL G */
+ {0x1d60f, 1, 198}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL H */
+ {0x1d610, 1, 46}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL I */
+ {0x1d611, 1, 221}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL J */
+ {0x1d612, 1, 228}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL K */
+ {0x1d613, 1, 232}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL L */
+ {0x1d614, 1, 912}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL M */
+ {0x1d615, 1, 54}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL N */
+ {0x1d616, 1, 56}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL O */
+ {0x1d617, 1, 914}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL P */
+ {0x1d618, 1, 1942}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q */
+ {0x1d619, 1, 274}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL R */
+ {0x1d61a, 1, 286}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL S */
+ {0x1d61b, 1, 302}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL T */
+ {0x1d61c, 1, 66}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL U */
+ {0x1d61d, 1, 1183}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL V */
+ {0x1d61e, 1, 334}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL W */
+ {0x1d61f, 1, 1211}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL X */
+ {0x1d620, 1, 74}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y */
+ {0x1d621, 1, 344}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z */
+ {0x1d622, 1, 3}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL A */
+ {0x1d623, 1, 918}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL B */
+ {0x1d624, 1, 88}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL C */
+ {0x1d625, 1, 160}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL D */
+ {0x1d626, 1, 90}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL E */
+ {0x1d627, 1, 997}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL F */
+ {0x1d628, 1, 184}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL G */
+ {0x1d629, 1, 200}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL H */
+ {0x1d62a, 1, 98}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL I */
+ {0x1d62b, 1, 223}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL J */
+ {0x1d62c, 1, 230}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL K */
+ {0x1d62d, 1, 234}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL L */
+ {0x1d62e, 1, 922}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL M */
+ {0x1d62f, 1, 106}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL N */
+ {0x1d630, 1, 14}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL O */
+ {0x1d631, 1, 927}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL P */
+ {0x1d632, 1, 2335}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL Q */
+ {0x1d633, 1, 276}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL R */
+ {0x1d634, 1, 288}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL S */
+ {0x1d635, 1, 304}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL T */
+ {0x1d636, 1, 118}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL U */
+ {0x1d637, 1, 930}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL V */
+ {0x1d638, 1, 336}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL W */
+ {0x1d639, 1, 579}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL X */
+ {0x1d63a, 1, 126}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL Y */
+ {0x1d63b, 1, 346}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL Z */
+ {0x1d63c, 1, 24}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A */
+ {0x1d63d, 1, 910}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B */
+ {0x1d63e, 1, 36}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C */
+ {0x1d63f, 1, 158}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D */
+ {0x1d640, 1, 38}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E */
+ {0x1d641, 1, 995}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F */
+ {0x1d642, 1, 182}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G */
+ {0x1d643, 1, 198}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H */
+ {0x1d644, 1, 46}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I */
+ {0x1d645, 1, 221}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J */
+ {0x1d646, 1, 228}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K */
+ {0x1d647, 1, 232}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L */
+ {0x1d648, 1, 912}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M */
+ {0x1d649, 1, 54}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N */
+ {0x1d64a, 1, 56}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O */
+ {0x1d64b, 1, 914}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P */
+ {0x1d64c, 1, 1942}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q */
+ {0x1d64d, 1, 274}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R */
+ {0x1d64e, 1, 286}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S */
+ {0x1d64f, 1, 302}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T */
+ {0x1d650, 1, 66}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U */
+ {0x1d651, 1, 1183}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V */
+ {0x1d652, 1, 334}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W */
+ {0x1d653, 1, 1211}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X */
+ {0x1d654, 1, 74}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y */
+ {0x1d655, 1, 344}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z */
+ {0x1d656, 1, 3}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A */
+ {0x1d657, 1, 918}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B */
+ {0x1d658, 1, 88}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C */
+ {0x1d659, 1, 160}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D */
+ {0x1d65a, 1, 90}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E */
+ {0x1d65b, 1, 997}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F */
+ {0x1d65c, 1, 184}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G */
+ {0x1d65d, 1, 200}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H */
+ {0x1d65e, 1, 98}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I */
+ {0x1d65f, 1, 223}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J */
+ {0x1d660, 1, 230}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K */
+ {0x1d661, 1, 234}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L */
+ {0x1d662, 1, 922}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M */
+ {0x1d663, 1, 106}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N */
+ {0x1d664, 1, 14}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O */
+ {0x1d665, 1, 927}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P */
+ {0x1d666, 1, 2335}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q */
+ {0x1d667, 1, 276}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R */
+ {0x1d668, 1, 288}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S */
+ {0x1d669, 1, 304}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T */
+ {0x1d66a, 1, 118}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U */
+ {0x1d66b, 1, 930}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V */
+ {0x1d66c, 1, 336}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W */
+ {0x1d66d, 1, 579}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X */
+ {0x1d66e, 1, 126}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y */
+ {0x1d66f, 1, 346}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z */
+ {0x1d670, 1, 24}, /* MATHEMATICAL MONOSPACE CAPITAL A */
+ {0x1d671, 1, 910}, /* MATHEMATICAL MONOSPACE CAPITAL B */
+ {0x1d672, 1, 36}, /* MATHEMATICAL MONOSPACE CAPITAL C */
+ {0x1d673, 1, 158}, /* MATHEMATICAL MONOSPACE CAPITAL D */
+ {0x1d674, 1, 38}, /* MATHEMATICAL MONOSPACE CAPITAL E */
+ {0x1d675, 1, 995}, /* MATHEMATICAL MONOSPACE CAPITAL F */
+ {0x1d676, 1, 182}, /* MATHEMATICAL MONOSPACE CAPITAL G */
+ {0x1d677, 1, 198}, /* MATHEMATICAL MONOSPACE CAPITAL H */
+ {0x1d678, 1, 46}, /* MATHEMATICAL MONOSPACE CAPITAL I */
+ {0x1d679, 1, 221}, /* MATHEMATICAL MONOSPACE CAPITAL J */
+ {0x1d67a, 1, 228}, /* MATHEMATICAL MONOSPACE CAPITAL K */
+ {0x1d67b, 1, 232}, /* MATHEMATICAL MONOSPACE CAPITAL L */
+ {0x1d67c, 1, 912}, /* MATHEMATICAL MONOSPACE CAPITAL M */
+ {0x1d67d, 1, 54}, /* MATHEMATICAL MONOSPACE CAPITAL N */
+ {0x1d67e, 1, 56}, /* MATHEMATICAL MONOSPACE CAPITAL O */
+ {0x1d67f, 1, 914}, /* MATHEMATICAL MONOSPACE CAPITAL P */
+ {0x1d680, 1, 1942}, /* MATHEMATICAL MONOSPACE CAPITAL Q */
+ {0x1d681, 1, 274}, /* MATHEMATICAL MONOSPACE CAPITAL R */
+ {0x1d682, 1, 286}, /* MATHEMATICAL MONOSPACE CAPITAL S */
+ {0x1d683, 1, 302}, /* MATHEMATICAL MONOSPACE CAPITAL T */
+ {0x1d684, 1, 66}, /* MATHEMATICAL MONOSPACE CAPITAL U */
+ {0x1d685, 1, 1183}, /* MATHEMATICAL MONOSPACE CAPITAL V */
+ {0x1d686, 1, 334}, /* MATHEMATICAL MONOSPACE CAPITAL W */
+ {0x1d687, 1, 1211}, /* MATHEMATICAL MONOSPACE CAPITAL X */
+ {0x1d688, 1, 74}, /* MATHEMATICAL MONOSPACE CAPITAL Y */
+ {0x1d689, 1, 344}, /* MATHEMATICAL MONOSPACE CAPITAL Z */
+ {0x1d68a, 1, 3}, /* MATHEMATICAL MONOSPACE SMALL A */
+ {0x1d68b, 1, 918}, /* MATHEMATICAL MONOSPACE SMALL B */
+ {0x1d68c, 1, 88}, /* MATHEMATICAL MONOSPACE SMALL C */
+ {0x1d68d, 1, 160}, /* MATHEMATICAL MONOSPACE SMALL D */
+ {0x1d68e, 1, 90}, /* MATHEMATICAL MONOSPACE SMALL E */
+ {0x1d68f, 1, 997}, /* MATHEMATICAL MONOSPACE SMALL F */
+ {0x1d690, 1, 184}, /* MATHEMATICAL MONOSPACE SMALL G */
+ {0x1d691, 1, 200}, /* MATHEMATICAL MONOSPACE SMALL H */
+ {0x1d692, 1, 98}, /* MATHEMATICAL MONOSPACE SMALL I */
+ {0x1d693, 1, 223}, /* MATHEMATICAL MONOSPACE SMALL J */
+ {0x1d694, 1, 230}, /* MATHEMATICAL MONOSPACE SMALL K */
+ {0x1d695, 1, 234}, /* MATHEMATICAL MONOSPACE SMALL L */
+ {0x1d696, 1, 922}, /* MATHEMATICAL MONOSPACE SMALL M */
+ {0x1d697, 1, 106}, /* MATHEMATICAL MONOSPACE SMALL N */
+ {0x1d698, 1, 14}, /* MATHEMATICAL MONOSPACE SMALL O */
+ {0x1d699, 1, 927}, /* MATHEMATICAL MONOSPACE SMALL P */
+ {0x1d69a, 1, 2335}, /* MATHEMATICAL MONOSPACE SMALL Q */
+ {0x1d69b, 1, 276}, /* MATHEMATICAL MONOSPACE SMALL R */
+ {0x1d69c, 1, 288}, /* MATHEMATICAL MONOSPACE SMALL S */
+ {0x1d69d, 1, 304}, /* MATHEMATICAL MONOSPACE SMALL T */
+ {0x1d69e, 1, 118}, /* MATHEMATICAL MONOSPACE SMALL U */
+ {0x1d69f, 1, 930}, /* MATHEMATICAL MONOSPACE SMALL V */
+ {0x1d6a0, 1, 336}, /* MATHEMATICAL MONOSPACE SMALL W */
+ {0x1d6a1, 1, 579}, /* MATHEMATICAL MONOSPACE SMALL X */
+ {0x1d6a2, 1, 126}, /* MATHEMATICAL MONOSPACE SMALL Y */
+ {0x1d6a3, 1, 346}, /* MATHEMATICAL MONOSPACE SMALL Z */
+ {0x1d6a8, 1, 590}, /* MATHEMATICAL BOLD CAPITAL ALPHA */
+ {0x1d6a9, 1, 5148}, /* MATHEMATICAL BOLD CAPITAL BETA */
+ {0x1d6aa, 1, 1957}, /* MATHEMATICAL BOLD CAPITAL GAMMA */
+ {0x1d6ab, 1, 5149}, /* MATHEMATICAL BOLD CAPITAL DELTA */
+ {0x1d6ac, 1, 592}, /* MATHEMATICAL BOLD CAPITAL EPSILON */
+ {0x1d6ad, 1, 5150}, /* MATHEMATICAL BOLD CAPITAL ZETA */
+ {0x1d6ae, 1, 594}, /* MATHEMATICAL BOLD CAPITAL ETA */
+ {0x1d6af, 1, 641}, /* MATHEMATICAL BOLD CAPITAL THETA */
+ {0x1d6b0, 1, 596}, /* MATHEMATICAL BOLD CAPITAL IOTA */
+ {0x1d6b1, 1, 5151}, /* MATHEMATICAL BOLD CAPITAL KAPPA */
+ {0x1d6b2, 1, 5152}, /* MATHEMATICAL BOLD CAPITAL LAMDA */
+ {0x1d6b3, 1, 5153}, /* MATHEMATICAL BOLD CAPITAL MU */
+ {0x1d6b4, 1, 5154}, /* MATHEMATICAL BOLD CAPITAL NU */
+ {0x1d6b5, 1, 5155}, /* MATHEMATICAL BOLD CAPITAL XI */
+ {0x1d6b6, 1, 598}, /* MATHEMATICAL BOLD CAPITAL OMICRON */
+ {0x1d6b7, 1, 1958}, /* MATHEMATICAL BOLD CAPITAL PI */
+ {0x1d6b8, 1, 1843}, /* MATHEMATICAL BOLD CAPITAL RHO */
+ {0x1d6b9, 1, 5156}, /* MATHEMATICAL BOLD CAPITAL THETA SYMBOL */
+ {0x1d6ba, 1, 642}, /* MATHEMATICAL BOLD CAPITAL SIGMA */
+ {0x1d6bb, 1, 5157}, /* MATHEMATICAL BOLD CAPITAL TAU */
+ {0x1d6bc, 1, 600}, /* MATHEMATICAL BOLD CAPITAL UPSILON */
+ {0x1d6bd, 1, 5158}, /* MATHEMATICAL BOLD CAPITAL PHI */
+ {0x1d6be, 1, 5159}, /* MATHEMATICAL BOLD CAPITAL CHI */
+ {0x1d6bf, 1, 5160}, /* MATHEMATICAL BOLD CAPITAL PSI */
+ {0x1d6c0, 1, 602}, /* MATHEMATICAL BOLD CAPITAL OMEGA */
+ {0x1d6c1, 1, 5161}, /* MATHEMATICAL BOLD NABLA */
+ {0x1d6c2, 1, 610}, /* MATHEMATICAL BOLD SMALL ALPHA */
+ {0x1d6c3, 1, 630}, /* MATHEMATICAL BOLD SMALL BETA */
+ {0x1d6c4, 1, 932}, /* MATHEMATICAL BOLD SMALL GAMMA */
+ {0x1d6c5, 1, 933}, /* MATHEMATICAL BOLD SMALL DELTA */
+ {0x1d6c6, 1, 612}, /* MATHEMATICAL BOLD SMALL EPSILON */
+ {0x1d6c7, 1, 5162}, /* MATHEMATICAL BOLD SMALL ZETA */
+ {0x1d6c8, 1, 614}, /* MATHEMATICAL BOLD SMALL ETA */
+ {0x1d6c9, 1, 631}, /* MATHEMATICAL BOLD SMALL THETA */
+ {0x1d6ca, 1, 616}, /* MATHEMATICAL BOLD SMALL IOTA */
+ {0x1d6cb, 1, 638}, /* MATHEMATICAL BOLD SMALL KAPPA */
+ {0x1d6cc, 1, 5163}, /* MATHEMATICAL BOLD SMALL LAMDA */
+ {0x1d6cd, 1, 10}, /* MATHEMATICAL BOLD SMALL MU */
+ {0x1d6ce, 1, 5164}, /* MATHEMATICAL BOLD SMALL NU */
+ {0x1d6cf, 1, 5165}, /* MATHEMATICAL BOLD SMALL XI */
+ {0x1d6d0, 1, 624}, /* MATHEMATICAL BOLD SMALL OMICRON */
+ {0x1d6d1, 1, 637}, /* MATHEMATICAL BOLD SMALL PI */
+ {0x1d6d2, 1, 639}, /* MATHEMATICAL BOLD SMALL RHO */
+ {0x1d6d3, 1, 640}, /* MATHEMATICAL BOLD SMALL FINAL SIGMA */
+ {0x1d6d4, 1, 5166}, /* MATHEMATICAL BOLD SMALL SIGMA */
+ {0x1d6d5, 1, 5167}, /* MATHEMATICAL BOLD SMALL TAU */
+ {0x1d6d6, 1, 622}, /* MATHEMATICAL BOLD SMALL UPSILON */
+ {0x1d6d7, 1, 636}, /* MATHEMATICAL BOLD SMALL PHI */
+ {0x1d6d8, 1, 934}, /* MATHEMATICAL BOLD SMALL CHI */
+ {0x1d6d9, 1, 5168}, /* MATHEMATICAL BOLD SMALL PSI */
+ {0x1d6da, 1, 628}, /* MATHEMATICAL BOLD SMALL OMEGA */
+ {0x1d6db, 1, 5169}, /* MATHEMATICAL BOLD PARTIAL DIFFERENTIAL */
+ {0x1d6dc, 1, 5170}, /* MATHEMATICAL BOLD EPSILON SYMBOL */
+ {0x1d6dd, 1, 5171}, /* MATHEMATICAL BOLD THETA SYMBOL */
+ {0x1d6de, 1, 5172}, /* MATHEMATICAL BOLD KAPPA SYMBOL */
+ {0x1d6df, 1, 5173}, /* MATHEMATICAL BOLD PHI SYMBOL */
+ {0x1d6e0, 1, 5174}, /* MATHEMATICAL BOLD RHO SYMBOL */
+ {0x1d6e1, 1, 5175}, /* MATHEMATICAL BOLD PI SYMBOL */
+ {0x1d6e2, 1, 590}, /* MATHEMATICAL ITALIC CAPITAL ALPHA */
+ {0x1d6e3, 1, 5148}, /* MATHEMATICAL ITALIC CAPITAL BETA */
+ {0x1d6e4, 1, 1957}, /* MATHEMATICAL ITALIC CAPITAL GAMMA */
+ {0x1d6e5, 1, 5149}, /* MATHEMATICAL ITALIC CAPITAL DELTA */
+ {0x1d6e6, 1, 592}, /* MATHEMATICAL ITALIC CAPITAL EPSILON */
+ {0x1d6e7, 1, 5150}, /* MATHEMATICAL ITALIC CAPITAL ZETA */
+ {0x1d6e8, 1, 594}, /* MATHEMATICAL ITALIC CAPITAL ETA */
+ {0x1d6e9, 1, 641}, /* MATHEMATICAL ITALIC CAPITAL THETA */
+ {0x1d6ea, 1, 596}, /* MATHEMATICAL ITALIC CAPITAL IOTA */
+ {0x1d6eb, 1, 5151}, /* MATHEMATICAL ITALIC CAPITAL KAPPA */
+ {0x1d6ec, 1, 5152}, /* MATHEMATICAL ITALIC CAPITAL LAMDA */
+ {0x1d6ed, 1, 5153}, /* MATHEMATICAL ITALIC CAPITAL MU */
+ {0x1d6ee, 1, 5154}, /* MATHEMATICAL ITALIC CAPITAL NU */
+ {0x1d6ef, 1, 5155}, /* MATHEMATICAL ITALIC CAPITAL XI */
+ {0x1d6f0, 1, 598}, /* MATHEMATICAL ITALIC CAPITAL OMICRON */
+ {0x1d6f1, 1, 1958}, /* MATHEMATICAL ITALIC CAPITAL PI */
+ {0x1d6f2, 1, 1843}, /* MATHEMATICAL ITALIC CAPITAL RHO */
+ {0x1d6f3, 1, 5156}, /* MATHEMATICAL ITALIC CAPITAL THETA SYMBOL */
+ {0x1d6f4, 1, 642}, /* MATHEMATICAL ITALIC CAPITAL SIGMA */
+ {0x1d6f5, 1, 5157}, /* MATHEMATICAL ITALIC CAPITAL TAU */
+ {0x1d6f6, 1, 600}, /* MATHEMATICAL ITALIC CAPITAL UPSILON */
+ {0x1d6f7, 1, 5158}, /* MATHEMATICAL ITALIC CAPITAL PHI */
+ {0x1d6f8, 1, 5159}, /* MATHEMATICAL ITALIC CAPITAL CHI */
+ {0x1d6f9, 1, 5160}, /* MATHEMATICAL ITALIC CAPITAL PSI */
+ {0x1d6fa, 1, 602}, /* MATHEMATICAL ITALIC CAPITAL OMEGA */
+ {0x1d6fb, 1, 5161}, /* MATHEMATICAL ITALIC NABLA */
+ {0x1d6fc, 1, 610}, /* MATHEMATICAL ITALIC SMALL ALPHA */
+ {0x1d6fd, 1, 630}, /* MATHEMATICAL ITALIC SMALL BETA */
+ {0x1d6fe, 1, 932}, /* MATHEMATICAL ITALIC SMALL GAMMA */
+ {0x1d6ff, 1, 933}, /* MATHEMATICAL ITALIC SMALL DELTA */
+ {0x1d700, 1, 612}, /* MATHEMATICAL ITALIC SMALL EPSILON */
+ {0x1d701, 1, 5162}, /* MATHEMATICAL ITALIC SMALL ZETA */
+ {0x1d702, 1, 614}, /* MATHEMATICAL ITALIC SMALL ETA */
+ {0x1d703, 1, 631}, /* MATHEMATICAL ITALIC SMALL THETA */
+ {0x1d704, 1, 616}, /* MATHEMATICAL ITALIC SMALL IOTA */
+ {0x1d705, 1, 638}, /* MATHEMATICAL ITALIC SMALL KAPPA */
+ {0x1d706, 1, 5163}, /* MATHEMATICAL ITALIC SMALL LAMDA */
+ {0x1d707, 1, 10}, /* MATHEMATICAL ITALIC SMALL MU */
+ {0x1d708, 1, 5164}, /* MATHEMATICAL ITALIC SMALL NU */
+ {0x1d709, 1, 5165}, /* MATHEMATICAL ITALIC SMALL XI */
+ {0x1d70a, 1, 624}, /* MATHEMATICAL ITALIC SMALL OMICRON */
+ {0x1d70b, 1, 637}, /* MATHEMATICAL ITALIC SMALL PI */
+ {0x1d70c, 1, 639}, /* MATHEMATICAL ITALIC SMALL RHO */
+ {0x1d70d, 1, 640}, /* MATHEMATICAL ITALIC SMALL FINAL SIGMA */
+ {0x1d70e, 1, 5166}, /* MATHEMATICAL ITALIC SMALL SIGMA */
+ {0x1d70f, 1, 5167}, /* MATHEMATICAL ITALIC SMALL TAU */
+ {0x1d710, 1, 622}, /* MATHEMATICAL ITALIC SMALL UPSILON */
+ {0x1d711, 1, 636}, /* MATHEMATICAL ITALIC SMALL PHI */
+ {0x1d712, 1, 934}, /* MATHEMATICAL ITALIC SMALL CHI */
+ {0x1d713, 1, 5168}, /* MATHEMATICAL ITALIC SMALL PSI */
+ {0x1d714, 1, 628}, /* MATHEMATICAL ITALIC SMALL OMEGA */
+ {0x1d715, 1, 5169}, /* MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL */
+ {0x1d716, 1, 5170}, /* MATHEMATICAL ITALIC EPSILON SYMBOL */
+ {0x1d717, 1, 5171}, /* MATHEMATICAL ITALIC THETA SYMBOL */
+ {0x1d718, 1, 5172}, /* MATHEMATICAL ITALIC KAPPA SYMBOL */
+ {0x1d719, 1, 5173}, /* MATHEMATICAL ITALIC PHI SYMBOL */
+ {0x1d71a, 1, 5174}, /* MATHEMATICAL ITALIC RHO SYMBOL */
+ {0x1d71b, 1, 5175}, /* MATHEMATICAL ITALIC PI SYMBOL */
+ {0x1d71c, 1, 590}, /* MATHEMATICAL BOLD ITALIC CAPITAL ALPHA */
+ {0x1d71d, 1, 5148}, /* MATHEMATICAL BOLD ITALIC CAPITAL BETA */
+ {0x1d71e, 1, 1957}, /* MATHEMATICAL BOLD ITALIC CAPITAL GAMMA */
+ {0x1d71f, 1, 5149}, /* MATHEMATICAL BOLD ITALIC CAPITAL DELTA */
+ {0x1d720, 1, 592}, /* MATHEMATICAL BOLD ITALIC CAPITAL EPSILON */
+ {0x1d721, 1, 5150}, /* MATHEMATICAL BOLD ITALIC CAPITAL ZETA */
+ {0x1d722, 1, 594}, /* MATHEMATICAL BOLD ITALIC CAPITAL ETA */
+ {0x1d723, 1, 641}, /* MATHEMATICAL BOLD ITALIC CAPITAL THETA */
+ {0x1d724, 1, 596}, /* MATHEMATICAL BOLD ITALIC CAPITAL IOTA */
+ {0x1d725, 1, 5151}, /* MATHEMATICAL BOLD ITALIC CAPITAL KAPPA */
+ {0x1d726, 1, 5152}, /* MATHEMATICAL BOLD ITALIC CAPITAL LAMDA */
+ {0x1d727, 1, 5153}, /* MATHEMATICAL BOLD ITALIC CAPITAL MU */
+ {0x1d728, 1, 5154}, /* MATHEMATICAL BOLD ITALIC CAPITAL NU */
+ {0x1d729, 1, 5155}, /* MATHEMATICAL BOLD ITALIC CAPITAL XI */
+ {0x1d72a, 1, 598}, /* MATHEMATICAL BOLD ITALIC CAPITAL OMICRON */
+ {0x1d72b, 1, 1958}, /* MATHEMATICAL BOLD ITALIC CAPITAL PI */
+ {0x1d72c, 1, 1843}, /* MATHEMATICAL BOLD ITALIC CAPITAL RHO */
+ {0x1d72d, 1, 5156}, /* MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL */
+ {0x1d72e, 1, 642}, /* MATHEMATICAL BOLD ITALIC CAPITAL SIGMA */
+ {0x1d72f, 1, 5157}, /* MATHEMATICAL BOLD ITALIC CAPITAL TAU */
+ {0x1d730, 1, 600}, /* MATHEMATICAL BOLD ITALIC CAPITAL UPSILON */
+ {0x1d731, 1, 5158}, /* MATHEMATICAL BOLD ITALIC CAPITAL PHI */
+ {0x1d732, 1, 5159}, /* MATHEMATICAL BOLD ITALIC CAPITAL CHI */
+ {0x1d733, 1, 5160}, /* MATHEMATICAL BOLD ITALIC CAPITAL PSI */
+ {0x1d734, 1, 602}, /* MATHEMATICAL BOLD ITALIC CAPITAL OMEGA */
+ {0x1d735, 1, 5161}, /* MATHEMATICAL BOLD ITALIC NABLA */
+ {0x1d736, 1, 610}, /* MATHEMATICAL BOLD ITALIC SMALL ALPHA */
+ {0x1d737, 1, 630}, /* MATHEMATICAL BOLD ITALIC SMALL BETA */
+ {0x1d738, 1, 932}, /* MATHEMATICAL BOLD ITALIC SMALL GAMMA */
+ {0x1d739, 1, 933}, /* MATHEMATICAL BOLD ITALIC SMALL DELTA */
+ {0x1d73a, 1, 612}, /* MATHEMATICAL BOLD ITALIC SMALL EPSILON */
+ {0x1d73b, 1, 5162}, /* MATHEMATICAL BOLD ITALIC SMALL ZETA */
+ {0x1d73c, 1, 614}, /* MATHEMATICAL BOLD ITALIC SMALL ETA */
+ {0x1d73d, 1, 631}, /* MATHEMATICAL BOLD ITALIC SMALL THETA */
+ {0x1d73e, 1, 616}, /* MATHEMATICAL BOLD ITALIC SMALL IOTA */
+ {0x1d73f, 1, 638}, /* MATHEMATICAL BOLD ITALIC SMALL KAPPA */
+ {0x1d740, 1, 5163}, /* MATHEMATICAL BOLD ITALIC SMALL LAMDA */
+ {0x1d741, 1, 10}, /* MATHEMATICAL BOLD ITALIC SMALL MU */
+ {0x1d742, 1, 5164}, /* MATHEMATICAL BOLD ITALIC SMALL NU */
+ {0x1d743, 1, 5165}, /* MATHEMATICAL BOLD ITALIC SMALL XI */
+ {0x1d744, 1, 624}, /* MATHEMATICAL BOLD ITALIC SMALL OMICRON */
+ {0x1d745, 1, 637}, /* MATHEMATICAL BOLD ITALIC SMALL PI */
+ {0x1d746, 1, 639}, /* MATHEMATICAL BOLD ITALIC SMALL RHO */
+ {0x1d747, 1, 640}, /* MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA */
+ {0x1d748, 1, 5166}, /* MATHEMATICAL BOLD ITALIC SMALL SIGMA */
+ {0x1d749, 1, 5167}, /* MATHEMATICAL BOLD ITALIC SMALL TAU */
+ {0x1d74a, 1, 622}, /* MATHEMATICAL BOLD ITALIC SMALL UPSILON */
+ {0x1d74b, 1, 636}, /* MATHEMATICAL BOLD ITALIC SMALL PHI */
+ {0x1d74c, 1, 934}, /* MATHEMATICAL BOLD ITALIC SMALL CHI */
+ {0x1d74d, 1, 5168}, /* MATHEMATICAL BOLD ITALIC SMALL PSI */
+ {0x1d74e, 1, 628}, /* MATHEMATICAL BOLD ITALIC SMALL OMEGA */
+ {0x1d74f, 1, 5169}, /* MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL */
+ {0x1d750, 1, 5170}, /* MATHEMATICAL BOLD ITALIC EPSILON SYMBOL */
+ {0x1d751, 1, 5171}, /* MATHEMATICAL BOLD ITALIC THETA SYMBOL */
+ {0x1d752, 1, 5172}, /* MATHEMATICAL BOLD ITALIC KAPPA SYMBOL */
+ {0x1d753, 1, 5173}, /* MATHEMATICAL BOLD ITALIC PHI SYMBOL */
+ {0x1d754, 1, 5174}, /* MATHEMATICAL BOLD ITALIC RHO SYMBOL */
+ {0x1d755, 1, 5175}, /* MATHEMATICAL BOLD ITALIC PI SYMBOL */
+ {0x1d756, 1, 590}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA */
+ {0x1d757, 1, 5148}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA */
+ {0x1d758, 1, 1957}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA */
+ {0x1d759, 1, 5149}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA */
+ {0x1d75a, 1, 592}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON */
+ {0x1d75b, 1, 5150}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA */
+ {0x1d75c, 1, 594}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA */
+ {0x1d75d, 1, 641}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA */
+ {0x1d75e, 1, 596}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA */
+ {0x1d75f, 1, 5151}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA */
+ {0x1d760, 1, 5152}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA */
+ {0x1d761, 1, 5153}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL MU */
+ {0x1d762, 1, 5154}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL NU */
+ {0x1d763, 1, 5155}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL XI */
+ {0x1d764, 1, 598}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON */
+ {0x1d765, 1, 1958}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL PI */
+ {0x1d766, 1, 1843}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO */
+ {0x1d767, 1, 5156}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL */
+ {0x1d768, 1, 642}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA */
+ {0x1d769, 1, 5157}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU */
+ {0x1d76a, 1, 600}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON */
+ {0x1d76b, 1, 5158}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI */
+ {0x1d76c, 1, 5159}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI */
+ {0x1d76d, 1, 5160}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI */
+ {0x1d76e, 1, 602}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA */
+ {0x1d76f, 1, 5161}, /* MATHEMATICAL SANS-SERIF BOLD NABLA */
+ {0x1d770, 1, 610}, /* MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA */
+ {0x1d771, 1, 630}, /* MATHEMATICAL SANS-SERIF BOLD SMALL BETA */
+ {0x1d772, 1, 932}, /* MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA */
+ {0x1d773, 1, 933}, /* MATHEMATICAL SANS-SERIF BOLD SMALL DELTA */
+ {0x1d774, 1, 612}, /* MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON */
+ {0x1d775, 1, 5162}, /* MATHEMATICAL SANS-SERIF BOLD SMALL ZETA */
+ {0x1d776, 1, 614}, /* MATHEMATICAL SANS-SERIF BOLD SMALL ETA */
+ {0x1d777, 1, 631}, /* MATHEMATICAL SANS-SERIF BOLD SMALL THETA */
+ {0x1d778, 1, 616}, /* MATHEMATICAL SANS-SERIF BOLD SMALL IOTA */
+ {0x1d779, 1, 638}, /* MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA */
+ {0x1d77a, 1, 5163}, /* MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA */
+ {0x1d77b, 1, 10}, /* MATHEMATICAL SANS-SERIF BOLD SMALL MU */
+ {0x1d77c, 1, 5164}, /* MATHEMATICAL SANS-SERIF BOLD SMALL NU */
+ {0x1d77d, 1, 5165}, /* MATHEMATICAL SANS-SERIF BOLD SMALL XI */
+ {0x1d77e, 1, 624}, /* MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON */
+ {0x1d77f, 1, 637}, /* MATHEMATICAL SANS-SERIF BOLD SMALL PI */
+ {0x1d780, 1, 639}, /* MATHEMATICAL SANS-SERIF BOLD SMALL RHO */
+ {0x1d781, 1, 640}, /* MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA */
+ {0x1d782, 1, 5166}, /* MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA */
+ {0x1d783, 1, 5167}, /* MATHEMATICAL SANS-SERIF BOLD SMALL TAU */
+ {0x1d784, 1, 622}, /* MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON */
+ {0x1d785, 1, 636}, /* MATHEMATICAL SANS-SERIF BOLD SMALL PHI */
+ {0x1d786, 1, 934}, /* MATHEMATICAL SANS-SERIF BOLD SMALL CHI */
+ {0x1d787, 1, 5168}, /* MATHEMATICAL SANS-SERIF BOLD SMALL PSI */
+ {0x1d788, 1, 628}, /* MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA */
+ {0x1d789, 1, 5169}, /* MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL */
+ {0x1d78a, 1, 5170}, /* MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL */
+ {0x1d78b, 1, 5171}, /* MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL */
+ {0x1d78c, 1, 5172}, /* MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL */
+ {0x1d78d, 1, 5173}, /* MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL */
+ {0x1d78e, 1, 5174}, /* MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL */
+ {0x1d78f, 1, 5175}, /* MATHEMATICAL SANS-SERIF BOLD PI SYMBOL */
+ {0x1d790, 1, 590}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA */
+ {0x1d791, 1, 5148}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA */
+ {0x1d792, 1, 1957}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA */
+ {0x1d793, 1, 5149}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA */
+ {0x1d794, 1, 592}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON */
+ {0x1d795, 1, 5150}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA */
+ {0x1d796, 1, 594}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA */
+ {0x1d797, 1, 641}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA */
+ {0x1d798, 1, 596}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA */
+ {0x1d799, 1, 5151}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA */
+ {0x1d79a, 1, 5152}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA */
+ {0x1d79b, 1, 5153}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU */
+ {0x1d79c, 1, 5154}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU */
+ {0x1d79d, 1, 5155}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI */
+ {0x1d79e, 1, 598}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON */
+ {0x1d79f, 1, 1958}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI */
+ {0x1d7a0, 1, 1843}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO */
+ {0x1d7a1, 1, 5156}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL */
+ {0x1d7a2, 1, 642}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA */
+ {0x1d7a3, 1, 5157}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU */
+ {0x1d7a4, 1, 600}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON */
+ {0x1d7a5, 1, 5158}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI */
+ {0x1d7a6, 1, 5159}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI */
+ {0x1d7a7, 1, 5160}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI */
+ {0x1d7a8, 1, 602}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA */
+ {0x1d7a9, 1, 5161}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA */
+ {0x1d7aa, 1, 610}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA */
+ {0x1d7ab, 1, 630}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA */
+ {0x1d7ac, 1, 932}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA */
+ {0x1d7ad, 1, 933}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA */
+ {0x1d7ae, 1, 612}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON */
+ {0x1d7af, 1, 5162}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA */
+ {0x1d7b0, 1, 614}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA */
+ {0x1d7b1, 1, 631}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA */
+ {0x1d7b2, 1, 616}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA */
+ {0x1d7b3, 1, 638}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA */
+ {0x1d7b4, 1, 5163}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA */
+ {0x1d7b5, 1, 10}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU */
+ {0x1d7b6, 1, 5164}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU */
+ {0x1d7b7, 1, 5165}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI */
+ {0x1d7b8, 1, 624}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON */
+ {0x1d7b9, 1, 637}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI */
+ {0x1d7ba, 1, 639}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO */
+ {0x1d7bb, 1, 640}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA */
+ {0x1d7bc, 1, 5166}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA */
+ {0x1d7bd, 1, 5167}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU */
+ {0x1d7be, 1, 622}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON */
+ {0x1d7bf, 1, 636}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI */
+ {0x1d7c0, 1, 934}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI */
+ {0x1d7c1, 1, 5168}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI */
+ {0x1d7c2, 1, 628}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA */
+ {0x1d7c3, 1, 5169}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL */
+ {0x1d7c4, 1, 5170}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL */
+ {0x1d7c5, 1, 5171}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL */
+ {0x1d7c6, 1, 5172}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL */
+ {0x1d7c7, 1, 5173}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL */
+ {0x1d7c8, 1, 5174}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL */
+ {0x1d7c9, 1, 5175}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL */
+ {0x1d7ce, 1, 1909}, /* MATHEMATICAL BOLD DIGIT ZERO */
+ {0x1d7cf, 1, 13}, /* MATHEMATICAL BOLD DIGIT ONE */
+ {0x1d7d0, 1, 6}, /* MATHEMATICAL BOLD DIGIT TWO */
+ {0x1d7d1, 1, 7}, /* MATHEMATICAL BOLD DIGIT THREE */
+ {0x1d7d2, 1, 17}, /* MATHEMATICAL BOLD DIGIT FOUR */
+ {0x1d7d3, 1, 1910}, /* MATHEMATICAL BOLD DIGIT FIVE */
+ {0x1d7d4, 1, 1911}, /* MATHEMATICAL BOLD DIGIT SIX */
+ {0x1d7d5, 1, 1912}, /* MATHEMATICAL BOLD DIGIT SEVEN */
+ {0x1d7d6, 1, 1913}, /* MATHEMATICAL BOLD DIGIT EIGHT */
+ {0x1d7d7, 1, 1914}, /* MATHEMATICAL BOLD DIGIT NINE */
+ {0x1d7d8, 1, 1909}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO */
+ {0x1d7d9, 1, 13}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT ONE */
+ {0x1d7da, 1, 6}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT TWO */
+ {0x1d7db, 1, 7}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT THREE */
+ {0x1d7dc, 1, 17}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR */
+ {0x1d7dd, 1, 1910}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE */
+ {0x1d7de, 1, 1911}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT SIX */
+ {0x1d7df, 1, 1912}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN */
+ {0x1d7e0, 1, 1913}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT */
+ {0x1d7e1, 1, 1914}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT NINE */
+ {0x1d7e2, 1, 1909}, /* MATHEMATICAL SANS-SERIF DIGIT ZERO */
+ {0x1d7e3, 1, 13}, /* MATHEMATICAL SANS-SERIF DIGIT ONE */
+ {0x1d7e4, 1, 6}, /* MATHEMATICAL SANS-SERIF DIGIT TWO */
+ {0x1d7e5, 1, 7}, /* MATHEMATICAL SANS-SERIF DIGIT THREE */
+ {0x1d7e6, 1, 17}, /* MATHEMATICAL SANS-SERIF DIGIT FOUR */
+ {0x1d7e7, 1, 1910}, /* MATHEMATICAL SANS-SERIF DIGIT FIVE */
+ {0x1d7e8, 1, 1911}, /* MATHEMATICAL SANS-SERIF DIGIT SIX */
+ {0x1d7e9, 1, 1912}, /* MATHEMATICAL SANS-SERIF DIGIT SEVEN */
+ {0x1d7ea, 1, 1913}, /* MATHEMATICAL SANS-SERIF DIGIT EIGHT */
+ {0x1d7eb, 1, 1914}, /* MATHEMATICAL SANS-SERIF DIGIT NINE */
+ {0x1d7ec, 1, 1909}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO */
+ {0x1d7ed, 1, 13}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT ONE */
+ {0x1d7ee, 1, 6}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT TWO */
+ {0x1d7ef, 1, 7}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT THREE */
+ {0x1d7f0, 1, 17}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR */
+ {0x1d7f1, 1, 1910}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE */
+ {0x1d7f2, 1, 1911}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT SIX */
+ {0x1d7f3, 1, 1912}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN */
+ {0x1d7f4, 1, 1913}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT */
+ {0x1d7f5, 1, 1914}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT NINE */
+ {0x1d7f6, 1, 1909}, /* MATHEMATICAL MONOSPACE DIGIT ZERO */
+ {0x1d7f7, 1, 13}, /* MATHEMATICAL MONOSPACE DIGIT ONE */
+ {0x1d7f8, 1, 6}, /* MATHEMATICAL MONOSPACE DIGIT TWO */
+ {0x1d7f9, 1, 7}, /* MATHEMATICAL MONOSPACE DIGIT THREE */
+ {0x1d7fa, 1, 17}, /* MATHEMATICAL MONOSPACE DIGIT FOUR */
+ {0x1d7fb, 1, 1910}, /* MATHEMATICAL MONOSPACE DIGIT FIVE */
+ {0x1d7fc, 1, 1911}, /* MATHEMATICAL MONOSPACE DIGIT SIX */
+ {0x1d7fd, 1, 1912}, /* MATHEMATICAL MONOSPACE DIGIT SEVEN */
+ {0x1d7fe, 1, 1913}, /* MATHEMATICAL MONOSPACE DIGIT EIGHT */
+ {0x1d7ff, 1, 1914}, /* MATHEMATICAL MONOSPACE DIGIT NINE */
+ {0x2f800, 1, 5176}, /* CJK COMPATIBILITY IDEOGRAPH-2F800 */
+ {0x2f801, 1, 5177}, /* CJK COMPATIBILITY IDEOGRAPH-2F801 */
+ {0x2f802, 1, 5178}, /* CJK COMPATIBILITY IDEOGRAPH-2F802 */
+ {0x2f803, 1, 5179}, /* CJK COMPATIBILITY IDEOGRAPH-2F803 */
+ {0x2f804, 1, 5180}, /* CJK COMPATIBILITY IDEOGRAPH-2F804 */
+ {0x2f805, 1, 4142}, /* CJK COMPATIBILITY IDEOGRAPH-2F805 */
+ {0x2f806, 1, 5181}, /* CJK COMPATIBILITY IDEOGRAPH-2F806 */
+ {0x2f807, 1, 5182}, /* CJK COMPATIBILITY IDEOGRAPH-2F807 */
+ {0x2f808, 1, 5183}, /* CJK COMPATIBILITY IDEOGRAPH-2F808 */
+ {0x2f809, 1, 5184}, /* CJK COMPATIBILITY IDEOGRAPH-2F809 */
+ {0x2f80a, 1, 4143}, /* CJK COMPATIBILITY IDEOGRAPH-2F80A */
+ {0x2f80b, 1, 5185}, /* CJK COMPATIBILITY IDEOGRAPH-2F80B */
+ {0x2f80c, 1, 5186}, /* CJK COMPATIBILITY IDEOGRAPH-2F80C */
+ {0x2f80d, 1, 5187}, /* CJK COMPATIBILITY IDEOGRAPH-2F80D */
+ {0x2f80e, 1, 4144}, /* CJK COMPATIBILITY IDEOGRAPH-2F80E */
+ {0x2f80f, 1, 5188}, /* CJK COMPATIBILITY IDEOGRAPH-2F80F */
+ {0x2f810, 1, 5189}, /* CJK COMPATIBILITY IDEOGRAPH-2F810 */
+ {0x2f811, 1, 5190}, /* CJK COMPATIBILITY IDEOGRAPH-2F811 */
+ {0x2f812, 1, 5191}, /* CJK COMPATIBILITY IDEOGRAPH-2F812 */
+ {0x2f813, 1, 5192}, /* CJK COMPATIBILITY IDEOGRAPH-2F813 */
+ {0x2f814, 1, 5193}, /* CJK COMPATIBILITY IDEOGRAPH-2F814 */
+ {0x2f815, 1, 5194}, /* CJK COMPATIBILITY IDEOGRAPH-2F815 */
+ {0x2f816, 1, 5195}, /* CJK COMPATIBILITY IDEOGRAPH-2F816 */
+ {0x2f817, 1, 5196}, /* CJK COMPATIBILITY IDEOGRAPH-2F817 */
+ {0x2f818, 1, 5197}, /* CJK COMPATIBILITY IDEOGRAPH-2F818 */
+ {0x2f819, 1, 5198}, /* CJK COMPATIBILITY IDEOGRAPH-2F819 */
+ {0x2f81a, 1, 5199}, /* CJK COMPATIBILITY IDEOGRAPH-2F81A */
+ {0x2f81b, 1, 5200}, /* CJK COMPATIBILITY IDEOGRAPH-2F81B */
+ {0x2f81c, 1, 5201}, /* CJK COMPATIBILITY IDEOGRAPH-2F81C */
+ {0x2f81d, 1, 2389}, /* CJK COMPATIBILITY IDEOGRAPH-2F81D */
+ {0x2f81e, 1, 5202}, /* CJK COMPATIBILITY IDEOGRAPH-2F81E */
+ {0x2f81f, 1, 5203}, /* CJK COMPATIBILITY IDEOGRAPH-2F81F */
+ {0x2f820, 1, 5204}, /* CJK COMPATIBILITY IDEOGRAPH-2F820 */
+ {0x2f821, 1, 5205}, /* CJK COMPATIBILITY IDEOGRAPH-2F821 */
+ {0x2f822, 1, 5206}, /* CJK COMPATIBILITY IDEOGRAPH-2F822 */
+ {0x2f823, 1, 5207}, /* CJK COMPATIBILITY IDEOGRAPH-2F823 */
+ {0x2f824, 1, 5208}, /* CJK COMPATIBILITY IDEOGRAPH-2F824 */
+ {0x2f825, 1, 5209}, /* CJK COMPATIBILITY IDEOGRAPH-2F825 */
+ {0x2f826, 1, 4145}, /* CJK COMPATIBILITY IDEOGRAPH-2F826 */
+ {0x2f827, 1, 4146}, /* CJK COMPATIBILITY IDEOGRAPH-2F827 */
+ {0x2f828, 1, 5210}, /* CJK COMPATIBILITY IDEOGRAPH-2F828 */
+ {0x2f829, 1, 5211}, /* CJK COMPATIBILITY IDEOGRAPH-2F829 */
+ {0x2f82a, 1, 5212}, /* CJK COMPATIBILITY IDEOGRAPH-2F82A */
+ {0x2f82b, 1, 3965}, /* CJK COMPATIBILITY IDEOGRAPH-2F82B */
+ {0x2f82c, 1, 5213}, /* CJK COMPATIBILITY IDEOGRAPH-2F82C */
+ {0x2f82d, 1, 4147}, /* CJK COMPATIBILITY IDEOGRAPH-2F82D */
+ {0x2f82e, 1, 5214}, /* CJK COMPATIBILITY IDEOGRAPH-2F82E */
+ {0x2f82f, 1, 5215}, /* CJK COMPATIBILITY IDEOGRAPH-2F82F */
+ {0x2f830, 1, 5216}, /* CJK COMPATIBILITY IDEOGRAPH-2F830 */
+ {0x2f831, 1, 5217}, /* CJK COMPATIBILITY IDEOGRAPH-2F831 */
+ {0x2f832, 1, 5217}, /* CJK COMPATIBILITY IDEOGRAPH-2F832 */
+ {0x2f833, 1, 5217}, /* CJK COMPATIBILITY IDEOGRAPH-2F833 */
+ {0x2f834, 1, 5218}, /* CJK COMPATIBILITY IDEOGRAPH-2F834 */
+ {0x2f835, 1, 5219}, /* CJK COMPATIBILITY IDEOGRAPH-2F835 */
+ {0x2f836, 1, 5220}, /* CJK COMPATIBILITY IDEOGRAPH-2F836 */
+ {0x2f837, 1, 5221}, /* CJK COMPATIBILITY IDEOGRAPH-2F837 */
+ {0x2f838, 1, 5222}, /* CJK COMPATIBILITY IDEOGRAPH-2F838 */
+ {0x2f839, 1, 5223}, /* CJK COMPATIBILITY IDEOGRAPH-2F839 */
+ {0x2f83a, 1, 5224}, /* CJK COMPATIBILITY IDEOGRAPH-2F83A */
+ {0x2f83b, 1, 5225}, /* CJK COMPATIBILITY IDEOGRAPH-2F83B */
+ {0x2f83c, 1, 5226}, /* CJK COMPATIBILITY IDEOGRAPH-2F83C */
+ {0x2f83d, 1, 5227}, /* CJK COMPATIBILITY IDEOGRAPH-2F83D */
+ {0x2f83e, 1, 5228}, /* CJK COMPATIBILITY IDEOGRAPH-2F83E */
+ {0x2f83f, 1, 5229}, /* CJK COMPATIBILITY IDEOGRAPH-2F83F */
+ {0x2f840, 1, 5230}, /* CJK COMPATIBILITY IDEOGRAPH-2F840 */
+ {0x2f841, 1, 5231}, /* CJK COMPATIBILITY IDEOGRAPH-2F841 */
+ {0x2f842, 1, 5232}, /* CJK COMPATIBILITY IDEOGRAPH-2F842 */
+ {0x2f843, 1, 5233}, /* CJK COMPATIBILITY IDEOGRAPH-2F843 */
+ {0x2f844, 1, 5234}, /* CJK COMPATIBILITY IDEOGRAPH-2F844 */
+ {0x2f845, 1, 5235}, /* CJK COMPATIBILITY IDEOGRAPH-2F845 */
+ {0x2f846, 1, 5235}, /* CJK COMPATIBILITY IDEOGRAPH-2F846 */
+ {0x2f847, 1, 5236}, /* CJK COMPATIBILITY IDEOGRAPH-2F847 */
+ {0x2f848, 1, 5237}, /* CJK COMPATIBILITY IDEOGRAPH-2F848 */
+ {0x2f849, 1, 5238}, /* CJK COMPATIBILITY IDEOGRAPH-2F849 */
+ {0x2f84a, 1, 5239}, /* CJK COMPATIBILITY IDEOGRAPH-2F84A */
+ {0x2f84b, 1, 5240}, /* CJK COMPATIBILITY IDEOGRAPH-2F84B */
+ {0x2f84c, 1, 4149}, /* CJK COMPATIBILITY IDEOGRAPH-2F84C */
+ {0x2f84d, 1, 5241}, /* CJK COMPATIBILITY IDEOGRAPH-2F84D */
+ {0x2f84e, 1, 5242}, /* CJK COMPATIBILITY IDEOGRAPH-2F84E */
+ {0x2f84f, 1, 5243}, /* CJK COMPATIBILITY IDEOGRAPH-2F84F */
+ {0x2f850, 1, 4111}, /* CJK COMPATIBILITY IDEOGRAPH-2F850 */
+ {0x2f851, 1, 5244}, /* CJK COMPATIBILITY IDEOGRAPH-2F851 */
+ {0x2f852, 1, 5245}, /* CJK COMPATIBILITY IDEOGRAPH-2F852 */
+ {0x2f853, 1, 5246}, /* CJK COMPATIBILITY IDEOGRAPH-2F853 */
+ {0x2f854, 1, 5247}, /* CJK COMPATIBILITY IDEOGRAPH-2F854 */
+ {0x2f855, 1, 5248}, /* CJK COMPATIBILITY IDEOGRAPH-2F855 */
+ {0x2f856, 1, 5249}, /* CJK COMPATIBILITY IDEOGRAPH-2F856 */
+ {0x2f857, 1, 5250}, /* CJK COMPATIBILITY IDEOGRAPH-2F857 */
+ {0x2f858, 1, 5251}, /* CJK COMPATIBILITY IDEOGRAPH-2F858 */
+ {0x2f859, 1, 5252}, /* CJK COMPATIBILITY IDEOGRAPH-2F859 */
+ {0x2f85a, 1, 5253}, /* CJK COMPATIBILITY IDEOGRAPH-2F85A */
+ {0x2f85b, 1, 5254}, /* CJK COMPATIBILITY IDEOGRAPH-2F85B */
+ {0x2f85c, 1, 5255}, /* CJK COMPATIBILITY IDEOGRAPH-2F85C */
+ {0x2f85d, 1, 5256}, /* CJK COMPATIBILITY IDEOGRAPH-2F85D */
+ {0x2f85e, 1, 5257}, /* CJK COMPATIBILITY IDEOGRAPH-2F85E */
+ {0x2f85f, 1, 5258}, /* CJK COMPATIBILITY IDEOGRAPH-2F85F */
+ {0x2f860, 1, 5259}, /* CJK COMPATIBILITY IDEOGRAPH-2F860 */
+ {0x2f861, 1, 5260}, /* CJK COMPATIBILITY IDEOGRAPH-2F861 */
+ {0x2f862, 1, 5261}, /* CJK COMPATIBILITY IDEOGRAPH-2F862 */
+ {0x2f863, 1, 5262}, /* CJK COMPATIBILITY IDEOGRAPH-2F863 */
+ {0x2f864, 1, 5263}, /* CJK COMPATIBILITY IDEOGRAPH-2F864 */
+ {0x2f865, 1, 5264}, /* CJK COMPATIBILITY IDEOGRAPH-2F865 */
+ {0x2f866, 1, 5265}, /* CJK COMPATIBILITY IDEOGRAPH-2F866 */
+ {0x2f867, 1, 5266}, /* CJK COMPATIBILITY IDEOGRAPH-2F867 */
+ {0x2f868, 1, 5267}, /* CJK COMPATIBILITY IDEOGRAPH-2F868 */
+ {0x2f869, 1, 5268}, /* CJK COMPATIBILITY IDEOGRAPH-2F869 */
+ {0x2f86a, 1, 5269}, /* CJK COMPATIBILITY IDEOGRAPH-2F86A */
+ {0x2f86b, 1, 5269}, /* CJK COMPATIBILITY IDEOGRAPH-2F86B */
+ {0x2f86c, 1, 5270}, /* CJK COMPATIBILITY IDEOGRAPH-2F86C */
+ {0x2f86d, 1, 5271}, /* CJK COMPATIBILITY IDEOGRAPH-2F86D */
+ {0x2f86e, 1, 5272}, /* CJK COMPATIBILITY IDEOGRAPH-2F86E */
+ {0x2f86f, 1, 3961}, /* CJK COMPATIBILITY IDEOGRAPH-2F86F */
+ {0x2f870, 1, 5273}, /* CJK COMPATIBILITY IDEOGRAPH-2F870 */
+ {0x2f871, 1, 5274}, /* CJK COMPATIBILITY IDEOGRAPH-2F871 */
+ {0x2f872, 1, 5275}, /* CJK COMPATIBILITY IDEOGRAPH-2F872 */
+ {0x2f873, 1, 5276}, /* CJK COMPATIBILITY IDEOGRAPH-2F873 */
+ {0x2f874, 1, 5277}, /* CJK COMPATIBILITY IDEOGRAPH-2F874 */
+ {0x2f875, 1, 2415}, /* CJK COMPATIBILITY IDEOGRAPH-2F875 */
+ {0x2f876, 1, 5278}, /* CJK COMPATIBILITY IDEOGRAPH-2F876 */
+ {0x2f877, 1, 5279}, /* CJK COMPATIBILITY IDEOGRAPH-2F877 */
+ {0x2f878, 1, 2417}, /* CJK COMPATIBILITY IDEOGRAPH-2F878 */
+ {0x2f879, 1, 5280}, /* CJK COMPATIBILITY IDEOGRAPH-2F879 */
+ {0x2f87a, 1, 5281}, /* CJK COMPATIBILITY IDEOGRAPH-2F87A */
+ {0x2f87b, 1, 5282}, /* CJK COMPATIBILITY IDEOGRAPH-2F87B */
+ {0x2f87c, 1, 5283}, /* CJK COMPATIBILITY IDEOGRAPH-2F87C */
+ {0x2f87d, 1, 5284}, /* CJK COMPATIBILITY IDEOGRAPH-2F87D */
+ {0x2f87e, 1, 5285}, /* CJK COMPATIBILITY IDEOGRAPH-2F87E */
+ {0x2f87f, 1, 5286}, /* CJK COMPATIBILITY IDEOGRAPH-2F87F */
+ {0x2f880, 1, 5287}, /* CJK COMPATIBILITY IDEOGRAPH-2F880 */
+ {0x2f881, 1, 5288}, /* CJK COMPATIBILITY IDEOGRAPH-2F881 */
+ {0x2f882, 1, 5289}, /* CJK COMPATIBILITY IDEOGRAPH-2F882 */
+ {0x2f883, 1, 5290}, /* CJK COMPATIBILITY IDEOGRAPH-2F883 */
+ {0x2f884, 1, 5291}, /* CJK COMPATIBILITY IDEOGRAPH-2F884 */
+ {0x2f885, 1, 5292}, /* CJK COMPATIBILITY IDEOGRAPH-2F885 */
+ {0x2f886, 1, 5293}, /* CJK COMPATIBILITY IDEOGRAPH-2F886 */
+ {0x2f887, 1, 5294}, /* CJK COMPATIBILITY IDEOGRAPH-2F887 */
+ {0x2f888, 1, 5295}, /* CJK COMPATIBILITY IDEOGRAPH-2F888 */
+ {0x2f889, 1, 5296}, /* CJK COMPATIBILITY IDEOGRAPH-2F889 */
+ {0x2f88a, 1, 5297}, /* CJK COMPATIBILITY IDEOGRAPH-2F88A */
+ {0x2f88b, 1, 5298}, /* CJK COMPATIBILITY IDEOGRAPH-2F88B */
+ {0x2f88c, 1, 5299}, /* CJK COMPATIBILITY IDEOGRAPH-2F88C */
+ {0x2f88d, 1, 5300}, /* CJK COMPATIBILITY IDEOGRAPH-2F88D */
+ {0x2f88e, 1, 3909}, /* CJK COMPATIBILITY IDEOGRAPH-2F88E */
+ {0x2f88f, 1, 5301}, /* CJK COMPATIBILITY IDEOGRAPH-2F88F */
+ {0x2f890, 1, 2427}, /* CJK COMPATIBILITY IDEOGRAPH-2F890 */
+ {0x2f891, 1, 5302}, /* CJK COMPATIBILITY IDEOGRAPH-2F891 */
+ {0x2f892, 1, 5302}, /* CJK COMPATIBILITY IDEOGRAPH-2F892 */
+ {0x2f893, 1, 5303}, /* CJK COMPATIBILITY IDEOGRAPH-2F893 */
+ {0x2f894, 1, 5304}, /* CJK COMPATIBILITY IDEOGRAPH-2F894 */
+ {0x2f895, 1, 5304}, /* CJK COMPATIBILITY IDEOGRAPH-2F895 */
+ {0x2f896, 1, 5305}, /* CJK COMPATIBILITY IDEOGRAPH-2F896 */
+ {0x2f897, 1, 5306}, /* CJK COMPATIBILITY IDEOGRAPH-2F897 */
+ {0x2f898, 1, 5307}, /* CJK COMPATIBILITY IDEOGRAPH-2F898 */
+ {0x2f899, 1, 5308}, /* CJK COMPATIBILITY IDEOGRAPH-2F899 */
+ {0x2f89a, 1, 5309}, /* CJK COMPATIBILITY IDEOGRAPH-2F89A */
+ {0x2f89b, 1, 5310}, /* CJK COMPATIBILITY IDEOGRAPH-2F89B */
+ {0x2f89c, 1, 5311}, /* CJK COMPATIBILITY IDEOGRAPH-2F89C */
+ {0x2f89d, 1, 5312}, /* CJK COMPATIBILITY IDEOGRAPH-2F89D */
+ {0x2f89e, 1, 5313}, /* CJK COMPATIBILITY IDEOGRAPH-2F89E */
+ {0x2f89f, 1, 5314}, /* CJK COMPATIBILITY IDEOGRAPH-2F89F */
+ {0x2f8a0, 1, 5315}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A0 */
+ {0x2f8a1, 1, 5316}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A1 */
+ {0x2f8a2, 1, 5317}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A2 */
+ {0x2f8a3, 1, 4154}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A3 */
+ {0x2f8a4, 1, 5318}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A4 */
+ {0x2f8a5, 1, 5319}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A5 */
+ {0x2f8a6, 1, 5320}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A6 */
+ {0x2f8a7, 1, 5321}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A7 */
+ {0x2f8a8, 1, 5322}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A8 */
+ {0x2f8a9, 1, 5321}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A9 */
+ {0x2f8aa, 1, 5323}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AA */
+ {0x2f8ab, 1, 4156}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AB */
+ {0x2f8ac, 1, 5324}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AC */
+ {0x2f8ad, 1, 5325}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AD */
+ {0x2f8ae, 1, 5326}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AE */
+ {0x2f8af, 1, 5327}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AF */
+ {0x2f8b0, 1, 4157}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B0 */
+ {0x2f8b1, 1, 3882}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B1 */
+ {0x2f8b2, 1, 3553}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B2 */
+ {0x2f8b3, 1, 5328}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B3 */
+ {0x2f8b4, 1, 5329}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B4 */
+ {0x2f8b5, 1, 5330}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B5 */
+ {0x2f8b6, 1, 5331}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B6 */
+ {0x2f8b7, 1, 5332}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B7 */
+ {0x2f8b8, 1, 5333}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B8 */
+ {0x2f8b9, 1, 5334}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B9 */
+ {0x2f8ba, 1, 5335}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BA */
+ {0x2f8bb, 1, 5336}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BB */
+ {0x2f8bc, 1, 5337}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BC */
+ {0x2f8bd, 1, 5338}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BD */
+ {0x2f8be, 1, 5339}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BE */
+ {0x2f8bf, 1, 5340}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BF */
+ {0x2f8c0, 1, 5341}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C0 */
+ {0x2f8c1, 1, 5342}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C1 */
+ {0x2f8c2, 1, 5343}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C2 */
+ {0x2f8c3, 1, 5344}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C3 */
+ {0x2f8c4, 1, 5345}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C4 */
+ {0x2f8c5, 1, 5346}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C5 */
+ {0x2f8c6, 1, 5347}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C6 */
+ {0x2f8c7, 1, 5348}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C7 */
+ {0x2f8c8, 1, 4158}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C8 */
+ {0x2f8c9, 1, 5349}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C9 */
+ {0x2f8ca, 1, 5350}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CA */
+ {0x2f8cb, 1, 5351}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CB */
+ {0x2f8cc, 1, 5352}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CC */
+ {0x2f8cd, 1, 5353}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CD */
+ {0x2f8ce, 1, 5354}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CE */
+ {0x2f8cf, 1, 4160}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CF */
+ {0x2f8d0, 1, 5355}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D0 */
+ {0x2f8d1, 1, 5356}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D1 */
+ {0x2f8d2, 1, 5357}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D2 */
+ {0x2f8d3, 1, 5358}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D3 */
+ {0x2f8d4, 1, 5359}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D4 */
+ {0x2f8d5, 1, 5360}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D5 */
+ {0x2f8d6, 1, 5361}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D6 */
+ {0x2f8d7, 1, 5362}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D7 */
+ {0x2f8d8, 1, 3910}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D8 */
+ {0x2f8d9, 1, 5363}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D9 */
+ {0x2f8da, 1, 5364}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DA */
+ {0x2f8db, 1, 5365}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DB */
+ {0x2f8dc, 1, 5366}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DC */
+ {0x2f8dd, 1, 5367}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DD */
+ {0x2f8de, 1, 5368}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DE */
+ {0x2f8df, 1, 5369}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DF */
+ {0x2f8e0, 1, 5370}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E0 */
+ {0x2f8e1, 1, 5371}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E1 */
+ {0x2f8e2, 1, 4161}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E2 */
+ {0x2f8e3, 1, 5372}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E3 */
+ {0x2f8e4, 1, 5373}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E4 */
+ {0x2f8e5, 1, 5374}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E5 */
+ {0x2f8e6, 1, 5375}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E6 */
+ {0x2f8e7, 1, 5376}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E7 */
+ {0x2f8e8, 1, 5377}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E8 */
+ {0x2f8e9, 1, 5378}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E9 */
+ {0x2f8ea, 1, 5379}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EA */
+ {0x2f8eb, 1, 5380}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EB */
+ {0x2f8ec, 1, 5381}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EC */
+ {0x2f8ed, 1, 5382}, /* CJK COMPATIBILITY IDEOGRAPH-2F8ED */
+ {0x2f8ee, 1, 5383}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EE */
+ {0x2f8ef, 1, 5384}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EF */
+ {0x2f8f0, 1, 5385}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F0 */
+ {0x2f8f1, 1, 5386}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F1 */
+ {0x2f8f2, 1, 5387}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F2 */
+ {0x2f8f3, 1, 5388}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F3 */
+ {0x2f8f4, 1, 5389}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F4 */
+ {0x2f8f5, 1, 3978}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F5 */
+ {0x2f8f6, 1, 5390}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F6 */
+ {0x2f8f7, 1, 5391}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F7 */
+ {0x2f8f8, 1, 5392}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F8 */
+ {0x2f8f9, 1, 5393}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F9 */
+ {0x2f8fa, 1, 5394}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FA */
+ {0x2f8fb, 1, 5395}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FB */
+ {0x2f8fc, 1, 5396}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FC */
+ {0x2f8fd, 1, 5397}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FD */
+ {0x2f8fe, 1, 5398}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FE */
+ {0x2f8ff, 1, 5399}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FF */
+ {0x2f900, 1, 5400}, /* CJK COMPATIBILITY IDEOGRAPH-2F900 */
+ {0x2f901, 1, 4162}, /* CJK COMPATIBILITY IDEOGRAPH-2F901 */
+ {0x2f902, 1, 4061}, /* CJK COMPATIBILITY IDEOGRAPH-2F902 */
+ {0x2f903, 1, 5401}, /* CJK COMPATIBILITY IDEOGRAPH-2F903 */
+ {0x2f904, 1, 5402}, /* CJK COMPATIBILITY IDEOGRAPH-2F904 */
+ {0x2f905, 1, 5403}, /* CJK COMPATIBILITY IDEOGRAPH-2F905 */
+ {0x2f906, 1, 5404}, /* CJK COMPATIBILITY IDEOGRAPH-2F906 */
+ {0x2f907, 1, 5405}, /* CJK COMPATIBILITY IDEOGRAPH-2F907 */
+ {0x2f908, 1, 5406}, /* CJK COMPATIBILITY IDEOGRAPH-2F908 */
+ {0x2f909, 1, 5407}, /* CJK COMPATIBILITY IDEOGRAPH-2F909 */
+ {0x2f90a, 1, 5408}, /* CJK COMPATIBILITY IDEOGRAPH-2F90A */
+ {0x2f90b, 1, 5409}, /* CJK COMPATIBILITY IDEOGRAPH-2F90B */
+ {0x2f90c, 1, 5410}, /* CJK COMPATIBILITY IDEOGRAPH-2F90C */
+ {0x2f90d, 1, 5411}, /* CJK COMPATIBILITY IDEOGRAPH-2F90D */
+ {0x2f90e, 1, 5412}, /* CJK COMPATIBILITY IDEOGRAPH-2F90E */
+ {0x2f90f, 1, 5413}, /* CJK COMPATIBILITY IDEOGRAPH-2F90F */
+ {0x2f910, 1, 5414}, /* CJK COMPATIBILITY IDEOGRAPH-2F910 */
+ {0x2f911, 1, 5415}, /* CJK COMPATIBILITY IDEOGRAPH-2F911 */
+ {0x2f912, 1, 5416}, /* CJK COMPATIBILITY IDEOGRAPH-2F912 */
+ {0x2f913, 1, 5417}, /* CJK COMPATIBILITY IDEOGRAPH-2F913 */
+ {0x2f914, 1, 5418}, /* CJK COMPATIBILITY IDEOGRAPH-2F914 */
+ {0x2f915, 1, 5419}, /* CJK COMPATIBILITY IDEOGRAPH-2F915 */
+ {0x2f916, 1, 5420}, /* CJK COMPATIBILITY IDEOGRAPH-2F916 */
+ {0x2f917, 1, 5421}, /* CJK COMPATIBILITY IDEOGRAPH-2F917 */
+ {0x2f918, 1, 5422}, /* CJK COMPATIBILITY IDEOGRAPH-2F918 */
+ {0x2f919, 1, 5423}, /* CJK COMPATIBILITY IDEOGRAPH-2F919 */
+ {0x2f91a, 1, 5424}, /* CJK COMPATIBILITY IDEOGRAPH-2F91A */
+ {0x2f91b, 1, 5425}, /* CJK COMPATIBILITY IDEOGRAPH-2F91B */
+ {0x2f91c, 1, 5426}, /* CJK COMPATIBILITY IDEOGRAPH-2F91C */
+ {0x2f91d, 1, 5427}, /* CJK COMPATIBILITY IDEOGRAPH-2F91D */
+ {0x2f91e, 1, 5428}, /* CJK COMPATIBILITY IDEOGRAPH-2F91E */
+ {0x2f91f, 1, 5429}, /* CJK COMPATIBILITY IDEOGRAPH-2F91F */
+ {0x2f920, 1, 5430}, /* CJK COMPATIBILITY IDEOGRAPH-2F920 */
+ {0x2f921, 1, 5431}, /* CJK COMPATIBILITY IDEOGRAPH-2F921 */
+ {0x2f922, 1, 5432}, /* CJK COMPATIBILITY IDEOGRAPH-2F922 */
+ {0x2f923, 1, 5433}, /* CJK COMPATIBILITY IDEOGRAPH-2F923 */
+ {0x2f924, 1, 5434}, /* CJK COMPATIBILITY IDEOGRAPH-2F924 */
+ {0x2f925, 1, 5435}, /* CJK COMPATIBILITY IDEOGRAPH-2F925 */
+ {0x2f926, 1, 5436}, /* CJK COMPATIBILITY IDEOGRAPH-2F926 */
+ {0x2f927, 1, 5437}, /* CJK COMPATIBILITY IDEOGRAPH-2F927 */
+ {0x2f928, 1, 5438}, /* CJK COMPATIBILITY IDEOGRAPH-2F928 */
+ {0x2f929, 1, 5439}, /* CJK COMPATIBILITY IDEOGRAPH-2F929 */
+ {0x2f92a, 1, 5440}, /* CJK COMPATIBILITY IDEOGRAPH-2F92A */
+ {0x2f92b, 1, 5441}, /* CJK COMPATIBILITY IDEOGRAPH-2F92B */
+ {0x2f92c, 1, 5442}, /* CJK COMPATIBILITY IDEOGRAPH-2F92C */
+ {0x2f92d, 1, 5442}, /* CJK COMPATIBILITY IDEOGRAPH-2F92D */
+ {0x2f92e, 1, 5443}, /* CJK COMPATIBILITY IDEOGRAPH-2F92E */
+ {0x2f92f, 1, 5444}, /* CJK COMPATIBILITY IDEOGRAPH-2F92F */
+ {0x2f930, 1, 5445}, /* CJK COMPATIBILITY IDEOGRAPH-2F930 */
+ {0x2f931, 1, 5446}, /* CJK COMPATIBILITY IDEOGRAPH-2F931 */
+ {0x2f932, 1, 5447}, /* CJK COMPATIBILITY IDEOGRAPH-2F932 */
+ {0x2f933, 1, 5448}, /* CJK COMPATIBILITY IDEOGRAPH-2F933 */
+ {0x2f934, 1, 5449}, /* CJK COMPATIBILITY IDEOGRAPH-2F934 */
+ {0x2f935, 1, 5450}, /* CJK COMPATIBILITY IDEOGRAPH-2F935 */
+ {0x2f936, 1, 5451}, /* CJK COMPATIBILITY IDEOGRAPH-2F936 */
+ {0x2f937, 1, 5452}, /* CJK COMPATIBILITY IDEOGRAPH-2F937 */
+ {0x2f938, 1, 3964}, /* CJK COMPATIBILITY IDEOGRAPH-2F938 */
+ {0x2f939, 1, 5453}, /* CJK COMPATIBILITY IDEOGRAPH-2F939 */
+ {0x2f93a, 1, 5454}, /* CJK COMPATIBILITY IDEOGRAPH-2F93A */
+ {0x2f93b, 1, 5455}, /* CJK COMPATIBILITY IDEOGRAPH-2F93B */
+ {0x2f93c, 1, 5456}, /* CJK COMPATIBILITY IDEOGRAPH-2F93C */
+ {0x2f93d, 1, 5457}, /* CJK COMPATIBILITY IDEOGRAPH-2F93D */
+ {0x2f93e, 1, 5458}, /* CJK COMPATIBILITY IDEOGRAPH-2F93E */
+ {0x2f93f, 1, 5459}, /* CJK COMPATIBILITY IDEOGRAPH-2F93F */
+ {0x2f940, 1, 5460}, /* CJK COMPATIBILITY IDEOGRAPH-2F940 */
+ {0x2f941, 1, 5461}, /* CJK COMPATIBILITY IDEOGRAPH-2F941 */
+ {0x2f942, 1, 5462}, /* CJK COMPATIBILITY IDEOGRAPH-2F942 */
+ {0x2f943, 1, 5463}, /* CJK COMPATIBILITY IDEOGRAPH-2F943 */
+ {0x2f944, 1, 5464}, /* CJK COMPATIBILITY IDEOGRAPH-2F944 */
+ {0x2f945, 1, 5465}, /* CJK COMPATIBILITY IDEOGRAPH-2F945 */
+ {0x2f946, 1, 5466}, /* CJK COMPATIBILITY IDEOGRAPH-2F946 */
+ {0x2f947, 1, 5466}, /* CJK COMPATIBILITY IDEOGRAPH-2F947 */
+ {0x2f948, 1, 5467}, /* CJK COMPATIBILITY IDEOGRAPH-2F948 */
+ {0x2f949, 1, 5468}, /* CJK COMPATIBILITY IDEOGRAPH-2F949 */
+ {0x2f94a, 1, 5469}, /* CJK COMPATIBILITY IDEOGRAPH-2F94A */
+ {0x2f94b, 1, 5470}, /* CJK COMPATIBILITY IDEOGRAPH-2F94B */
+ {0x2f94c, 1, 5471}, /* CJK COMPATIBILITY IDEOGRAPH-2F94C */
+ {0x2f94d, 1, 5472}, /* CJK COMPATIBILITY IDEOGRAPH-2F94D */
+ {0x2f94e, 1, 5473}, /* CJK COMPATIBILITY IDEOGRAPH-2F94E */
+ {0x2f94f, 1, 3927}, /* CJK COMPATIBILITY IDEOGRAPH-2F94F */
+ {0x2f950, 1, 5474}, /* CJK COMPATIBILITY IDEOGRAPH-2F950 */
+ {0x2f951, 1, 5475}, /* CJK COMPATIBILITY IDEOGRAPH-2F951 */
+ {0x2f952, 1, 5476}, /* CJK COMPATIBILITY IDEOGRAPH-2F952 */
+ {0x2f953, 1, 4172}, /* CJK COMPATIBILITY IDEOGRAPH-2F953 */
+ {0x2f954, 1, 5477}, /* CJK COMPATIBILITY IDEOGRAPH-2F954 */
+ {0x2f955, 1, 5478}, /* CJK COMPATIBILITY IDEOGRAPH-2F955 */
+ {0x2f956, 1, 4131}, /* CJK COMPATIBILITY IDEOGRAPH-2F956 */
+ {0x2f957, 1, 5479}, /* CJK COMPATIBILITY IDEOGRAPH-2F957 */
+ {0x2f958, 1, 5480}, /* CJK COMPATIBILITY IDEOGRAPH-2F958 */
+ {0x2f959, 1, 4175}, /* CJK COMPATIBILITY IDEOGRAPH-2F959 */
+ {0x2f95a, 1, 5481}, /* CJK COMPATIBILITY IDEOGRAPH-2F95A */
+ {0x2f95b, 1, 5482}, /* CJK COMPATIBILITY IDEOGRAPH-2F95B */
+ {0x2f95c, 1, 5483}, /* CJK COMPATIBILITY IDEOGRAPH-2F95C */
+ {0x2f95d, 1, 5484}, /* CJK COMPATIBILITY IDEOGRAPH-2F95D */
+ {0x2f95e, 1, 5484}, /* CJK COMPATIBILITY IDEOGRAPH-2F95E */
+ {0x2f95f, 1, 5485}, /* CJK COMPATIBILITY IDEOGRAPH-2F95F */
+ {0x2f960, 1, 5486}, /* CJK COMPATIBILITY IDEOGRAPH-2F960 */
+ {0x2f961, 1, 5487}, /* CJK COMPATIBILITY IDEOGRAPH-2F961 */
+ {0x2f962, 1, 5488}, /* CJK COMPATIBILITY IDEOGRAPH-2F962 */
+ {0x2f963, 1, 5489}, /* CJK COMPATIBILITY IDEOGRAPH-2F963 */
+ {0x2f964, 1, 5490}, /* CJK COMPATIBILITY IDEOGRAPH-2F964 */
+ {0x2f965, 1, 5491}, /* CJK COMPATIBILITY IDEOGRAPH-2F965 */
+ {0x2f966, 1, 5492}, /* CJK COMPATIBILITY IDEOGRAPH-2F966 */
+ {0x2f967, 1, 5493}, /* CJK COMPATIBILITY IDEOGRAPH-2F967 */
+ {0x2f968, 1, 5494}, /* CJK COMPATIBILITY IDEOGRAPH-2F968 */
+ {0x2f969, 1, 5495}, /* CJK COMPATIBILITY IDEOGRAPH-2F969 */
+ {0x2f96a, 1, 5496}, /* CJK COMPATIBILITY IDEOGRAPH-2F96A */
+ {0x2f96b, 1, 5497}, /* CJK COMPATIBILITY IDEOGRAPH-2F96B */
+ {0x2f96c, 1, 5498}, /* CJK COMPATIBILITY IDEOGRAPH-2F96C */
+ {0x2f96d, 1, 5499}, /* CJK COMPATIBILITY IDEOGRAPH-2F96D */
+ {0x2f96e, 1, 5500}, /* CJK COMPATIBILITY IDEOGRAPH-2F96E */
+ {0x2f96f, 1, 5501}, /* CJK COMPATIBILITY IDEOGRAPH-2F96F */
+ {0x2f970, 1, 5502}, /* CJK COMPATIBILITY IDEOGRAPH-2F970 */
+ {0x2f971, 1, 5503}, /* CJK COMPATIBILITY IDEOGRAPH-2F971 */
+ {0x2f972, 1, 5504}, /* CJK COMPATIBILITY IDEOGRAPH-2F972 */
+ {0x2f973, 1, 5505}, /* CJK COMPATIBILITY IDEOGRAPH-2F973 */
+ {0x2f974, 1, 5506}, /* CJK COMPATIBILITY IDEOGRAPH-2F974 */
+ {0x2f975, 1, 5507}, /* CJK COMPATIBILITY IDEOGRAPH-2F975 */
+ {0x2f976, 1, 5508}, /* CJK COMPATIBILITY IDEOGRAPH-2F976 */
+ {0x2f977, 1, 5509}, /* CJK COMPATIBILITY IDEOGRAPH-2F977 */
+ {0x2f978, 1, 5510}, /* CJK COMPATIBILITY IDEOGRAPH-2F978 */
+ {0x2f979, 1, 5511}, /* CJK COMPATIBILITY IDEOGRAPH-2F979 */
+ {0x2f97a, 1, 4181}, /* CJK COMPATIBILITY IDEOGRAPH-2F97A */
+ {0x2f97b, 1, 5512}, /* CJK COMPATIBILITY IDEOGRAPH-2F97B */
+ {0x2f97c, 1, 5513}, /* CJK COMPATIBILITY IDEOGRAPH-2F97C */
+ {0x2f97d, 1, 5514}, /* CJK COMPATIBILITY IDEOGRAPH-2F97D */
+ {0x2f97e, 1, 5515}, /* CJK COMPATIBILITY IDEOGRAPH-2F97E */
+ {0x2f97f, 1, 5516}, /* CJK COMPATIBILITY IDEOGRAPH-2F97F */
+ {0x2f980, 1, 5517}, /* CJK COMPATIBILITY IDEOGRAPH-2F980 */
+ {0x2f981, 1, 5518}, /* CJK COMPATIBILITY IDEOGRAPH-2F981 */
+ {0x2f982, 1, 5519}, /* CJK COMPATIBILITY IDEOGRAPH-2F982 */
+ {0x2f983, 1, 5520}, /* CJK COMPATIBILITY IDEOGRAPH-2F983 */
+ {0x2f984, 1, 5521}, /* CJK COMPATIBILITY IDEOGRAPH-2F984 */
+ {0x2f985, 1, 5522}, /* CJK COMPATIBILITY IDEOGRAPH-2F985 */
+ {0x2f986, 1, 5523}, /* CJK COMPATIBILITY IDEOGRAPH-2F986 */
+ {0x2f987, 1, 5524}, /* CJK COMPATIBILITY IDEOGRAPH-2F987 */
+ {0x2f988, 1, 5525}, /* CJK COMPATIBILITY IDEOGRAPH-2F988 */
+ {0x2f989, 1, 5526}, /* CJK COMPATIBILITY IDEOGRAPH-2F989 */
+ {0x2f98a, 1, 5527}, /* CJK COMPATIBILITY IDEOGRAPH-2F98A */
+ {0x2f98b, 1, 5303}, /* CJK COMPATIBILITY IDEOGRAPH-2F98B */
+ {0x2f98c, 1, 5528}, /* CJK COMPATIBILITY IDEOGRAPH-2F98C */
+ {0x2f98d, 1, 5529}, /* CJK COMPATIBILITY IDEOGRAPH-2F98D */
+ {0x2f98e, 1, 5530}, /* CJK COMPATIBILITY IDEOGRAPH-2F98E */
+ {0x2f98f, 1, 5531}, /* CJK COMPATIBILITY IDEOGRAPH-2F98F */
+ {0x2f990, 1, 5532}, /* CJK COMPATIBILITY IDEOGRAPH-2F990 */
+ {0x2f991, 1, 5533}, /* CJK COMPATIBILITY IDEOGRAPH-2F991 */
+ {0x2f992, 1, 5534}, /* CJK COMPATIBILITY IDEOGRAPH-2F992 */
+ {0x2f993, 1, 5535}, /* CJK COMPATIBILITY IDEOGRAPH-2F993 */
+ {0x2f994, 1, 5536}, /* CJK COMPATIBILITY IDEOGRAPH-2F994 */
+ {0x2f995, 1, 5537}, /* CJK COMPATIBILITY IDEOGRAPH-2F995 */
+ {0x2f996, 1, 5538}, /* CJK COMPATIBILITY IDEOGRAPH-2F996 */
+ {0x2f997, 1, 5539}, /* CJK COMPATIBILITY IDEOGRAPH-2F997 */
+ {0x2f998, 1, 3981}, /* CJK COMPATIBILITY IDEOGRAPH-2F998 */
+ {0x2f999, 1, 5540}, /* CJK COMPATIBILITY IDEOGRAPH-2F999 */
+ {0x2f99a, 1, 5541}, /* CJK COMPATIBILITY IDEOGRAPH-2F99A */
+ {0x2f99b, 1, 5542}, /* CJK COMPATIBILITY IDEOGRAPH-2F99B */
+ {0x2f99c, 1, 5543}, /* CJK COMPATIBILITY IDEOGRAPH-2F99C */
+ {0x2f99d, 1, 5544}, /* CJK COMPATIBILITY IDEOGRAPH-2F99D */
+ {0x2f99e, 1, 5545}, /* CJK COMPATIBILITY IDEOGRAPH-2F99E */
+ {0x2f99f, 1, 4184}, /* CJK COMPATIBILITY IDEOGRAPH-2F99F */
+ {0x2f9a0, 1, 5546}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A0 */
+ {0x2f9a1, 1, 5547}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A1 */
+ {0x2f9a2, 1, 5548}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A2 */
+ {0x2f9a3, 1, 5549}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A3 */
+ {0x2f9a4, 1, 5550}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A4 */
+ {0x2f9a5, 1, 5551}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A5 */
+ {0x2f9a6, 1, 5552}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A6 */
+ {0x2f9a7, 1, 5553}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A7 */
+ {0x2f9a8, 1, 5554}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A8 */
+ {0x2f9a9, 1, 5555}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A9 */
+ {0x2f9aa, 1, 5556}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AA */
+ {0x2f9ab, 1, 5557}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AB */
+ {0x2f9ac, 1, 5558}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AC */
+ {0x2f9ad, 1, 5559}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AD */
+ {0x2f9ae, 1, 5560}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AE */
+ {0x2f9af, 1, 5561}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AF */
+ {0x2f9b0, 1, 5562}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B0 */
+ {0x2f9b1, 1, 5563}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B1 */
+ {0x2f9b2, 1, 5564}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B2 */
+ {0x2f9b3, 1, 5565}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B3 */
+ {0x2f9b4, 1, 3922}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B4 */
+ {0x2f9b5, 1, 5566}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B5 */
+ {0x2f9b6, 1, 5567}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B6 */
+ {0x2f9b7, 1, 5568}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B7 */
+ {0x2f9b8, 1, 5569}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B8 */
+ {0x2f9b9, 1, 5570}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B9 */
+ {0x2f9ba, 1, 5571}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BA */
+ {0x2f9bb, 1, 5572}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BB */
+ {0x2f9bc, 1, 5573}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BC */
+ {0x2f9bd, 1, 5574}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BD */
+ {0x2f9be, 1, 5575}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BE */
+ {0x2f9bf, 1, 5576}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BF */
+ {0x2f9c0, 1, 5577}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C0 */
+ {0x2f9c1, 1, 5578}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C1 */
+ {0x2f9c2, 1, 5579}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C2 */
+ {0x2f9c3, 1, 5580}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C3 */
+ {0x2f9c4, 1, 2517}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C4 */
+ {0x2f9c5, 1, 5581}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C5 */
+ {0x2f9c6, 1, 5582}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C6 */
+ {0x2f9c7, 1, 5583}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C7 */
+ {0x2f9c8, 1, 5584}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C8 */
+ {0x2f9c9, 1, 5585}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C9 */
+ {0x2f9ca, 1, 5586}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CA */
+ {0x2f9cb, 1, 5587}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CB */
+ {0x2f9cc, 1, 5588}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CC */
+ {0x2f9cd, 1, 5589}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CD */
+ {0x2f9ce, 1, 5590}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CE */
+ {0x2f9cf, 1, 5591}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CF */
+ {0x2f9d0, 1, 5592}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D0 */
+ {0x2f9d1, 1, 5593}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D1 */
+ {0x2f9d2, 1, 2524}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D2 */
+ {0x2f9d3, 1, 5594}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D3 */
+ {0x2f9d4, 1, 5595}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D4 */
+ {0x2f9d5, 1, 5596}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D5 */
+ {0x2f9d6, 1, 5597}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D6 */
+ {0x2f9d7, 1, 5598}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D7 */
+ {0x2f9d8, 1, 5599}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D8 */
+ {0x2f9d9, 1, 5600}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D9 */
+ {0x2f9da, 1, 5601}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DA */
+ {0x2f9db, 1, 5602}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DB */
+ {0x2f9dc, 1, 5603}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DC */
+ {0x2f9dd, 1, 5604}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DD */
+ {0x2f9de, 1, 5605}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DE */
+ {0x2f9df, 1, 5606}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DF */
+ {0x2f9e0, 1, 5607}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E0 */
+ {0x2f9e1, 1, 5608}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E1 */
+ {0x2f9e2, 1, 5609}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E2 */
+ {0x2f9e3, 1, 5610}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E3 */
+ {0x2f9e4, 1, 5611}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E4 */
+ {0x2f9e5, 1, 5612}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E5 */
+ {0x2f9e6, 1, 5613}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E6 */
+ {0x2f9e7, 1, 5614}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E7 */
+ {0x2f9e8, 1, 5615}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E8 */
+ {0x2f9e9, 1, 5616}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E9 */
+ {0x2f9ea, 1, 5617}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EA */
+ {0x2f9eb, 1, 5618}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EB */
+ {0x2f9ec, 1, 5619}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EC */
+ {0x2f9ed, 1, 5620}, /* CJK COMPATIBILITY IDEOGRAPH-2F9ED */
+ {0x2f9ee, 1, 5621}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EE */
+ {0x2f9ef, 1, 5622}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EF */
+ {0x2f9f0, 1, 5623}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F0 */
+ {0x2f9f1, 1, 5624}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F1 */
+ {0x2f9f2, 1, 5625}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F2 */
+ {0x2f9f3, 1, 5626}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F3 */
+ {0x2f9f4, 1, 5627}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F4 */
+ {0x2f9f5, 1, 5628}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F5 */
+ {0x2f9f6, 1, 5629}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F6 */
+ {0x2f9f7, 1, 5630}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F7 */
+ {0x2f9f8, 1, 5631}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F8 */
+ {0x2f9f9, 1, 5632}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F9 */
+ {0x2f9fa, 1, 5633}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FA */
+ {0x2f9fb, 1, 5634}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FB */
+ {0x2f9fc, 1, 5635}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FC */
+ {0x2f9fd, 1, 5636}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FD */
+ {0x2f9fe, 1, 5637}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FE */
+ {0x2f9ff, 1, 5637}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FF */
+ {0x2fa00, 1, 5638}, /* CJK COMPATIBILITY IDEOGRAPH-2FA00 */
+ {0x2fa01, 1, 5639}, /* CJK COMPATIBILITY IDEOGRAPH-2FA01 */
+ {0x2fa02, 1, 5640}, /* CJK COMPATIBILITY IDEOGRAPH-2FA02 */
+ {0x2fa03, 1, 5641}, /* CJK COMPATIBILITY IDEOGRAPH-2FA03 */
+ {0x2fa04, 1, 5642}, /* CJK COMPATIBILITY IDEOGRAPH-2FA04 */
+ {0x2fa05, 1, 5643}, /* CJK COMPATIBILITY IDEOGRAPH-2FA05 */
+ {0x2fa06, 1, 5644}, /* CJK COMPATIBILITY IDEOGRAPH-2FA06 */
+ {0x2fa07, 1, 5645}, /* CJK COMPATIBILITY IDEOGRAPH-2FA07 */
+ {0x2fa08, 1, 5646}, /* CJK COMPATIBILITY IDEOGRAPH-2FA08 */
+ {0x2fa09, 1, 5647}, /* CJK COMPATIBILITY IDEOGRAPH-2FA09 */
+ {0x2fa0a, 1, 5648}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0A */
+ {0x2fa0b, 1, 5649}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0B */
+ {0x2fa0c, 1, 5650}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0C */
+ {0x2fa0d, 1, 5651}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0D */
+ {0x2fa0e, 1, 5652}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0E */
+ {0x2fa0f, 1, 5653}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0F */
+ {0x2fa10, 1, 5654}, /* CJK COMPATIBILITY IDEOGRAPH-2FA10 */
+ {0x2fa11, 1, 5655}, /* CJK COMPATIBILITY IDEOGRAPH-2FA11 */
+ {0x2fa12, 1, 5656}, /* CJK COMPATIBILITY IDEOGRAPH-2FA12 */
+ {0x2fa13, 1, 5657}, /* CJK COMPATIBILITY IDEOGRAPH-2FA13 */
+ {0x2fa14, 1, 5658}, /* CJK COMPATIBILITY IDEOGRAPH-2FA14 */
+ {0x2fa15, 1, 2572}, /* CJK COMPATIBILITY IDEOGRAPH-2FA15 */
+ {0x2fa16, 1, 5659}, /* CJK COMPATIBILITY IDEOGRAPH-2FA16 */
+ {0x2fa17, 1, 2576}, /* CJK COMPATIBILITY IDEOGRAPH-2FA17 */
+ {0x2fa18, 1, 5660}, /* CJK COMPATIBILITY IDEOGRAPH-2FA18 */
+ {0x2fa19, 1, 5661}, /* CJK COMPATIBILITY IDEOGRAPH-2FA19 */
+ {0x2fa1a, 1, 5662}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1A */
+ {0x2fa1b, 1, 5663}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1B */
+ {0x2fa1c, 1, 2581}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1C */
+ {0x2fa1d, 1, 5664}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1D */
+};
+
+const size_t _wind_normalize_table_size = 5224;
+
+const uint32_t _wind_normalize_val_table[] = {
+ 0x20,
+ 0x20,
+ 0x308,
+ 0x61,
+ 0x20,
+ 0x304,
+ 0x32,
+ 0x33,
+ 0x20,
+ 0x301,
+ 0x3bc,
+ 0x20,
+ 0x327,
+ 0x31,
+ 0x6f,
+ 0x31,
+ 0x2044,
+ 0x34,
+ 0x31,
+ 0x2044,
+ 0x32,
+ 0x33,
+ 0x2044,
+ 0x34,
+ 0x41,
+ 0x300,
+ 0x41,
+ 0x301,
+ 0x41,
+ 0x302,
+ 0x41,
+ 0x303,
+ 0x41,
+ 0x308,
+ 0x41,
+ 0x30a,
+ 0x43,
+ 0x327,
+ 0x45,
+ 0x300,
+ 0x45,
+ 0x301,
+ 0x45,
+ 0x302,
+ 0x45,
+ 0x308,
+ 0x49,
+ 0x300,
+ 0x49,
+ 0x301,
+ 0x49,
+ 0x302,
+ 0x49,
+ 0x308,
+ 0x4e,
+ 0x303,
+ 0x4f,
+ 0x300,
+ 0x4f,
+ 0x301,
+ 0x4f,
+ 0x302,
+ 0x4f,
+ 0x303,
+ 0x4f,
+ 0x308,
+ 0x55,
+ 0x300,
+ 0x55,
+ 0x301,
+ 0x55,
+ 0x302,
+ 0x55,
+ 0x308,
+ 0x59,
+ 0x301,
+ 0x61,
+ 0x300,
+ 0x61,
+ 0x301,
+ 0x61,
+ 0x302,
+ 0x61,
+ 0x303,
+ 0x61,
+ 0x308,
+ 0x61,
+ 0x30a,
+ 0x63,
+ 0x327,
+ 0x65,
+ 0x300,
+ 0x65,
+ 0x301,
+ 0x65,
+ 0x302,
+ 0x65,
+ 0x308,
+ 0x69,
+ 0x300,
+ 0x69,
+ 0x301,
+ 0x69,
+ 0x302,
+ 0x69,
+ 0x308,
+ 0x6e,
+ 0x303,
+ 0x6f,
+ 0x300,
+ 0x6f,
+ 0x301,
+ 0x6f,
+ 0x302,
+ 0x6f,
+ 0x303,
+ 0x6f,
+ 0x308,
+ 0x75,
+ 0x300,
+ 0x75,
+ 0x301,
+ 0x75,
+ 0x302,
+ 0x75,
+ 0x308,
+ 0x79,
+ 0x301,
+ 0x79,
+ 0x308,
+ 0x41,
+ 0x304,
+ 0x61,
+ 0x304,
+ 0x41,
+ 0x306,
+ 0x61,
+ 0x306,
+ 0x41,
+ 0x328,
+ 0x61,
+ 0x328,
+ 0x43,
+ 0x301,
+ 0x63,
+ 0x301,
+ 0x43,
+ 0x302,
+ 0x63,
+ 0x302,
+ 0x43,
+ 0x307,
+ 0x63,
+ 0x307,
+ 0x43,
+ 0x30c,
+ 0x63,
+ 0x30c,
+ 0x44,
+ 0x30c,
+ 0x64,
+ 0x30c,
+ 0x45,
+ 0x304,
+ 0x65,
+ 0x304,
+ 0x45,
+ 0x306,
+ 0x65,
+ 0x306,
+ 0x45,
+ 0x307,
+ 0x65,
+ 0x307,
+ 0x45,
+ 0x328,
+ 0x65,
+ 0x328,
+ 0x45,
+ 0x30c,
+ 0x65,
+ 0x30c,
+ 0x47,
+ 0x302,
+ 0x67,
+ 0x302,
+ 0x47,
+ 0x306,
+ 0x67,
+ 0x306,
+ 0x47,
+ 0x307,
+ 0x67,
+ 0x307,
+ 0x47,
+ 0x327,
+ 0x67,
+ 0x327,
+ 0x48,
+ 0x302,
+ 0x68,
+ 0x302,
+ 0x49,
+ 0x303,
+ 0x69,
+ 0x303,
+ 0x49,
+ 0x304,
+ 0x69,
+ 0x304,
+ 0x49,
+ 0x306,
+ 0x69,
+ 0x306,
+ 0x49,
+ 0x328,
+ 0x69,
+ 0x328,
+ 0x49,
+ 0x307,
+ 0x49,
+ 0x4a,
+ 0x69,
+ 0x6a,
+ 0x4a,
+ 0x302,
+ 0x6a,
+ 0x302,
+ 0x4b,
+ 0x327,
+ 0x6b,
+ 0x327,
+ 0x4c,
+ 0x301,
+ 0x6c,
+ 0x301,
+ 0x4c,
+ 0x327,
+ 0x6c,
+ 0x327,
+ 0x4c,
+ 0x30c,
+ 0x6c,
+ 0x30c,
+ 0x4c,
+ 0xb7,
+ 0x6c,
+ 0xb7,
+ 0x4e,
+ 0x301,
+ 0x6e,
+ 0x301,
+ 0x4e,
+ 0x327,
+ 0x6e,
+ 0x327,
+ 0x4e,
+ 0x30c,
+ 0x6e,
+ 0x30c,
+ 0x2bc,
+ 0x6e,
+ 0x4f,
+ 0x304,
+ 0x6f,
+ 0x304,
+ 0x4f,
+ 0x306,
+ 0x6f,
+ 0x306,
+ 0x4f,
+ 0x30b,
+ 0x6f,
+ 0x30b,
+ 0x52,
+ 0x301,
+ 0x72,
+ 0x301,
+ 0x52,
+ 0x327,
+ 0x72,
+ 0x327,
+ 0x52,
+ 0x30c,
+ 0x72,
+ 0x30c,
+ 0x53,
+ 0x301,
+ 0x73,
+ 0x301,
+ 0x53,
+ 0x302,
+ 0x73,
+ 0x302,
+ 0x53,
+ 0x327,
+ 0x73,
+ 0x327,
+ 0x53,
+ 0x30c,
+ 0x73,
+ 0x30c,
+ 0x54,
+ 0x327,
+ 0x74,
+ 0x327,
+ 0x54,
+ 0x30c,
+ 0x74,
+ 0x30c,
+ 0x55,
+ 0x303,
+ 0x75,
+ 0x303,
+ 0x55,
+ 0x304,
+ 0x75,
+ 0x304,
+ 0x55,
+ 0x306,
+ 0x75,
+ 0x306,
+ 0x55,
+ 0x30a,
+ 0x75,
+ 0x30a,
+ 0x55,
+ 0x30b,
+ 0x75,
+ 0x30b,
+ 0x55,
+ 0x328,
+ 0x75,
+ 0x328,
+ 0x57,
+ 0x302,
+ 0x77,
+ 0x302,
+ 0x59,
+ 0x302,
+ 0x79,
+ 0x302,
+ 0x59,
+ 0x308,
+ 0x5a,
+ 0x301,
+ 0x7a,
+ 0x301,
+ 0x5a,
+ 0x307,
+ 0x7a,
+ 0x307,
+ 0x5a,
+ 0x30c,
+ 0x7a,
+ 0x30c,
+ 0x4f,
+ 0x31b,
+ 0x6f,
+ 0x31b,
+ 0x55,
+ 0x31b,
+ 0x75,
+ 0x31b,
+ 0x44,
+ 0x17d,
+ 0x44,
+ 0x17e,
+ 0x64,
+ 0x17e,
+ 0x4c,
+ 0x4a,
+ 0x4c,
+ 0x6a,
+ 0x6c,
+ 0x6a,
+ 0x4e,
+ 0x4a,
+ 0x4e,
+ 0x6a,
+ 0x6e,
+ 0x6a,
+ 0x41,
+ 0x30c,
+ 0x61,
+ 0x30c,
+ 0x49,
+ 0x30c,
+ 0x69,
+ 0x30c,
+ 0x4f,
+ 0x30c,
+ 0x6f,
+ 0x30c,
+ 0x55,
+ 0x30c,
+ 0x75,
+ 0x30c,
+ 0xdc,
+ 0x304,
+ 0xfc,
+ 0x304,
+ 0xdc,
+ 0x301,
+ 0xfc,
+ 0x301,
+ 0xdc,
+ 0x30c,
+ 0xfc,
+ 0x30c,
+ 0xdc,
+ 0x300,
+ 0xfc,
+ 0x300,
+ 0xc4,
+ 0x304,
+ 0xe4,
+ 0x304,
+ 0x226,
+ 0x304,
+ 0x227,
+ 0x304,
+ 0xc6,
+ 0x304,
+ 0xe6,
+ 0x304,
+ 0x47,
+ 0x30c,
+ 0x67,
+ 0x30c,
+ 0x4b,
+ 0x30c,
+ 0x6b,
+ 0x30c,
+ 0x4f,
+ 0x328,
+ 0x6f,
+ 0x328,
+ 0x1ea,
+ 0x304,
+ 0x1eb,
+ 0x304,
+ 0x1b7,
+ 0x30c,
+ 0x292,
+ 0x30c,
+ 0x6a,
+ 0x30c,
+ 0x44,
+ 0x5a,
+ 0x44,
+ 0x7a,
+ 0x64,
+ 0x7a,
+ 0x47,
+ 0x301,
+ 0x67,
+ 0x301,
+ 0x4e,
+ 0x300,
+ 0x6e,
+ 0x300,
+ 0xc5,
+ 0x301,
+ 0xe5,
+ 0x301,
+ 0xc6,
+ 0x301,
+ 0xe6,
+ 0x301,
+ 0xd8,
+ 0x301,
+ 0xf8,
+ 0x301,
+ 0x41,
+ 0x30f,
+ 0x61,
+ 0x30f,
+ 0x41,
+ 0x311,
+ 0x61,
+ 0x311,
+ 0x45,
+ 0x30f,
+ 0x65,
+ 0x30f,
+ 0x45,
+ 0x311,
+ 0x65,
+ 0x311,
+ 0x49,
+ 0x30f,
+ 0x69,
+ 0x30f,
+ 0x49,
+ 0x311,
+ 0x69,
+ 0x311,
+ 0x4f,
+ 0x30f,
+ 0x6f,
+ 0x30f,
+ 0x4f,
+ 0x311,
+ 0x6f,
+ 0x311,
+ 0x52,
+ 0x30f,
+ 0x72,
+ 0x30f,
+ 0x52,
+ 0x311,
+ 0x72,
+ 0x311,
+ 0x55,
+ 0x30f,
+ 0x75,
+ 0x30f,
+ 0x55,
+ 0x311,
+ 0x75,
+ 0x311,
+ 0x53,
+ 0x326,
+ 0x73,
+ 0x326,
+ 0x54,
+ 0x326,
+ 0x74,
+ 0x326,
+ 0x48,
+ 0x30c,
+ 0x68,
+ 0x30c,
+ 0x41,
+ 0x307,
+ 0x61,
+ 0x307,
+ 0x45,
+ 0x327,
+ 0x65,
+ 0x327,
+ 0xd6,
+ 0x304,
+ 0xf6,
+ 0x304,
+ 0xd5,
+ 0x304,
+ 0xf5,
+ 0x304,
+ 0x4f,
+ 0x307,
+ 0x6f,
+ 0x307,
+ 0x22e,
+ 0x304,
+ 0x22f,
+ 0x304,
+ 0x59,
+ 0x304,
+ 0x79,
+ 0x304,
+ 0x266,
+ 0x279,
+ 0x27b,
+ 0x281,
+ 0x20,
+ 0x306,
+ 0x20,
+ 0x307,
+ 0x20,
+ 0x30a,
+ 0x20,
+ 0x328,
+ 0x20,
+ 0x303,
+ 0x20,
+ 0x30b,
+ 0x263,
+ 0x78,
+ 0x295,
+ 0x313,
+ 0x308,
+ 0x301,
+ 0x2b9,
+ 0x20,
+ 0x345,
+ 0x3b,
+ 0xa8,
+ 0x301,
+ 0x391,
+ 0x301,
+ 0x395,
+ 0x301,
+ 0x397,
+ 0x301,
+ 0x399,
+ 0x301,
+ 0x39f,
+ 0x301,
+ 0x3a5,
+ 0x301,
+ 0x3a9,
+ 0x301,
+ 0x3ca,
+ 0x301,
+ 0x399,
+ 0x308,
+ 0x3a5,
+ 0x308,
+ 0x3b1,
+ 0x301,
+ 0x3b5,
+ 0x301,
+ 0x3b7,
+ 0x301,
+ 0x3b9,
+ 0x301,
+ 0x3cb,
+ 0x301,
+ 0x3b9,
+ 0x308,
+ 0x3c5,
+ 0x308,
+ 0x3bf,
+ 0x301,
+ 0x3c5,
+ 0x301,
+ 0x3c9,
+ 0x301,
+ 0x3b2,
+ 0x3b8,
+ 0x3d2,
+ 0x301,
+ 0x3d2,
+ 0x308,
+ 0x3c6,
+ 0x3c0,
+ 0x3ba,
+ 0x3c1,
+ 0x3c2,
+ 0x398,
+ 0x3a3,
+ 0x415,
+ 0x300,
+ 0x415,
+ 0x308,
+ 0x413,
+ 0x301,
+ 0x406,
+ 0x308,
+ 0x41a,
+ 0x301,
+ 0x418,
+ 0x300,
+ 0x423,
+ 0x306,
+ 0x418,
+ 0x306,
+ 0x438,
+ 0x306,
+ 0x435,
+ 0x300,
+ 0x435,
+ 0x308,
+ 0x433,
+ 0x301,
+ 0x456,
+ 0x308,
+ 0x43a,
+ 0x301,
+ 0x438,
+ 0x300,
+ 0x443,
+ 0x306,
+ 0x474,
+ 0x30f,
+ 0x475,
+ 0x30f,
+ 0x416,
+ 0x306,
+ 0x436,
+ 0x306,
+ 0x410,
+ 0x306,
+ 0x430,
+ 0x306,
+ 0x410,
+ 0x308,
+ 0x430,
+ 0x308,
+ 0x415,
+ 0x306,
+ 0x435,
+ 0x306,
+ 0x4d8,
+ 0x308,
+ 0x4d9,
+ 0x308,
+ 0x416,
+ 0x308,
+ 0x436,
+ 0x308,
+ 0x417,
+ 0x308,
+ 0x437,
+ 0x308,
+ 0x418,
+ 0x304,
+ 0x438,
+ 0x304,
+ 0x418,
+ 0x308,
+ 0x438,
+ 0x308,
+ 0x41e,
+ 0x308,
+ 0x43e,
+ 0x308,
+ 0x4e8,
+ 0x308,
+ 0x4e9,
+ 0x308,
+ 0x42d,
+ 0x308,
+ 0x44d,
+ 0x308,
+ 0x423,
+ 0x304,
+ 0x443,
+ 0x304,
+ 0x423,
+ 0x308,
+ 0x443,
+ 0x308,
+ 0x423,
+ 0x30b,
+ 0x443,
+ 0x30b,
+ 0x427,
+ 0x308,
+ 0x447,
+ 0x308,
+ 0x42b,
+ 0x308,
+ 0x44b,
+ 0x308,
+ 0x565,
+ 0x582,
+ 0x627,
+ 0x653,
+ 0x627,
+ 0x654,
+ 0x648,
+ 0x654,
+ 0x627,
+ 0x655,
+ 0x64a,
+ 0x654,
+ 0x627,
+ 0x674,
+ 0x648,
+ 0x674,
+ 0x6c7,
+ 0x674,
+ 0x64a,
+ 0x674,
+ 0x6d5,
+ 0x654,
+ 0x6c1,
+ 0x654,
+ 0x6d2,
+ 0x654,
+ 0x928,
+ 0x93c,
+ 0x930,
+ 0x93c,
+ 0x933,
+ 0x93c,
+ 0x915,
+ 0x93c,
+ 0x916,
+ 0x93c,
+ 0x917,
+ 0x93c,
+ 0x91c,
+ 0x93c,
+ 0x921,
+ 0x93c,
+ 0x922,
+ 0x93c,
+ 0x92b,
+ 0x93c,
+ 0x92f,
+ 0x93c,
+ 0x9c7,
+ 0x9be,
+ 0x9c7,
+ 0x9d7,
+ 0x9a1,
+ 0x9bc,
+ 0x9a2,
+ 0x9bc,
+ 0x9af,
+ 0x9bc,
+ 0xa32,
+ 0xa3c,
+ 0xa38,
+ 0xa3c,
+ 0xa16,
+ 0xa3c,
+ 0xa17,
+ 0xa3c,
+ 0xa1c,
+ 0xa3c,
+ 0xa2b,
+ 0xa3c,
+ 0xb47,
+ 0xb56,
+ 0xb47,
+ 0xb3e,
+ 0xb47,
+ 0xb57,
+ 0xb21,
+ 0xb3c,
+ 0xb22,
+ 0xb3c,
+ 0xb92,
+ 0xbd7,
+ 0xbc6,
+ 0xbbe,
+ 0xbc7,
+ 0xbbe,
+ 0xbc6,
+ 0xbd7,
+ 0xc46,
+ 0xc56,
+ 0xcbf,
+ 0xcd5,
+ 0xcc6,
+ 0xcd5,
+ 0xcc6,
+ 0xcd6,
+ 0xcc6,
+ 0xcc2,
+ 0xcca,
+ 0xcd5,
+ 0xd46,
+ 0xd3e,
+ 0xd47,
+ 0xd3e,
+ 0xd46,
+ 0xd57,
+ 0xdd9,
+ 0xdca,
+ 0xdd9,
+ 0xdcf,
+ 0xddc,
+ 0xdca,
+ 0xdd9,
+ 0xddf,
+ 0xe4d,
+ 0xe32,
+ 0xecd,
+ 0xeb2,
+ 0xeab,
+ 0xe99,
+ 0xeab,
+ 0xea1,
+ 0xf0b,
+ 0xf42,
+ 0xfb7,
+ 0xf4c,
+ 0xfb7,
+ 0xf51,
+ 0xfb7,
+ 0xf56,
+ 0xfb7,
+ 0xf5b,
+ 0xfb7,
+ 0xf40,
+ 0xfb5,
+ 0xf71,
+ 0xf72,
+ 0xf71,
+ 0xf74,
+ 0xfb2,
+ 0xf80,
+ 0xfb2,
+ 0xf81,
+ 0xfb3,
+ 0xf80,
+ 0xfb3,
+ 0xf81,
+ 0xf71,
+ 0xf80,
+ 0xf92,
+ 0xfb7,
+ 0xf9c,
+ 0xfb7,
+ 0xfa1,
+ 0xfb7,
+ 0xfa6,
+ 0xfb7,
+ 0xfab,
+ 0xfb7,
+ 0xf90,
+ 0xfb5,
+ 0x1025,
+ 0x102e,
+ 0x42,
+ 0x18e,
+ 0x4d,
+ 0x222,
+ 0x50,
+ 0x250,
+ 0x251,
+ 0x1d02,
+ 0x62,
+ 0x259,
+ 0x25b,
+ 0x25c,
+ 0x6d,
+ 0x14b,
+ 0x254,
+ 0x1d16,
+ 0x1d17,
+ 0x70,
+ 0x1d1d,
+ 0x26f,
+ 0x76,
+ 0x1d25,
+ 0x3b3,
+ 0x3b4,
+ 0x3c7,
+ 0x41,
+ 0x325,
+ 0x61,
+ 0x325,
+ 0x42,
+ 0x307,
+ 0x62,
+ 0x307,
+ 0x42,
+ 0x323,
+ 0x62,
+ 0x323,
+ 0x42,
+ 0x331,
+ 0x62,
+ 0x331,
+ 0xc7,
+ 0x301,
+ 0xe7,
+ 0x301,
+ 0x44,
+ 0x307,
+ 0x64,
+ 0x307,
+ 0x44,
+ 0x323,
+ 0x64,
+ 0x323,
+ 0x44,
+ 0x331,
+ 0x64,
+ 0x331,
+ 0x44,
+ 0x327,
+ 0x64,
+ 0x327,
+ 0x44,
+ 0x32d,
+ 0x64,
+ 0x32d,
+ 0x112,
+ 0x300,
+ 0x113,
+ 0x300,
+ 0x112,
+ 0x301,
+ 0x113,
+ 0x301,
+ 0x45,
+ 0x32d,
+ 0x65,
+ 0x32d,
+ 0x45,
+ 0x330,
+ 0x65,
+ 0x330,
+ 0x228,
+ 0x306,
+ 0x229,
+ 0x306,
+ 0x46,
+ 0x307,
+ 0x66,
+ 0x307,
+ 0x47,
+ 0x304,
+ 0x67,
+ 0x304,
+ 0x48,
+ 0x307,
+ 0x68,
+ 0x307,
+ 0x48,
+ 0x323,
+ 0x68,
+ 0x323,
+ 0x48,
+ 0x308,
+ 0x68,
+ 0x308,
+ 0x48,
+ 0x327,
+ 0x68,
+ 0x327,
+ 0x48,
+ 0x32e,
+ 0x68,
+ 0x32e,
+ 0x49,
+ 0x330,
+ 0x69,
+ 0x330,
+ 0xcf,
+ 0x301,
+ 0xef,
+ 0x301,
+ 0x4b,
+ 0x301,
+ 0x6b,
+ 0x301,
+ 0x4b,
+ 0x323,
+ 0x6b,
+ 0x323,
+ 0x4b,
+ 0x331,
+ 0x6b,
+ 0x331,
+ 0x4c,
+ 0x323,
+ 0x6c,
+ 0x323,
+ 0x1e36,
+ 0x304,
+ 0x1e37,
+ 0x304,
+ 0x4c,
+ 0x331,
+ 0x6c,
+ 0x331,
+ 0x4c,
+ 0x32d,
+ 0x6c,
+ 0x32d,
+ 0x4d,
+ 0x301,
+ 0x6d,
+ 0x301,
+ 0x4d,
+ 0x307,
+ 0x6d,
+ 0x307,
+ 0x4d,
+ 0x323,
+ 0x6d,
+ 0x323,
+ 0x4e,
+ 0x307,
+ 0x6e,
+ 0x307,
+ 0x4e,
+ 0x323,
+ 0x6e,
+ 0x323,
+ 0x4e,
+ 0x331,
+ 0x6e,
+ 0x331,
+ 0x4e,
+ 0x32d,
+ 0x6e,
+ 0x32d,
+ 0xd5,
+ 0x301,
+ 0xf5,
+ 0x301,
+ 0xd5,
+ 0x308,
+ 0xf5,
+ 0x308,
+ 0x14c,
+ 0x300,
+ 0x14d,
+ 0x300,
+ 0x14c,
+ 0x301,
+ 0x14d,
+ 0x301,
+ 0x50,
+ 0x301,
+ 0x70,
+ 0x301,
+ 0x50,
+ 0x307,
+ 0x70,
+ 0x307,
+ 0x52,
+ 0x307,
+ 0x72,
+ 0x307,
+ 0x52,
+ 0x323,
+ 0x72,
+ 0x323,
+ 0x1e5a,
+ 0x304,
+ 0x1e5b,
+ 0x304,
+ 0x52,
+ 0x331,
+ 0x72,
+ 0x331,
+ 0x53,
+ 0x307,
+ 0x73,
+ 0x307,
+ 0x53,
+ 0x323,
+ 0x73,
+ 0x323,
+ 0x15a,
+ 0x307,
+ 0x15b,
+ 0x307,
+ 0x160,
+ 0x307,
+ 0x161,
+ 0x307,
+ 0x1e62,
+ 0x307,
+ 0x1e63,
+ 0x307,
+ 0x54,
+ 0x307,
+ 0x74,
+ 0x307,
+ 0x54,
+ 0x323,
+ 0x74,
+ 0x323,
+ 0x54,
+ 0x331,
+ 0x74,
+ 0x331,
+ 0x54,
+ 0x32d,
+ 0x74,
+ 0x32d,
+ 0x55,
+ 0x324,
+ 0x75,
+ 0x324,
+ 0x55,
+ 0x330,
+ 0x75,
+ 0x330,
+ 0x55,
+ 0x32d,
+ 0x75,
+ 0x32d,
+ 0x168,
+ 0x301,
+ 0x169,
+ 0x301,
+ 0x16a,
+ 0x308,
+ 0x16b,
+ 0x308,
+ 0x56,
+ 0x303,
+ 0x76,
+ 0x303,
+ 0x56,
+ 0x323,
+ 0x76,
+ 0x323,
+ 0x57,
+ 0x300,
+ 0x77,
+ 0x300,
+ 0x57,
+ 0x301,
+ 0x77,
+ 0x301,
+ 0x57,
+ 0x308,
+ 0x77,
+ 0x308,
+ 0x57,
+ 0x307,
+ 0x77,
+ 0x307,
+ 0x57,
+ 0x323,
+ 0x77,
+ 0x323,
+ 0x58,
+ 0x307,
+ 0x78,
+ 0x307,
+ 0x58,
+ 0x308,
+ 0x78,
+ 0x308,
+ 0x59,
+ 0x307,
+ 0x79,
+ 0x307,
+ 0x5a,
+ 0x302,
+ 0x7a,
+ 0x302,
+ 0x5a,
+ 0x323,
+ 0x7a,
+ 0x323,
+ 0x5a,
+ 0x331,
+ 0x7a,
+ 0x331,
+ 0x68,
+ 0x331,
+ 0x74,
+ 0x308,
+ 0x77,
+ 0x30a,
+ 0x79,
+ 0x30a,
+ 0x61,
+ 0x2be,
+ 0x17f,
+ 0x307,
+ 0x41,
+ 0x323,
+ 0x61,
+ 0x323,
+ 0x41,
+ 0x309,
+ 0x61,
+ 0x309,
+ 0xc2,
+ 0x301,
+ 0xe2,
+ 0x301,
+ 0xc2,
+ 0x300,
+ 0xe2,
+ 0x300,
+ 0xc2,
+ 0x309,
+ 0xe2,
+ 0x309,
+ 0xc2,
+ 0x303,
+ 0xe2,
+ 0x303,
+ 0x1ea0,
+ 0x302,
+ 0x1ea1,
+ 0x302,
+ 0x102,
+ 0x301,
+ 0x103,
+ 0x301,
+ 0x102,
+ 0x300,
+ 0x103,
+ 0x300,
+ 0x102,
+ 0x309,
+ 0x103,
+ 0x309,
+ 0x102,
+ 0x303,
+ 0x103,
+ 0x303,
+ 0x1ea0,
+ 0x306,
+ 0x1ea1,
+ 0x306,
+ 0x45,
+ 0x323,
+ 0x65,
+ 0x323,
+ 0x45,
+ 0x309,
+ 0x65,
+ 0x309,
+ 0x45,
+ 0x303,
+ 0x65,
+ 0x303,
+ 0xca,
+ 0x301,
+ 0xea,
+ 0x301,
+ 0xca,
+ 0x300,
+ 0xea,
+ 0x300,
+ 0xca,
+ 0x309,
+ 0xea,
+ 0x309,
+ 0xca,
+ 0x303,
+ 0xea,
+ 0x303,
+ 0x1eb8,
+ 0x302,
+ 0x1eb9,
+ 0x302,
+ 0x49,
+ 0x309,
+ 0x69,
+ 0x309,
+ 0x49,
+ 0x323,
+ 0x69,
+ 0x323,
+ 0x4f,
+ 0x323,
+ 0x6f,
+ 0x323,
+ 0x4f,
+ 0x309,
+ 0x6f,
+ 0x309,
+ 0xd4,
+ 0x301,
+ 0xf4,
+ 0x301,
+ 0xd4,
+ 0x300,
+ 0xf4,
+ 0x300,
+ 0xd4,
+ 0x309,
+ 0xf4,
+ 0x309,
+ 0xd4,
+ 0x303,
+ 0xf4,
+ 0x303,
+ 0x1ecc,
+ 0x302,
+ 0x1ecd,
+ 0x302,
+ 0x1a0,
+ 0x301,
+ 0x1a1,
+ 0x301,
+ 0x1a0,
+ 0x300,
+ 0x1a1,
+ 0x300,
+ 0x1a0,
+ 0x309,
+ 0x1a1,
+ 0x309,
+ 0x1a0,
+ 0x303,
+ 0x1a1,
+ 0x303,
+ 0x1a0,
+ 0x323,
+ 0x1a1,
+ 0x323,
+ 0x55,
+ 0x323,
+ 0x75,
+ 0x323,
+ 0x55,
+ 0x309,
+ 0x75,
+ 0x309,
+ 0x1af,
+ 0x301,
+ 0x1b0,
+ 0x301,
+ 0x1af,
+ 0x300,
+ 0x1b0,
+ 0x300,
+ 0x1af,
+ 0x309,
+ 0x1b0,
+ 0x309,
+ 0x1af,
+ 0x303,
+ 0x1b0,
+ 0x303,
+ 0x1af,
+ 0x323,
+ 0x1b0,
+ 0x323,
+ 0x59,
+ 0x300,
+ 0x79,
+ 0x300,
+ 0x59,
+ 0x323,
+ 0x79,
+ 0x323,
+ 0x59,
+ 0x309,
+ 0x79,
+ 0x309,
+ 0x59,
+ 0x303,
+ 0x79,
+ 0x303,
+ 0x3b1,
+ 0x313,
+ 0x3b1,
+ 0x314,
+ 0x1f00,
+ 0x300,
+ 0x1f01,
+ 0x300,
+ 0x1f00,
+ 0x301,
+ 0x1f01,
+ 0x301,
+ 0x1f00,
+ 0x342,
+ 0x1f01,
+ 0x342,
+ 0x391,
+ 0x313,
+ 0x391,
+ 0x314,
+ 0x1f08,
+ 0x300,
+ 0x1f09,
+ 0x300,
+ 0x1f08,
+ 0x301,
+ 0x1f09,
+ 0x301,
+ 0x1f08,
+ 0x342,
+ 0x1f09,
+ 0x342,
+ 0x3b5,
+ 0x313,
+ 0x3b5,
+ 0x314,
+ 0x1f10,
+ 0x300,
+ 0x1f11,
+ 0x300,
+ 0x1f10,
+ 0x301,
+ 0x1f11,
+ 0x301,
+ 0x395,
+ 0x313,
+ 0x395,
+ 0x314,
+ 0x1f18,
+ 0x300,
+ 0x1f19,
+ 0x300,
+ 0x1f18,
+ 0x301,
+ 0x1f19,
+ 0x301,
+ 0x3b7,
+ 0x313,
+ 0x3b7,
+ 0x314,
+ 0x1f20,
+ 0x300,
+ 0x1f21,
+ 0x300,
+ 0x1f20,
+ 0x301,
+ 0x1f21,
+ 0x301,
+ 0x1f20,
+ 0x342,
+ 0x1f21,
+ 0x342,
+ 0x397,
+ 0x313,
+ 0x397,
+ 0x314,
+ 0x1f28,
+ 0x300,
+ 0x1f29,
+ 0x300,
+ 0x1f28,
+ 0x301,
+ 0x1f29,
+ 0x301,
+ 0x1f28,
+ 0x342,
+ 0x1f29,
+ 0x342,
+ 0x3b9,
+ 0x313,
+ 0x3b9,
+ 0x314,
+ 0x1f30,
+ 0x300,
+ 0x1f31,
+ 0x300,
+ 0x1f30,
+ 0x301,
+ 0x1f31,
+ 0x301,
+ 0x1f30,
+ 0x342,
+ 0x1f31,
+ 0x342,
+ 0x399,
+ 0x313,
+ 0x399,
+ 0x314,
+ 0x1f38,
+ 0x300,
+ 0x1f39,
+ 0x300,
+ 0x1f38,
+ 0x301,
+ 0x1f39,
+ 0x301,
+ 0x1f38,
+ 0x342,
+ 0x1f39,
+ 0x342,
+ 0x3bf,
+ 0x313,
+ 0x3bf,
+ 0x314,
+ 0x1f40,
+ 0x300,
+ 0x1f41,
+ 0x300,
+ 0x1f40,
+ 0x301,
+ 0x1f41,
+ 0x301,
+ 0x39f,
+ 0x313,
+ 0x39f,
+ 0x314,
+ 0x1f48,
+ 0x300,
+ 0x1f49,
+ 0x300,
+ 0x1f48,
+ 0x301,
+ 0x1f49,
+ 0x301,
+ 0x3c5,
+ 0x313,
+ 0x3c5,
+ 0x314,
+ 0x1f50,
+ 0x300,
+ 0x1f51,
+ 0x300,
+ 0x1f50,
+ 0x301,
+ 0x1f51,
+ 0x301,
+ 0x1f50,
+ 0x342,
+ 0x1f51,
+ 0x342,
+ 0x3a5,
+ 0x314,
+ 0x1f59,
+ 0x300,
+ 0x1f59,
+ 0x301,
+ 0x1f59,
+ 0x342,
+ 0x3c9,
+ 0x313,
+ 0x3c9,
+ 0x314,
+ 0x1f60,
+ 0x300,
+ 0x1f61,
+ 0x300,
+ 0x1f60,
+ 0x301,
+ 0x1f61,
+ 0x301,
+ 0x1f60,
+ 0x342,
+ 0x1f61,
+ 0x342,
+ 0x3a9,
+ 0x313,
+ 0x3a9,
+ 0x314,
+ 0x1f68,
+ 0x300,
+ 0x1f69,
+ 0x300,
+ 0x1f68,
+ 0x301,
+ 0x1f69,
+ 0x301,
+ 0x1f68,
+ 0x342,
+ 0x1f69,
+ 0x342,
+ 0x3b1,
+ 0x300,
+ 0x3ac,
+ 0x3b5,
+ 0x300,
+ 0x3ad,
+ 0x3b7,
+ 0x300,
+ 0x3ae,
+ 0x3b9,
+ 0x300,
+ 0x3af,
+ 0x3bf,
+ 0x300,
+ 0x3cc,
+ 0x3c5,
+ 0x300,
+ 0x3cd,
+ 0x3c9,
+ 0x300,
+ 0x3ce,
+ 0x1f00,
+ 0x345,
+ 0x1f01,
+ 0x345,
+ 0x1f02,
+ 0x345,
+ 0x1f03,
+ 0x345,
+ 0x1f04,
+ 0x345,
+ 0x1f05,
+ 0x345,
+ 0x1f06,
+ 0x345,
+ 0x1f07,
+ 0x345,
+ 0x1f08,
+ 0x345,
+ 0x1f09,
+ 0x345,
+ 0x1f0a,
+ 0x345,
+ 0x1f0b,
+ 0x345,
+ 0x1f0c,
+ 0x345,
+ 0x1f0d,
+ 0x345,
+ 0x1f0e,
+ 0x345,
+ 0x1f0f,
+ 0x345,
+ 0x1f20,
+ 0x345,
+ 0x1f21,
+ 0x345,
+ 0x1f22,
+ 0x345,
+ 0x1f23,
+ 0x345,
+ 0x1f24,
+ 0x345,
+ 0x1f25,
+ 0x345,
+ 0x1f26,
+ 0x345,
+ 0x1f27,
+ 0x345,
+ 0x1f28,
+ 0x345,
+ 0x1f29,
+ 0x345,
+ 0x1f2a,
+ 0x345,
+ 0x1f2b,
+ 0x345,
+ 0x1f2c,
+ 0x345,
+ 0x1f2d,
+ 0x345,
+ 0x1f2e,
+ 0x345,
+ 0x1f2f,
+ 0x345,
+ 0x1f60,
+ 0x345,
+ 0x1f61,
+ 0x345,
+ 0x1f62,
+ 0x345,
+ 0x1f63,
+ 0x345,
+ 0x1f64,
+ 0x345,
+ 0x1f65,
+ 0x345,
+ 0x1f66,
+ 0x345,
+ 0x1f67,
+ 0x345,
+ 0x1f68,
+ 0x345,
+ 0x1f69,
+ 0x345,
+ 0x1f6a,
+ 0x345,
+ 0x1f6b,
+ 0x345,
+ 0x1f6c,
+ 0x345,
+ 0x1f6d,
+ 0x345,
+ 0x1f6e,
+ 0x345,
+ 0x1f6f,
+ 0x345,
+ 0x3b1,
+ 0x306,
+ 0x3b1,
+ 0x304,
+ 0x1f70,
+ 0x345,
+ 0x3b1,
+ 0x345,
+ 0x3ac,
+ 0x345,
+ 0x3b1,
+ 0x342,
+ 0x1fb6,
+ 0x345,
+ 0x391,
+ 0x306,
+ 0x391,
+ 0x304,
+ 0x391,
+ 0x300,
+ 0x386,
+ 0x391,
+ 0x345,
+ 0x20,
+ 0x313,
+ 0x20,
+ 0x342,
+ 0xa8,
+ 0x342,
+ 0x1f74,
+ 0x345,
+ 0x3b7,
+ 0x345,
+ 0x3ae,
+ 0x345,
+ 0x3b7,
+ 0x342,
+ 0x1fc6,
+ 0x345,
+ 0x395,
+ 0x300,
+ 0x388,
+ 0x397,
+ 0x300,
+ 0x389,
+ 0x397,
+ 0x345,
+ 0x1fbf,
+ 0x300,
+ 0x1fbf,
+ 0x301,
+ 0x1fbf,
+ 0x342,
+ 0x3b9,
+ 0x306,
+ 0x3b9,
+ 0x304,
+ 0x3ca,
+ 0x300,
+ 0x390,
+ 0x3b9,
+ 0x342,
+ 0x3ca,
+ 0x342,
+ 0x399,
+ 0x306,
+ 0x399,
+ 0x304,
+ 0x399,
+ 0x300,
+ 0x38a,
+ 0x1ffe,
+ 0x300,
+ 0x1ffe,
+ 0x301,
+ 0x1ffe,
+ 0x342,
+ 0x3c5,
+ 0x306,
+ 0x3c5,
+ 0x304,
+ 0x3cb,
+ 0x300,
+ 0x3b0,
+ 0x3c1,
+ 0x313,
+ 0x3c1,
+ 0x314,
+ 0x3c5,
+ 0x342,
+ 0x3cb,
+ 0x342,
+ 0x3a5,
+ 0x306,
+ 0x3a5,
+ 0x304,
+ 0x3a5,
+ 0x300,
+ 0x38e,
+ 0x3a1,
+ 0x314,
+ 0xa8,
+ 0x300,
+ 0x385,
+ 0x60,
+ 0x1f7c,
+ 0x345,
+ 0x3c9,
+ 0x345,
+ 0x3ce,
+ 0x345,
+ 0x3c9,
+ 0x342,
+ 0x1ff6,
+ 0x345,
+ 0x39f,
+ 0x300,
+ 0x38c,
+ 0x3a9,
+ 0x300,
+ 0x38f,
+ 0x3a9,
+ 0x345,
+ 0xb4,
+ 0x20,
+ 0x314,
+ 0x2002,
+ 0x2003,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x2010,
+ 0x20,
+ 0x333,
+ 0x2e,
+ 0x2e,
+ 0x2e,
+ 0x20,
+ 0x2032,
+ 0x2032,
+ 0x2032,
+ 0x2032,
+ 0x2032,
+ 0x2035,
+ 0x2035,
+ 0x2035,
+ 0x2035,
+ 0x2035,
+ 0x21,
+ 0x21,
+ 0x20,
+ 0x305,
+ 0x3f,
+ 0x3f,
+ 0x3f,
+ 0x21,
+ 0x21,
+ 0x3f,
+ 0x20,
+ 0x30,
+ 0x35,
+ 0x36,
+ 0x37,
+ 0x38,
+ 0x39,
+ 0x2b,
+ 0x2212,
+ 0x3d,
+ 0x28,
+ 0x29,
+ 0x52,
+ 0x73,
+ 0x61,
+ 0x2f,
+ 0x63,
+ 0x61,
+ 0x2f,
+ 0x73,
+ 0xb0,
+ 0x43,
+ 0x63,
+ 0x2f,
+ 0x6f,
+ 0x63,
+ 0x2f,
+ 0x75,
+ 0x190,
+ 0xb0,
+ 0x46,
+ 0x127,
+ 0x4e,
+ 0x6f,
+ 0x51,
+ 0x53,
+ 0x4d,
+ 0x54,
+ 0x45,
+ 0x4c,
+ 0x54,
+ 0x4d,
+ 0x5d0,
+ 0x5d1,
+ 0x5d2,
+ 0x5d3,
+ 0x46,
+ 0x41,
+ 0x58,
+ 0x393,
+ 0x3a0,
+ 0x2211,
+ 0x31,
+ 0x2044,
+ 0x33,
+ 0x32,
+ 0x2044,
+ 0x33,
+ 0x31,
+ 0x2044,
+ 0x35,
+ 0x32,
+ 0x2044,
+ 0x35,
+ 0x33,
+ 0x2044,
+ 0x35,
+ 0x34,
+ 0x2044,
+ 0x35,
+ 0x31,
+ 0x2044,
+ 0x36,
+ 0x35,
+ 0x2044,
+ 0x36,
+ 0x31,
+ 0x2044,
+ 0x38,
+ 0x33,
+ 0x2044,
+ 0x38,
+ 0x35,
+ 0x2044,
+ 0x38,
+ 0x37,
+ 0x2044,
+ 0x38,
+ 0x49,
+ 0x49,
+ 0x49,
+ 0x49,
+ 0x49,
+ 0x49,
+ 0x56,
+ 0x56,
+ 0x49,
+ 0x56,
+ 0x49,
+ 0x49,
+ 0x56,
+ 0x49,
+ 0x49,
+ 0x49,
+ 0x49,
+ 0x58,
+ 0x58,
+ 0x49,
+ 0x58,
+ 0x49,
+ 0x49,
+ 0x69,
+ 0x69,
+ 0x69,
+ 0x69,
+ 0x69,
+ 0x69,
+ 0x76,
+ 0x76,
+ 0x69,
+ 0x76,
+ 0x69,
+ 0x69,
+ 0x76,
+ 0x69,
+ 0x69,
+ 0x69,
+ 0x69,
+ 0x78,
+ 0x78,
+ 0x69,
+ 0x78,
+ 0x69,
+ 0x69,
+ 0x2190,
+ 0x338,
+ 0x2192,
+ 0x338,
+ 0x2194,
+ 0x338,
+ 0x21d0,
+ 0x338,
+ 0x21d4,
+ 0x338,
+ 0x21d2,
+ 0x338,
+ 0x2203,
+ 0x338,
+ 0x2208,
+ 0x338,
+ 0x220b,
+ 0x338,
+ 0x2223,
+ 0x338,
+ 0x2225,
+ 0x338,
+ 0x222b,
+ 0x222b,
+ 0x222b,
+ 0x222b,
+ 0x222b,
+ 0x222e,
+ 0x222e,
+ 0x222e,
+ 0x222e,
+ 0x222e,
+ 0x223c,
+ 0x338,
+ 0x2243,
+ 0x338,
+ 0x2245,
+ 0x338,
+ 0x2248,
+ 0x338,
+ 0x3d,
+ 0x338,
+ 0x2261,
+ 0x338,
+ 0x224d,
+ 0x338,
+ 0x3c,
+ 0x338,
+ 0x3e,
+ 0x338,
+ 0x2264,
+ 0x338,
+ 0x2265,
+ 0x338,
+ 0x2272,
+ 0x338,
+ 0x2273,
+ 0x338,
+ 0x2276,
+ 0x338,
+ 0x2277,
+ 0x338,
+ 0x227a,
+ 0x338,
+ 0x227b,
+ 0x338,
+ 0x2282,
+ 0x338,
+ 0x2283,
+ 0x338,
+ 0x2286,
+ 0x338,
+ 0x2287,
+ 0x338,
+ 0x22a2,
+ 0x338,
+ 0x22a8,
+ 0x338,
+ 0x22a9,
+ 0x338,
+ 0x22ab,
+ 0x338,
+ 0x227c,
+ 0x338,
+ 0x227d,
+ 0x338,
+ 0x2291,
+ 0x338,
+ 0x2292,
+ 0x338,
+ 0x22b2,
+ 0x338,
+ 0x22b3,
+ 0x338,
+ 0x22b4,
+ 0x338,
+ 0x22b5,
+ 0x338,
+ 0x3008,
+ 0x3009,
+ 0x31,
+ 0x30,
+ 0x31,
+ 0x31,
+ 0x31,
+ 0x32,
+ 0x31,
+ 0x33,
+ 0x31,
+ 0x34,
+ 0x31,
+ 0x35,
+ 0x31,
+ 0x36,
+ 0x31,
+ 0x37,
+ 0x31,
+ 0x38,
+ 0x31,
+ 0x39,
+ 0x32,
+ 0x30,
+ 0x28,
+ 0x31,
+ 0x29,
+ 0x28,
+ 0x32,
+ 0x29,
+ 0x28,
+ 0x33,
+ 0x29,
+ 0x28,
+ 0x34,
+ 0x29,
+ 0x28,
+ 0x35,
+ 0x29,
+ 0x28,
+ 0x36,
+ 0x29,
+ 0x28,
+ 0x37,
+ 0x29,
+ 0x28,
+ 0x38,
+ 0x29,
+ 0x28,
+ 0x39,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x30,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x31,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x32,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x33,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x34,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x35,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x36,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x37,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x38,
+ 0x29,
+ 0x28,
+ 0x31,
+ 0x39,
+ 0x29,
+ 0x28,
+ 0x32,
+ 0x30,
+ 0x29,
+ 0x31,
+ 0x2e,
+ 0x32,
+ 0x2e,
+ 0x33,
+ 0x2e,
+ 0x34,
+ 0x2e,
+ 0x35,
+ 0x2e,
+ 0x36,
+ 0x2e,
+ 0x37,
+ 0x2e,
+ 0x38,
+ 0x2e,
+ 0x39,
+ 0x2e,
+ 0x31,
+ 0x30,
+ 0x2e,
+ 0x31,
+ 0x31,
+ 0x2e,
+ 0x31,
+ 0x32,
+ 0x2e,
+ 0x31,
+ 0x33,
+ 0x2e,
+ 0x31,
+ 0x34,
+ 0x2e,
+ 0x31,
+ 0x35,
+ 0x2e,
+ 0x31,
+ 0x36,
+ 0x2e,
+ 0x31,
+ 0x37,
+ 0x2e,
+ 0x31,
+ 0x38,
+ 0x2e,
+ 0x31,
+ 0x39,
+ 0x2e,
+ 0x32,
+ 0x30,
+ 0x2e,
+ 0x28,
+ 0x61,
+ 0x29,
+ 0x28,
+ 0x62,
+ 0x29,
+ 0x28,
+ 0x63,
+ 0x29,
+ 0x28,
+ 0x64,
+ 0x29,
+ 0x28,
+ 0x65,
+ 0x29,
+ 0x28,
+ 0x66,
+ 0x29,
+ 0x28,
+ 0x67,
+ 0x29,
+ 0x28,
+ 0x68,
+ 0x29,
+ 0x28,
+ 0x69,
+ 0x29,
+ 0x28,
+ 0x6a,
+ 0x29,
+ 0x28,
+ 0x6b,
+ 0x29,
+ 0x28,
+ 0x6c,
+ 0x29,
+ 0x28,
+ 0x6d,
+ 0x29,
+ 0x28,
+ 0x6e,
+ 0x29,
+ 0x28,
+ 0x6f,
+ 0x29,
+ 0x28,
+ 0x70,
+ 0x29,
+ 0x28,
+ 0x71,
+ 0x29,
+ 0x28,
+ 0x72,
+ 0x29,
+ 0x28,
+ 0x73,
+ 0x29,
+ 0x28,
+ 0x74,
+ 0x29,
+ 0x28,
+ 0x75,
+ 0x29,
+ 0x28,
+ 0x76,
+ 0x29,
+ 0x28,
+ 0x77,
+ 0x29,
+ 0x28,
+ 0x78,
+ 0x29,
+ 0x28,
+ 0x79,
+ 0x29,
+ 0x28,
+ 0x7a,
+ 0x29,
+ 0x3a,
+ 0x3a,
+ 0x3d,
+ 0x3d,
+ 0x3d,
+ 0x2add,
+ 0x338,
+ 0x6bcd,
+ 0x9f9f,
+ 0x4e00,
+ 0x4e28,
+ 0x4e36,
+ 0x4e3f,
+ 0x4e59,
+ 0x4e85,
+ 0x4e8c,
+ 0x4ea0,
+ 0x4eba,
+ 0x513f,
+ 0x5165,
+ 0x516b,
+ 0x5182,
+ 0x5196,
+ 0x51ab,
+ 0x51e0,
+ 0x51f5,
+ 0x5200,
+ 0x529b,
+ 0x52f9,
+ 0x5315,
+ 0x531a,
+ 0x5338,
+ 0x5341,
+ 0x535c,
+ 0x5369,
+ 0x5382,
+ 0x53b6,
+ 0x53c8,
+ 0x53e3,
+ 0x56d7,
+ 0x571f,
+ 0x58eb,
+ 0x5902,
+ 0x590a,
+ 0x5915,
+ 0x5927,
+ 0x5973,
+ 0x5b50,
+ 0x5b80,
+ 0x5bf8,
+ 0x5c0f,
+ 0x5c22,
+ 0x5c38,
+ 0x5c6e,
+ 0x5c71,
+ 0x5ddb,
+ 0x5de5,
+ 0x5df1,
+ 0x5dfe,
+ 0x5e72,
+ 0x5e7a,
+ 0x5e7f,
+ 0x5ef4,
+ 0x5efe,
+ 0x5f0b,
+ 0x5f13,
+ 0x5f50,
+ 0x5f61,
+ 0x5f73,
+ 0x5fc3,
+ 0x6208,
+ 0x6236,
+ 0x624b,
+ 0x652f,
+ 0x6534,
+ 0x6587,
+ 0x6597,
+ 0x65a4,
+ 0x65b9,
+ 0x65e0,
+ 0x65e5,
+ 0x66f0,
+ 0x6708,
+ 0x6728,
+ 0x6b20,
+ 0x6b62,
+ 0x6b79,
+ 0x6bb3,
+ 0x6bcb,
+ 0x6bd4,
+ 0x6bdb,
+ 0x6c0f,
+ 0x6c14,
+ 0x6c34,
+ 0x706b,
+ 0x722a,
+ 0x7236,
+ 0x723b,
+ 0x723f,
+ 0x7247,
+ 0x7259,
+ 0x725b,
+ 0x72ac,
+ 0x7384,
+ 0x7389,
+ 0x74dc,
+ 0x74e6,
+ 0x7518,
+ 0x751f,
+ 0x7528,
+ 0x7530,
+ 0x758b,
+ 0x7592,
+ 0x7676,
+ 0x767d,
+ 0x76ae,
+ 0x76bf,
+ 0x76ee,
+ 0x77db,
+ 0x77e2,
+ 0x77f3,
+ 0x793a,
+ 0x79b8,
+ 0x79be,
+ 0x7a74,
+ 0x7acb,
+ 0x7af9,
+ 0x7c73,
+ 0x7cf8,
+ 0x7f36,
+ 0x7f51,
+ 0x7f8a,
+ 0x7fbd,
+ 0x8001,
+ 0x800c,
+ 0x8012,
+ 0x8033,
+ 0x807f,
+ 0x8089,
+ 0x81e3,
+ 0x81ea,
+ 0x81f3,
+ 0x81fc,
+ 0x820c,
+ 0x821b,
+ 0x821f,
+ 0x826e,
+ 0x8272,
+ 0x8278,
+ 0x864d,
+ 0x866b,
+ 0x8840,
+ 0x884c,
+ 0x8863,
+ 0x897e,
+ 0x898b,
+ 0x89d2,
+ 0x8a00,
+ 0x8c37,
+ 0x8c46,
+ 0x8c55,
+ 0x8c78,
+ 0x8c9d,
+ 0x8d64,
+ 0x8d70,
+ 0x8db3,
+ 0x8eab,
+ 0x8eca,
+ 0x8f9b,
+ 0x8fb0,
+ 0x8fb5,
+ 0x9091,
+ 0x9149,
+ 0x91c6,
+ 0x91cc,
+ 0x91d1,
+ 0x9577,
+ 0x9580,
+ 0x961c,
+ 0x96b6,
+ 0x96b9,
+ 0x96e8,
+ 0x9751,
+ 0x975e,
+ 0x9762,
+ 0x9769,
+ 0x97cb,
+ 0x97ed,
+ 0x97f3,
+ 0x9801,
+ 0x98a8,
+ 0x98db,
+ 0x98df,
+ 0x9996,
+ 0x9999,
+ 0x99ac,
+ 0x9aa8,
+ 0x9ad8,
+ 0x9adf,
+ 0x9b25,
+ 0x9b2f,
+ 0x9b32,
+ 0x9b3c,
+ 0x9b5a,
+ 0x9ce5,
+ 0x9e75,
+ 0x9e7f,
+ 0x9ea5,
+ 0x9ebb,
+ 0x9ec3,
+ 0x9ecd,
+ 0x9ed1,
+ 0x9ef9,
+ 0x9efd,
+ 0x9f0e,
+ 0x9f13,
+ 0x9f20,
+ 0x9f3b,
+ 0x9f4a,
+ 0x9f52,
+ 0x9f8d,
+ 0x9f9c,
+ 0x9fa0,
+ 0x20,
+ 0x3012,
+ 0x5344,
+ 0x5345,
+ 0x304b,
+ 0x3099,
+ 0x304d,
+ 0x3099,
+ 0x304f,
+ 0x3099,
+ 0x3051,
+ 0x3099,
+ 0x3053,
+ 0x3099,
+ 0x3055,
+ 0x3099,
+ 0x3057,
+ 0x3099,
+ 0x3059,
+ 0x3099,
+ 0x305b,
+ 0x3099,
+ 0x305d,
+ 0x3099,
+ 0x305f,
+ 0x3099,
+ 0x3061,
+ 0x3099,
+ 0x3064,
+ 0x3099,
+ 0x3066,
+ 0x3099,
+ 0x3068,
+ 0x3099,
+ 0x306f,
+ 0x3099,
+ 0x306f,
+ 0x309a,
+ 0x3072,
+ 0x3099,
+ 0x3072,
+ 0x309a,
+ 0x3075,
+ 0x3099,
+ 0x3075,
+ 0x309a,
+ 0x3078,
+ 0x3099,
+ 0x3078,
+ 0x309a,
+ 0x307b,
+ 0x3099,
+ 0x307b,
+ 0x309a,
+ 0x3046,
+ 0x3099,
+ 0x20,
+ 0x3099,
+ 0x20,
+ 0x309a,
+ 0x309d,
+ 0x3099,
+ 0x3088,
+ 0x308a,
+ 0x30ab,
+ 0x3099,
+ 0x30ad,
+ 0x3099,
+ 0x30af,
+ 0x3099,
+ 0x30b1,
+ 0x3099,
+ 0x30b3,
+ 0x3099,
+ 0x30b5,
+ 0x3099,
+ 0x30b7,
+ 0x3099,
+ 0x30b9,
+ 0x3099,
+ 0x30bb,
+ 0x3099,
+ 0x30bd,
+ 0x3099,
+ 0x30bf,
+ 0x3099,
+ 0x30c1,
+ 0x3099,
+ 0x30c4,
+ 0x3099,
+ 0x30c6,
+ 0x3099,
+ 0x30c8,
+ 0x3099,
+ 0x30cf,
+ 0x3099,
+ 0x30cf,
+ 0x309a,
+ 0x30d2,
+ 0x3099,
+ 0x30d2,
+ 0x309a,
+ 0x30d5,
+ 0x3099,
+ 0x30d5,
+ 0x309a,
+ 0x30d8,
+ 0x3099,
+ 0x30d8,
+ 0x309a,
+ 0x30db,
+ 0x3099,
+ 0x30db,
+ 0x309a,
+ 0x30a6,
+ 0x3099,
+ 0x30ef,
+ 0x3099,
+ 0x30f0,
+ 0x3099,
+ 0x30f1,
+ 0x3099,
+ 0x30f2,
+ 0x3099,
+ 0x30fd,
+ 0x3099,
+ 0x30b3,
+ 0x30c8,
+ 0x1100,
+ 0x1101,
+ 0x11aa,
+ 0x1102,
+ 0x11ac,
+ 0x11ad,
+ 0x1103,
+ 0x1104,
+ 0x1105,
+ 0x11b0,
+ 0x11b1,
+ 0x11b2,
+ 0x11b3,
+ 0x11b4,
+ 0x11b5,
+ 0x111a,
+ 0x1106,
+ 0x1107,
+ 0x1108,
+ 0x1121,
+ 0x1109,
+ 0x110a,
+ 0x110b,
+ 0x110c,
+ 0x110d,
+ 0x110e,
+ 0x110f,
+ 0x1110,
+ 0x1111,
+ 0x1112,
+ 0x1161,
+ 0x1162,
+ 0x1163,
+ 0x1164,
+ 0x1165,
+ 0x1166,
+ 0x1167,
+ 0x1168,
+ 0x1169,
+ 0x116a,
+ 0x116b,
+ 0x116c,
+ 0x116d,
+ 0x116e,
+ 0x116f,
+ 0x1170,
+ 0x1171,
+ 0x1172,
+ 0x1173,
+ 0x1174,
+ 0x1175,
+ 0x1160,
+ 0x1114,
+ 0x1115,
+ 0x11c7,
+ 0x11c8,
+ 0x11cc,
+ 0x11ce,
+ 0x11d3,
+ 0x11d7,
+ 0x11d9,
+ 0x111c,
+ 0x11dd,
+ 0x11df,
+ 0x111d,
+ 0x111e,
+ 0x1120,
+ 0x1122,
+ 0x1123,
+ 0x1127,
+ 0x1129,
+ 0x112b,
+ 0x112c,
+ 0x112d,
+ 0x112e,
+ 0x112f,
+ 0x1132,
+ 0x1136,
+ 0x1140,
+ 0x1147,
+ 0x114c,
+ 0x11f1,
+ 0x11f2,
+ 0x1157,
+ 0x1158,
+ 0x1159,
+ 0x1184,
+ 0x1185,
+ 0x1188,
+ 0x1191,
+ 0x1192,
+ 0x1194,
+ 0x119e,
+ 0x11a1,
+ 0x4e09,
+ 0x56db,
+ 0x4e0a,
+ 0x4e2d,
+ 0x4e0b,
+ 0x7532,
+ 0x4e19,
+ 0x4e01,
+ 0x5929,
+ 0x5730,
+ 0x28,
+ 0x1100,
+ 0x29,
+ 0x28,
+ 0x1102,
+ 0x29,
+ 0x28,
+ 0x1103,
+ 0x29,
+ 0x28,
+ 0x1105,
+ 0x29,
+ 0x28,
+ 0x1106,
+ 0x29,
+ 0x28,
+ 0x1107,
+ 0x29,
+ 0x28,
+ 0x1109,
+ 0x29,
+ 0x28,
+ 0x110b,
+ 0x29,
+ 0x28,
+ 0x110c,
+ 0x29,
+ 0x28,
+ 0x110e,
+ 0x29,
+ 0x28,
+ 0x110f,
+ 0x29,
+ 0x28,
+ 0x1110,
+ 0x29,
+ 0x28,
+ 0x1111,
+ 0x29,
+ 0x28,
+ 0x1112,
+ 0x29,
+ 0x28,
+ 0x1100,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1102,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1103,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1105,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1106,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1107,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1109,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x110b,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x110c,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x110e,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x110f,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1110,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1111,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x1112,
+ 0x1161,
+ 0x29,
+ 0x28,
+ 0x110c,
+ 0x116e,
+ 0x29,
+ 0x28,
+ 0x110b,
+ 0x1169,
+ 0x110c,
+ 0x1165,
+ 0x11ab,
+ 0x29,
+ 0x28,
+ 0x110b,
+ 0x1169,
+ 0x1112,
+ 0x116e,
+ 0x29,
+ 0x28,
+ 0x4e00,
+ 0x29,
+ 0x28,
+ 0x4e8c,
+ 0x29,
+ 0x28,
+ 0x4e09,
+ 0x29,
+ 0x28,
+ 0x56db,
+ 0x29,
+ 0x28,
+ 0x4e94,
+ 0x29,
+ 0x28,
+ 0x516d,
+ 0x29,
+ 0x28,
+ 0x4e03,
+ 0x29,
+ 0x28,
+ 0x516b,
+ 0x29,
+ 0x28,
+ 0x4e5d,
+ 0x29,
+ 0x28,
+ 0x5341,
+ 0x29,
+ 0x28,
+ 0x6708,
+ 0x29,
+ 0x28,
+ 0x706b,
+ 0x29,
+ 0x28,
+ 0x6c34,
+ 0x29,
+ 0x28,
+ 0x6728,
+ 0x29,
+ 0x28,
+ 0x91d1,
+ 0x29,
+ 0x28,
+ 0x571f,
+ 0x29,
+ 0x28,
+ 0x65e5,
+ 0x29,
+ 0x28,
+ 0x682a,
+ 0x29,
+ 0x28,
+ 0x6709,
+ 0x29,
+ 0x28,
+ 0x793e,
+ 0x29,
+ 0x28,
+ 0x540d,
+ 0x29,
+ 0x28,
+ 0x7279,
+ 0x29,
+ 0x28,
+ 0x8ca1,
+ 0x29,
+ 0x28,
+ 0x795d,
+ 0x29,
+ 0x28,
+ 0x52b4,
+ 0x29,
+ 0x28,
+ 0x4ee3,
+ 0x29,
+ 0x28,
+ 0x547c,
+ 0x29,
+ 0x28,
+ 0x5b66,
+ 0x29,
+ 0x28,
+ 0x76e3,
+ 0x29,
+ 0x28,
+ 0x4f01,
+ 0x29,
+ 0x28,
+ 0x8cc7,
+ 0x29,
+ 0x28,
+ 0x5354,
+ 0x29,
+ 0x28,
+ 0x796d,
+ 0x29,
+ 0x28,
+ 0x4f11,
+ 0x29,
+ 0x28,
+ 0x81ea,
+ 0x29,
+ 0x28,
+ 0x81f3,
+ 0x29,
+ 0x50,
+ 0x54,
+ 0x45,
+ 0x32,
+ 0x32,
+ 0x32,
+ 0x34,
+ 0x32,
+ 0x35,
+ 0x32,
+ 0x36,
+ 0x32,
+ 0x37,
+ 0x32,
+ 0x38,
+ 0x32,
+ 0x39,
+ 0x33,
+ 0x30,
+ 0x33,
+ 0x33,
+ 0x33,
+ 0x34,
+ 0x33,
+ 0x35,
+ 0x110e,
+ 0x1161,
+ 0x11b7,
+ 0x1100,
+ 0x1169,
+ 0x110c,
+ 0x116e,
+ 0x110b,
+ 0x1174,
+ 0x79d8,
+ 0x7537,
+ 0x9069,
+ 0x512a,
+ 0x5370,
+ 0x6ce8,
+ 0x9805,
+ 0x5199,
+ 0x6b63,
+ 0x5de6,
+ 0x53f3,
+ 0x533b,
+ 0x5b97,
+ 0x591c,
+ 0x33,
+ 0x36,
+ 0x33,
+ 0x37,
+ 0x33,
+ 0x38,
+ 0x33,
+ 0x39,
+ 0x34,
+ 0x30,
+ 0x34,
+ 0x34,
+ 0x34,
+ 0x35,
+ 0x34,
+ 0x36,
+ 0x34,
+ 0x37,
+ 0x34,
+ 0x38,
+ 0x34,
+ 0x39,
+ 0x35,
+ 0x30,
+ 0x31,
+ 0x6708,
+ 0x32,
+ 0x6708,
+ 0x33,
+ 0x6708,
+ 0x34,
+ 0x6708,
+ 0x35,
+ 0x6708,
+ 0x36,
+ 0x6708,
+ 0x37,
+ 0x6708,
+ 0x38,
+ 0x6708,
+ 0x39,
+ 0x6708,
+ 0x31,
+ 0x30,
+ 0x6708,
+ 0x31,
+ 0x31,
+ 0x6708,
+ 0x31,
+ 0x32,
+ 0x6708,
+ 0x48,
+ 0x67,
+ 0x65,
+ 0x72,
+ 0x67,
+ 0x65,
+ 0x56,
+ 0x4c,
+ 0x54,
+ 0x44,
+ 0x30a2,
+ 0x30a4,
+ 0x30a8,
+ 0x30aa,
+ 0x30ca,
+ 0x30cb,
+ 0x30cc,
+ 0x30cd,
+ 0x30ce,
+ 0x30de,
+ 0x30df,
+ 0x30e0,
+ 0x30e1,
+ 0x30e2,
+ 0x30e4,
+ 0x30e6,
+ 0x30e8,
+ 0x30e9,
+ 0x30ea,
+ 0x30eb,
+ 0x30ec,
+ 0x30ed,
+ 0x30a2,
+ 0x30d1,
+ 0x30fc,
+ 0x30c8,
+ 0x30a2,
+ 0x30eb,
+ 0x30d5,
+ 0x30a1,
+ 0x30a2,
+ 0x30f3,
+ 0x30da,
+ 0x30a2,
+ 0x30a2,
+ 0x30fc,
+ 0x30eb,
+ 0x30a4,
+ 0x30cb,
+ 0x30f3,
+ 0x30b0,
+ 0x30a4,
+ 0x30f3,
+ 0x30c1,
+ 0x30a6,
+ 0x30a9,
+ 0x30f3,
+ 0x30a8,
+ 0x30b9,
+ 0x30af,
+ 0x30fc,
+ 0x30c9,
+ 0x30a8,
+ 0x30fc,
+ 0x30ab,
+ 0x30fc,
+ 0x30aa,
+ 0x30f3,
+ 0x30b9,
+ 0x30aa,
+ 0x30fc,
+ 0x30e0,
+ 0x30ab,
+ 0x30a4,
+ 0x30ea,
+ 0x30ab,
+ 0x30e9,
+ 0x30c3,
+ 0x30c8,
+ 0x30ab,
+ 0x30ed,
+ 0x30ea,
+ 0x30fc,
+ 0x30ac,
+ 0x30ed,
+ 0x30f3,
+ 0x30ac,
+ 0x30f3,
+ 0x30de,
+ 0x30ae,
+ 0x30ac,
+ 0x30ae,
+ 0x30cb,
+ 0x30fc,
+ 0x30ad,
+ 0x30e5,
+ 0x30ea,
+ 0x30fc,
+ 0x30ae,
+ 0x30eb,
+ 0x30c0,
+ 0x30fc,
+ 0x30ad,
+ 0x30ed,
+ 0x30ad,
+ 0x30ed,
+ 0x30b0,
+ 0x30e9,
+ 0x30e0,
+ 0x30ad,
+ 0x30ed,
+ 0x30e1,
+ 0x30fc,
+ 0x30c8,
+ 0x30eb,
+ 0x30ad,
+ 0x30ed,
+ 0x30ef,
+ 0x30c3,
+ 0x30c8,
+ 0x30b0,
+ 0x30e9,
+ 0x30e0,
+ 0x30c8,
+ 0x30f3,
+ 0x30af,
+ 0x30eb,
+ 0x30bc,
+ 0x30a4,
+ 0x30ed,
+ 0x30af,
+ 0x30ed,
+ 0x30fc,
+ 0x30cd,
+ 0x30b1,
+ 0x30fc,
+ 0x30b9,
+ 0x30b3,
+ 0x30eb,
+ 0x30ca,
+ 0x30b3,
+ 0x30fc,
+ 0x30dd,
+ 0x30b5,
+ 0x30a4,
+ 0x30af,
+ 0x30eb,
+ 0x30b5,
+ 0x30f3,
+ 0x30c1,
+ 0x30fc,
+ 0x30e0,
+ 0x30b7,
+ 0x30ea,
+ 0x30f3,
+ 0x30b0,
+ 0x30bb,
+ 0x30f3,
+ 0x30c1,
+ 0x30bb,
+ 0x30f3,
+ 0x30c8,
+ 0x30c0,
+ 0x30fc,
+ 0x30b9,
+ 0x30c7,
+ 0x30b7,
+ 0x30c9,
+ 0x30eb,
+ 0x30ca,
+ 0x30ce,
+ 0x30ce,
+ 0x30c3,
+ 0x30c8,
+ 0x30cf,
+ 0x30a4,
+ 0x30c4,
+ 0x30d1,
+ 0x30fc,
+ 0x30bb,
+ 0x30f3,
+ 0x30c8,
+ 0x30d1,
+ 0x30fc,
+ 0x30c4,
+ 0x30d0,
+ 0x30fc,
+ 0x30ec,
+ 0x30eb,
+ 0x30d4,
+ 0x30a2,
+ 0x30b9,
+ 0x30c8,
+ 0x30eb,
+ 0x30d4,
+ 0x30af,
+ 0x30eb,
+ 0x30d4,
+ 0x30b3,
+ 0x30d3,
+ 0x30eb,
+ 0x30d5,
+ 0x30a1,
+ 0x30e9,
+ 0x30c3,
+ 0x30c9,
+ 0x30d5,
+ 0x30a3,
+ 0x30fc,
+ 0x30c8,
+ 0x30d6,
+ 0x30c3,
+ 0x30b7,
+ 0x30a7,
+ 0x30eb,
+ 0x30d5,
+ 0x30e9,
+ 0x30f3,
+ 0x30d8,
+ 0x30af,
+ 0x30bf,
+ 0x30fc,
+ 0x30eb,
+ 0x30da,
+ 0x30bd,
+ 0x30da,
+ 0x30cb,
+ 0x30d2,
+ 0x30d8,
+ 0x30eb,
+ 0x30c4,
+ 0x30da,
+ 0x30f3,
+ 0x30b9,
+ 0x30da,
+ 0x30fc,
+ 0x30b8,
+ 0x30d9,
+ 0x30fc,
+ 0x30bf,
+ 0x30dd,
+ 0x30a4,
+ 0x30f3,
+ 0x30c8,
+ 0x30dc,
+ 0x30eb,
+ 0x30c8,
+ 0x30db,
+ 0x30f3,
+ 0x30dd,
+ 0x30f3,
+ 0x30c9,
+ 0x30db,
+ 0x30fc,
+ 0x30eb,
+ 0x30db,
+ 0x30fc,
+ 0x30f3,
+ 0x30de,
+ 0x30a4,
+ 0x30af,
+ 0x30ed,
+ 0x30de,
+ 0x30a4,
+ 0x30eb,
+ 0x30de,
+ 0x30c3,
+ 0x30cf,
+ 0x30de,
+ 0x30eb,
+ 0x30af,
+ 0x30de,
+ 0x30f3,
+ 0x30b7,
+ 0x30e7,
+ 0x30f3,
+ 0x30df,
+ 0x30af,
+ 0x30ed,
+ 0x30f3,
+ 0x30df,
+ 0x30ea,
+ 0x30df,
+ 0x30ea,
+ 0x30d0,
+ 0x30fc,
+ 0x30eb,
+ 0x30e1,
+ 0x30ac,
+ 0x30e1,
+ 0x30ac,
+ 0x30c8,
+ 0x30f3,
+ 0x30e4,
+ 0x30fc,
+ 0x30c9,
+ 0x30e4,
+ 0x30fc,
+ 0x30eb,
+ 0x30e6,
+ 0x30a2,
+ 0x30f3,
+ 0x30ea,
+ 0x30c3,
+ 0x30c8,
+ 0x30eb,
+ 0x30ea,
+ 0x30e9,
+ 0x30eb,
+ 0x30d4,
+ 0x30fc,
+ 0x30eb,
+ 0x30fc,
+ 0x30d6,
+ 0x30eb,
+ 0x30ec,
+ 0x30e0,
+ 0x30ec,
+ 0x30f3,
+ 0x30c8,
+ 0x30b2,
+ 0x30f3,
+ 0x30,
+ 0x70b9,
+ 0x31,
+ 0x70b9,
+ 0x32,
+ 0x70b9,
+ 0x33,
+ 0x70b9,
+ 0x34,
+ 0x70b9,
+ 0x35,
+ 0x70b9,
+ 0x36,
+ 0x70b9,
+ 0x37,
+ 0x70b9,
+ 0x38,
+ 0x70b9,
+ 0x39,
+ 0x70b9,
+ 0x31,
+ 0x30,
+ 0x70b9,
+ 0x31,
+ 0x31,
+ 0x70b9,
+ 0x31,
+ 0x32,
+ 0x70b9,
+ 0x31,
+ 0x33,
+ 0x70b9,
+ 0x31,
+ 0x34,
+ 0x70b9,
+ 0x31,
+ 0x35,
+ 0x70b9,
+ 0x31,
+ 0x36,
+ 0x70b9,
+ 0x31,
+ 0x37,
+ 0x70b9,
+ 0x31,
+ 0x38,
+ 0x70b9,
+ 0x31,
+ 0x39,
+ 0x70b9,
+ 0x32,
+ 0x30,
+ 0x70b9,
+ 0x32,
+ 0x31,
+ 0x70b9,
+ 0x32,
+ 0x32,
+ 0x70b9,
+ 0x32,
+ 0x33,
+ 0x70b9,
+ 0x32,
+ 0x34,
+ 0x70b9,
+ 0x68,
+ 0x50,
+ 0x61,
+ 0x64,
+ 0x61,
+ 0x41,
+ 0x55,
+ 0x62,
+ 0x61,
+ 0x72,
+ 0x6f,
+ 0x56,
+ 0x70,
+ 0x63,
+ 0x64,
+ 0x6d,
+ 0x64,
+ 0x6d,
+ 0xb2,
+ 0x64,
+ 0x6d,
+ 0xb3,
+ 0x49,
+ 0x55,
+ 0x5e73,
+ 0x6210,
+ 0x662d,
+ 0x548c,
+ 0x5927,
+ 0x6b63,
+ 0x660e,
+ 0x6cbb,
+ 0x682a,
+ 0x5f0f,
+ 0x4f1a,
+ 0x793e,
+ 0x70,
+ 0x41,
+ 0x6e,
+ 0x41,
+ 0x3bc,
+ 0x41,
+ 0x6d,
+ 0x41,
+ 0x6b,
+ 0x41,
+ 0x4b,
+ 0x42,
+ 0x4d,
+ 0x42,
+ 0x47,
+ 0x42,
+ 0x63,
+ 0x61,
+ 0x6c,
+ 0x6b,
+ 0x63,
+ 0x61,
+ 0x6c,
+ 0x70,
+ 0x46,
+ 0x6e,
+ 0x46,
+ 0x3bc,
+ 0x46,
+ 0x3bc,
+ 0x67,
+ 0x6d,
+ 0x67,
+ 0x6b,
+ 0x67,
+ 0x48,
+ 0x7a,
+ 0x6b,
+ 0x48,
+ 0x7a,
+ 0x4d,
+ 0x48,
+ 0x7a,
+ 0x47,
+ 0x48,
+ 0x7a,
+ 0x54,
+ 0x48,
+ 0x7a,
+ 0x3bc,
+ 0x2113,
+ 0x6d,
+ 0x2113,
+ 0x64,
+ 0x2113,
+ 0x6b,
+ 0x2113,
+ 0x66,
+ 0x6d,
+ 0x6e,
+ 0x6d,
+ 0x3bc,
+ 0x6d,
+ 0x6d,
+ 0x6d,
+ 0x63,
+ 0x6d,
+ 0x6b,
+ 0x6d,
+ 0x6d,
+ 0x6d,
+ 0xb2,
+ 0x63,
+ 0x6d,
+ 0xb2,
+ 0x6b,
+ 0x6d,
+ 0xb2,
+ 0x6d,
+ 0x6d,
+ 0xb3,
+ 0x63,
+ 0x6d,
+ 0xb3,
+ 0x6b,
+ 0x6d,
+ 0xb3,
+ 0x6d,
+ 0x2215,
+ 0x73,
+ 0x6d,
+ 0x2215,
+ 0x73,
+ 0xb2,
+ 0x6b,
+ 0x50,
+ 0x61,
+ 0x4d,
+ 0x50,
+ 0x61,
+ 0x47,
+ 0x50,
+ 0x61,
+ 0x72,
+ 0x61,
+ 0x64,
+ 0x72,
+ 0x61,
+ 0x64,
+ 0x2215,
+ 0x73,
+ 0x72,
+ 0x61,
+ 0x64,
+ 0x2215,
+ 0x73,
+ 0xb2,
+ 0x70,
+ 0x73,
+ 0x6e,
+ 0x73,
+ 0x3bc,
+ 0x73,
+ 0x6d,
+ 0x73,
+ 0x70,
+ 0x56,
+ 0x6e,
+ 0x56,
+ 0x3bc,
+ 0x56,
+ 0x6d,
+ 0x56,
+ 0x6b,
+ 0x56,
+ 0x4d,
+ 0x56,
+ 0x70,
+ 0x57,
+ 0x6e,
+ 0x57,
+ 0x3bc,
+ 0x57,
+ 0x6d,
+ 0x57,
+ 0x6b,
+ 0x57,
+ 0x4d,
+ 0x57,
+ 0x6b,
+ 0x3a9,
+ 0x4d,
+ 0x3a9,
+ 0x61,
+ 0x2e,
+ 0x6d,
+ 0x2e,
+ 0x42,
+ 0x71,
+ 0x63,
+ 0x63,
+ 0x43,
+ 0x2215,
+ 0x6b,
+ 0x67,
+ 0x43,
+ 0x6f,
+ 0x2e,
+ 0x64,
+ 0x42,
+ 0x47,
+ 0x79,
+ 0x68,
+ 0x61,
+ 0x48,
+ 0x50,
+ 0x69,
+ 0x6e,
+ 0x4b,
+ 0x4b,
+ 0x4b,
+ 0x4d,
+ 0x6b,
+ 0x74,
+ 0x6c,
+ 0x6d,
+ 0x6c,
+ 0x6e,
+ 0x6c,
+ 0x6f,
+ 0x67,
+ 0x6c,
+ 0x78,
+ 0x6d,
+ 0x62,
+ 0x6d,
+ 0x69,
+ 0x6c,
+ 0x6d,
+ 0x6f,
+ 0x6c,
+ 0x50,
+ 0x48,
+ 0x70,
+ 0x2e,
+ 0x6d,
+ 0x2e,
+ 0x50,
+ 0x50,
+ 0x4d,
+ 0x50,
+ 0x52,
+ 0x53,
+ 0x76,
+ 0x57,
+ 0x62,
+ 0x56,
+ 0x2215,
+ 0x6d,
+ 0x41,
+ 0x2215,
+ 0x6d,
+ 0x31,
+ 0x65e5,
+ 0x32,
+ 0x65e5,
+ 0x33,
+ 0x65e5,
+ 0x34,
+ 0x65e5,
+ 0x35,
+ 0x65e5,
+ 0x36,
+ 0x65e5,
+ 0x37,
+ 0x65e5,
+ 0x38,
+ 0x65e5,
+ 0x39,
+ 0x65e5,
+ 0x31,
+ 0x30,
+ 0x65e5,
+ 0x31,
+ 0x31,
+ 0x65e5,
+ 0x31,
+ 0x32,
+ 0x65e5,
+ 0x31,
+ 0x33,
+ 0x65e5,
+ 0x31,
+ 0x34,
+ 0x65e5,
+ 0x31,
+ 0x35,
+ 0x65e5,
+ 0x31,
+ 0x36,
+ 0x65e5,
+ 0x31,
+ 0x37,
+ 0x65e5,
+ 0x31,
+ 0x38,
+ 0x65e5,
+ 0x31,
+ 0x39,
+ 0x65e5,
+ 0x32,
+ 0x30,
+ 0x65e5,
+ 0x32,
+ 0x31,
+ 0x65e5,
+ 0x32,
+ 0x32,
+ 0x65e5,
+ 0x32,
+ 0x33,
+ 0x65e5,
+ 0x32,
+ 0x34,
+ 0x65e5,
+ 0x32,
+ 0x35,
+ 0x65e5,
+ 0x32,
+ 0x36,
+ 0x65e5,
+ 0x32,
+ 0x37,
+ 0x65e5,
+ 0x32,
+ 0x38,
+ 0x65e5,
+ 0x32,
+ 0x39,
+ 0x65e5,
+ 0x33,
+ 0x30,
+ 0x65e5,
+ 0x33,
+ 0x31,
+ 0x65e5,
+ 0x67,
+ 0x61,
+ 0x6c,
+ 0x8c48,
+ 0x66f4,
+ 0x8cc8,
+ 0x6ed1,
+ 0x4e32,
+ 0x53e5,
+ 0x5951,
+ 0x5587,
+ 0x5948,
+ 0x61f6,
+ 0x7669,
+ 0x7f85,
+ 0x863f,
+ 0x87ba,
+ 0x88f8,
+ 0x908f,
+ 0x6a02,
+ 0x6d1b,
+ 0x70d9,
+ 0x73de,
+ 0x843d,
+ 0x916a,
+ 0x99f1,
+ 0x4e82,
+ 0x5375,
+ 0x6b04,
+ 0x721b,
+ 0x862d,
+ 0x9e1e,
+ 0x5d50,
+ 0x6feb,
+ 0x85cd,
+ 0x8964,
+ 0x62c9,
+ 0x81d8,
+ 0x881f,
+ 0x5eca,
+ 0x6717,
+ 0x6d6a,
+ 0x72fc,
+ 0x90ce,
+ 0x4f86,
+ 0x51b7,
+ 0x52de,
+ 0x64c4,
+ 0x6ad3,
+ 0x7210,
+ 0x76e7,
+ 0x8606,
+ 0x865c,
+ 0x8def,
+ 0x9732,
+ 0x9b6f,
+ 0x9dfa,
+ 0x788c,
+ 0x797f,
+ 0x7da0,
+ 0x83c9,
+ 0x9304,
+ 0x8ad6,
+ 0x58df,
+ 0x5f04,
+ 0x7c60,
+ 0x807e,
+ 0x7262,
+ 0x78ca,
+ 0x8cc2,
+ 0x96f7,
+ 0x58d8,
+ 0x5c62,
+ 0x6a13,
+ 0x6dda,
+ 0x6f0f,
+ 0x7d2f,
+ 0x7e37,
+ 0x964b,
+ 0x52d2,
+ 0x808b,
+ 0x51dc,
+ 0x51cc,
+ 0x7a1c,
+ 0x7dbe,
+ 0x83f1,
+ 0x9675,
+ 0x8b80,
+ 0x62cf,
+ 0x8afe,
+ 0x4e39,
+ 0x5be7,
+ 0x6012,
+ 0x7387,
+ 0x7570,
+ 0x5317,
+ 0x78fb,
+ 0x4fbf,
+ 0x5fa9,
+ 0x4e0d,
+ 0x6ccc,
+ 0x6578,
+ 0x7d22,
+ 0x53c3,
+ 0x585e,
+ 0x7701,
+ 0x8449,
+ 0x8aaa,
+ 0x6bba,
+ 0x6c88,
+ 0x62fe,
+ 0x82e5,
+ 0x63a0,
+ 0x7565,
+ 0x4eae,
+ 0x5169,
+ 0x51c9,
+ 0x6881,
+ 0x7ce7,
+ 0x826f,
+ 0x8ad2,
+ 0x91cf,
+ 0x52f5,
+ 0x5442,
+ 0x5eec,
+ 0x65c5,
+ 0x6ffe,
+ 0x792a,
+ 0x95ad,
+ 0x9a6a,
+ 0x9e97,
+ 0x9ece,
+ 0x66c6,
+ 0x6b77,
+ 0x8f62,
+ 0x5e74,
+ 0x6190,
+ 0x6200,
+ 0x649a,
+ 0x6f23,
+ 0x7149,
+ 0x7489,
+ 0x79ca,
+ 0x7df4,
+ 0x806f,
+ 0x8f26,
+ 0x84ee,
+ 0x9023,
+ 0x934a,
+ 0x5217,
+ 0x52a3,
+ 0x54bd,
+ 0x70c8,
+ 0x88c2,
+ 0x5ec9,
+ 0x5ff5,
+ 0x637b,
+ 0x6bae,
+ 0x7c3e,
+ 0x7375,
+ 0x4ee4,
+ 0x56f9,
+ 0x5dba,
+ 0x601c,
+ 0x73b2,
+ 0x7469,
+ 0x7f9a,
+ 0x8046,
+ 0x9234,
+ 0x96f6,
+ 0x9748,
+ 0x9818,
+ 0x4f8b,
+ 0x79ae,
+ 0x91b4,
+ 0x96b8,
+ 0x60e1,
+ 0x4e86,
+ 0x50da,
+ 0x5bee,
+ 0x5c3f,
+ 0x6599,
+ 0x71ce,
+ 0x7642,
+ 0x84fc,
+ 0x907c,
+ 0x6688,
+ 0x962e,
+ 0x5289,
+ 0x677b,
+ 0x67f3,
+ 0x6d41,
+ 0x6e9c,
+ 0x7409,
+ 0x7559,
+ 0x786b,
+ 0x7d10,
+ 0x985e,
+ 0x622e,
+ 0x9678,
+ 0x502b,
+ 0x5d19,
+ 0x6dea,
+ 0x8f2a,
+ 0x5f8b,
+ 0x6144,
+ 0x6817,
+ 0x9686,
+ 0x5229,
+ 0x540f,
+ 0x5c65,
+ 0x6613,
+ 0x674e,
+ 0x68a8,
+ 0x6ce5,
+ 0x7406,
+ 0x75e2,
+ 0x7f79,
+ 0x88cf,
+ 0x88e1,
+ 0x96e2,
+ 0x533f,
+ 0x6eba,
+ 0x541d,
+ 0x71d0,
+ 0x7498,
+ 0x85fa,
+ 0x96a3,
+ 0x9c57,
+ 0x9e9f,
+ 0x6797,
+ 0x6dcb,
+ 0x81e8,
+ 0x7b20,
+ 0x7c92,
+ 0x72c0,
+ 0x7099,
+ 0x8b58,
+ 0x4ec0,
+ 0x8336,
+ 0x523a,
+ 0x5207,
+ 0x5ea6,
+ 0x62d3,
+ 0x7cd6,
+ 0x5b85,
+ 0x6d1e,
+ 0x66b4,
+ 0x8f3b,
+ 0x964d,
+ 0x5ed3,
+ 0x5140,
+ 0x55c0,
+ 0x585a,
+ 0x6674,
+ 0x51de,
+ 0x732a,
+ 0x76ca,
+ 0x793c,
+ 0x795e,
+ 0x7965,
+ 0x798f,
+ 0x9756,
+ 0x7cbe,
+ 0x8612,
+ 0x8af8,
+ 0x9038,
+ 0x90fd,
+ 0x98ef,
+ 0x98fc,
+ 0x9928,
+ 0x9db4,
+ 0x4fae,
+ 0x50e7,
+ 0x514d,
+ 0x52c9,
+ 0x52e4,
+ 0x5351,
+ 0x559d,
+ 0x5606,
+ 0x5668,
+ 0x5840,
+ 0x58a8,
+ 0x5c64,
+ 0x6094,
+ 0x6168,
+ 0x618e,
+ 0x61f2,
+ 0x654f,
+ 0x65e2,
+ 0x6691,
+ 0x6885,
+ 0x6d77,
+ 0x6e1a,
+ 0x6f22,
+ 0x716e,
+ 0x722b,
+ 0x7422,
+ 0x7891,
+ 0x7949,
+ 0x7948,
+ 0x7950,
+ 0x7956,
+ 0x798d,
+ 0x798e,
+ 0x7a40,
+ 0x7a81,
+ 0x7bc0,
+ 0x7e09,
+ 0x7e41,
+ 0x7f72,
+ 0x8005,
+ 0x81ed,
+ 0x8279,
+ 0x8457,
+ 0x8910,
+ 0x8996,
+ 0x8b01,
+ 0x8b39,
+ 0x8cd3,
+ 0x8d08,
+ 0x8fb6,
+ 0x96e3,
+ 0x97ff,
+ 0x983b,
+ 0x66,
+ 0x66,
+ 0x66,
+ 0x69,
+ 0x66,
+ 0x6c,
+ 0x66,
+ 0x66,
+ 0x6c,
+ 0x17f,
+ 0x74,
+ 0x73,
+ 0x74,
+ 0x574,
+ 0x576,
+ 0x574,
+ 0x565,
+ 0x574,
+ 0x56b,
+ 0x57e,
+ 0x576,
+ 0x574,
+ 0x56d,
+ 0x5d9,
+ 0x5b4,
+ 0x5f2,
+ 0x5b7,
+ 0x5e2,
+ 0x5d4,
+ 0x5db,
+ 0x5dc,
+ 0x5dd,
+ 0x5e8,
+ 0x5ea,
+ 0x5e9,
+ 0x5c1,
+ 0x5e9,
+ 0x5c2,
+ 0xfb49,
+ 0x5c1,
+ 0xfb49,
+ 0x5c2,
+ 0x5d0,
+ 0x5b7,
+ 0x5d0,
+ 0x5b8,
+ 0x5d0,
+ 0x5bc,
+ 0x5d1,
+ 0x5bc,
+ 0x5d2,
+ 0x5bc,
+ 0x5d3,
+ 0x5bc,
+ 0x5d4,
+ 0x5bc,
+ 0x5d5,
+ 0x5bc,
+ 0x5d6,
+ 0x5bc,
+ 0x5d8,
+ 0x5bc,
+ 0x5d9,
+ 0x5bc,
+ 0x5da,
+ 0x5bc,
+ 0x5db,
+ 0x5bc,
+ 0x5dc,
+ 0x5bc,
+ 0x5de,
+ 0x5bc,
+ 0x5e0,
+ 0x5bc,
+ 0x5e1,
+ 0x5bc,
+ 0x5e3,
+ 0x5bc,
+ 0x5e4,
+ 0x5bc,
+ 0x5e6,
+ 0x5bc,
+ 0x5e7,
+ 0x5bc,
+ 0x5e8,
+ 0x5bc,
+ 0x5e9,
+ 0x5bc,
+ 0x5ea,
+ 0x5bc,
+ 0x5d5,
+ 0x5b9,
+ 0x5d1,
+ 0x5bf,
+ 0x5db,
+ 0x5bf,
+ 0x5e4,
+ 0x5bf,
+ 0x5d0,
+ 0x5dc,
+ 0x671,
+ 0x67b,
+ 0x67e,
+ 0x680,
+ 0x67a,
+ 0x67f,
+ 0x679,
+ 0x6a4,
+ 0x6a6,
+ 0x684,
+ 0x683,
+ 0x686,
+ 0x687,
+ 0x68d,
+ 0x68c,
+ 0x68e,
+ 0x688,
+ 0x698,
+ 0x691,
+ 0x6a9,
+ 0x6af,
+ 0x6b3,
+ 0x6b1,
+ 0x6ba,
+ 0x6bb,
+ 0x6c0,
+ 0x6be,
+ 0x6d3,
+ 0x6ad,
+ 0x6c6,
+ 0x6c8,
+ 0x677,
+ 0x6cb,
+ 0x6c5,
+ 0x6c9,
+ 0x6d0,
+ 0x649,
+ 0x626,
+ 0x627,
+ 0x626,
+ 0x6d5,
+ 0x626,
+ 0x648,
+ 0x626,
+ 0x6c7,
+ 0x626,
+ 0x6c6,
+ 0x626,
+ 0x6c8,
+ 0x626,
+ 0x6d0,
+ 0x626,
+ 0x649,
+ 0x6cc,
+ 0x626,
+ 0x62c,
+ 0x626,
+ 0x62d,
+ 0x626,
+ 0x645,
+ 0x626,
+ 0x64a,
+ 0x628,
+ 0x62c,
+ 0x628,
+ 0x62d,
+ 0x628,
+ 0x62e,
+ 0x628,
+ 0x645,
+ 0x628,
+ 0x649,
+ 0x628,
+ 0x64a,
+ 0x62a,
+ 0x62c,
+ 0x62a,
+ 0x62d,
+ 0x62a,
+ 0x62e,
+ 0x62a,
+ 0x645,
+ 0x62a,
+ 0x649,
+ 0x62a,
+ 0x64a,
+ 0x62b,
+ 0x62c,
+ 0x62b,
+ 0x645,
+ 0x62b,
+ 0x649,
+ 0x62b,
+ 0x64a,
+ 0x62c,
+ 0x62d,
+ 0x62c,
+ 0x645,
+ 0x62d,
+ 0x645,
+ 0x62e,
+ 0x62c,
+ 0x62e,
+ 0x62d,
+ 0x62e,
+ 0x645,
+ 0x633,
+ 0x62c,
+ 0x633,
+ 0x62d,
+ 0x633,
+ 0x62e,
+ 0x633,
+ 0x645,
+ 0x635,
+ 0x62d,
+ 0x635,
+ 0x645,
+ 0x636,
+ 0x62c,
+ 0x636,
+ 0x62d,
+ 0x636,
+ 0x62e,
+ 0x636,
+ 0x645,
+ 0x637,
+ 0x62d,
+ 0x637,
+ 0x645,
+ 0x638,
+ 0x645,
+ 0x639,
+ 0x62c,
+ 0x639,
+ 0x645,
+ 0x63a,
+ 0x62c,
+ 0x63a,
+ 0x645,
+ 0x641,
+ 0x62c,
+ 0x641,
+ 0x62d,
+ 0x641,
+ 0x62e,
+ 0x641,
+ 0x645,
+ 0x641,
+ 0x649,
+ 0x641,
+ 0x64a,
+ 0x642,
+ 0x62d,
+ 0x642,
+ 0x645,
+ 0x642,
+ 0x649,
+ 0x642,
+ 0x64a,
+ 0x643,
+ 0x627,
+ 0x643,
+ 0x62c,
+ 0x643,
+ 0x62d,
+ 0x643,
+ 0x62e,
+ 0x643,
+ 0x644,
+ 0x643,
+ 0x645,
+ 0x643,
+ 0x649,
+ 0x643,
+ 0x64a,
+ 0x644,
+ 0x62c,
+ 0x644,
+ 0x62d,
+ 0x644,
+ 0x62e,
+ 0x644,
+ 0x645,
+ 0x644,
+ 0x649,
+ 0x644,
+ 0x64a,
+ 0x645,
+ 0x62c,
+ 0x645,
+ 0x645,
+ 0x645,
+ 0x649,
+ 0x645,
+ 0x64a,
+ 0x646,
+ 0x62c,
+ 0x646,
+ 0x62d,
+ 0x646,
+ 0x62e,
+ 0x646,
+ 0x645,
+ 0x646,
+ 0x649,
+ 0x646,
+ 0x64a,
+ 0x647,
+ 0x62c,
+ 0x647,
+ 0x645,
+ 0x647,
+ 0x649,
+ 0x647,
+ 0x64a,
+ 0x64a,
+ 0x62d,
+ 0x64a,
+ 0x62e,
+ 0x64a,
+ 0x649,
+ 0x630,
+ 0x670,
+ 0x631,
+ 0x670,
+ 0x649,
+ 0x670,
+ 0x20,
+ 0x64c,
+ 0x651,
+ 0x20,
+ 0x64d,
+ 0x651,
+ 0x20,
+ 0x64e,
+ 0x651,
+ 0x20,
+ 0x64f,
+ 0x651,
+ 0x20,
+ 0x650,
+ 0x651,
+ 0x20,
+ 0x651,
+ 0x670,
+ 0x626,
+ 0x631,
+ 0x626,
+ 0x632,
+ 0x626,
+ 0x646,
+ 0x628,
+ 0x631,
+ 0x628,
+ 0x632,
+ 0x628,
+ 0x646,
+ 0x62a,
+ 0x631,
+ 0x62a,
+ 0x632,
+ 0x62a,
+ 0x646,
+ 0x62b,
+ 0x631,
+ 0x62b,
+ 0x632,
+ 0x62b,
+ 0x646,
+ 0x645,
+ 0x627,
+ 0x646,
+ 0x631,
+ 0x646,
+ 0x632,
+ 0x646,
+ 0x646,
+ 0x64a,
+ 0x631,
+ 0x64a,
+ 0x632,
+ 0x626,
+ 0x62e,
+ 0x626,
+ 0x647,
+ 0x628,
+ 0x647,
+ 0x62a,
+ 0x647,
+ 0x635,
+ 0x62e,
+ 0x644,
+ 0x647,
+ 0x646,
+ 0x647,
+ 0x647,
+ 0x670,
+ 0x62b,
+ 0x647,
+ 0x633,
+ 0x647,
+ 0x634,
+ 0x645,
+ 0x634,
+ 0x647,
+ 0x640,
+ 0x64e,
+ 0x651,
+ 0x640,
+ 0x64f,
+ 0x651,
+ 0x640,
+ 0x650,
+ 0x651,
+ 0x637,
+ 0x649,
+ 0x637,
+ 0x64a,
+ 0x639,
+ 0x649,
+ 0x639,
+ 0x64a,
+ 0x63a,
+ 0x649,
+ 0x63a,
+ 0x64a,
+ 0x633,
+ 0x649,
+ 0x633,
+ 0x64a,
+ 0x634,
+ 0x649,
+ 0x634,
+ 0x64a,
+ 0x62d,
+ 0x649,
+ 0x62c,
+ 0x649,
+ 0x62c,
+ 0x64a,
+ 0x62e,
+ 0x649,
+ 0x635,
+ 0x649,
+ 0x635,
+ 0x64a,
+ 0x636,
+ 0x649,
+ 0x636,
+ 0x64a,
+ 0x634,
+ 0x62c,
+ 0x634,
+ 0x62d,
+ 0x634,
+ 0x62e,
+ 0x634,
+ 0x631,
+ 0x633,
+ 0x631,
+ 0x635,
+ 0x631,
+ 0x636,
+ 0x631,
+ 0x627,
+ 0x64b,
+ 0x62a,
+ 0x62c,
+ 0x645,
+ 0x62a,
+ 0x62d,
+ 0x62c,
+ 0x62a,
+ 0x62d,
+ 0x645,
+ 0x62a,
+ 0x62e,
+ 0x645,
+ 0x62a,
+ 0x645,
+ 0x62c,
+ 0x62a,
+ 0x645,
+ 0x62d,
+ 0x62a,
+ 0x645,
+ 0x62e,
+ 0x62d,
+ 0x645,
+ 0x64a,
+ 0x62d,
+ 0x645,
+ 0x649,
+ 0x633,
+ 0x62d,
+ 0x62c,
+ 0x633,
+ 0x62c,
+ 0x62d,
+ 0x633,
+ 0x62c,
+ 0x649,
+ 0x633,
+ 0x645,
+ 0x62d,
+ 0x633,
+ 0x645,
+ 0x62c,
+ 0x633,
+ 0x645,
+ 0x645,
+ 0x635,
+ 0x62d,
+ 0x62d,
+ 0x635,
+ 0x645,
+ 0x645,
+ 0x634,
+ 0x62d,
+ 0x645,
+ 0x634,
+ 0x62c,
+ 0x64a,
+ 0x634,
+ 0x645,
+ 0x62e,
+ 0x634,
+ 0x645,
+ 0x645,
+ 0x636,
+ 0x62d,
+ 0x649,
+ 0x636,
+ 0x62e,
+ 0x645,
+ 0x637,
+ 0x645,
+ 0x62d,
+ 0x637,
+ 0x645,
+ 0x645,
+ 0x637,
+ 0x645,
+ 0x64a,
+ 0x639,
+ 0x62c,
+ 0x645,
+ 0x639,
+ 0x645,
+ 0x645,
+ 0x639,
+ 0x645,
+ 0x649,
+ 0x63a,
+ 0x645,
+ 0x645,
+ 0x63a,
+ 0x645,
+ 0x64a,
+ 0x63a,
+ 0x645,
+ 0x649,
+ 0x641,
+ 0x62e,
+ 0x645,
+ 0x642,
+ 0x645,
+ 0x62d,
+ 0x642,
+ 0x645,
+ 0x645,
+ 0x644,
+ 0x62d,
+ 0x645,
+ 0x644,
+ 0x62d,
+ 0x64a,
+ 0x644,
+ 0x62d,
+ 0x649,
+ 0x644,
+ 0x62c,
+ 0x62c,
+ 0x644,
+ 0x62e,
+ 0x645,
+ 0x644,
+ 0x645,
+ 0x62d,
+ 0x645,
+ 0x62d,
+ 0x62c,
+ 0x645,
+ 0x62d,
+ 0x64a,
+ 0x645,
+ 0x62c,
+ 0x62d,
+ 0x645,
+ 0x62e,
+ 0x645,
+ 0x645,
+ 0x62c,
+ 0x62e,
+ 0x647,
+ 0x645,
+ 0x62c,
+ 0x647,
+ 0x645,
+ 0x645,
+ 0x646,
+ 0x62d,
+ 0x645,
+ 0x646,
+ 0x62d,
+ 0x649,
+ 0x646,
+ 0x62c,
+ 0x645,
+ 0x646,
+ 0x62c,
+ 0x649,
+ 0x646,
+ 0x645,
+ 0x64a,
+ 0x646,
+ 0x645,
+ 0x649,
+ 0x64a,
+ 0x645,
+ 0x645,
+ 0x628,
+ 0x62e,
+ 0x64a,
+ 0x62a,
+ 0x62c,
+ 0x64a,
+ 0x62a,
+ 0x62c,
+ 0x649,
+ 0x62a,
+ 0x62e,
+ 0x64a,
+ 0x62a,
+ 0x62e,
+ 0x649,
+ 0x62a,
+ 0x645,
+ 0x64a,
+ 0x62a,
+ 0x645,
+ 0x649,
+ 0x62c,
+ 0x645,
+ 0x64a,
+ 0x62c,
+ 0x62d,
+ 0x649,
+ 0x62c,
+ 0x645,
+ 0x649,
+ 0x633,
+ 0x62e,
+ 0x649,
+ 0x635,
+ 0x62d,
+ 0x64a,
+ 0x634,
+ 0x62d,
+ 0x64a,
+ 0x636,
+ 0x62d,
+ 0x64a,
+ 0x644,
+ 0x62c,
+ 0x64a,
+ 0x644,
+ 0x645,
+ 0x64a,
+ 0x64a,
+ 0x62c,
+ 0x64a,
+ 0x64a,
+ 0x645,
+ 0x64a,
+ 0x645,
+ 0x645,
+ 0x64a,
+ 0x642,
+ 0x645,
+ 0x64a,
+ 0x646,
+ 0x62d,
+ 0x64a,
+ 0x639,
+ 0x645,
+ 0x64a,
+ 0x643,
+ 0x645,
+ 0x64a,
+ 0x646,
+ 0x62c,
+ 0x62d,
+ 0x645,
+ 0x62e,
+ 0x64a,
+ 0x644,
+ 0x62c,
+ 0x645,
+ 0x643,
+ 0x645,
+ 0x645,
+ 0x62c,
+ 0x62d,
+ 0x64a,
+ 0x62d,
+ 0x62c,
+ 0x64a,
+ 0x645,
+ 0x62c,
+ 0x64a,
+ 0x641,
+ 0x645,
+ 0x64a,
+ 0x628,
+ 0x62d,
+ 0x64a,
+ 0x633,
+ 0x62e,
+ 0x64a,
+ 0x646,
+ 0x62c,
+ 0x64a,
+ 0x635,
+ 0x644,
+ 0x6d2,
+ 0x642,
+ 0x644,
+ 0x6d2,
+ 0x627,
+ 0x644,
+ 0x644,
+ 0x647,
+ 0x627,
+ 0x643,
+ 0x628,
+ 0x631,
+ 0x645,
+ 0x62d,
+ 0x645,
+ 0x62f,
+ 0x635,
+ 0x644,
+ 0x639,
+ 0x645,
+ 0x631,
+ 0x633,
+ 0x648,
+ 0x644,
+ 0x639,
+ 0x644,
+ 0x64a,
+ 0x647,
+ 0x648,
+ 0x633,
+ 0x644,
+ 0x645,
+ 0x635,
+ 0x644,
+ 0x649,
+ 0x635,
+ 0x644,
+ 0x649,
+ 0x20,
+ 0x627,
+ 0x644,
+ 0x644,
+ 0x647,
+ 0x20,
+ 0x639,
+ 0x644,
+ 0x64a,
+ 0x647,
+ 0x20,
+ 0x648,
+ 0x633,
+ 0x644,
+ 0x645,
+ 0x62c,
+ 0x644,
+ 0x20,
+ 0x62c,
+ 0x644,
+ 0x627,
+ 0x644,
+ 0x647,
+ 0x631,
+ 0x6cc,
+ 0x627,
+ 0x644,
+ 0x2025,
+ 0x2014,
+ 0x2013,
+ 0x5f,
+ 0x7b,
+ 0x7d,
+ 0x3014,
+ 0x3015,
+ 0x3010,
+ 0x3011,
+ 0x300a,
+ 0x300b,
+ 0x300c,
+ 0x300d,
+ 0x300e,
+ 0x300f,
+ 0x5b,
+ 0x5d,
+ 0x203e,
+ 0x2c,
+ 0x3001,
+ 0x23,
+ 0x26,
+ 0x2a,
+ 0x2d,
+ 0x5c,
+ 0x24,
+ 0x25,
+ 0x40,
+ 0x20,
+ 0x64b,
+ 0x640,
+ 0x64b,
+ 0x640,
+ 0x651,
+ 0x20,
+ 0x652,
+ 0x640,
+ 0x652,
+ 0x621,
+ 0x622,
+ 0x623,
+ 0x624,
+ 0x625,
+ 0x629,
+ 0x644,
+ 0x622,
+ 0x644,
+ 0x623,
+ 0x644,
+ 0x625,
+ 0x22,
+ 0x27,
+ 0x5e,
+ 0x7c,
+ 0x7e,
+ 0x2985,
+ 0x2986,
+ 0x3002,
+ 0x30fb,
+ 0x30a5,
+ 0x30e3,
+ 0x3164,
+ 0x3131,
+ 0x3132,
+ 0x3133,
+ 0x3134,
+ 0x3135,
+ 0x3136,
+ 0x3137,
+ 0x3138,
+ 0x3139,
+ 0x313a,
+ 0x313b,
+ 0x313c,
+ 0x313d,
+ 0x313e,
+ 0x313f,
+ 0x3140,
+ 0x3141,
+ 0x3142,
+ 0x3143,
+ 0x3144,
+ 0x3145,
+ 0x3146,
+ 0x3147,
+ 0x3148,
+ 0x3149,
+ 0x314a,
+ 0x314b,
+ 0x314c,
+ 0x314d,
+ 0x314e,
+ 0x314f,
+ 0x3150,
+ 0x3151,
+ 0x3152,
+ 0x3153,
+ 0x3154,
+ 0x3155,
+ 0x3156,
+ 0x3157,
+ 0x3158,
+ 0x3159,
+ 0x315a,
+ 0x315b,
+ 0x315c,
+ 0x315d,
+ 0x315e,
+ 0x315f,
+ 0x3160,
+ 0x3161,
+ 0x3162,
+ 0x3163,
+ 0xa2,
+ 0xa3,
+ 0xac,
+ 0xaf,
+ 0xa6,
+ 0xa5,
+ 0x20a9,
+ 0x2502,
+ 0x2191,
+ 0x2193,
+ 0x25a0,
+ 0x25cb,
+ 0x1d157,
+ 0x1d165,
+ 0x1d158,
+ 0x1d165,
+ 0x1d15f,
+ 0x1d16e,
+ 0x1d15f,
+ 0x1d16f,
+ 0x1d15f,
+ 0x1d170,
+ 0x1d15f,
+ 0x1d171,
+ 0x1d15f,
+ 0x1d172,
+ 0x1d1b9,
+ 0x1d165,
+ 0x1d1ba,
+ 0x1d165,
+ 0x1d1bb,
+ 0x1d16e,
+ 0x1d1bc,
+ 0x1d16e,
+ 0x1d1bb,
+ 0x1d16f,
+ 0x1d1bc,
+ 0x1d16f,
+ 0x392,
+ 0x394,
+ 0x396,
+ 0x39a,
+ 0x39b,
+ 0x39c,
+ 0x39d,
+ 0x39e,
+ 0x3f4,
+ 0x3a4,
+ 0x3a6,
+ 0x3a7,
+ 0x3a8,
+ 0x2207,
+ 0x3b6,
+ 0x3bb,
+ 0x3bd,
+ 0x3be,
+ 0x3c3,
+ 0x3c4,
+ 0x3c8,
+ 0x2202,
+ 0x3f5,
+ 0x3d1,
+ 0x3f0,
+ 0x3d5,
+ 0x3f1,
+ 0x3d6,
+ 0x4e3d,
+ 0x4e38,
+ 0x4e41,
+ 0x20122,
+ 0x4f60,
+ 0x4fbb,
+ 0x5002,
+ 0x507a,
+ 0x5099,
+ 0x50cf,
+ 0x349e,
+ 0x2063a,
+ 0x5154,
+ 0x5164,
+ 0x5177,
+ 0x2051c,
+ 0x34b9,
+ 0x5167,
+ 0x518d,
+ 0x2054b,
+ 0x5197,
+ 0x51a4,
+ 0x4ecc,
+ 0x51ac,
+ 0x51b5,
+ 0x291df,
+ 0x5203,
+ 0x34df,
+ 0x523b,
+ 0x5246,
+ 0x5272,
+ 0x5277,
+ 0x3515,
+ 0x52c7,
+ 0x52fa,
+ 0x5305,
+ 0x5306,
+ 0x5349,
+ 0x535a,
+ 0x5373,
+ 0x537d,
+ 0x537f,
+ 0x20a2c,
+ 0x7070,
+ 0x53ca,
+ 0x53df,
+ 0x20b63,
+ 0x53eb,
+ 0x53f1,
+ 0x5406,
+ 0x549e,
+ 0x5438,
+ 0x5448,
+ 0x5468,
+ 0x54a2,
+ 0x54f6,
+ 0x5510,
+ 0x5553,
+ 0x5563,
+ 0x5584,
+ 0x5599,
+ 0x55ab,
+ 0x55b3,
+ 0x55c2,
+ 0x5716,
+ 0x5717,
+ 0x5651,
+ 0x5674,
+ 0x58ee,
+ 0x57ce,
+ 0x57f4,
+ 0x580d,
+ 0x578b,
+ 0x5832,
+ 0x5831,
+ 0x58ac,
+ 0x214e4,
+ 0x58f2,
+ 0x58f7,
+ 0x5906,
+ 0x591a,
+ 0x5922,
+ 0x5962,
+ 0x216a8,
+ 0x216ea,
+ 0x59ec,
+ 0x5a1b,
+ 0x5a27,
+ 0x59d8,
+ 0x5a66,
+ 0x36ee,
+ 0x36fc,
+ 0x5b08,
+ 0x5b3e,
+ 0x219c8,
+ 0x5bc3,
+ 0x5bd8,
+ 0x5bf3,
+ 0x21b18,
+ 0x5bff,
+ 0x5c06,
+ 0x5f53,
+ 0x3781,
+ 0x5c60,
+ 0x5cc0,
+ 0x5c8d,
+ 0x21de4,
+ 0x5d43,
+ 0x21de6,
+ 0x5d6e,
+ 0x5d6b,
+ 0x5d7c,
+ 0x5de1,
+ 0x5de2,
+ 0x382f,
+ 0x5dfd,
+ 0x5e28,
+ 0x5e3d,
+ 0x5e69,
+ 0x3862,
+ 0x22183,
+ 0x387c,
+ 0x5eb0,
+ 0x5eb3,
+ 0x5eb6,
+ 0x2a392,
+ 0x22331,
+ 0x8201,
+ 0x5f22,
+ 0x38c7,
+ 0x232b8,
+ 0x261da,
+ 0x5f62,
+ 0x5f6b,
+ 0x38e3,
+ 0x5f9a,
+ 0x5fcd,
+ 0x5fd7,
+ 0x5ff9,
+ 0x6081,
+ 0x393a,
+ 0x391c,
+ 0x226d4,
+ 0x60c7,
+ 0x6148,
+ 0x614c,
+ 0x614e,
+ 0x617a,
+ 0x61b2,
+ 0x61a4,
+ 0x61af,
+ 0x61de,
+ 0x621b,
+ 0x625d,
+ 0x62b1,
+ 0x62d4,
+ 0x6350,
+ 0x22b0c,
+ 0x633d,
+ 0x62fc,
+ 0x6368,
+ 0x6383,
+ 0x63e4,
+ 0x22bf1,
+ 0x6422,
+ 0x63c5,
+ 0x63a9,
+ 0x3a2e,
+ 0x6469,
+ 0x647e,
+ 0x649d,
+ 0x6477,
+ 0x3a6c,
+ 0x656c,
+ 0x2300a,
+ 0x65e3,
+ 0x66f8,
+ 0x6649,
+ 0x3b19,
+ 0x3b08,
+ 0x3ae4,
+ 0x5192,
+ 0x5195,
+ 0x6700,
+ 0x669c,
+ 0x80ad,
+ 0x43d9,
+ 0x671b,
+ 0x6721,
+ 0x675e,
+ 0x6753,
+ 0x233c3,
+ 0x3b49,
+ 0x67fa,
+ 0x6785,
+ 0x6852,
+ 0x2346d,
+ 0x688e,
+ 0x681f,
+ 0x6914,
+ 0x3b9d,
+ 0x6942,
+ 0x69a3,
+ 0x69ea,
+ 0x6aa8,
+ 0x236a3,
+ 0x6adb,
+ 0x3c18,
+ 0x6b21,
+ 0x238a7,
+ 0x6b54,
+ 0x3c4e,
+ 0x6b72,
+ 0x6b9f,
+ 0x6bbb,
+ 0x23a8d,
+ 0x21d0b,
+ 0x23afa,
+ 0x6c4e,
+ 0x23cbc,
+ 0x6cbf,
+ 0x6ccd,
+ 0x6c67,
+ 0x6d16,
+ 0x6d3e,
+ 0x6d69,
+ 0x6d78,
+ 0x6d85,
+ 0x23d1e,
+ 0x6d34,
+ 0x6e2f,
+ 0x6e6e,
+ 0x3d33,
+ 0x6ecb,
+ 0x6ec7,
+ 0x23ed1,
+ 0x6df9,
+ 0x6f6e,
+ 0x23f5e,
+ 0x23f8e,
+ 0x6fc6,
+ 0x7039,
+ 0x701e,
+ 0x701b,
+ 0x3d96,
+ 0x704a,
+ 0x707d,
+ 0x7077,
+ 0x70ad,
+ 0x20525,
+ 0x7145,
+ 0x24263,
+ 0x719c,
+ 0x243ab,
+ 0x7228,
+ 0x7235,
+ 0x7250,
+ 0x24608,
+ 0x7280,
+ 0x7295,
+ 0x24735,
+ 0x24814,
+ 0x737a,
+ 0x738b,
+ 0x3eac,
+ 0x73a5,
+ 0x3eb8,
+ 0x7447,
+ 0x745c,
+ 0x7471,
+ 0x7485,
+ 0x74ca,
+ 0x3f1b,
+ 0x7524,
+ 0x24c36,
+ 0x753e,
+ 0x24c92,
+ 0x2219f,
+ 0x7610,
+ 0x24fa1,
+ 0x24fb8,
+ 0x25044,
+ 0x3ffc,
+ 0x4008,
+ 0x76f4,
+ 0x250f3,
+ 0x250f2,
+ 0x25119,
+ 0x25133,
+ 0x771e,
+ 0x771f,
+ 0x774a,
+ 0x4039,
+ 0x778b,
+ 0x4046,
+ 0x4096,
+ 0x2541d,
+ 0x784e,
+ 0x78cc,
+ 0x40e3,
+ 0x25626,
+ 0x2569a,
+ 0x256c5,
+ 0x79eb,
+ 0x412f,
+ 0x7a4a,
+ 0x7a4f,
+ 0x2597c,
+ 0x25aa7,
+ 0x7aee,
+ 0x4202,
+ 0x25bab,
+ 0x7bc6,
+ 0x7bc9,
+ 0x4227,
+ 0x25c80,
+ 0x7cd2,
+ 0x42a0,
+ 0x7ce8,
+ 0x7ce3,
+ 0x7d00,
+ 0x25f86,
+ 0x7d63,
+ 0x4301,
+ 0x7dc7,
+ 0x7e02,
+ 0x7e45,
+ 0x4334,
+ 0x26228,
+ 0x26247,
+ 0x4359,
+ 0x262d9,
+ 0x7f7a,
+ 0x2633e,
+ 0x7f95,
+ 0x7ffa,
+ 0x264da,
+ 0x26523,
+ 0x8060,
+ 0x265a8,
+ 0x8070,
+ 0x2335f,
+ 0x43d5,
+ 0x80b2,
+ 0x8103,
+ 0x440b,
+ 0x813e,
+ 0x5ab5,
+ 0x267a7,
+ 0x267b5,
+ 0x23393,
+ 0x2339c,
+ 0x8204,
+ 0x8f9e,
+ 0x446b,
+ 0x8291,
+ 0x828b,
+ 0x829d,
+ 0x52b3,
+ 0x82b1,
+ 0x82b3,
+ 0x82bd,
+ 0x82e6,
+ 0x26b3c,
+ 0x831d,
+ 0x8363,
+ 0x83ad,
+ 0x8323,
+ 0x83bd,
+ 0x83e7,
+ 0x8353,
+ 0x83ca,
+ 0x83cc,
+ 0x83dc,
+ 0x26c36,
+ 0x26d6b,
+ 0x26cd5,
+ 0x452b,
+ 0x84f1,
+ 0x84f3,
+ 0x8516,
+ 0x273ca,
+ 0x8564,
+ 0x26f2c,
+ 0x455d,
+ 0x4561,
+ 0x26fb1,
+ 0x270d2,
+ 0x456b,
+ 0x8650,
+ 0x8667,
+ 0x8669,
+ 0x86a9,
+ 0x8688,
+ 0x870e,
+ 0x86e2,
+ 0x8779,
+ 0x8728,
+ 0x876b,
+ 0x8786,
+ 0x45d7,
+ 0x87e1,
+ 0x8801,
+ 0x45f9,
+ 0x8860,
+ 0x27667,
+ 0x88d7,
+ 0x88de,
+ 0x4635,
+ 0x88fa,
+ 0x34bb,
+ 0x278ae,
+ 0x27966,
+ 0x46be,
+ 0x46c7,
+ 0x8aa0,
+ 0x8aed,
+ 0x8b8a,
+ 0x27ca8,
+ 0x8cab,
+ 0x8cc1,
+ 0x8d1b,
+ 0x8d77,
+ 0x27f2f,
+ 0x20804,
+ 0x8dcb,
+ 0x8dbc,
+ 0x8df0,
+ 0x208de,
+ 0x8ed4,
+ 0x8f38,
+ 0x285d2,
+ 0x285ed,
+ 0x9094,
+ 0x90f1,
+ 0x9111,
+ 0x2872e,
+ 0x911b,
+ 0x9238,
+ 0x92d7,
+ 0x92d8,
+ 0x927c,
+ 0x93f9,
+ 0x9415,
+ 0x28bfa,
+ 0x958b,
+ 0x4995,
+ 0x95b7,
+ 0x28d77,
+ 0x49e6,
+ 0x96c3,
+ 0x5db2,
+ 0x9723,
+ 0x29145,
+ 0x2921a,
+ 0x4a6e,
+ 0x4a76,
+ 0x97e0,
+ 0x2940a,
+ 0x4ab2,
+ 0x29496,
+ 0x980b,
+ 0x9829,
+ 0x295b6,
+ 0x98e2,
+ 0x4b33,
+ 0x9929,
+ 0x99a7,
+ 0x99c2,
+ 0x99fe,
+ 0x4bce,
+ 0x29b30,
+ 0x9b12,
+ 0x9c40,
+ 0x9cfd,
+ 0x4cce,
+ 0x4ced,
+ 0x9d67,
+ 0x2a0ce,
+ 0x4cf8,
+ 0x2a105,
+ 0x2a20e,
+ 0x2a291,
+ 0x4d56,
+ 0x9efe,
+ 0x9f05,
+ 0x9f0f,
+ 0x9f16,
+ 0x2a600,
+};
+
+const struct canon_node _wind_canon_table[] = {
+ {0x0, 0, 3, 0},
+ {0x0, 0, 10, 3},
+ {0x0, 0, 16, 13},
+ {0x0, 0, 15, 29},
+ {0x0, 1, 14, 44},
+ {0x2f993, 16, 16, 57},
+ {0x0, 0, 16, 57},
+ {0x0, 0, 16, 73},
+ {0x0, 8, 16, 89},
+ {0xf942, 16, 16, 97},
+ {0x2f994, 16, 16, 97},
+ {0x0, 0, 16, 97},
+ {0x0, 9, 15, 113},
+ {0x0, 5, 6, 119},
+ {0x2f9ef, 16, 16, 120},
+ {0x0, 0, 16, 120},
+ {0x0, 0, 16, 136},
+ {0x0, 0, 16, 152},
+ {0x0, 0, 1, 168},
+ {0x0, 0, 1, 169},
+ {0x0, 3, 4, 170},
+ {0x0, 4, 5, 171},
+ {0x0, 5, 6, 172},
+ {0x1f94, 16, 16, 173},
+ {0x0, 0, 16, 173},
+ {0x0, 0, 12, 189},
+ {0x0, 10, 12, 201},
+ {0x2f8f6, 16, 16, 203},
+ {0xf970, 16, 16, 203},
+ {0x0, 0, 16, 203},
+ {0x0, 2, 14, 219},
+ {0x0, 2, 6, 231},
+ {0x0, 0, 1, 235},
+ {0x0, 0, 1, 236},
+ {0x0, 6, 7, 237},
+ {0x0, 5, 6, 238},
+ {0x0, 4, 5, 239},
+ {0x6c0, 16, 16, 240},
+ {0x0, 0, 16, 240},
+ {0x0, 0, 13, 256},
+ {0x0, 9, 10, 269},
+ {0xf9ae, 16, 16, 270},
+ {0x0, 0, 16, 270},
+ {0x0, 2, 16, 286},
+ {0x0, 15, 16, 300},
+ {0xfa69, 16, 16, 301},
+ {0x0, 0, 11, 301},
+ {0x0, 1, 16, 312},
+ {0x0, 3, 14, 327},
+ {0x0, 6, 7, 338},
+ {0x2f9a4, 16, 16, 339},
+ {0x0, 4, 15, 339},
+ {0x0, 9, 10, 350},
+ {0xf9be, 16, 16, 351},
+ {0x0, 1, 12, 351},
+ {0x0, 7, 8, 362},
+ {0x2f864, 16, 16, 363},
+ {0x0, 0, 13, 363},
+ {0x0, 0, 1, 376},
+ {0x0, 0, 1, 377},
+ {0x0, 3, 4, 378},
+ {0x0, 4, 5, 379},
+ {0x0, 5, 6, 380},
+ {0x1fc2, 16, 16, 381},
+ {0x0, 0, 16, 381},
+ {0x0, 0, 16, 397},
+ {0x0, 1, 16, 413},
+ {0x0, 0, 1, 428},
+ {0x0, 3, 4, 429},
+ {0x0, 0, 1, 430},
+ {0x0, 9, 10, 431},
+ {0x0, 9, 10, 432},
+ {0x3065, 16, 16, 433},
+ {0x0, 0, 3, 433},
+ {0x0, 0, 12, 436},
+ {0x0, 3, 14, 448},
+ {0x0, 0, 1, 459},
+ {0x0, 0, 1, 460},
+ {0x0, 3, 4, 461},
+ {0x0, 3, 4, 462},
+ {0x0, 8, 9, 463},
+ {0x2244, 16, 16, 464},
+ {0x0, 0, 15, 464},
+ {0x0, 0, 12, 479},
+ {0x0, 0, 1, 491},
+ {0x0, 0, 1, 492},
+ {0x0, 3, 4, 493},
+ {0x0, 0, 1, 494},
+ {0x0, 8, 9, 495},
+ {0x1e7b, 16, 16, 496},
+ {0x0, 1, 16, 496},
+ {0x0, 0, 1, 511},
+ {0x0, 3, 4, 512},
+ {0x0, 0, 1, 513},
+ {0x0, 9, 10, 514},
+ {0x0, 9, 10, 515},
+ {0x30ba, 16, 16, 516},
+ {0x2f995, 16, 16, 516},
+ {0x0, 0, 15, 516},
+ {0x0, 0, 15, 531},
+ {0x0, 0, 1, 546},
+ {0x0, 0, 1, 547},
+ {0x0, 3, 4, 548},
+ {0x0, 0, 1, 549},
+ {0x0, 8, 9, 550},
+ {0x4df, 16, 16, 551},
+ {0x0, 0, 16, 551},
+ {0x0, 7, 8, 567},
+ {0x2f9d7, 16, 16, 568},
+ {0x0, 0, 16, 568},
+ {0x0, 14, 15, 584},
+ {0x2f86b, 16, 16, 585},
+ {0xf94a, 16, 16, 585},
+ {0x0, 4, 14, 585},
+ {0x0, 9, 13, 595},
+ {0x0, 0, 1, 599},
+ {0x0, 0, 1, 600},
+ {0x0, 13, 14, 601},
+ {0x0, 12, 13, 602},
+ {0x0, 10, 11, 603},
+ {0xddd, 16, 16, 604},
+ {0x0, 2, 16, 604},
+ {0x0, 1, 15, 618},
+ {0xf91a, 16, 16, 632},
+ {0x0, 0, 16, 632},
+ {0x0, 1, 4, 648},
+ {0x0, 9, 10, 651},
+ {0x2f943, 16, 16, 652},
+ {0x0, 0, 16, 652},
+ {0x0, 10, 11, 668},
+ {0x0, 8, 9, 669},
+ {0x2f9d3, 16, 16, 670},
+ {0x0, 3, 16, 670},
+ {0x0, 1, 16, 683},
+ {0x0, 0, 1, 698},
+ {0x0, 0, 1, 699},
+ {0x0, 3, 4, 700},
+ {0x0, 0, 3, 701},
+ {0x0, 1, 13, 704},
+ {0x10c, 16, 16, 716},
+ {0x0, 1, 16, 716},
+ {0x0, 1, 2, 731},
+ {0xf958, 16, 16, 732},
+ {0x0, 0, 1, 732},
+ {0x0, 0, 1, 733},
+ {0x0, 3, 4, 734},
+ {0x0, 0, 1, 735},
+ {0x0, 0, 9, 736},
+ {0x4e5, 16, 16, 745},
+ {0x439, 16, 16, 745},
+ {0x4e3, 16, 16, 745},
+ {0x0, 2, 15, 745},
+ {0x0, 12, 13, 758},
+ {0x2f8c7, 16, 16, 759},
+ {0x0, 0, 1, 759},
+ {0x0, 3, 4, 760},
+ {0x0, 0, 1, 761},
+ {0x0, 9, 10, 762},
+ {0x0, 9, 10, 763},
+ {0x30b4, 16, 16, 764},
+ {0x45d, 16, 16, 764},
+ {0x0, 0, 16, 764},
+ {0x0, 0, 1, 780},
+ {0x0, 0, 1, 781},
+ {0x0, 3, 4, 782},
+ {0x0, 0, 3, 783},
+ {0x0, 0, 10, 786},
+ {0x1ee8, 16, 16, 796},
+ {0x0, 0, 16, 796},
+ {0x0, 0, 1, 812},
+ {0x0, 0, 1, 813},
+ {0x0, 3, 4, 814},
+ {0x0, 0, 4, 815},
+ {0x0, 3, 14, 819},
+ {0x1eb9, 16, 16, 830},
+ {0x1eee, 16, 16, 830},
+ {0x229, 16, 16, 830},
+ {0x1eec, 16, 16, 830},
+ {0x119, 16, 16, 830},
+ {0x2fa07, 16, 16, 830},
+ {0x10a, 16, 16, 830},
+ {0x106, 16, 16, 830},
+ {0x108, 16, 16, 830},
+ {0x0, 1, 16, 830},
+ {0x0, 9, 10, 845},
+ {0x2f90e, 16, 16, 846},
+ {0x0, 0, 14, 846},
+ {0x0, 1, 16, 860},
+ {0x0, 0, 1, 875},
+ {0x0, 0, 1, 876},
+ {0x0, 3, 4, 877},
+ {0x0, 0, 2, 878},
+ {0x0, 4, 5, 880},
+ {0x1f59, 16, 16, 881},
+ {0x0, 6, 12, 881},
+ {0x0, 14, 15, 887},
+ {0x2f9f8, 16, 16, 888},
+ {0x0, 0, 11, 888},
+ {0x0, 0, 1, 899},
+ {0x0, 0, 1, 900},
+ {0x0, 3, 4, 901},
+ {0x0, 0, 4, 902},
+ {0x0, 1, 2, 906},
+ {0x212, 16, 16, 907},
+ {0x0, 0, 1, 907},
+ {0x0, 0, 1, 908},
+ {0x0, 3, 4, 909},
+ {0x0, 0, 3, 910},
+ {0x0, 1, 12, 913},
+ {0x20f, 16, 16, 924},
+ {0x0, 2, 14, 924},
+ {0x0, 0, 1, 936},
+ {0x0, 0, 1, 937},
+ {0x0, 3, 4, 938},
+ {0x0, 3, 4, 939},
+ {0x0, 8, 9, 940},
+ {0x22e1, 16, 16, 941},
+ {0x0, 0, 15, 941},
+ {0x0, 13, 14, 956},
+ {0xf967, 16, 16, 957},
+ {0x1e19, 16, 16, 957},
+ {0x0, 1, 16, 957},
+ {0x0, 10, 11, 972},
+ {0xf9f0, 16, 16, 973},
+ {0x0, 0, 15, 973},
+ {0x0, 2, 3, 988},
+ {0x2f807, 16, 16, 989},
+ {0x0, 3, 15, 989},
+ {0x0, 13, 14, 1001},
+ {0x2f8b9, 16, 16, 1002},
+ {0x0, 0, 1, 1002},
+ {0x0, 0, 1, 1003},
+ {0x0, 3, 4, 1004},
+ {0x0, 0, 4, 1005},
+ {0x0, 0, 16, 1009},
+ {0x1d0, 16, 16, 1025},
+ {0x0, 0, 14, 1025},
+ {0x0, 9, 10, 1039},
+ {0x2f974, 16, 16, 1040},
+ {0x0, 1, 12, 1040},
+ {0x0, 1, 5, 1051},
+ {0x0, 5, 6, 1055},
+ {0x2f91b, 16, 16, 1056},
+ {0x0, 0, 1, 1056},
+ {0x0, 0, 1, 1057},
+ {0x0, 3, 4, 1058},
+ {0x0, 3, 4, 1059},
+ {0x0, 8, 9, 1060},
+ {0x22e0, 16, 16, 1061},
+ {0x0, 0, 16, 1061},
+ {0x0, 1, 11, 1077},
+ {0x2f82e, 16, 16, 1087},
+ {0x0, 0, 16, 1087},
+ {0x0, 0, 1, 1103},
+ {0x0, 0, 1, 1104},
+ {0x0, 3, 4, 1105},
+ {0x0, 0, 2, 1106},
+ {0x0, 3, 5, 1108},
+ {0x1f19, 16, 16, 1110},
+ {0x0, 0, 10, 1110},
+ {0x0, 9, 10, 1120},
+ {0x2f8ce, 16, 16, 1121},
+ {0x1f18, 16, 16, 1121},
+ {0x0, 1, 15, 1121},
+ {0x1f7d, 0, 1, 1135},
+ {0x0, 0, 1, 1136},
+ {0x0, 3, 4, 1137},
+ {0x0, 4, 5, 1138},
+ {0x0, 5, 6, 1139},
+ {0x1ff4, 16, 16, 1140},
+ {0x0, 0, 16, 1140},
+ {0x0, 9, 10, 1156},
+ {0xf9dd, 16, 16, 1157},
+ {0x0, 1, 14, 1157},
+ {0x2f991, 16, 16, 1170},
+ {0x0, 2, 16, 1170},
+ {0x0, 3, 4, 1184},
+ {0xfa0b, 16, 16, 1185},
+ {0x0, 6, 16, 1185},
+ {0x0, 0, 1, 1195},
+ {0x0, 0, 1, 1196},
+ {0x0, 3, 4, 1197},
+ {0x0, 0, 5, 1198},
+ {0x0, 2, 3, 1203},
+ {0x1fcf, 16, 16, 1204},
+ {0x0, 0, 15, 1204},
+ {0x0, 8, 9, 1219},
+ {0x2f9bc, 16, 16, 1220},
+ {0x0, 6, 7, 1220},
+ {0x0, 3, 4, 1221},
+ {0x2f838, 16, 16, 1222},
+ {0x0, 0, 7, 1222},
+ {0x0, 9, 10, 1229},
+ {0x0, 2, 3, 1230},
+ {0x2f88f, 16, 16, 1231},
+ {0x0, 2, 6, 1231},
+ {0x0, 0, 1, 1235},
+ {0x0, 0, 1, 1236},
+ {0x0, 3, 4, 1237},
+ {0x0, 3, 4, 1238},
+ {0x0, 8, 9, 1239},
+ {0x22ec, 16, 16, 1240},
+ {0x0, 0, 7, 1240},
+ {0x2f88d, 16, 16, 1247},
+ {0x0, 4, 16, 1247},
+ {0x0, 14, 15, 1259},
+ {0xfa3f, 16, 16, 1260},
+ {0x2f98f, 16, 16, 1260},
+ {0x0, 8, 12, 1260},
+ {0x0, 11, 12, 1264},
+ {0x2f9ee, 16, 16, 1265},
+ {0xfa35, 16, 16, 1265},
+ {0x0, 0, 1, 1265},
+ {0x0, 0, 1, 1266},
+ {0x0, 3, 4, 1267},
+ {0x0, 0, 3, 1268},
+ {0x0, 1, 2, 1271},
+ {0x203, 16, 16, 1272},
+ {0x0, 6, 8, 1272},
+ {0x0, 0, 1, 1274},
+ {0x0, 0, 1, 1275},
+ {0x0, 13, 14, 1276},
+ {0x0, 3, 6, 1277},
+ {0x0, 7, 8, 1280},
+ {0xd4c, 16, 16, 1281},
+ {0x0, 0, 15, 1281},
+ {0x0, 2, 3, 1296},
+ {0xfa20, 16, 16, 1297},
+ {0x0, 3, 13, 1297},
+ {0x0, 0, 2, 1307},
+ {0x0, 0, 1, 1309},
+ {0x0, 0, 1, 1310},
+ {0x0, 3, 4, 1311},
+ {0x0, 0, 1, 1312},
+ {0x0, 2, 7, 1313},
+ {0x1eac, 16, 16, 1318},
+ {0x0, 0, 16, 1318},
+ {0x0, 3, 4, 1334},
+ {0x2f874, 16, 16, 1335},
+ {0x1eb6, 16, 16, 1335},
+ {0x0, 0, 1, 1335},
+ {0x0, 0, 1, 1336},
+ {0x0, 3, 4, 1337},
+ {0x0, 4, 5, 1338},
+ {0x0, 5, 6, 1339},
+ {0x1f9c, 16, 16, 1340},
+ {0x0, 2, 12, 1340},
+ {0x0, 6, 16, 1350},
+ {0x0, 0, 1, 1360},
+ {0x0, 0, 1, 1361},
+ {0x0, 3, 4, 1362},
+ {0x0, 0, 1, 1363},
+ {0x0, 6, 7, 1364},
+ {0x1e1d, 16, 16, 1365},
+ {0x0, 1, 14, 1365},
+ {0x0, 0, 14, 1378},
+ {0x2f918, 16, 16, 1392},
+ {0x0, 2, 14, 1392},
+ {0x0, 9, 10, 1404},
+ {0x2f975, 16, 16, 1405},
+ {0x0, 1, 10, 1405},
+ {0x0, 11, 12, 1414},
+ {0xfa0a, 16, 16, 1415},
+ {0x0, 0, 16, 1415},
+ {0x0, 2, 4, 1431},
+ {0xf992, 16, 16, 1433},
+ {0xfa47, 16, 16, 1433},
+ {0x0, 2, 15, 1433},
+ {0x0, 13, 16, 1446},
+ {0xfa53, 16, 16, 1449},
+ {0xfa52, 16, 16, 1449},
+ {0xfa1b, 16, 16, 1449},
+ {0x0, 0, 1, 1449},
+ {0x0, 3, 4, 1450},
+ {0x0, 0, 1, 1451},
+ {0x0, 9, 10, 1452},
+ {0x0, 9, 10, 1453},
+ {0x30b2, 16, 16, 1454},
+ {0x0, 0, 1, 1454},
+ {0x0, 0, 1, 1455},
+ {0x0, 3, 4, 1456},
+ {0x0, 0, 5, 1457},
+ {0x0, 0, 2, 1462},
+ {0x1fca, 16, 16, 1464},
+ {0x389, 16, 16, 1464},
+ {0x0, 1, 16, 1464},
+ {0x0, 12, 13, 1479},
+ {0x2f93e, 16, 16, 1480},
+ {0x0, 3, 15, 1480},
+ {0x0, 3, 9, 1492},
+ {0x2f968, 16, 16, 1498},
+ {0x0, 0, 1, 1498},
+ {0x0, 0, 1, 1499},
+ {0x0, 3, 4, 1500},
+ {0x0, 0, 5, 1501},
+ {0x0, 2, 6, 1506},
+ {0x1f2e, 16, 16, 1510},
+ {0x1f98, 16, 16, 1510},
+ {0x0, 6, 12, 1510},
+ {0x0, 0, 1, 1516},
+ {0x2f804, 16, 16, 1517},
+ {0x2f919, 16, 16, 1517},
+ {0x2f835, 16, 16, 1517},
+ {0x0, 1, 2, 1517},
+ {0x0, 5, 6, 1518},
+ {0x2f824, 16, 16, 1519},
+ {0x0, 0, 16, 1519},
+ {0x1fe3, 16, 16, 1535},
+ {0x0, 2, 4, 1535},
+ {0x0, 0, 1, 1537},
+ {0x0, 0, 1, 1538},
+ {0x0, 3, 4, 1539},
+ {0x0, 0, 1, 1540},
+ {0x0, 7, 8, 1541},
+ {0x1e69, 16, 16, 1542},
+ {0x1fbe, 0, 1, 1542},
+ {0x0, 0, 16, 1543},
+ {0x0, 3, 4, 1559},
+ {0x2f96c, 16, 16, 1560},
+ {0x0, 0, 15, 1560},
+ {0x0, 10, 11, 1575},
+ {0x2f85d, 16, 16, 1576},
+ {0x0, 3, 11, 1576},
+ {0x2f836, 16, 16, 1584},
+ {0x0, 12, 13, 1584},
+ {0x2f92f, 16, 16, 1585},
+ {0x0, 0, 10, 1585},
+ {0x0, 0, 1, 1595},
+ {0x0, 0, 1, 1596},
+ {0x0, 3, 4, 1597},
+ {0x0, 0, 5, 1598},
+ {0x0, 2, 3, 1603},
+ {0x1f5f, 16, 16, 1604},
+ {0x0, 2, 3, 1604},
+ {0x0, 15, 16, 1605},
+ {0x2f9d8, 16, 16, 1606},
+ {0x0, 1, 16, 1606},
+ {0x0, 0, 12, 1621},
+ {0xf932, 16, 16, 1633},
+ {0x0, 0, 16, 1633},
+ {0x0, 11, 12, 1649},
+ {0xfa6a, 16, 16, 1650},
+ {0x0, 2, 16, 1650},
+ {0x0, 2, 4, 1664},
+ {0xfa68, 16, 16, 1666},
+ {0x0, 2, 16, 1666},
+ {0x212b, 0, 1, 1680},
+ {0x0, 0, 1, 1681},
+ {0x0, 3, 4, 1682},
+ {0x0, 0, 1, 1683},
+ {0x0, 1, 2, 1684},
+ {0x1fa, 16, 16, 1685},
+ {0x0, 1, 16, 1685},
+ {0x0, 0, 1, 1700},
+ {0x0, 3, 4, 1701},
+ {0x0, 0, 1, 1702},
+ {0x0, 9, 10, 1703},
+ {0x0, 9, 10, 1704},
+ {0x30c9, 16, 16, 1705},
+ {0xf9ea, 16, 16, 1705},
+ {0x0, 2, 16, 1705},
+ {0x0, 0, 1, 1719},
+ {0x0, 0, 1, 1720},
+ {0x0, 3, 4, 1721},
+ {0x0, 0, 1, 1722},
+ {0x0, 1, 2, 1723},
+ {0x1e09, 16, 16, 1724},
+ {0x0, 1, 11, 1724},
+ {0x0, 2, 3, 1734},
+ {0x2f8e1, 16, 16, 1735},
+ {0x0, 0, 14, 1735},
+ {0x0, 0, 1, 1749},
+ {0x0, 3, 4, 1750},
+ {0x0, 0, 1, 1751},
+ {0x0, 9, 10, 1752},
+ {0x0, 9, 10, 1753},
+ {0x30f9, 16, 16, 1754},
+ {0x0, 13, 14, 1754},
+ {0xf986, 16, 16, 1755},
+ {0x0, 0, 1, 1755},
+ {0x0, 0, 1, 1756},
+ {0x0, 3, 4, 1757},
+ {0x0, 0, 4, 1758},
+ {0x0, 7, 8, 1762},
+ {0x1e03, 16, 16, 1763},
+ {0x0, 0, 1, 1763},
+ {0x0, 0, 1, 1764},
+ {0x0, 3, 4, 1765},
+ {0x0, 0, 1, 1766},
+ {0x0, 1, 5, 1767},
+ {0x1fd, 16, 16, 1771},
+ {0x0, 0, 1, 1771},
+ {0x0, 0, 1, 1772},
+ {0x0, 3, 4, 1773},
+ {0x0, 3, 4, 1774},
+ {0x0, 8, 9, 1775},
+ {0x2281, 16, 16, 1776},
+ {0x1e3, 16, 16, 1776},
+ {0x0, 2, 12, 1776},
+ {0x0, 0, 1, 1786},
+ {0x0, 0, 1, 1787},
+ {0x0, 3, 4, 1788},
+ {0x0, 3, 4, 1789},
+ {0x0, 8, 9, 1790},
+ {0x22af, 16, 16, 1791},
+ {0xf96b, 16, 16, 1791},
+ {0x0, 2, 16, 1791},
+ {0x0, 3, 10, 1805},
+ {0x0, 2, 3, 1812},
+ {0x2f937, 16, 16, 1813},
+ {0x0, 2, 12, 1813},
+ {0x0, 2, 3, 1823},
+ {0xf98d, 16, 16, 1824},
+ {0x0, 6, 16, 1824},
+ {0x0, 0, 1, 1834},
+ {0x0, 3, 4, 1835},
+ {0x0, 0, 1, 1836},
+ {0x0, 9, 10, 1837},
+ {0x0, 9, 10, 1838},
+ {0x30b0, 16, 16, 1839},
+ {0x0, 0, 1, 1839},
+ {0x0, 0, 1, 1840},
+ {0x0, 3, 4, 1841},
+ {0x0, 0, 3, 1842},
+ {0x0, 1, 8, 1845},
+ {0x1e3e, 16, 16, 1852},
+ {0x1e40, 16, 16, 1852},
+ {0x0, 8, 9, 1852},
+ {0xfa65, 16, 16, 1853},
+ {0x0, 6, 16, 1853},
+ {0x0, 10, 11, 1863},
+ {0xf93a, 16, 16, 1864},
+ {0x0, 0, 16, 1864},
+ {0x0, 0, 1, 1880},
+ {0x0, 0, 1, 1881},
+ {0x0, 3, 4, 1882},
+ {0x0, 4, 5, 1883},
+ {0x0, 5, 6, 1884},
+ {0x1faa, 16, 16, 1885},
+ {0x0, 0, 1, 1885},
+ {0x0, 2, 4, 1886},
+ {0x2001, 16, 16, 1888},
+ {0x2000, 16, 16, 1888},
+ {0x0, 0, 16, 1888},
+ {0x0, 11, 12, 1904},
+ {0x0, 8, 9, 1905},
+ {0x2f897, 16, 16, 1906},
+ {0x0, 2, 15, 1906},
+ {0x0, 4, 5, 1919},
+ {0x2f934, 16, 16, 1920},
+ {0x0, 1, 13, 1920},
+ {0x0, 11, 12, 1932},
+ {0x2f848, 16, 16, 1933},
+ {0x0, 0, 16, 1933},
+ {0x0, 0, 1, 1949},
+ {0x0, 0, 1, 1950},
+ {0x0, 3, 4, 1951},
+ {0x0, 0, 5, 1952},
+ {0x0, 2, 6, 1957},
+ {0x1f07, 16, 16, 1961},
+ {0x1f81, 16, 16, 1961},
+ {0x0, 0, 1, 1961},
+ {0x0, 0, 1, 1962},
+ {0x0, 3, 4, 1963},
+ {0x0, 0, 4, 1964},
+ {0x0, 7, 13, 1968},
+ {0x1e0b, 16, 16, 1974},
+ {0x0, 0, 1, 1974},
+ {0x0, 0, 1, 1975},
+ {0x0, 3, 4, 1976},
+ {0x0, 4, 5, 1977},
+ {0x0, 5, 6, 1978},
+ {0x1f9b, 16, 16, 1979},
+ {0x0, 0, 1, 1979},
+ {0x0, 0, 1, 1980},
+ {0x0, 3, 4, 1981},
+ {0x0, 0, 3, 1982},
+ {0x0, 3, 4, 1985},
+ {0x1e43, 16, 16, 1986},
+ {0x0, 8, 9, 1986},
+ {0x0, 0, 1, 1987},
+ {0x0, 0, 1, 1988},
+ {0x0, 3, 4, 1989},
+ {0x0, 0, 5, 1990},
+ {0x0, 0, 2, 1995},
+ {0x1fed, 16, 16, 1997},
+ {0x385, 16, 16, 1997},
+ {0x0, 2, 4, 1997},
+ {0x0, 0, 1, 1999},
+ {0x0, 0, 1, 2000},
+ {0x0, 3, 4, 2001},
+ {0x0, 0, 1, 2002},
+ {0x0, 0, 2, 2003},
+ {0x1e17, 16, 16, 2005},
+ {0x0, 1, 15, 2005},
+ {0x0, 14, 15, 2019},
+ {0x2f95f, 16, 16, 2020},
+ {0x0, 0, 1, 2020},
+ {0x0, 0, 1, 2021},
+ {0x0, 3, 4, 2022},
+ {0x0, 0, 5, 2023},
+ {0x0, 0, 2, 2028},
+ {0x1f53, 16, 16, 2030},
+ {0x1f55, 16, 16, 2030},
+ {0x0, 0, 1, 2030},
+ {0x0, 0, 1, 2031},
+ {0x0, 3, 4, 2032},
+ {0x0, 3, 4, 2033},
+ {0x0, 8, 9, 2034},
+ {0x22ad, 16, 16, 2035},
+ {0x0, 2, 12, 2035},
+ {0x0, 0, 1, 2045},
+ {0x0, 3, 4, 2046},
+ {0x0, 0, 1, 2047},
+ {0x0, 9, 10, 2048},
+ {0x0, 9, 11, 2049},
+ {0x3079, 16, 16, 2051},
+ {0x0, 0, 1, 2051},
+ {0x0, 3, 4, 2052},
+ {0x0, 0, 1, 2053},
+ {0x0, 9, 10, 2054},
+ {0x0, 9, 11, 2055},
+ {0x307d, 16, 16, 2057},
+ {0x0, 3, 8, 2057},
+ {0x1e5a, 16, 16, 2062},
+ {0x156, 16, 16, 2062},
+ {0x0, 12, 13, 2062},
+ {0xf982, 16, 16, 2063},
+ {0x0, 10, 12, 2063},
+ {0x0, 0, 1, 2065},
+ {0x0, 0, 1, 2066},
+ {0x0, 3, 4, 2067},
+ {0x0, 0, 1, 2068},
+ {0x0, 4, 5, 2069},
+ {0x1ec, 16, 16, 2070},
+ {0x0, 4, 14, 2070},
+ {0x0, 3, 4, 2080},
+ {0xfa64, 16, 16, 2081},
+ {0x0, 0, 1, 2081},
+ {0x0, 0, 1, 2082},
+ {0x0, 3, 4, 2083},
+ {0x0, 4, 5, 2084},
+ {0x0, 5, 6, 2085},
+ {0x1f8e, 16, 16, 2086},
+ {0x0, 7, 8, 2086},
+ {0xf99c, 16, 16, 2087},
+ {0x0, 0, 10, 2087},
+ {0x0, 0, 1, 2097},
+ {0x0, 0, 1, 2098},
+ {0x0, 3, 4, 2099},
+ {0x0, 0, 5, 2100},
+ {0x0, 0, 2, 2105},
+ {0x1f3d, 16, 16, 2107},
+ {0x0, 0, 1, 2107},
+ {0x0, 3, 4, 2108},
+ {0x0, 0, 5, 2109},
+ {0x0, 2, 3, 2114},
+ {0x1fd6, 16, 16, 2115},
+ {0x0, 6, 15, 2115},
+ {0x0, 0, 1, 2124},
+ {0x0, 0, 1, 2125},
+ {0x0, 3, 4, 2126},
+ {0x0, 0, 5, 2127},
+ {0x0, 0, 2, 2132},
+ {0x1fde, 16, 16, 2134},
+ {0x1fdd, 16, 16, 2134},
+ {0x0, 0, 1, 2134},
+ {0x0, 0, 1, 2135},
+ {0x0, 3, 4, 2136},
+ {0x0, 4, 5, 2137},
+ {0x0, 5, 6, 2138},
+ {0x1f95, 16, 16, 2139},
+ {0x0, 4, 8, 2139},
+ {0xf90b, 16, 16, 2143},
+ {0x2f846, 16, 16, 2143},
+ {0x0, 3, 6, 2143},
+ {0x0, 0, 1, 2146},
+ {0x0, 0, 1, 2147},
+ {0x0, 3, 4, 2148},
+ {0x0, 3, 4, 2149},
+ {0x0, 8, 9, 2150},
+ {0x2224, 16, 16, 2151},
+ {0x0, 0, 16, 2151},
+ {0x0, 12, 13, 2167},
+ {0xfa08, 16, 16, 2168},
+ {0x0, 5, 6, 2168},
+ {0x2f905, 16, 16, 2169},
+ {0x0, 10, 11, 2169},
+ {0xf995, 16, 16, 2170},
+ {0x0, 0, 1, 2170},
+ {0x0, 3, 4, 2171},
+ {0x0, 0, 1, 2172},
+ {0x0, 9, 10, 2173},
+ {0x0, 9, 10, 2174},
+ {0x30c7, 16, 16, 2175},
+ {0x0, 0, 1, 2175},
+ {0x0, 0, 1, 2176},
+ {0x0, 3, 4, 2177},
+ {0x0, 0, 5, 2178},
+ {0x0, 0, 2, 2183},
+ {0x1f22, 16, 16, 2185},
+ {0x0, 5, 11, 2185},
+ {0xf97f, 16, 16, 2191},
+ {0x0, 9, 10, 2191},
+ {0x2fa00, 16, 16, 2192},
+ {0x0, 7, 16, 2192},
+ {0x0, 2, 11, 2201},
+ {0xf9e6, 16, 16, 2210},
+ {0x0, 1, 16, 2210},
+ {0x0, 10, 11, 2225},
+ {0xfa17, 16, 16, 2226},
+ {0xfa5a, 16, 16, 2226},
+ {0x0, 10, 12, 2226},
+ {0x0, 0, 1, 2228},
+ {0x0, 0, 1, 2229},
+ {0x0, 3, 4, 2230},
+ {0x0, 0, 1, 2231},
+ {0x0, 4, 5, 2232},
+ {0x1e5d, 16, 16, 2233},
+ {0x0, 7, 10, 2233},
+ {0x2f9b5, 16, 16, 2236},
+ {0x2f9b6, 16, 16, 2236},
+ {0x0, 0, 12, 2236},
+ {0x0, 0, 16, 2248},
+ {0xf997, 16, 16, 2264},
+ {0x0, 1, 12, 2264},
+ {0x0, 11, 12, 2275},
+ {0x0, 6, 7, 2276},
+ {0x2fa01, 16, 16, 2277},
+ {0x0, 10, 16, 2277},
+ {0x0, 8, 15, 2283},
+ {0xfa22, 16, 16, 2290},
+ {0x0, 0, 10, 2290},
+ {0x0, 0, 1, 2300},
+ {0x0, 0, 1, 2301},
+ {0x0, 3, 4, 2302},
+ {0x0, 0, 1, 2303},
+ {0x0, 0, 2, 2304},
+ {0x1f4a, 16, 16, 2306},
+ {0x0, 4, 13, 2306},
+ {0x0, 6, 7, 2315},
+ {0x0, 0, 1, 2316},
+ {0x0, 0, 1, 2317},
+ {0x0, 12, 13, 2318},
+ {0x0, 5, 6, 2319},
+ {0x0, 6, 7, 2320},
+ {0xc48, 16, 16, 2321},
+ {0x2f976, 16, 16, 2321},
+ {0x0, 15, 16, 2321},
+ {0xf97c, 16, 16, 2322},
+ {0x0, 2, 13, 2322},
+ {0x0, 4, 5, 2333},
+ {0xf930, 16, 16, 2334},
+ {0x212a, 0, 1, 2334},
+ {0x0, 0, 1, 2335},
+ {0x0, 3, 4, 2336},
+ {0x0, 0, 4, 2337},
+ {0x0, 1, 2, 2341},
+ {0x1e34, 16, 16, 2342},
+ {0x0, 2, 11, 2342},
+ {0x0, 3, 4, 2351},
+ {0x2f97c, 16, 16, 2352},
+ {0x0, 2, 3, 2352},
+ {0x2f85f, 16, 16, 2353},
+ {0x0, 0, 1, 2353},
+ {0x0, 0, 1, 2354},
+ {0x0, 3, 4, 2355},
+ {0x0, 0, 1, 2356},
+ {0x0, 6, 9, 2357},
+ {0x4d1, 16, 16, 2360},
+ {0x0, 1, 2, 2360},
+ {0xfa55, 16, 16, 2361},
+ {0x0, 5, 14, 2361},
+ {0x0, 15, 16, 2370},
+ {0x0, 10, 11, 2371},
+ {0x2f9ed, 16, 16, 2372},
+ {0x2f97d, 16, 16, 2372},
+ {0x0, 9, 10, 2372},
+ {0xf90e, 16, 16, 2373},
+ {0x0, 0, 1, 2373},
+ {0x0, 0, 1, 2374},
+ {0x0, 3, 4, 2375},
+ {0x0, 0, 5, 2376},
+ {0x0, 0, 2, 2381},
+ {0x1f0a, 16, 16, 2383},
+ {0x1f0c, 16, 16, 2383},
+ {0x0, 0, 1, 2383},
+ {0x0, 0, 1, 2384},
+ {0x0, 3, 4, 2385},
+ {0x0, 0, 5, 2386},
+ {0x0, 2, 6, 2391},
+ {0x1f67, 16, 16, 2395},
+ {0x0, 0, 1, 2395},
+ {0x0, 0, 1, 2396},
+ {0x0, 3, 4, 2397},
+ {0x0, 0, 3, 2398},
+ {0x0, 7, 8, 2401},
+ {0xe7, 16, 16, 2402},
+ {0x1fa1, 16, 16, 2402},
+ {0x1eea, 16, 16, 2402},
+ {0x0, 5, 11, 2402},
+ {0x2f978, 16, 16, 2408},
+ {0x0, 2, 3, 2408},
+ {0x0, 0, 1, 2409},
+ {0x0, 0, 1, 2410},
+ {0x0, 3, 4, 2411},
+ {0x0, 0, 1, 2412},
+ {0x0, 1, 9, 2413},
+ {0x3d4, 16, 16, 2421},
+ {0x0, 4, 14, 2421},
+ {0x0, 12, 13, 2431},
+ {0x2f91e, 16, 16, 2432},
+ {0x3d3, 16, 16, 2432},
+ {0x0, 3, 14, 2432},
+ {0x0, 7, 9, 2443},
+ {0x2f9e9, 16, 16, 2445},
+ {0x0, 0, 1, 2445},
+ {0x0, 0, 1, 2446},
+ {0x0, 3, 4, 2447},
+ {0x0, 0, 3, 2448},
+ {0x0, 0, 10, 2451},
+ {0x176, 16, 16, 2461},
+ {0xdd, 16, 16, 2461},
+ {0x1ef2, 16, 16, 2461},
+ {0x1e8e, 16, 16, 2461},
+ {0x232, 16, 16, 2461},
+ {0x0, 6, 16, 2461},
+ {0x0, 0, 1, 2471},
+ {0x0, 3, 4, 2472},
+ {0x0, 0, 1, 2473},
+ {0x0, 9, 10, 2474},
+ {0x0, 9, 10, 2475},
+ {0x3094, 16, 16, 2476},
+ {0x1ef6, 16, 16, 2476},
+ {0x178, 16, 16, 2476},
+ {0x0, 0, 1, 2476},
+ {0x0, 0, 1, 2477},
+ {0x0, 3, 4, 2478},
+ {0x0, 0, 1, 2479},
+ {0x0, 7, 8, 2480},
+ {0x1e68, 16, 16, 2481},
+ {0x2f9e8, 16, 16, 2481},
+ {0x0, 13, 14, 2481},
+ {0x2f999, 16, 16, 2482},
+ {0x0, 0, 1, 2482},
+ {0x0, 0, 1, 2483},
+ {0x0, 3, 4, 2484},
+ {0x0, 0, 3, 2485},
+ {0x0, 0, 9, 2488},
+ {0x1e82, 16, 16, 2497},
+ {0x0, 4, 16, 2497},
+ {0x0, 14, 15, 2509},
+ {0x2f94e, 16, 16, 2510},
+ {0x174, 16, 16, 2510},
+ {0x1e86, 16, 16, 2510},
+ {0x0, 0, 1, 2510},
+ {0x0, 0, 1, 2511},
+ {0x0, 3, 4, 2512},
+ {0x0, 0, 1, 2513},
+ {0x0, 4, 5, 2514},
+ {0x1de, 16, 16, 2515},
+ {0xf9af, 16, 16, 2515},
+ {0x0, 2, 15, 2515},
+ {0x0, 3, 4, 2528},
+ {0x2f89b, 16, 16, 2529},
+ {0x0, 3, 5, 2529},
+ {0x1f28, 16, 16, 2531},
+ {0x1f29, 16, 16, 2531},
+ {0x0, 8, 16, 2531},
+ {0x0, 10, 11, 2539},
+ {0x2f8f9, 16, 16, 2540},
+ {0x0, 10, 11, 2540},
+ {0x2f89c, 16, 16, 2541},
+ {0x0, 1, 2, 2541},
+ {0x1e07, 16, 16, 2542},
+ {0x0, 0, 1, 2542},
+ {0x0, 3, 4, 2543},
+ {0x0, 0, 1, 2544},
+ {0x0, 9, 10, 2545},
+ {0x0, 9, 11, 2546},
+ {0x30d0, 16, 16, 2548},
+ {0x0, 11, 12, 2548},
+ {0x2f9d6, 16, 16, 2549},
+ {0x0, 0, 13, 2549},
+ {0x0, 0, 15, 2562},
+ {0xfa3c, 16, 16, 2577},
+ {0x0, 7, 8, 2577},
+ {0x2f92e, 16, 16, 2578},
+ {0x0, 0, 1, 2578},
+ {0x0, 3, 4, 2579},
+ {0x0, 0, 1, 2580},
+ {0x0, 9, 10, 2581},
+ {0x0, 9, 10, 2582},
+ {0x30ae, 16, 16, 2583},
+ {0x0, 1, 16, 2583},
+ {0x0, 0, 1, 2598},
+ {0x0, 3, 4, 2599},
+ {0x0, 0, 1, 2600},
+ {0x0, 9, 10, 2601},
+ {0x0, 9, 10, 2602},
+ {0x3058, 16, 16, 2603},
+ {0x0, 0, 1, 2603},
+ {0x0, 0, 1, 2604},
+ {0x0, 3, 4, 2605},
+ {0x0, 0, 4, 2606},
+ {0x0, 0, 16, 2610},
+ {0xcb, 16, 16, 2626},
+ {0x1eba, 16, 16, 2626},
+ {0xca, 16, 16, 2626},
+ {0x1ebc, 16, 16, 2626},
+ {0xc8, 16, 16, 2626},
+ {0xc9, 16, 16, 2626},
+ {0x114, 16, 16, 2626},
+ {0x116, 16, 16, 2626},
+ {0x112, 16, 16, 2626},
+ {0xf94b, 16, 16, 2626},
+ {0x2f877, 16, 16, 2626},
+ {0xf9df, 16, 16, 2626},
+ {0xfa3b, 16, 16, 2626},
+ {0x0, 0, 1, 2626},
+ {0x0, 0, 1, 2627},
+ {0x0, 3, 4, 2628},
+ {0x0, 0, 1, 2629},
+ {0x0, 6, 7, 2630},
+ {0x1e1c, 16, 16, 2631},
+ {0x0, 4, 16, 2631},
+ {0x0, 4, 5, 2643},
+ {0x2f93d, 16, 16, 2644},
+ {0x0, 0, 1, 2644},
+ {0x0, 0, 1, 2645},
+ {0x0, 3, 4, 2646},
+ {0x0, 0, 1, 2647},
+ {0x0, 1, 2, 2648},
+ {0x1fb, 16, 16, 2649},
+ {0x0, 6, 7, 2649},
+ {0x0, 13, 14, 2650},
+ {0x2f8e3, 16, 16, 2651},
+ {0x0, 2, 8, 2651},
+ {0x2f85b, 16, 16, 2657},
+ {0x2f85a, 16, 16, 2657},
+ {0x307c, 16, 16, 2657},
+ {0x0, 0, 1, 2657},
+ {0x0, 0, 1, 2658},
+ {0x0, 3, 4, 2659},
+ {0x0, 0, 5, 2660},
+ {0x0, 2, 6, 2665},
+ {0x1f06, 16, 16, 2669},
+ {0x11a, 16, 16, 2669},
+ {0x204, 16, 16, 2669},
+ {0x1f80, 16, 16, 2669},
+ {0x307a, 16, 16, 2669},
+ {0x0, 0, 1, 2669},
+ {0x0, 8, 9, 2670},
+ {0x2f923, 16, 16, 2671},
+ {0x0, 3, 4, 2671},
+ {0x2f944, 16, 16, 2672},
+ {0x0, 10, 11, 2672},
+ {0xf94d, 16, 16, 2673},
+ {0x0, 3, 4, 2673},
+ {0x1ef0, 16, 16, 2674},
+ {0x0, 11, 12, 2674},
+ {0xf9d4, 16, 16, 2675},
+ {0x0, 0, 16, 2675},
+ {0x113, 16, 16, 2691},
+ {0x115, 16, 16, 2691},
+ {0x117, 16, 16, 2691},
+ {0xe8, 16, 16, 2691},
+ {0xe9, 16, 16, 2691},
+ {0xea, 16, 16, 2691},
+ {0x1ebd, 16, 16, 2691},
+ {0x0, 0, 1, 2691},
+ {0x0, 0, 1, 2692},
+ {0x0, 3, 4, 2693},
+ {0x0, 0, 1, 2694},
+ {0x0, 1, 2, 2695},
+ {0x1e08, 16, 16, 2696},
+ {0xeb, 16, 16, 2696},
+ {0x1ebb, 16, 16, 2696},
+ {0x0, 12, 14, 2696},
+ {0x0, 0, 1, 2698},
+ {0x0, 0, 1, 2699},
+ {0x0, 3, 4, 2700},
+ {0x0, 0, 1, 2701},
+ {0x0, 0, 2, 2702},
+ {0x1e52, 16, 16, 2704},
+ {0x0, 9, 14, 2704},
+ {0x0, 0, 5, 2709},
+ {0x0, 0, 1, 2714},
+ {0x0, 0, 1, 2715},
+ {0x0, 3, 4, 2716},
+ {0x0, 3, 4, 2717},
+ {0x0, 8, 9, 2718},
+ {0x21cf, 16, 16, 2719},
+ {0x0, 0, 1, 2719},
+ {0x0, 0, 1, 2720},
+ {0x0, 3, 4, 2721},
+ {0x0, 0, 1, 2722},
+ {0x0, 2, 3, 2723},
+ {0x134, 16, 16, 2724},
+ {0x0, 0, 1, 2724},
+ {0x0, 0, 1, 2725},
+ {0x0, 3, 4, 2726},
+ {0x0, 0, 5, 2727},
+ {0x0, 0, 2, 2732},
+ {0x1f54, 16, 16, 2734},
+ {0x1f52, 16, 16, 2734},
+ {0x0, 1, 2, 2734},
+ {0x1e5e, 16, 16, 2735},
+ {0x0, 8, 9, 2735},
+ {0xf99f, 16, 16, 2736},
+ {0x0, 1, 5, 2736},
+ {0x0, 14, 15, 2740},
+ {0x2f8f2, 16, 16, 2741},
+ {0x205, 16, 16, 2741},
+ {0x11b, 16, 16, 2741},
+ {0x2f88b, 16, 16, 2741},
+ {0x2f88c, 16, 16, 2741},
+ {0x0, 3, 8, 2741},
+ {0x2f81e, 16, 16, 2746},
+ {0x0, 0, 1, 2746},
+ {0x0, 0, 1, 2747},
+ {0x0, 3, 4, 2748},
+ {0x0, 0, 5, 2749},
+ {0x0, 3, 5, 2754},
+ {0x1f01, 16, 16, 2756},
+ {0xfa00, 16, 16, 2756},
+ {0x0, 3, 16, 2756},
+ {0x2f830, 16, 16, 2769},
+ {0x0, 2, 13, 2769},
+ {0x0, 0, 4, 2780},
+ {0x0, 0, 1, 2784},
+ {0x0, 0, 1, 2785},
+ {0x0, 9, 10, 2786},
+ {0x0, 3, 4, 2787},
+ {0x0, 12, 13, 2788},
+ {0x931, 16, 16, 2789},
+ {0x2f833, 16, 16, 2789},
+ {0x0, 0, 1, 2789},
+ {0x0, 0, 1, 2790},
+ {0x0, 3, 4, 2791},
+ {0x0, 0, 1, 2792},
+ {0x0, 8, 9, 2793},
+ {0x1e7a, 16, 16, 2794},
+ {0x0, 14, 15, 2794},
+ {0xf9d0, 16, 16, 2795},
+ {0x0, 9, 14, 2795},
+ {0x2f847, 16, 16, 2800},
+ {0x0, 13, 14, 2800},
+ {0x0, 2, 3, 2801},
+ {0x2f9b1, 16, 16, 2802},
+ {0x0, 4, 13, 2802},
+ {0x0, 7, 8, 2811},
+ {0x0, 0, 1, 2812},
+ {0x0, 0, 1, 2813},
+ {0x0, 11, 12, 2814},
+ {0x0, 3, 6, 2815},
+ {0x0, 14, 15, 2818},
+ {0xb4b, 16, 16, 2819},
+ {0x0, 6, 8, 2819},
+ {0x0, 0, 1, 2821},
+ {0x0, 0, 1, 2822},
+ {0x0, 3, 4, 2823},
+ {0x0, 0, 1, 2824},
+ {0x0, 4, 5, 2825},
+ {0x1e39, 16, 16, 2826},
+ {0x0, 0, 1, 2826},
+ {0x0, 0, 1, 2827},
+ {0x0, 3, 4, 2828},
+ {0x0, 0, 1, 2829},
+ {0x0, 2, 13, 2830},
+ {0x135, 16, 16, 2841},
+ {0x0, 13, 14, 2841},
+ {0x2f9d0, 16, 16, 2842},
+ {0x0, 4, 14, 2842},
+ {0x0, 0, 15, 2852},
+ {0x0, 4, 7, 2867},
+ {0x2f87d, 16, 16, 2870},
+ {0x2f87b, 16, 16, 2870},
+ {0x0, 7, 8, 2870},
+ {0x0, 0, 1, 2871},
+ {0x0, 0, 1, 2872},
+ {0x0, 9, 10, 2873},
+ {0x0, 11, 14, 2874},
+ {0x0, 14, 15, 2877},
+ {0x9cb, 16, 16, 2878},
+ {0x0, 1, 6, 2878},
+ {0x0, 0, 1, 2883},
+ {0x0, 0, 1, 2884},
+ {0x0, 3, 4, 2885},
+ {0x0, 3, 4, 2886},
+ {0x0, 8, 9, 2887},
+ {0x2270, 16, 16, 2888},
+ {0x0, 5, 9, 2888},
+ {0xf959, 16, 16, 2892},
+ {0xfa36, 16, 16, 2892},
+ {0x0, 0, 1, 2892},
+ {0x0, 0, 1, 2893},
+ {0x0, 3, 4, 2894},
+ {0x0, 3, 4, 2895},
+ {0x0, 8, 9, 2896},
+ {0x2271, 16, 16, 2897},
+ {0x0, 9, 10, 2897},
+ {0xfa5e, 16, 16, 2898},
+ {0x0, 0, 1, 2898},
+ {0x0, 0, 1, 2899},
+ {0x0, 3, 4, 2900},
+ {0x0, 0, 1, 2901},
+ {0x0, 1, 2, 2902},
+ {0x453, 16, 16, 2903},
+ {0xf9d3, 16, 16, 2903},
+ {0x0, 12, 14, 2903},
+ {0x0, 0, 1, 2905},
+ {0x0, 0, 1, 2906},
+ {0x0, 3, 4, 2907},
+ {0x0, 0, 1, 2908},
+ {0x0, 2, 3, 2909},
+ {0x1ed8, 16, 16, 2910},
+ {0x0, 2, 16, 2910},
+ {0xf9e7, 16, 16, 2924},
+ {0xf91c, 16, 16, 2924},
+ {0x0, 1, 16, 2924},
+ {0x0, 4, 9, 2939},
+ {0xf901, 16, 16, 2944},
+ {0x2f82f, 16, 16, 2944},
+ {0x0, 15, 16, 2944},
+ {0x2f883, 16, 16, 2945},
+ {0x0, 0, 5, 2945},
+ {0x0, 0, 1, 2950},
+ {0x0, 0, 1, 2951},
+ {0x0, 3, 4, 2952},
+ {0x0, 3, 4, 2953},
+ {0x0, 8, 9, 2954},
+ {0x21ae, 16, 16, 2955},
+ {0x0, 11, 12, 2955},
+ {0x0, 12, 13, 2956},
+ {0x2f8fb, 16, 16, 2957},
+ {0x0, 0, 1, 2957},
+ {0x0, 0, 1, 2958},
+ {0x0, 3, 4, 2959},
+ {0x0, 0, 5, 2960},
+ {0x0, 3, 5, 2965},
+ {0x1f21, 16, 16, 2967},
+ {0x1f0, 16, 16, 2967},
+ {0x1f20, 16, 16, 2967},
+ {0x0, 0, 11, 2967},
+ {0x0, 0, 1, 2978},
+ {0x2f967, 16, 16, 2979},
+ {0x0, 3, 9, 2979},
+ {0x12f, 16, 16, 2985},
+ {0x0, 7, 15, 2985},
+ {0x2f9c7, 16, 16, 2993},
+ {0x1ecb, 16, 16, 2993},
+ {0x0, 2, 12, 2993},
+ {0x0, 0, 1, 3003},
+ {0x0, 3, 4, 3004},
+ {0x0, 0, 1, 3005},
+ {0x0, 9, 10, 3006},
+ {0x0, 9, 11, 3007},
+ {0x30dc, 16, 16, 3009},
+ {0x0, 6, 11, 3009},
+ {0x0, 0, 1, 3014},
+ {0x0, 0, 1, 3015},
+ {0x0, 12, 13, 3016},
+ {0x0, 13, 14, 3017},
+ {0x0, 5, 6, 3018},
+ {0xccb, 16, 16, 3019},
+ {0x0, 4, 9, 3019},
+ {0x2f9e7, 16, 16, 3024},
+ {0x0, 3, 8, 3024},
+ {0x1e32, 16, 16, 3029},
+ {0x0, 0, 1, 3029},
+ {0x0, 0, 1, 3030},
+ {0x0, 3, 4, 3031},
+ {0x0, 0, 5, 3032},
+ {0x0, 2, 3, 3037},
+ {0x1f36, 16, 16, 3038},
+ {0x0, 3, 14, 3038},
+ {0x0, 0, 1, 3049},
+ {0x0, 0, 1, 3050},
+ {0x0, 3, 4, 3051},
+ {0x0, 0, 1, 3052},
+ {0x0, 4, 12, 3053},
+ {0x45e, 16, 16, 3061},
+ {0x136, 16, 16, 3061},
+ {0x0, 6, 8, 3061},
+ {0x0, 0, 1, 3063},
+ {0x0, 0, 1, 3064},
+ {0x0, 11, 12, 3065},
+ {0x0, 11, 14, 3066},
+ {0x0, 7, 8, 3069},
+ {0xbcc, 16, 16, 3070},
+ {0x0, 3, 4, 3070},
+ {0xf981, 16, 16, 3071},
+ {0x0, 0, 1, 3071},
+ {0x0, 0, 1, 3072},
+ {0x0, 3, 4, 3073},
+ {0x0, 0, 4, 3074},
+ {0x0, 0, 16, 3078},
+ {0x1ec8, 16, 16, 3094},
+ {0x0, 3, 4, 3094},
+ {0x343, 16, 16, 3095},
+ {0x12c, 16, 16, 3095},
+ {0x0, 3, 16, 3095},
+ {0x2f870, 16, 16, 3108},
+ {0xf9b1, 16, 16, 3108},
+ {0x0, 0, 15, 3108},
+ {0x2f97f, 16, 16, 3123},
+ {0x2f8cc, 16, 16, 3123},
+ {0x0, 0, 1, 3123},
+ {0x0, 0, 1, 3124},
+ {0x0, 3, 4, 3125},
+ {0x0, 0, 1, 3126},
+ {0x0, 4, 5, 3127},
+ {0x1ed, 16, 16, 3128},
+ {0x30dd, 16, 16, 3128},
+ {0x0, 0, 7, 3128},
+ {0x0, 11, 12, 3135},
+ {0x2f984, 16, 16, 3136},
+ {0x0, 1, 12, 3136},
+ {0x0, 13, 14, 3147},
+ {0x0, 4, 5, 3148},
+ {0x2f8a4, 16, 16, 3149},
+ {0x2f9c6, 16, 16, 3149},
+ {0x2f872, 16, 16, 3149},
+ {0x0, 2, 16, 3149},
+ {0x0, 12, 13, 3163},
+ {0xf9c3, 16, 16, 3164},
+ {0xf945, 16, 16, 3164},
+ {0x0, 5, 6, 3164},
+ {0xf90f, 16, 16, 3165},
+ {0x0, 1, 16, 3165},
+ {0x0, 13, 14, 3180},
+ {0x2f884, 16, 16, 3181},
+ {0x0, 0, 1, 3181},
+ {0x0, 0, 1, 3182},
+ {0x0, 3, 4, 3183},
+ {0x0, 0, 1, 3184},
+ {0x0, 8, 9, 3185},
+ {0x4f9, 16, 16, 3186},
+ {0x0, 5, 6, 3186},
+ {0x2f921, 16, 16, 3187},
+ {0x0, 8, 10, 3187},
+ {0xfa4d, 16, 16, 3189},
+ {0xfa4e, 16, 16, 3189},
+ {0x0, 1, 16, 3189},
+ {0x0, 11, 12, 3204},
+ {0x2fa15, 16, 16, 3205},
+ {0x0, 7, 16, 3205},
+ {0xf988, 16, 16, 3214},
+ {0x0, 11, 12, 3214},
+ {0x2f863, 16, 16, 3215},
+ {0x0, 0, 5, 3215},
+ {0x0, 7, 8, 3220},
+ {0xf950, 16, 16, 3221},
+ {0x0, 0, 16, 3221},
+ {0x0, 9, 16, 3237},
+ {0xf95b, 16, 16, 3244},
+ {0x0, 0, 1, 3244},
+ {0x0, 0, 1, 3245},
+ {0x0, 3, 4, 3246},
+ {0x0, 0, 1, 3247},
+ {0x0, 7, 9, 3248},
+ {0x1e8a, 16, 16, 3250},
+ {0x0, 0, 1, 3250},
+ {0x0, 0, 1, 3251},
+ {0x0, 3, 4, 3252},
+ {0x0, 0, 5, 3253},
+ {0x0, 0, 2, 3258},
+ {0x3b0, 16, 16, 3260},
+ {0x1fe2, 16, 16, 3260},
+ {0x0, 1, 15, 3260},
+ {0x0, 2, 3, 3274},
+ {0x2f8e8, 16, 16, 3275},
+ {0xf9f3, 16, 16, 3275},
+ {0x1e8c, 16, 16, 3275},
+ {0x0, 0, 1, 3275},
+ {0x0, 3, 4, 3276},
+ {0x0, 0, 1, 3277},
+ {0x0, 9, 10, 3278},
+ {0x0, 9, 10, 3279},
+ {0x30bc, 16, 16, 3280},
+ {0x0, 0, 1, 3280},
+ {0x0, 0, 1, 3281},
+ {0x0, 3, 4, 3282},
+ {0x0, 0, 1, 3283},
+ {0x0, 4, 5, 3284},
+ {0x1e38, 16, 16, 3285},
+ {0x0, 9, 10, 3285},
+ {0xf966, 16, 16, 3286},
+ {0x0, 2, 3, 3286},
+ {0x0, 14, 15, 3287},
+ {0x2f9e5, 16, 16, 3288},
+ {0x0, 1, 2, 3288},
+ {0x206, 16, 16, 3289},
+ {0x0, 5, 16, 3289},
+ {0x1fcb, 16, 16, 3300},
+ {0x0, 3, 4, 3300},
+ {0x1e42, 16, 16, 3301},
+ {0x0, 4, 16, 3301},
+ {0x0, 0, 1, 3313},
+ {0x2fa0b, 16, 16, 3314},
+ {0x0, 13, 14, 3314},
+ {0x2f89d, 16, 16, 3315},
+ {0x0, 1, 15, 3315},
+ {0xfa44, 16, 16, 3329},
+ {0x0, 8, 13, 3329},
+ {0xfa3a, 16, 16, 3334},
+ {0x0, 1, 15, 3334},
+ {0x0, 2, 13, 3348},
+ {0xf960, 16, 16, 3359},
+ {0x0, 1, 2, 3359},
+ {0x0, 13, 14, 3360},
+ {0x2f94d, 16, 16, 3361},
+ {0x0, 13, 14, 3361},
+ {0xf923, 16, 16, 3362},
+ {0x0, 4, 5, 3362},
+ {0xf91d, 16, 16, 3363},
+ {0x0, 12, 13, 3363},
+ {0x0, 14, 15, 3364},
+ {0x2fa10, 16, 16, 3365},
+ {0x0, 0, 1, 3365},
+ {0x0, 0, 1, 3366},
+ {0x0, 3, 4, 3367},
+ {0x0, 0, 5, 3368},
+ {0x0, 0, 2, 3373},
+ {0x1f33, 16, 16, 3375},
+ {0x0, 0, 1, 3375},
+ {0x0, 0, 1, 3376},
+ {0x0, 3, 4, 3377},
+ {0x0, 0, 1, 3378},
+ {0x0, 7, 8, 3379},
+ {0x1e1e, 16, 16, 3380},
+ {0x1f35, 16, 16, 3380},
+ {0x0, 15, 16, 3380},
+ {0xfa41, 16, 16, 3381},
+ {0xf9ac, 16, 16, 3381},
+ {0x2f858, 16, 16, 3381},
+ {0x0, 0, 1, 3381},
+ {0x0, 0, 1, 3382},
+ {0x0, 3, 4, 3383},
+ {0x0, 4, 5, 3384},
+ {0x0, 5, 6, 3385},
+ {0x1f82, 16, 16, 3386},
+ {0x0, 11, 12, 3386},
+ {0xf9d8, 16, 16, 3387},
+ {0x0, 0, 15, 3387},
+ {0x0, 0, 1, 3402},
+ {0x0, 0, 1, 3403},
+ {0x0, 3, 4, 3404},
+ {0x0, 0, 1, 3405},
+ {0x0, 0, 9, 3406},
+ {0x4d6, 16, 16, 3415},
+ {0x0, 5, 6, 3415},
+ {0xf983, 16, 16, 3416},
+ {0x400, 16, 16, 3416},
+ {0x0, 0, 1, 3416},
+ {0x0, 0, 1, 3417},
+ {0x0, 3, 4, 3418},
+ {0x0, 0, 5, 3419},
+ {0x0, 0, 2, 3424},
+ {0x1f0d, 16, 16, 3426},
+ {0x1f0b, 16, 16, 3426},
+ {0x401, 16, 16, 3426},
+ {0x0, 10, 14, 3426},
+ {0x2f8c5, 16, 16, 3430},
+ {0xf991, 16, 16, 3430},
+ {0x0, 1, 2, 3430},
+ {0x207, 16, 16, 3431},
+ {0x0, 10, 12, 3431},
+ {0x0, 0, 1, 3433},
+ {0x0, 0, 1, 3434},
+ {0x0, 3, 4, 3435},
+ {0x0, 0, 1, 3436},
+ {0x0, 7, 8, 3437},
+ {0x1e64, 16, 16, 3438},
+ {0x0, 5, 6, 3438},
+ {0x2f9a6, 16, 16, 3439},
+ {0x0, 4, 8, 3439},
+ {0x387, 16, 16, 3443},
+ {0x1ffd, 16, 16, 3443},
+ {0x0, 9, 11, 3443},
+ {0xf928, 16, 16, 3445},
+ {0x0, 0, 1, 3445},
+ {0x0, 0, 1, 3446},
+ {0x0, 3, 4, 3447},
+ {0x0, 0, 3, 3448},
+ {0x0, 3, 4, 3451},
+ {0x1ee2, 16, 16, 3452},
+ {0x0, 4, 16, 3452},
+ {0x0, 4, 14, 3464},
+ {0xf9d1, 16, 16, 3474},
+ {0x0, 1, 14, 3474},
+ {0x0, 1, 12, 3487},
+ {0x2f9e6, 16, 16, 3498},
+ {0x0, 13, 14, 3498},
+ {0x2fa0c, 16, 16, 3499},
+ {0x0, 0, 1, 3499},
+ {0x0, 0, 1, 3500},
+ {0x0, 3, 4, 3501},
+ {0x0, 0, 1, 3502},
+ {0x0, 4, 5, 3503},
+ {0x230, 16, 16, 3504},
+ {0x0, 0, 1, 3504},
+ {0x0, 0, 1, 3505},
+ {0x0, 3, 4, 3506},
+ {0x0, 4, 5, 3507},
+ {0x0, 5, 6, 3508},
+ {0x1faf, 16, 16, 3509},
+ {0x0, 14, 15, 3509},
+ {0xf9a6, 16, 16, 3510},
+ {0x0, 13, 14, 3510},
+ {0x2f87a, 16, 16, 3511},
+ {0x0, 0, 7, 3511},
+ {0x3ac, 16, 16, 3518},
+ {0x1f70, 16, 16, 3518},
+ {0x0, 7, 8, 3518},
+ {0x0, 0, 1, 3519},
+ {0x0, 0, 1, 3520},
+ {0x0, 6, 7, 3521},
+ {0x0, 5, 6, 3522},
+ {0x0, 3, 6, 3523},
+ {0x623, 16, 16, 3526},
+ {0x625, 16, 16, 3526},
+ {0x1fb1, 16, 16, 3526},
+ {0x1fb0, 16, 16, 3526},
+ {0xf9a2, 16, 16, 3526},
+ {0x0, 10, 11, 3526},
+ {0xf9d6, 16, 16, 3527},
+ {0x0, 3, 4, 3527},
+ {0x2f844, 16, 16, 3528},
+ {0x0, 1, 2, 3528},
+ {0x1e0f, 16, 16, 3529},
+ {0x0, 14, 15, 3529},
+ {0xf9c0, 16, 16, 3530},
+ {0x0, 6, 7, 3530},
+ {0xf9dc, 16, 16, 3531},
+ {0x2f810, 16, 16, 3531},
+ {0x2f814, 16, 16, 3531},
+ {0xf978, 16, 16, 3531},
+ {0x2f9e4, 16, 16, 3531},
+ {0x0, 0, 16, 3531},
+ {0x0, 13, 14, 3547},
+ {0xf9ed, 16, 16, 3548},
+ {0x0, 0, 1, 3548},
+ {0x0, 3, 4, 3549},
+ {0x0, 0, 1, 3550},
+ {0x0, 9, 10, 3551},
+ {0x0, 9, 11, 3552},
+ {0x3071, 16, 16, 3554},
+ {0x0, 2, 16, 3554},
+ {0x0, 1, 12, 3568},
+ {0x2f9af, 16, 16, 3579},
+ {0x0, 0, 1, 3579},
+ {0x0, 0, 1, 3580},
+ {0x0, 3, 4, 3581},
+ {0x0, 0, 4, 3582},
+ {0x0, 3, 14, 3586},
+ {0x1e4b, 16, 16, 3597},
+ {0x0, 0, 1, 3597},
+ {0x0, 0, 1, 3598},
+ {0x0, 3, 4, 3599},
+ {0x0, 4, 5, 3600},
+ {0x0, 5, 6, 3601},
+ {0x1f9a, 16, 16, 3602},
+ {0x0, 5, 7, 3602},
+ {0x2f829, 16, 16, 3604},
+ {0x2f82a, 16, 16, 3604},
+ {0x0, 3, 16, 3604},
+ {0x0, 14, 15, 3617},
+ {0xf999, 16, 16, 3618},
+ {0x0, 7, 15, 3618},
+ {0xf9bc, 16, 16, 3626},
+ {0x0, 0, 1, 3626},
+ {0x0, 0, 1, 3627},
+ {0x0, 3, 4, 3628},
+ {0x0, 3, 4, 3629},
+ {0x0, 8, 9, 3630},
+ {0x21cd, 16, 16, 3631},
+ {0x0, 0, 1, 3631},
+ {0x0, 0, 1, 3632},
+ {0x0, 3, 4, 3633},
+ {0x0, 3, 4, 3634},
+ {0x0, 8, 9, 3635},
+ {0x2262, 16, 16, 3636},
+ {0x0, 0, 2, 3636},
+ {0x3ae, 16, 16, 3638},
+ {0x1f74, 16, 16, 3638},
+ {0x0, 0, 1, 3638},
+ {0x0, 0, 1, 3639},
+ {0x0, 3, 4, 3640},
+ {0x0, 0, 4, 3641},
+ {0x0, 1, 2, 3645},
+ {0x1e96, 16, 16, 3646},
+ {0x0, 0, 1, 3646},
+ {0x0, 3, 4, 3647},
+ {0x0, 0, 1, 3648},
+ {0x0, 9, 10, 3649},
+ {0x0, 9, 10, 3650},
+ {0x30b8, 16, 16, 3651},
+ {0x0, 2, 7, 3651},
+ {0xf97d, 16, 16, 3656},
+ {0xf941, 16, 16, 3656},
+ {0x1e47, 16, 16, 3656},
+ {0x146, 16, 16, 3656},
+ {0x0, 0, 1, 3656},
+ {0x1e2d, 16, 16, 3657},
+ {0x2f9b2, 16, 16, 3657},
+ {0x0, 0, 1, 3657},
+ {0xf9fa, 16, 16, 3658},
+ {0x3070, 16, 16, 3658},
+ {0x0, 8, 9, 3658},
+ {0xf90c, 16, 16, 3659},
+ {0x0, 0, 1, 3659},
+ {0x0, 0, 1, 3660},
+ {0x0, 3, 4, 3661},
+ {0x0, 0, 1, 3662},
+ {0x0, 0, 10, 3663},
+ {0x1ea6, 16, 16, 3673},
+ {0x1ea4, 16, 16, 3673},
+ {0x1eaa, 16, 16, 3673},
+ {0x0, 14, 15, 3673},
+ {0xf92c, 16, 16, 3674},
+ {0x1ea8, 16, 16, 3674},
+ {0x0, 0, 1, 3674},
+ {0x0, 3, 4, 3675},
+ {0x0, 0, 1, 3676},
+ {0x0, 9, 10, 3677},
+ {0x0, 9, 10, 3678},
+ {0x30c2, 16, 16, 3679},
+ {0x0, 0, 9, 3679},
+ {0x340, 16, 16, 3688},
+ {0x341, 16, 16, 3688},
+ {0x0, 0, 15, 3688},
+ {0x0, 6, 7, 3703},
+ {0x2f94c, 16, 16, 3704},
+ {0x0, 3, 4, 3704},
+ {0x2f8e9, 16, 16, 3705},
+ {0x0, 6, 7, 3705},
+ {0xf9fe, 16, 16, 3706},
+ {0x0, 8, 9, 3706},
+ {0x0, 0, 1, 3707},
+ {0x2f965, 16, 16, 3708},
+ {0x0, 12, 13, 3708},
+ {0x0, 0, 1, 3709},
+ {0x0, 0, 1, 3710},
+ {0x0, 3, 4, 3711},
+ {0x0, 3, 4, 3712},
+ {0x0, 8, 9, 3713},
+ {0x2241, 16, 16, 3714},
+ {0x1f75, 0, 1, 3714},
+ {0x0, 0, 1, 3715},
+ {0x0, 3, 4, 3716},
+ {0x0, 4, 5, 3717},
+ {0x0, 5, 6, 3718},
+ {0x1fc4, 16, 16, 3719},
+ {0x0, 8, 9, 3719},
+ {0x0, 1, 2, 3720},
+ {0x2f876, 16, 16, 3721},
+ {0x0, 0, 15, 3721},
+ {0xfa19, 16, 16, 3736},
+ {0x0, 15, 16, 3736},
+ {0x0, 0, 1, 3737},
+ {0x0, 3, 4, 3738},
+ {0x0, 0, 1, 3739},
+ {0x0, 9, 10, 3740},
+ {0x0, 9, 10, 3741},
+ {0x30f7, 16, 16, 3742},
+ {0x0, 1, 2, 3742},
+ {0xf9e8, 16, 16, 3743},
+ {0x0, 1, 16, 3743},
+ {0x154, 16, 16, 3758},
+ {0x0, 7, 8, 3758},
+ {0x0, 12, 13, 3759},
+ {0x2f95c, 16, 16, 3760},
+ {0x0, 7, 8, 3760},
+ {0xf933, 16, 16, 3761},
+ {0x0, 0, 16, 3761},
+ {0x0, 3, 11, 3777},
+ {0x2f8df, 16, 16, 3785},
+ {0xfa50, 16, 16, 3785},
+ {0xfa4f, 16, 16, 3785},
+ {0x0, 8, 12, 3785},
+ {0x2f920, 16, 16, 3789},
+ {0x0, 3, 4, 3789},
+ {0x1e88, 16, 16, 3790},
+ {0x0, 0, 1, 3790},
+ {0x0, 3, 4, 3791},
+ {0x0, 0, 1, 3792},
+ {0x0, 9, 10, 3793},
+ {0x0, 9, 11, 3794},
+ {0x3077, 16, 16, 3796},
+ {0x0, 10, 11, 3796},
+ {0x2f917, 16, 16, 3797},
+ {0x0, 14, 16, 3797},
+ {0x0, 12, 13, 3799},
+ {0x2f868, 16, 16, 3800},
+ {0x0, 1, 7, 3800},
+ {0x0, 2, 3, 3806},
+ {0x2fa0a, 16, 16, 3807},
+ {0x0, 0, 1, 3807},
+ {0x0, 0, 1, 3808},
+ {0x0, 3, 4, 3809},
+ {0x0, 4, 5, 3810},
+ {0x0, 5, 6, 3811},
+ {0x1f86, 16, 16, 3812},
+ {0x0, 1, 6, 3812},
+ {0xfa59, 16, 16, 3817},
+ {0x2f970, 16, 16, 3817},
+ {0x0, 9, 10, 3817},
+ {0x2f887, 16, 16, 3818},
+ {0x0, 0, 9, 3818},
+ {0x0, 8, 9, 3827},
+ {0xf9fc, 16, 16, 3828},
+ {0x0, 7, 8, 3828},
+ {0xf9f4, 16, 16, 3829},
+ {0x0, 8, 10, 3829},
+ {0x0, 0, 1, 3831},
+ {0x0, 0, 1, 3832},
+ {0x0, 3, 4, 3833},
+ {0x0, 0, 1, 3834},
+ {0x0, 8, 9, 3835},
+ {0x4da, 16, 16, 3836},
+ {0x0, 1, 2, 3836},
+ {0xf9b9, 16, 16, 3837},
+ {0x0, 3, 13, 3837},
+ {0x0, 14, 15, 3847},
+ {0x2f9cd, 16, 16, 3848},
+ {0x0, 6, 7, 3848},
+ {0x2f866, 16, 16, 3849},
+ {0x0, 8, 10, 3849},
+ {0x0, 0, 1, 3851},
+ {0x0, 0, 1, 3852},
+ {0x0, 3, 4, 3853},
+ {0x0, 0, 1, 3854},
+ {0x0, 2, 3, 3855},
+ {0x1ec7, 16, 16, 3856},
+ {0x0, 14, 15, 3856},
+ {0x2f867, 16, 16, 3857},
+ {0x0, 3, 14, 3857},
+ {0x118, 16, 16, 3868},
+ {0x0, 0, 1, 3868},
+ {0x0, 0, 1, 3869},
+ {0x0, 3, 4, 3870},
+ {0x0, 0, 5, 3871},
+ {0x0, 0, 2, 3876},
+ {0x1f2d, 16, 16, 3878},
+ {0x228, 16, 16, 3878},
+ {0x0, 4, 15, 3878},
+ {0x0, 7, 8, 3889},
+ {0x2f8fe, 16, 16, 3890},
+ {0x1eb8, 16, 16, 3890},
+ {0x0, 2, 13, 3890},
+ {0x0, 0, 1, 3901},
+ {0xf9f8, 16, 16, 3902},
+ {0x0, 14, 15, 3902},
+ {0xf989, 16, 16, 3903},
+ {0x0, 2, 8, 3903},
+ {0x2f8f3, 16, 16, 3909},
+ {0x0, 6, 7, 3909},
+ {0x2f873, 16, 16, 3910},
+ {0x0, 0, 16, 3910},
+ {0x0, 1, 2, 3926},
+ {0x2f8be, 16, 16, 3927},
+ {0x0, 12, 15, 3927},
+ {0xfa18, 16, 16, 3930},
+ {0x0, 8, 9, 3930},
+ {0xf969, 16, 16, 3931},
+ {0x0, 5, 13, 3931},
+ {0x0, 3, 13, 3939},
+ {0x2f98a, 16, 16, 3949},
+ {0x0, 9, 10, 3949},
+ {0xf9cd, 16, 16, 3950},
+ {0x1e18, 16, 16, 3950},
+ {0x0, 0, 1, 3950},
+ {0x0, 0, 1, 3951},
+ {0x0, 3, 4, 3952},
+ {0x0, 0, 1, 3953},
+ {0x0, 4, 5, 3954},
+ {0x1e5c, 16, 16, 3955},
+ {0xf98c, 16, 16, 3955},
+ {0x0, 12, 16, 3955},
+ {0x0, 13, 14, 3959},
+ {0x2fa0e, 16, 16, 3960},
+ {0x0, 9, 14, 3960},
+ {0x0, 15, 16, 3965},
+ {0x2f81f, 16, 16, 3966},
+ {0x0, 2, 13, 3966},
+ {0x0, 6, 7, 3977},
+ {0x2f952, 16, 16, 3978},
+ {0x0, 0, 1, 3978},
+ {0x0, 0, 1, 3979},
+ {0x0, 3, 4, 3980},
+ {0x0, 0, 3, 3981},
+ {0x0, 1, 13, 3984},
+ {0x160, 16, 16, 3996},
+ {0x0, 0, 1, 3996},
+ {0x0, 3, 4, 3997},
+ {0x0, 0, 1, 3998},
+ {0x0, 9, 10, 3999},
+ {0x0, 9, 10, 4000},
+ {0x30ac, 16, 16, 4001},
+ {0x0, 9, 10, 4001},
+ {0xf9d5, 16, 16, 4002},
+ {0x0, 0, 1, 4002},
+ {0x0, 0, 1, 4003},
+ {0x0, 3, 4, 4004},
+ {0x0, 0, 5, 4005},
+ {0x0, 0, 2, 4010},
+ {0x3ce, 16, 16, 4012},
+ {0x0, 11, 12, 4012},
+ {0x2f8f8, 16, 16, 4013},
+ {0x0, 0, 1, 4013},
+ {0x0, 0, 1, 4014},
+ {0x0, 3, 4, 4015},
+ {0x0, 0, 1, 4016},
+ {0x0, 0, 9, 4017},
+ {0x451, 16, 16, 4026},
+ {0x450, 16, 16, 4026},
+ {0x0, 3, 13, 4026},
+ {0x0, 3, 4, 4036},
+ {0x2fa03, 16, 16, 4037},
+ {0x4d7, 16, 16, 4037},
+ {0xf9c9, 16, 16, 4037},
+ {0x1e60, 16, 16, 4037},
+ {0x15a, 16, 16, 4037},
+ {0x15c, 16, 16, 4037},
+ {0xf91e, 16, 16, 4037},
+ {0x0, 0, 1, 4037},
+ {0x0, 0, 1, 4038},
+ {0x0, 3, 4, 4039},
+ {0x0, 0, 1, 4040},
+ {0x0, 0, 10, 4041},
+ {0x1eab, 16, 16, 4051},
+ {0x1ea7, 16, 16, 4051},
+ {0x1ea5, 16, 16, 4051},
+ {0x1ea9, 16, 16, 4051},
+ {0x0, 2, 14, 4051},
+ {0x0, 10, 11, 4063},
+ {0xfa16, 16, 16, 4064},
+ {0x0, 11, 12, 4064},
+ {0xf9a4, 16, 16, 4065},
+ {0x0, 0, 1, 4065},
+ {0x0, 0, 1, 4066},
+ {0x0, 3, 4, 4067},
+ {0x0, 3, 4, 4068},
+ {0x0, 8, 9, 4069},
+ {0x226d, 16, 16, 4070},
+ {0x0, 0, 1, 4070},
+ {0x0, 0, 1, 4071},
+ {0x0, 3, 4, 4072},
+ {0x0, 4, 5, 4073},
+ {0x0, 5, 6, 4074},
+ {0x1f9f, 16, 16, 4075},
+ {0x0, 0, 1, 4075},
+ {0x0, 0, 1, 4076},
+ {0x0, 3, 4, 4077},
+ {0x0, 4, 5, 4078},
+ {0x0, 5, 6, 4079},
+ {0x1fad, 16, 16, 4080},
+ {0x0, 0, 1, 4080},
+ {0x0, 0, 1, 4081},
+ {0x0, 3, 4, 4082},
+ {0x0, 0, 3, 4083},
+ {0x0, 3, 4, 4086},
+ {0x1ee3, 16, 16, 4087},
+ {0x0, 13, 14, 4087},
+ {0x2f9ae, 16, 16, 4088},
+ {0x0, 3, 15, 4088},
+ {0x1e2b, 16, 16, 4100},
+ {0x0, 12, 13, 4100},
+ {0x2f9ea, 16, 16, 4101},
+ {0x0, 12, 13, 4101},
+ {0x0, 10, 11, 4102},
+ {0x2f9ab, 16, 16, 4103},
+ {0x0, 0, 1, 4103},
+ {0x0, 0, 1, 4104},
+ {0x0, 3, 4, 4105},
+ {0x0, 0, 5, 4106},
+ {0x0, 0, 7, 4111},
+ {0x1fba, 16, 16, 4118},
+ {0x386, 16, 16, 4118},
+ {0x1fb8, 16, 16, 4118},
+ {0x0, 7, 8, 4118},
+ {0x2f811, 16, 16, 4119},
+ {0x1fb9, 16, 16, 4119},
+ {0x0, 1, 14, 4119},
+ {0x0, 14, 15, 4132},
+ {0x2f909, 16, 16, 4133},
+ {0x0, 0, 13, 4133},
+ {0xf936, 16, 16, 4146},
+ {0x0, 6, 7, 4146},
+ {0x0, 0, 1, 4147},
+ {0x0, 0, 1, 4148},
+ {0x0, 3, 4, 4149},
+ {0x0, 4, 5, 4150},
+ {0x0, 5, 6, 4151},
+ {0x1fc7, 16, 16, 4152},
+ {0x0, 0, 11, 4152},
+ {0x0, 0, 1, 4163},
+ {0x0, 0, 1, 4164},
+ {0x0, 3, 4, 4165},
+ {0x0, 0, 1, 4166},
+ {0x0, 7, 9, 4167},
+ {0x1e8b, 16, 16, 4169},
+ {0x0, 1, 8, 4169},
+ {0x1e3f, 16, 16, 4176},
+ {0x1e41, 16, 16, 4176},
+ {0x0, 0, 16, 4176},
+ {0x0, 4, 5, 4192},
+ {0xf93f, 16, 16, 4193},
+ {0x0, 7, 8, 4193},
+ {0x2f964, 16, 16, 4194},
+ {0x0, 6, 7, 4194},
+ {0x2f9be, 16, 16, 4195},
+ {0x1e8d, 16, 16, 4195},
+ {0x0, 0, 1, 4195},
+ {0x0, 0, 1, 4196},
+ {0x0, 3, 4, 4197},
+ {0x0, 0, 1, 4198},
+ {0x0, 0, 2, 4199},
+ {0x1e14, 16, 16, 4201},
+ {0x0, 7, 8, 4201},
+ {0xfa31, 16, 16, 4202},
+ {0x0, 0, 1, 4202},
+ {0x0, 0, 1, 4203},
+ {0x0, 3, 4, 4204},
+ {0x0, 0, 1, 4205},
+ {0x0, 1, 2, 4206},
+ {0x1e2f, 16, 16, 4207},
+ {0x0, 7, 8, 4207},
+ {0xf963, 16, 16, 4208},
+ {0x2f9b3, 16, 16, 4208},
+ {0x0, 0, 1, 4208},
+ {0x0, 0, 1, 4209},
+ {0x0, 3, 4, 4210},
+ {0x0, 0, 5, 4211},
+ {0x0, 2, 3, 4216},
+ {0x1f3e, 16, 16, 4217},
+ {0x0, 0, 1, 4217},
+ {0x0, 0, 1, 4218},
+ {0x0, 3, 4, 4219},
+ {0x0, 0, 1, 4220},
+ {0x0, 1, 2, 4221},
+ {0x1e2e, 16, 16, 4222},
+ {0x1e29, 16, 16, 4222},
+ {0x0, 0, 1, 4222},
+ {0x0, 0, 1, 4223},
+ {0x0, 3, 4, 4224},
+ {0x0, 0, 4, 4225},
+ {0x0, 1, 2, 4229},
+ {0x1e06, 16, 16, 4230},
+ {0x1e25, 16, 16, 4230},
+ {0xec, 16, 16, 4230},
+ {0xed, 16, 16, 4230},
+ {0xee, 16, 16, 4230},
+ {0x129, 16, 16, 4230},
+ {0x12b, 16, 16, 4230},
+ {0x12d, 16, 16, 4230},
+ {0xef, 16, 16, 4230},
+ {0x1ec9, 16, 16, 4230},
+ {0x0, 6, 16, 4230},
+ {0x2f83b, 16, 16, 4240},
+ {0x0, 1, 2, 4240},
+ {0xf909, 16, 16, 4241},
+ {0x2f969, 16, 16, 4241},
+ {0x0, 8, 11, 4241},
+ {0x2f9c9, 16, 16, 4244},
+ {0x0, 1, 13, 4244},
+ {0x1e30, 16, 16, 4256},
+ {0x1a1, 16, 16, 4256},
+ {0x0, 3, 12, 4256},
+ {0x0, 0, 1, 4265},
+ {0x0, 0, 1, 4266},
+ {0x0, 3, 4, 4267},
+ {0x0, 3, 4, 4268},
+ {0x0, 8, 9, 4269},
+ {0x2209, 16, 16, 4270},
+ {0x0, 13, 14, 4270},
+ {0xf918, 16, 16, 4271},
+ {0xf97b, 16, 16, 4271},
+ {0x0, 1, 13, 4271},
+ {0x2f9a9, 16, 16, 4283},
+ {0x2f9a8, 16, 16, 4283},
+ {0x0, 8, 9, 4283},
+ {0x2f86e, 16, 16, 4284},
+ {0x0, 4, 5, 4284},
+ {0x2f9e2, 16, 16, 4285},
+ {0xf9de, 16, 16, 4285},
+ {0x1e8, 16, 16, 4285},
+ {0x0, 3, 4, 4285},
+ {0x2f99c, 16, 16, 4286},
+ {0x0, 6, 7, 4286},
+ {0x2f94b, 16, 16, 4287},
+ {0x209, 16, 16, 4287},
+ {0x0, 2, 3, 4287},
+ {0xfa4a, 16, 16, 4288},
+ {0xf9c2, 16, 16, 4288},
+ {0x0, 0, 1, 4288},
+ {0x0, 0, 1, 4289},
+ {0x0, 3, 4, 4290},
+ {0x0, 0, 1, 4291},
+ {0x0, 8, 9, 4292},
+ {0x4db, 16, 16, 4293},
+ {0x0, 5, 6, 4293},
+ {0xfa1a, 16, 16, 4294},
+ {0x0, 4, 15, 4294},
+ {0x2f8a9, 16, 16, 4305},
+ {0x0, 3, 14, 4305},
+ {0x0, 0, 1, 4316},
+ {0x0, 0, 1, 4317},
+ {0x0, 3, 4, 4318},
+ {0x0, 0, 1, 4319},
+ {0x0, 4, 12, 4320},
+ {0x4f0, 16, 16, 4328},
+ {0x0, 5, 10, 4328},
+ {0xf993, 16, 16, 4333},
+ {0x2f8a8, 16, 16, 4333},
+ {0x2f91c, 16, 16, 4333},
+ {0x40e, 16, 16, 4333},
+ {0x4ee, 16, 16, 4333},
+ {0x0, 5, 6, 4333},
+ {0x2f986, 16, 16, 4334},
+ {0x0, 11, 12, 4334},
+ {0xf922, 16, 16, 4335},
+ {0x0, 5, 6, 4335},
+ {0x1fcc, 16, 16, 4336},
+ {0x0, 0, 1, 4336},
+ {0x0, 3, 4, 4337},
+ {0x0, 0, 1, 4338},
+ {0x0, 9, 10, 4339},
+ {0x0, 9, 10, 4340},
+ {0x3056, 16, 16, 4341},
+ {0x0, 7, 16, 4341},
+ {0xf9da, 16, 16, 4350},
+ {0x0, 7, 8, 4350},
+ {0x2f96e, 16, 16, 4351},
+ {0xf9d9, 16, 16, 4351},
+ {0x4f2, 16, 16, 4351},
+ {0x2f8a6, 16, 16, 4351},
+ {0x0, 8, 9, 4351},
+ {0x2f869, 16, 16, 4352},
+ {0x0, 8, 9, 4352},
+ {0xf9ef, 16, 16, 4353},
+ {0x0, 5, 6, 4353},
+ {0x2f8e0, 16, 16, 4354},
+ {0x0, 0, 9, 4354},
+ {0x0, 11, 12, 4363},
+ {0x2f94a, 16, 16, 4364},
+ {0x0, 0, 10, 4364},
+ {0x0, 13, 14, 4374},
+ {0xf9c4, 16, 16, 4375},
+ {0x2f8e5, 16, 16, 4375},
+ {0x0, 0, 1, 4375},
+ {0x1e1a, 16, 16, 4376},
+ {0x0, 10, 11, 4376},
+ {0x0, 11, 12, 4377},
+ {0x2f91f, 16, 16, 4378},
+ {0x0, 0, 1, 4378},
+ {0x0, 0, 1, 4379},
+ {0x0, 3, 4, 4380},
+ {0x0, 0, 3, 4381},
+ {0x0, 0, 16, 4384},
+ {0x200, 16, 16, 4400},
+ {0x1cd, 16, 16, 4400},
+ {0xc5, 16, 16, 4400},
+ {0x0, 13, 14, 4400},
+ {0x2f8d6, 16, 16, 4401},
+ {0x0, 5, 6, 4401},
+ {0xf976, 16, 16, 4402},
+ {0x0, 6, 12, 4402},
+ {0xf9b5, 16, 16, 4408},
+ {0x0, 0, 1, 4408},
+ {0x0, 0, 1, 4409},
+ {0x0, 3, 4, 4410},
+ {0x0, 0, 4, 4411},
+ {0x0, 3, 14, 4415},
+ {0x21a, 16, 16, 4426},
+ {0x162, 16, 16, 4426},
+ {0x1e6c, 16, 16, 4426},
+ {0x0, 0, 2, 4426},
+ {0x1f05, 16, 16, 4428},
+ {0x1f03, 16, 16, 4428},
+ {0x0, 1, 2, 4428},
+ {0x2f8ef, 16, 16, 4429},
+ {0x0, 7, 8, 4429},
+ {0x2f9ce, 16, 16, 4430},
+ {0xf92d, 16, 16, 4430},
+ {0x0, 10, 15, 4430},
+ {0x0, 8, 9, 4435},
+ {0x2f860, 16, 16, 4436},
+ {0x1e70, 16, 16, 4436},
+ {0x0, 4, 5, 4436},
+ {0xfa2d, 16, 16, 4437},
+ {0x0, 12, 13, 4437},
+ {0x2f8c9, 16, 16, 4438},
+ {0x102, 16, 16, 4438},
+ {0x226, 16, 16, 4438},
+ {0x100, 16, 16, 4438},
+ {0xc2, 16, 16, 4438},
+ {0xc3, 16, 16, 4438},
+ {0xc0, 16, 16, 4438},
+ {0xc1, 16, 16, 4438},
+ {0x0, 2, 3, 4438},
+ {0x2fa06, 16, 16, 4439},
+ {0x0, 2, 3, 4439},
+ {0x1f57, 16, 16, 4440},
+ {0x0, 5, 6, 4440},
+ {0x2f9d2, 16, 16, 4441},
+ {0xc4, 16, 16, 4441},
+ {0x1ea2, 16, 16, 4441},
+ {0x0, 8, 9, 4441},
+ {0x2f8bb, 16, 16, 4442},
+ {0x0, 15, 16, 4442},
+ {0xf910, 16, 16, 4443},
+ {0x0, 0, 1, 4443},
+ {0x0, 0, 1, 4444},
+ {0x0, 3, 4, 4445},
+ {0x0, 0, 1, 4446},
+ {0x0, 1, 8, 4447},
+ {0x1e57, 16, 16, 4454},
+ {0x1e55, 16, 16, 4454},
+ {0x0, 3, 4, 4454},
+ {0xf9e0, 16, 16, 4455},
+ {0x0, 0, 1, 4455},
+ {0x0, 0, 1, 4456},
+ {0x0, 3, 4, 4457},
+ {0x0, 0, 3, 4458},
+ {0x0, 0, 16, 4461},
+ {0xd5, 16, 16, 4477},
+ {0x0, 0, 10, 4477},
+ {0x1ee0, 16, 16, 4487},
+ {0x1eda, 16, 16, 4487},
+ {0x1edc, 16, 16, 4487},
+ {0x0, 0, 1, 4487},
+ {0x0, 0, 1, 4488},
+ {0x0, 3, 4, 4489},
+ {0x0, 3, 4, 4490},
+ {0x0, 8, 9, 4491},
+ {0x22ea, 16, 16, 4492},
+ {0x1ede, 16, 16, 4492},
+ {0x0, 1, 16, 4492},
+ {0x0, 14, 15, 4507},
+ {0x2f852, 16, 16, 4508},
+ {0x0, 0, 12, 4508},
+ {0x2f8b2, 16, 16, 4520},
+ {0x0, 12, 14, 4520},
+ {0x0, 4, 5, 4522},
+ {0x2f9de, 16, 16, 4523},
+ {0x0, 12, 13, 4523},
+ {0x2f88a, 16, 16, 4524},
+ {0x0, 0, 14, 4524},
+ {0xfa32, 16, 16, 4538},
+ {0x0, 0, 1, 4538},
+ {0x0, 0, 1, 4539},
+ {0x0, 3, 4, 4540},
+ {0x0, 0, 1, 4541},
+ {0x0, 7, 8, 4542},
+ {0x1e67, 16, 16, 4543},
+ {0x0, 8, 9, 4543},
+ {0x2f9b8, 16, 16, 4544},
+ {0x0, 9, 10, 4544},
+ {0x2f8de, 16, 16, 4545},
+ {0x1f7c, 16, 16, 4545},
+ {0x0, 2, 3, 4545},
+ {0x1fdf, 16, 16, 4546},
+ {0x0, 6, 7, 4546},
+ {0x0, 11, 12, 4547},
+ {0x2f9a5, 16, 16, 4548},
+ {0x0, 6, 7, 4548},
+ {0xfa01, 16, 16, 4549},
+ {0x0, 9, 10, 4549},
+ {0x2f809, 16, 16, 4550},
+ {0x0, 4, 14, 4550},
+ {0x0, 15, 16, 4560},
+ {0x2f81c, 16, 16, 4561},
+ {0x0, 9, 10, 4561},
+ {0x2f9b7, 16, 16, 4562},
+ {0x0, 12, 15, 4562},
+ {0xf973, 16, 16, 4565},
+ {0x0, 0, 1, 4565},
+ {0x0, 3, 4, 4566},
+ {0x0, 0, 1, 4567},
+ {0x0, 9, 10, 4568},
+ {0x0, 9, 10, 4569},
+ {0x30c0, 16, 16, 4570},
+ {0x0, 3, 5, 4570},
+ {0x1f08, 16, 16, 4572},
+ {0x2f8b3, 16, 16, 4572},
+ {0x1f09, 16, 16, 4572},
+ {0x2f8ba, 16, 16, 4572},
+ {0x0, 0, 1, 4572},
+ {0x0, 0, 1, 4573},
+ {0x0, 3, 4, 4574},
+ {0x0, 0, 5, 4575},
+ {0x0, 0, 2, 4580},
+ {0x1fd2, 16, 16, 4582},
+ {0x390, 16, 16, 4582},
+ {0xfa0c, 16, 16, 4582},
+ {0x0, 0, 1, 4582},
+ {0x0, 0, 1, 4583},
+ {0x0, 3, 4, 4584},
+ {0x0, 0, 1, 4585},
+ {0x0, 1, 2, 4586},
+ {0x1e79, 16, 16, 4587},
+ {0x0, 4, 16, 4587},
+ {0x2f8ad, 16, 16, 4599},
+ {0x0, 2, 3, 4599},
+ {0x0, 15, 16, 4600},
+ {0x2f958, 16, 16, 4601},
+ {0x0, 5, 8, 4601},
+ {0x2f81b, 16, 16, 4604},
+ {0x0, 0, 1, 4604},
+ {0x0, 0, 1, 4605},
+ {0x0, 3, 4, 4606},
+ {0x0, 3, 4, 4607},
+ {0x0, 8, 9, 4608},
+ {0x2275, 16, 16, 4609},
+ {0x0, 0, 13, 4609},
+ {0x148, 16, 16, 4622},
+ {0x0, 0, 15, 4622},
+ {0x0, 14, 15, 4637},
+ {0x2f985, 16, 16, 4638},
+ {0x0, 0, 7, 4638},
+ {0xfa66, 16, 16, 4645},
+ {0xf971, 16, 16, 4645},
+ {0x0, 1, 2, 4645},
+ {0x20b, 16, 16, 4646},
+ {0x0, 0, 1, 4646},
+ {0x0, 0, 1, 4647},
+ {0x0, 3, 4, 4648},
+ {0x0, 0, 5, 4649},
+ {0x0, 2, 3, 4654},
+ {0x1fe6, 16, 16, 4655},
+ {0x0, 2, 3, 4655},
+ {0x1f3f, 16, 16, 4656},
+ {0x0, 7, 8, 4656},
+ {0x0, 1, 2, 4657},
+ {0x0, 0, 1, 4658},
+ {0x0, 0, 1, 4659},
+ {0x0, 15, 16, 4660},
+ {0x0, 7, 9, 4661},
+ {0x0, 0, 1, 4663},
+ {0xf81, 16, 16, 4664},
+ {0x0, 0, 1, 4664},
+ {0x0, 0, 1, 4665},
+ {0x0, 3, 4, 4666},
+ {0x0, 4, 5, 4667},
+ {0x0, 5, 6, 4668},
+ {0x1fb2, 16, 16, 4669},
+ {0x0, 3, 4, 4669},
+ {0x1e04, 16, 16, 4670},
+ {0x0, 1, 2, 4670},
+ {0x2f96d, 16, 16, 4671},
+ {0x0, 0, 16, 4671},
+ {0x2f95b, 16, 16, 4687},
+ {0x2f95a, 16, 16, 4687},
+ {0x1e45, 16, 16, 4687},
+ {0x1f9, 16, 16, 4687},
+ {0x144, 16, 16, 4687},
+ {0x0, 9, 10, 4687},
+ {0x2f9eb, 16, 16, 4688},
+ {0xf1, 16, 16, 4688},
+ {0x0, 0, 1, 4688},
+ {0x0, 0, 1, 4689},
+ {0x0, 3, 4, 4690},
+ {0x0, 0, 1, 4691},
+ {0x0, 2, 7, 4692},
+ {0x1ead, 16, 16, 4697},
+ {0x0, 9, 10, 4697},
+ {0x2f913, 16, 16, 4698},
+ {0x1eb7, 16, 16, 4698},
+ {0x0, 0, 1, 4698},
+ {0x0, 0, 1, 4699},
+ {0x0, 3, 4, 4700},
+ {0x0, 0, 4, 4701},
+ {0x0, 0, 13, 4705},
+ {0x147, 16, 16, 4718},
+ {0x0, 11, 14, 4718},
+ {0xfa09, 16, 16, 4721},
+ {0x0, 8, 9, 4721},
+ {0x2f83d, 16, 16, 4722},
+ {0x0, 10, 12, 4722},
+ {0x0, 7, 8, 4724},
+ {0x2f987, 16, 16, 4725},
+ {0x0, 3, 4, 4725},
+ {0x2f951, 16, 16, 4726},
+ {0x0, 5, 9, 4726},
+ {0x0, 14, 15, 4730},
+ {0x2f910, 16, 16, 4731},
+ {0xfa54, 16, 16, 4731},
+ {0x0, 10, 11, 4731},
+ {0xfa46, 16, 16, 4732},
+ {0x0, 3, 4, 4732},
+ {0x2f86d, 16, 16, 4733},
+ {0x0, 0, 16, 4733},
+ {0x1ecf, 16, 16, 4749},
+ {0xf6, 16, 16, 4749},
+ {0x14d, 16, 16, 4749},
+ {0x0, 3, 4, 4749},
+ {0x2f9a0, 16, 16, 4750},
+ {0x14f, 16, 16, 4750},
+ {0xf3, 16, 16, 4750},
+ {0xf2, 16, 16, 4750},
+ {0xf5, 16, 16, 4750},
+ {0xf4, 16, 16, 4750},
+ {0x0, 5, 6, 4750},
+ {0x2f8c0, 16, 16, 4751},
+ {0x0, 6, 7, 4751},
+ {0x2f841, 16, 16, 4752},
+ {0x0, 0, 1, 4752},
+ {0x0, 0, 1, 4753},
+ {0x0, 3, 4, 4754},
+ {0x0, 4, 5, 4755},
+ {0x0, 5, 6, 4756},
+ {0x1f9d, 16, 16, 4757},
+ {0x0, 15, 16, 4757},
+ {0xf93c, 16, 16, 4758},
+ {0x0, 0, 13, 4758},
+ {0xf9fd, 16, 16, 4771},
+ {0x0, 0, 2, 4771},
+ {0x1f65, 16, 16, 4773},
+ {0x1f63, 16, 16, 4773},
+ {0x2f8ae, 16, 16, 4773},
+ {0x0, 0, 1, 4773},
+ {0x0, 0, 1, 4774},
+ {0x0, 3, 4, 4775},
+ {0x0, 0, 1, 4776},
+ {0x0, 4, 5, 4777},
+ {0x231, 16, 16, 4778},
+ {0x0, 2, 4, 4778},
+ {0x2f942, 16, 16, 4780},
+ {0x2f941, 16, 16, 4780},
+ {0xf951, 16, 16, 4780},
+ {0x0, 8, 9, 4780},
+ {0x2f8ee, 16, 16, 4781},
+ {0x2f819, 16, 16, 4781},
+ {0x20d, 16, 16, 4781},
+ {0x1d2, 16, 16, 4781},
+ {0x151, 16, 16, 4781},
+ {0x0, 0, 1, 4781},
+ {0x0, 0, 1, 4782},
+ {0x0, 3, 4, 4783},
+ {0x0, 0, 3, 4784},
+ {0x0, 3, 4, 4787},
+ {0x1e7f, 16, 16, 4788},
+ {0x0, 14, 15, 4788},
+ {0x2f80c, 16, 16, 4789},
+ {0x2f828, 16, 16, 4789},
+ {0x0, 15, 16, 4789},
+ {0x2f980, 16, 16, 4790},
+ {0x0, 5, 10, 4790},
+ {0x2f931, 16, 16, 4795},
+ {0x0, 14, 15, 4795},
+ {0x2f98d, 16, 16, 4796},
+ {0x0, 9, 10, 4796},
+ {0xfa63, 16, 16, 4797},
+ {0xf994, 16, 16, 4797},
+ {0x0, 14, 16, 4797},
+ {0x2f947, 16, 16, 4799},
+ {0x0, 2, 8, 4799},
+ {0x0, 0, 1, 4805},
+ {0x0, 0, 1, 4806},
+ {0x0, 3, 4, 4807},
+ {0x0, 3, 4, 4808},
+ {0x0, 8, 9, 4809},
+ {0x2289, 16, 16, 4810},
+ {0x0, 13, 14, 4810},
+ {0x0, 1, 2, 4811},
+ {0x2f90d, 16, 16, 4812},
+ {0x0, 7, 8, 4812},
+ {0x2f8a5, 16, 16, 4813},
+ {0x0, 5, 11, 4813},
+ {0xf9a7, 16, 16, 4819},
+ {0x0, 9, 12, 4819},
+ {0x2f813, 16, 16, 4822},
+ {0x0, 8, 10, 4822},
+ {0x0, 15, 16, 4824},
+ {0x2f939, 16, 16, 4825},
+ {0x0, 0, 1, 4825},
+ {0x0, 0, 1, 4826},
+ {0x0, 3, 4, 4827},
+ {0x0, 0, 1, 4828},
+ {0x0, 0, 10, 4829},
+ {0x1ec1, 16, 16, 4839},
+ {0x0, 10, 11, 4839},
+ {0xf911, 16, 16, 4840},
+ {0x2f928, 16, 16, 4840},
+ {0x0, 11, 12, 4840},
+ {0xf9c8, 16, 16, 4841},
+ {0x0, 0, 1, 4841},
+ {0xf962, 16, 16, 4842},
+ {0x0, 14, 15, 4842},
+ {0xf957, 16, 16, 4843},
+ {0x0, 0, 1, 4843},
+ {0x0, 0, 1, 4844},
+ {0x0, 3, 4, 4845},
+ {0x0, 0, 1, 4846},
+ {0x0, 4, 5, 4847},
+ {0x1e1, 16, 16, 4848},
+ {0x0, 1, 2, 4848},
+ {0x1e6e, 16, 16, 4849},
+ {0x0, 10, 11, 4849},
+ {0x2f8aa, 16, 16, 4850},
+ {0x0, 8, 9, 4850},
+ {0xf9c5, 16, 16, 4851},
+ {0x0, 0, 1, 4851},
+ {0x0, 0, 1, 4852},
+ {0x0, 3, 4, 4853},
+ {0x0, 0, 1, 4854},
+ {0x0, 4, 5, 4855},
+ {0x1df, 16, 16, 4856},
+ {0x0, 0, 2, 4856},
+ {0x1f02, 16, 16, 4858},
+ {0x1f04, 16, 16, 4858},
+ {0x0, 14, 15, 4858},
+ {0xf984, 16, 16, 4859},
+ {0x0, 2, 3, 4859},
+ {0x0, 5, 6, 4860},
+ {0x0, 0, 1, 4861},
+ {0x0, 1, 2, 4862},
+ {0x0, 0, 1, 4863},
+ {0x0, 2, 3, 4864},
+ {0x0, 14, 15, 4865},
+ {0x1026, 16, 16, 4866},
+ {0x0, 14, 15, 4866},
+ {0x2f8fa, 16, 16, 4867},
+ {0x2f9ca, 16, 16, 4867},
+ {0x0, 0, 1, 4867},
+ {0x0, 0, 1, 4868},
+ {0x0, 3, 4, 4869},
+ {0x0, 0, 5, 4870},
+ {0x0, 0, 2, 4875},
+ {0x1f25, 16, 16, 4877},
+ {0x0, 11, 16, 4877},
+ {0x2f806, 16, 16, 4882},
+ {0x0, 1, 2, 4882},
+ {0x202, 16, 16, 4883},
+ {0x0, 0, 1, 4883},
+ {0x2f8b7, 16, 16, 4884},
+ {0x0, 2, 3, 4884},
+ {0x2f982, 16, 16, 4885},
+ {0x0, 8, 10, 4885},
+ {0x0, 0, 1, 4887},
+ {0x0, 0, 1, 4888},
+ {0x0, 3, 4, 4889},
+ {0x0, 0, 1, 4890},
+ {0x0, 8, 9, 4891},
+ {0x4ea, 16, 16, 4892},
+ {0x0, 0, 1, 4892},
+ {0xf98f, 16, 16, 4893},
+ {0x0, 13, 15, 4893},
+ {0x0, 13, 14, 4895},
+ {0x2f9e1, 16, 16, 4896},
+ {0x0, 0, 1, 4896},
+ {0x0, 0, 1, 4897},
+ {0x0, 3, 4, 4898},
+ {0x0, 0, 2, 4899},
+ {0x0, 0, 2, 4901},
+ {0x38c, 16, 16, 4903},
+ {0x0, 2, 7, 4903},
+ {0xf90d, 16, 16, 4908},
+ {0x0, 2, 3, 4908},
+ {0x2f875, 16, 16, 4909},
+ {0x0, 14, 15, 4909},
+ {0xf9d2, 16, 16, 4910},
+ {0x0, 10, 11, 4910},
+ {0xf902, 16, 16, 4911},
+ {0x22f, 16, 16, 4911},
+ {0x0, 2, 3, 4911},
+ {0x1f56, 16, 16, 4912},
+ {0x0, 3, 8, 4912},
+ {0x15e, 16, 16, 4917},
+ {0x218, 16, 16, 4917},
+ {0x1e62, 16, 16, 4917},
+ {0x0, 2, 7, 4917},
+ {0xf9ba, 16, 16, 4922},
+ {0xf91b, 16, 16, 4922},
+ {0x0, 3, 10, 4922},
+ {0x0, 6, 7, 4929},
+ {0x2f916, 16, 16, 4930},
+ {0x0, 0, 1, 4930},
+ {0x0, 0, 1, 4931},
+ {0x0, 3, 4, 4932},
+ {0x0, 3, 4, 4933},
+ {0x0, 8, 9, 4934},
+ {0x22ae, 16, 16, 4935},
+ {0x0, 7, 8, 4935},
+ {0x2f973, 16, 16, 4936},
+ {0x0, 0, 1, 4936},
+ {0x0, 0, 1, 4937},
+ {0x0, 3, 4, 4938},
+ {0x0, 4, 5, 4939},
+ {0x0, 5, 6, 4940},
+ {0x1fa6, 16, 16, 4941},
+ {0x0, 0, 1, 4941},
+ {0x0, 0, 1, 4942},
+ {0x0, 3, 4, 4943},
+ {0x0, 0, 1, 4944},
+ {0x0, 0, 2, 4945},
+ {0x1f42, 16, 16, 4947},
+ {0x1f44, 16, 16, 4947},
+ {0x0, 3, 4, 4947},
+ {0x2f843, 16, 16, 4948},
+ {0x0, 10, 11, 4948},
+ {0x0, 3, 4, 4949},
+ {0x2f8ec, 16, 16, 4950},
+ {0x0, 0, 10, 4950},
+ {0x1edd, 16, 16, 4960},
+ {0x1edb, 16, 16, 4960},
+ {0x0, 15, 16, 4960},
+ {0xf9eb, 16, 16, 4961},
+ {0x1ee1, 16, 16, 4961},
+ {0x1edf, 16, 16, 4961},
+ {0x622, 16, 16, 4961},
+ {0x0, 0, 1, 4961},
+ {0x0, 3, 4, 4962},
+ {0x0, 0, 1, 4963},
+ {0x0, 9, 10, 4964},
+ {0x0, 9, 11, 4965},
+ {0x30d3, 16, 16, 4967},
+ {0x0, 1, 4, 4967},
+ {0x0, 12, 13, 4970},
+ {0x2f8a2, 16, 16, 4971},
+ {0x0, 0, 1, 4971},
+ {0xf944, 16, 16, 4972},
+ {0x0, 0, 1, 4972},
+ {0x1e2c, 16, 16, 4973},
+ {0x0, 0, 1, 4973},
+ {0x0, 0, 1, 4974},
+ {0x0, 3, 4, 4975},
+ {0x0, 0, 4, 4976},
+ {0x0, 3, 8, 4980},
+ {0x1e33, 16, 16, 4985},
+ {0x0, 2, 3, 4985},
+ {0x2f888, 16, 16, 4986},
+ {0x0, 4, 5, 4986},
+ {0x2f80f, 16, 16, 4987},
+ {0x0, 0, 10, 4987},
+ {0x0, 14, 15, 4997},
+ {0x2fa13, 16, 16, 4998},
+ {0x0, 2, 3, 4998},
+ {0x2f960, 16, 16, 4999},
+ {0x0, 8, 9, 4999},
+ {0x0, 0, 1, 5000},
+ {0x0, 0, 1, 5001},
+ {0x0, 9, 10, 5002},
+ {0x0, 3, 4, 5003},
+ {0x0, 12, 13, 5004},
+ {0x929, 16, 16, 5005},
+ {0x0, 0, 1, 5005},
+ {0x0, 10, 11, 5006},
+ {0x2f8ca, 16, 16, 5007},
+ {0x0, 0, 1, 5007},
+ {0x0, 0, 1, 5008},
+ {0x0, 3, 4, 5009},
+ {0x0, 0, 5, 5010},
+ {0x0, 2, 6, 5015},
+ {0x1fa8, 16, 16, 5019},
+ {0x0, 0, 1, 5019},
+ {0x0, 0, 1, 5020},
+ {0x0, 3, 4, 5021},
+ {0x0, 4, 5, 5022},
+ {0x0, 5, 6, 5023},
+ {0x1f9e, 16, 16, 5024},
+ {0x0, 0, 1, 5024},
+ {0x0, 3, 4, 5025},
+ {0x0, 0, 1, 5026},
+ {0x0, 9, 10, 5027},
+ {0x0, 9, 10, 5028},
+ {0x30fe, 16, 16, 5029},
+ {0x0, 2, 13, 5029},
+ {0x1e27, 16, 16, 5040},
+ {0x1e23, 16, 16, 5040},
+ {0x125, 16, 16, 5040},
+ {0x0, 4, 5, 5040},
+ {0x2f8f1, 16, 16, 5041},
+ {0x0, 3, 5, 5041},
+ {0x1f60, 16, 16, 5043},
+ {0x0, 4, 5, 5043},
+ {0x2f971, 16, 16, 5044},
+ {0x30d4, 16, 16, 5044},
+ {0x1f61, 16, 16, 5044},
+ {0x0, 0, 1, 5044},
+ {0x0, 3, 4, 5045},
+ {0x0, 0, 1, 5046},
+ {0x0, 9, 10, 5047},
+ {0x0, 9, 10, 5048},
+ {0x304c, 16, 16, 5049},
+ {0x0, 0, 1, 5049},
+ {0x0, 0, 1, 5050},
+ {0x0, 3, 4, 5051},
+ {0x0, 0, 1, 5052},
+ {0x0, 1, 2, 5053},
+ {0x1e78, 16, 16, 5054},
+ {0x0, 0, 1, 5054},
+ {0x0, 3, 4, 5055},
+ {0x0, 0, 1, 5056},
+ {0x0, 9, 10, 5057},
+ {0x0, 9, 11, 5058},
+ {0x30d9, 16, 16, 5060},
+ {0x0, 8, 9, 5060},
+ {0xf9b3, 16, 16, 5061},
+ {0x0, 11, 15, 5061},
+ {0x2f914, 16, 16, 5065},
+ {0x0, 8, 14, 5065},
+ {0xfa5c, 16, 16, 5071},
+ {0x0, 0, 2, 5071},
+ {0x1f34, 16, 16, 5073},
+ {0x2f915, 16, 16, 5073},
+ {0x0, 0, 1, 5073},
+ {0x0, 0, 1, 5074},
+ {0x0, 3, 4, 5075},
+ {0x0, 4, 5, 5076},
+ {0x0, 5, 6, 5077},
+ {0x1f85, 16, 16, 5078},
+ {0x0, 4, 15, 5078},
+ {0x2f907, 16, 16, 5089},
+ {0x0, 2, 3, 5089},
+ {0x2f8bf, 16, 16, 5090},
+ {0x0, 15, 16, 5090},
+ {0xf937, 16, 16, 5091},
+ {0x2126, 0, 1, 5091},
+ {0x0, 0, 1, 5092},
+ {0x0, 3, 4, 5093},
+ {0x0, 0, 5, 5094},
+ {0x0, 0, 2, 5099},
+ {0x1ffa, 16, 16, 5101},
+ {0x38f, 16, 16, 5101},
+ {0x0, 4, 13, 5101},
+ {0x0, 0, 1, 5110},
+ {0x0, 0, 1, 5111},
+ {0x0, 3, 4, 5112},
+ {0x0, 0, 1, 5113},
+ {0x0, 1, 2, 5114},
+ {0x1ff, 16, 16, 5115},
+ {0x0, 0, 1, 5115},
+ {0x0, 0, 1, 5116},
+ {0x0, 3, 4, 5117},
+ {0x0, 4, 5, 5118},
+ {0x0, 5, 6, 5119},
+ {0x1f84, 16, 16, 5120},
+ {0xf9f6, 16, 16, 5120},
+ {0x0, 8, 10, 5120},
+ {0x2329, 16, 16, 5122},
+ {0x232a, 16, 16, 5122},
+ {0x0, 0, 1, 5122},
+ {0x0, 0, 1, 5123},
+ {0x0, 3, 4, 5124},
+ {0x0, 3, 4, 5125},
+ {0x0, 8, 9, 5126},
+ {0x2274, 16, 16, 5127},
+ {0x30da, 16, 16, 5127},
+ {0x0, 4, 13, 5127},
+ {0x0, 0, 1, 5136},
+ {0x0, 0, 1, 5137},
+ {0x0, 3, 4, 5138},
+ {0x0, 0, 1, 5139},
+ {0x0, 0, 10, 5140},
+ {0x1ed4, 16, 16, 5150},
+ {0x0, 4, 5, 5150},
+ {0xfa34, 16, 16, 5151},
+ {0x1ed0, 16, 16, 5151},
+ {0x1ed2, 16, 16, 5151},
+ {0x1ed6, 16, 16, 5151},
+ {0x2f900, 16, 16, 5151},
+ {0x0, 4, 5, 5151},
+ {0x2f940, 16, 16, 5152},
+ {0x0, 0, 1, 5152},
+ {0x0, 0, 1, 5153},
+ {0x0, 3, 4, 5154},
+ {0x0, 0, 1, 5155},
+ {0x0, 1, 9, 5156},
+ {0x1e4e, 16, 16, 5164},
+ {0x1e4c, 16, 16, 5164},
+ {0x22c, 16, 16, 5164},
+ {0x0, 9, 15, 5164},
+ {0x2fa18, 16, 16, 5170},
+ {0x0, 12, 13, 5170},
+ {0x0, 8, 9, 5171},
+ {0x2f86c, 16, 16, 5172},
+ {0x0, 7, 8, 5172},
+ {0x2fa0f, 16, 16, 5173},
+ {0x0, 1, 3, 5173},
+ {0x0, 0, 1, 5175},
+ {0x0, 0, 1, 5176},
+ {0x0, 3, 4, 5177},
+ {0x0, 3, 4, 5178},
+ {0x0, 8, 9, 5179},
+ {0x22e2, 16, 16, 5180},
+ {0x0, 4, 5, 5180},
+ {0xfa06, 16, 16, 5181},
+ {0x0, 0, 1, 5181},
+ {0x0, 0, 1, 5182},
+ {0x0, 3, 4, 5183},
+ {0x0, 0, 4, 5184},
+ {0x0, 1, 16, 5188},
+ {0x155, 16, 16, 5203},
+ {0x0, 8, 9, 5203},
+ {0xfa3e, 16, 16, 5204},
+ {0x0, 0, 1, 5204},
+ {0xf93d, 16, 16, 5205},
+ {0x0, 0, 8, 5205},
+ {0x0, 0, 1, 5213},
+ {0x0, 0, 1, 5214},
+ {0x0, 3, 4, 5215},
+ {0x0, 0, 3, 5216},
+ {0x0, 3, 4, 5219},
+ {0x1ef1, 16, 16, 5220},
+ {0x0, 6, 7, 5220},
+ {0x2f935, 16, 16, 5221},
+ {0x2fa17, 16, 16, 5221},
+ {0x0, 14, 15, 5221},
+ {0xfa48, 16, 16, 5222},
+ {0x0, 15, 16, 5222},
+ {0xf939, 16, 16, 5223},
+ {0x0, 0, 1, 5223},
+ {0x0, 0, 1, 5224},
+ {0x0, 3, 4, 5225},
+ {0x0, 0, 1, 5226},
+ {0x0, 12, 13, 5227},
+ {0x1ee, 16, 16, 5228},
+ {0x0, 8, 9, 5228},
+ {0x2fa11, 16, 16, 5229},
+ {0x0, 8, 9, 5229},
+ {0x2f97e, 16, 16, 5230},
+ {0x0, 4, 5, 5230},
+ {0xfa12, 16, 16, 5231},
+ {0x0, 0, 1, 5231},
+ {0x0, 3, 4, 5232},
+ {0x0, 0, 1, 5233},
+ {0x0, 9, 10, 5234},
+ {0x0, 9, 10, 5235},
+ {0x305c, 16, 16, 5236},
+ {0x0, 10, 11, 5236},
+ {0x2f954, 16, 16, 5237},
+ {0x0, 7, 13, 5237},
+ {0x1e6a, 16, 16, 5243},
+ {0x0, 0, 1, 5243},
+ {0x0, 0, 1, 5244},
+ {0x0, 3, 4, 5245},
+ {0x0, 0, 1, 5246},
+ {0x0, 1, 2, 5247},
+ {0x344, 16, 16, 5248},
+ {0x0, 0, 1, 5248},
+ {0x0, 0, 1, 5249},
+ {0x0, 3, 4, 5250},
+ {0x0, 0, 1, 5251},
+ {0x0, 0, 2, 5252},
+ {0x1f45, 16, 16, 5254},
+ {0x1f43, 16, 16, 5254},
+ {0x0, 0, 1, 5254},
+ {0x0, 0, 1, 5255},
+ {0x0, 3, 4, 5256},
+ {0x0, 0, 4, 5257},
+ {0x0, 1, 2, 5261},
+ {0x1e94, 16, 16, 5262},
+ {0x0, 15, 16, 5262},
+ {0xf9bd, 16, 16, 5263},
+ {0x0, 1, 13, 5263},
+ {0xfa43, 16, 16, 5275},
+ {0x0, 0, 1, 5275},
+ {0x0, 0, 1, 5276},
+ {0x0, 3, 4, 5277},
+ {0x0, 0, 1, 5278},
+ {0x0, 0, 2, 5279},
+ {0x1e51, 16, 16, 5281},
+ {0x1e53, 16, 16, 5281},
+ {0x0, 3, 4, 5281},
+ {0x2f889, 16, 16, 5282},
+ {0x0, 3, 9, 5282},
+ {0x104, 16, 16, 5288},
+ {0x164, 16, 16, 5288},
+ {0x0, 7, 8, 5288},
+ {0x2fa05, 16, 16, 5289},
+ {0x1ea0, 16, 16, 5289},
+ {0x1e00, 16, 16, 5289},
+ {0x0, 13, 14, 5289},
+ {0x0, 0, 1, 5290},
+ {0x0, 3, 4, 5291},
+ {0x0, 0, 1, 5292},
+ {0x0, 9, 10, 5293},
+ {0x0, 9, 10, 5294},
+ {0x309e, 16, 16, 5295},
+ {0x0, 2, 3, 5295},
+ {0x2f840, 16, 16, 5296},
+ {0x0, 10, 11, 5296},
+ {0x2f948, 16, 16, 5297},
+ {0x2f8d5, 16, 16, 5297},
+ {0x0, 11, 12, 5297},
+ {0xf9f7, 16, 16, 5298},
+ {0x0, 0, 1, 5298},
+ {0x0, 0, 1, 5299},
+ {0x0, 3, 4, 5300},
+ {0x0, 0, 1, 5301},
+ {0x0, 6, 9, 5302},
+ {0x4c1, 16, 16, 5305},
+ {0x1f24, 16, 16, 5305},
+ {0x0, 0, 1, 5305},
+ {0x0, 0, 1, 5306},
+ {0x0, 3, 4, 5307},
+ {0x0, 0, 5, 5308},
+ {0x0, 2, 6, 5313},
+ {0x1f6f, 16, 16, 5317},
+ {0x4dc, 16, 16, 5317},
+ {0x0, 0, 1, 5317},
+ {0x0, 0, 1, 5318},
+ {0x0, 3, 4, 5319},
+ {0x0, 0, 1, 5320},
+ {0x0, 1, 2, 5321},
+ {0x1fe, 16, 16, 5322},
+ {0x1fa9, 16, 16, 5322},
+ {0x0, 13, 14, 5322},
+ {0x2f99b, 16, 16, 5323},
+ {0x0, 0, 1, 5323},
+ {0x0, 0, 1, 5324},
+ {0x0, 3, 4, 5325},
+ {0x0, 3, 4, 5326},
+ {0x0, 8, 9, 5327},
+ {0x2204, 16, 16, 5328},
+ {0x0, 10, 12, 5328},
+ {0x0, 8, 9, 5330},
+ {0x2f92d, 16, 16, 5331},
+ {0x0, 0, 1, 5331},
+ {0x0, 0, 1, 5332},
+ {0x0, 3, 4, 5333},
+ {0x0, 0, 1, 5334},
+ {0x0, 0, 10, 5335},
+ {0x1ec2, 16, 16, 5345},
+ {0x1ebe, 16, 16, 5345},
+ {0x1ec0, 16, 16, 5345},
+ {0x1ec4, 16, 16, 5345},
+ {0x0, 2, 3, 5345},
+ {0x2f9e0, 16, 16, 5346},
+ {0x0, 2, 3, 5346},
+ {0x0, 12, 13, 5347},
+ {0x2f834, 16, 16, 5348},
+ {0x0, 7, 9, 5348},
+ {0x2f904, 16, 16, 5350},
+ {0x0, 6, 7, 5350},
+ {0x0, 0, 1, 5351},
+ {0x0, 0, 1, 5352},
+ {0x0, 3, 4, 5353},
+ {0x0, 0, 1, 5354},
+ {0x0, 8, 9, 5355},
+ {0x457, 16, 16, 5356},
+ {0x0, 0, 1, 5356},
+ {0x0, 0, 1, 5357},
+ {0x0, 3, 4, 5358},
+ {0x0, 0, 2, 5359},
+ {0x0, 0, 2, 5361},
+ {0x3ad, 16, 16, 5363},
+ {0x0, 0, 14, 5363},
+ {0x0, 8, 9, 5377},
+ {0x2f8eb, 16, 16, 5378},
+ {0x0, 0, 1, 5378},
+ {0x0, 0, 1, 5379},
+ {0x0, 3, 4, 5380},
+ {0x0, 0, 3, 5381},
+ {0x0, 3, 8, 5384},
+ {0x1e63, 16, 16, 5389},
+ {0x15f, 16, 16, 5389},
+ {0x219, 16, 16, 5389},
+ {0x0, 0, 1, 5389},
+ {0x0, 0, 1, 5390},
+ {0x0, 3, 4, 5391},
+ {0x0, 3, 4, 5392},
+ {0x0, 8, 9, 5393},
+ {0x2285, 16, 16, 5394},
+ {0x4ef, 16, 16, 5394},
+ {0xcf, 16, 16, 5394},
+ {0x0, 0, 1, 5394},
+ {0x0, 0, 1, 5395},
+ {0x0, 13, 14, 5396},
+ {0x0, 12, 14, 5397},
+ {0x0, 15, 16, 5399},
+ {0xdde, 16, 16, 5400},
+ {0x4f1, 16, 16, 5400},
+ {0x130, 16, 16, 5400},
+ {0x12a, 16, 16, 5400},
+ {0xce, 16, 16, 5400},
+ {0x128, 16, 16, 5400},
+ {0xcc, 16, 16, 5400},
+ {0xcd, 16, 16, 5400},
+ {0x0, 10, 11, 5400},
+ {0x2f8ea, 16, 16, 5401},
+ {0x0, 2, 6, 5401},
+ {0x1fc3, 16, 16, 5405},
+ {0x0, 7, 8, 5405},
+ {0x1e02, 16, 16, 5406},
+ {0x1fc6, 16, 16, 5406},
+ {0x0, 2, 4, 5406},
+ {0x0, 0, 1, 5408},
+ {0x0, 0, 1, 5409},
+ {0x0, 3, 4, 5410},
+ {0x0, 0, 1, 5411},
+ {0x0, 0, 10, 5412},
+ {0x1eaf, 16, 16, 5422},
+ {0x0, 2, 16, 5422},
+ {0x2fa02, 16, 16, 5436},
+ {0x0, 2, 6, 5436},
+ {0x1fb3, 16, 16, 5440},
+ {0x0, 0, 1, 5440},
+ {0x0, 0, 1, 5441},
+ {0x0, 3, 4, 5442},
+ {0x0, 0, 1, 5443},
+ {0x0, 8, 9, 5444},
+ {0x4f4, 16, 16, 5445},
+ {0x1fb6, 16, 16, 5445},
+ {0x0, 6, 7, 5445},
+ {0xfa1c, 16, 16, 5446},
+ {0x0, 2, 3, 5446},
+ {0x1f37, 16, 16, 5447},
+ {0x0, 13, 14, 5447},
+ {0x2f815, 16, 16, 5448},
+ {0x0, 11, 12, 5448},
+ {0x2f855, 16, 16, 5449},
+ {0x0, 12, 14, 5449},
+ {0x2f8fd, 16, 16, 5451},
+ {0x4f3, 16, 16, 5451},
+ {0xf968, 16, 16, 5451},
+ {0x208, 16, 16, 5451},
+ {0x0, 1, 2, 5451},
+ {0xf90a, 16, 16, 5452},
+ {0x1cf, 16, 16, 5452},
+ {0x0, 14, 15, 5452},
+ {0xf9c6, 16, 16, 5453},
+ {0xfa2a, 16, 16, 5453},
+ {0x0, 3, 5, 5453},
+ {0x1f68, 16, 16, 5455},
+ {0x1f69, 16, 16, 5455},
+ {0x0, 1, 5, 5455},
+ {0x2f98c, 16, 16, 5459},
+ {0x2f893, 16, 16, 5459},
+ {0x0, 8, 9, 5459},
+ {0xf926, 16, 16, 5460},
+ {0x0, 3, 9, 5460},
+ {0x1ecd, 16, 16, 5466},
+ {0x0, 0, 1, 5466},
+ {0x0, 3, 4, 5467},
+ {0x0, 0, 1, 5468},
+ {0x0, 9, 10, 5469},
+ {0x0, 9, 10, 5470},
+ {0x3052, 16, 16, 5471},
+ {0x1eb, 16, 16, 5471},
+ {0x0, 0, 10, 5471},
+ {0xf975, 16, 16, 5481},
+ {0x2f8c1, 16, 16, 5481},
+ {0x0, 0, 1, 5481},
+ {0x0, 0, 1, 5482},
+ {0x0, 3, 4, 5483},
+ {0x0, 0, 4, 5484},
+ {0x0, 7, 13, 5488},
+ {0x1e0a, 16, 16, 5494},
+ {0x0, 0, 1, 5494},
+ {0x2f9dc, 16, 16, 5495},
+ {0x0, 0, 1, 5495},
+ {0x1e1b, 16, 16, 5496},
+ {0x0, 2, 15, 5496},
+ {0xf952, 16, 16, 5509},
+ {0x0, 13, 14, 5509},
+ {0xfa1e, 16, 16, 5510},
+ {0x0, 4, 5, 5510},
+ {0x2f8d1, 16, 16, 5511},
+ {0x10e, 16, 16, 5511},
+ {0x0, 14, 15, 5511},
+ {0xf977, 16, 16, 5512},
+ {0x0, 0, 1, 5512},
+ {0xfa60, 16, 16, 5513},
+ {0x0, 10, 12, 5513},
+ {0x0, 1, 2, 5515},
+ {0x2f93b, 16, 16, 5516},
+ {0x0, 3, 4, 5516},
+ {0x1e7d, 16, 16, 5517},
+ {0x0, 0, 1, 5517},
+ {0x0, 0, 1, 5518},
+ {0x0, 3, 4, 5519},
+ {0x0, 4, 5, 5520},
+ {0x0, 5, 6, 5521},
+ {0x1fac, 16, 16, 5522},
+ {0x0, 1, 2, 5522},
+ {0x0, 8, 9, 5523},
+ {0x2f871, 16, 16, 5524},
+ {0x0, 10, 13, 5524},
+ {0xf947, 16, 16, 5527},
+ {0x2f950, 16, 16, 5527},
+ {0x0, 0, 1, 5527},
+ {0x0, 0, 1, 5528},
+ {0x0, 3, 4, 5529},
+ {0x0, 4, 5, 5530},
+ {0x0, 5, 6, 5531},
+ {0x1ff7, 16, 16, 5532},
+ {0x0, 10, 15, 5532},
+ {0xf96c, 16, 16, 5537},
+ {0x0, 0, 1, 5537},
+ {0x0, 0, 1, 5538},
+ {0x0, 3, 4, 5539},
+ {0x0, 0, 1, 5540},
+ {0x0, 8, 9, 5541},
+ {0x4ec, 16, 16, 5542},
+ {0xfa10, 16, 16, 5542},
+ {0x0, 0, 10, 5542},
+ {0x0, 10, 11, 5552},
+ {0x2f9fb, 16, 16, 5553},
+ {0xf92f, 16, 16, 5553},
+ {0x0, 6, 7, 5553},
+ {0xf98b, 16, 16, 5554},
+ {0x0, 4, 5, 5554},
+ {0x2f8e6, 16, 16, 5555},
+ {0x0, 0, 1, 5555},
+ {0x0, 0, 1, 5556},
+ {0x0, 3, 4, 5557},
+ {0x0, 4, 5, 5558},
+ {0x0, 5, 6, 5559},
+ {0x1fab, 16, 16, 5560},
+ {0x0, 7, 8, 5560},
+ {0x0, 7, 8, 5561},
+ {0x2f9f1, 16, 16, 5562},
+ {0x0, 0, 1, 5562},
+ {0x0, 0, 1, 5563},
+ {0x0, 3, 4, 5564},
+ {0x0, 0, 1, 5565},
+ {0x0, 4, 5, 5566},
+ {0x22a, 16, 16, 5567},
+ {0x0, 0, 1, 5567},
+ {0x0, 0, 1, 5568},
+ {0x0, 3, 4, 5569},
+ {0x0, 3, 4, 5570},
+ {0x0, 8, 9, 5571},
+ {0x219a, 16, 16, 5572},
+ {0xf92e, 16, 16, 5572},
+ {0xf965, 16, 16, 5572},
+ {0x0, 0, 1, 5572},
+ {0x0, 0, 1, 5573},
+ {0x0, 3, 4, 5574},
+ {0x0, 0, 4, 5575},
+ {0x0, 7, 13, 5579},
+ {0x165, 16, 16, 5585},
+ {0x0, 2, 6, 5585},
+ {0x1f99, 16, 16, 5589},
+ {0x1f2f, 16, 16, 5589},
+ {0x0, 0, 1, 5589},
+ {0x0, 0, 1, 5590},
+ {0x0, 3, 4, 5591},
+ {0x0, 0, 1, 5592},
+ {0x0, 8, 9, 5593},
+ {0x4de, 16, 16, 5594},
+ {0x0, 14, 15, 5594},
+ {0xfa1d, 16, 16, 5595},
+ {0x1ec3, 16, 16, 5595},
+ {0x0, 0, 1, 5595},
+ {0x0, 0, 1, 5596},
+ {0x0, 3, 4, 5597},
+ {0x0, 0, 2, 5598},
+ {0x0, 0, 2, 5600},
+ {0x1f78, 16, 16, 5602},
+ {0x3cc, 16, 16, 5602},
+ {0x1ec5, 16, 16, 5602},
+ {0x1ebf, 16, 16, 5602},
+ {0x0, 11, 12, 5602},
+ {0x2fa1c, 16, 16, 5603},
+ {0x0, 3, 15, 5603},
+ {0x2f8db, 16, 16, 5615},
+ {0x0, 1, 2, 5615},
+ {0xf904, 16, 16, 5616},
+ {0x0, 3, 4, 5616},
+ {0x1e92, 16, 16, 5617},
+ {0x0, 1, 2, 5617},
+ {0x2f9c1, 16, 16, 5618},
+ {0x1e6b, 16, 16, 5618},
+ {0x1e97, 16, 16, 5618},
+ {0x0, 0, 1, 5618},
+ {0x0, 0, 1, 5619},
+ {0x0, 3, 4, 5620},
+ {0x0, 4, 5, 5621},
+ {0x0, 5, 6, 5622},
+ {0x1ff2, 16, 16, 5623},
+ {0x0, 0, 1, 5623},
+ {0x0, 0, 1, 5624},
+ {0x0, 3, 4, 5625},
+ {0x0, 0, 2, 5626},
+ {0x0, 0, 9, 5628},
+ {0x3aa, 16, 16, 5637},
+ {0x0, 0, 1, 5637},
+ {0x0, 0, 1, 5638},
+ {0x0, 3, 4, 5639},
+ {0x0, 0, 1, 5640},
+ {0x0, 6, 9, 5641},
+ {0x4c2, 16, 16, 5644},
+ {0x4dd, 16, 16, 5644},
+ {0x0, 8, 9, 5644},
+ {0x2f885, 16, 16, 5645},
+ {0x1fda, 16, 16, 5645},
+ {0x38a, 16, 16, 5645},
+ {0x1fd8, 16, 16, 5645},
+ {0x1fd9, 16, 16, 5645},
+ {0x0, 5, 10, 5645},
+ {0xf9a3, 16, 16, 5650},
+ {0x0, 0, 1, 5650},
+ {0xf921, 16, 16, 5651},
+ {0x2f89f, 16, 16, 5651},
+ {0x0, 0, 1, 5651},
+ {0x0, 0, 1, 5652},
+ {0x0, 3, 4, 5653},
+ {0x0, 3, 4, 5654},
+ {0x0, 8, 9, 5655},
+ {0x2288, 16, 16, 5656},
+ {0x0, 0, 1, 5656},
+ {0x0, 0, 1, 5657},
+ {0x0, 3, 4, 5658},
+ {0x0, 0, 4, 5659},
+ {0x0, 1, 12, 5663},
+ {0x1b0, 16, 16, 5674},
+ {0xf9aa, 16, 16, 5674},
+ {0x0, 2, 3, 5674},
+ {0x0, 0, 1, 5675},
+ {0x0, 0, 1, 5676},
+ {0x0, 3, 4, 5677},
+ {0x0, 0, 1, 5678},
+ {0x0, 12, 13, 5679},
+ {0x1ef, 16, 16, 5680},
+ {0x217, 16, 16, 5680},
+ {0x0, 11, 12, 5680},
+ {0x2f9bd, 16, 16, 5681},
+ {0x0, 0, 1, 5681},
+ {0x0, 0, 1, 5682},
+ {0x0, 3, 4, 5683},
+ {0x0, 0, 4, 5684},
+ {0x0, 0, 1, 5688},
+ {0x1e74, 16, 16, 5689},
+ {0x0, 0, 1, 5689},
+ {0x0, 0, 1, 5690},
+ {0x0, 3, 4, 5691},
+ {0x0, 0, 1, 5692},
+ {0x0, 0, 10, 5693},
+ {0x1eb0, 16, 16, 5703},
+ {0x1eae, 16, 16, 5703},
+ {0x1eb4, 16, 16, 5703},
+ {0x1eb2, 16, 16, 5703},
+ {0x0, 8, 9, 5703},
+ {0x2f972, 16, 16, 5704},
+ {0x0, 15, 16, 5704},
+ {0x2f837, 16, 16, 5705},
+ {0x0, 0, 1, 5705},
+ {0x0, 0, 1, 5706},
+ {0x0, 3, 4, 5707},
+ {0x0, 4, 5, 5708},
+ {0x0, 5, 6, 5709},
+ {0x1fa7, 16, 16, 5710},
+ {0x0, 0, 1, 5710},
+ {0x0, 3, 4, 5711},
+ {0x0, 0, 1, 5712},
+ {0x0, 9, 10, 5713},
+ {0x0, 9, 10, 5714},
+ {0x305a, 16, 16, 5715},
+ {0x0, 1, 13, 5715},
+ {0x1e9, 16, 16, 5727},
+ {0x0, 15, 16, 5727},
+ {0x2f908, 16, 16, 5728},
+ {0x0, 15, 16, 5728},
+ {0x2f8fc, 16, 16, 5729},
+ {0xfa51, 16, 16, 5729},
+ {0x0, 13, 14, 5729},
+ {0x2f8e7, 16, 16, 5730},
+ {0x0, 5, 6, 5730},
+ {0x1fbc, 16, 16, 5731},
+ {0x0, 10, 11, 5731},
+ {0x2f8a1, 16, 16, 5732},
+ {0x0, 1, 14, 5732},
+ {0xfa26, 16, 16, 5745},
+ {0x0, 11, 15, 5745},
+ {0x0, 0, 1, 5749},
+ {0x0, 0, 1, 5750},
+ {0x0, 3, 4, 5751},
+ {0x0, 3, 4, 5752},
+ {0x0, 8, 9, 5753},
+ {0x2260, 16, 16, 5754},
+ {0x0, 3, 4, 5754},
+ {0x0, 12, 13, 5755},
+ {0x2f997, 16, 16, 5756},
+ {0x0, 4, 5, 5756},
+ {0x2f853, 16, 16, 5757},
+ {0x3076, 16, 16, 5757},
+ {0x0, 12, 13, 5757},
+ {0xf92b, 16, 16, 5758},
+ {0x0, 2, 3, 5758},
+ {0x0, 2, 3, 5759},
+ {0x2f803, 16, 16, 5760},
+ {0x0, 1, 2, 5760},
+ {0x20a, 16, 16, 5761},
+ {0x0, 0, 1, 5761},
+ {0x0, 0, 1, 5762},
+ {0x0, 12, 13, 5763},
+ {0x0, 12, 14, 5764},
+ {0x0, 2, 3, 5766},
+ {0xcca, 16, 16, 5767},
+ {0x0, 8, 9, 5767},
+ {0x2f865, 16, 16, 5768},
+ {0x1e31, 16, 16, 5768},
+ {0x0, 3, 4, 5768},
+ {0x0, 10, 11, 5769},
+ {0x2f80d, 16, 16, 5770},
+ {0x0, 2, 8, 5770},
+ {0x2f817, 16, 16, 5776},
+ {0x2f8d2, 16, 16, 5776},
+ {0x2f9e3, 16, 16, 5776},
+ {0x0, 0, 2, 5776},
+ {0x1f3c, 16, 16, 5778},
+ {0x1f3a, 16, 16, 5778},
+ {0x0, 6, 8, 5778},
+ {0xb48, 16, 16, 5780},
+ {0xb4c, 16, 16, 5780},
+ {0x0, 0, 1, 5780},
+ {0x0, 0, 1, 5781},
+ {0x0, 3, 4, 5782},
+ {0x0, 3, 4, 5783},
+ {0x0, 8, 9, 5784},
+ {0x2280, 16, 16, 5785},
+ {0x0, 0, 1, 5785},
+ {0x0, 3, 4, 5786},
+ {0x0, 0, 1, 5787},
+ {0x0, 9, 10, 5788},
+ {0x0, 9, 10, 5789},
+ {0x30f4, 16, 16, 5790},
+ {0x0, 6, 8, 5790},
+ {0xf9b2, 16, 16, 5792},
+ {0x0, 3, 8, 5792},
+ {0x1e5b, 16, 16, 5797},
+ {0x0, 0, 1, 5797},
+ {0x0, 0, 1, 5798},
+ {0x0, 3, 4, 5799},
+ {0x0, 0, 1, 5800},
+ {0x0, 8, 9, 5801},
+ {0x4f5, 16, 16, 5802},
+ {0x157, 16, 16, 5802},
+ {0x0, 9, 10, 5802},
+ {0x2f9c2, 16, 16, 5803},
+ {0x0, 5, 6, 5803},
+ {0x2f988, 16, 16, 5804},
+ {0x0, 0, 1, 5804},
+ {0x0, 0, 1, 5805},
+ {0x0, 3, 4, 5806},
+ {0x0, 0, 1, 5807},
+ {0x0, 0, 9, 5808},
+ {0x40d, 16, 16, 5817},
+ {0x0, 0, 1, 5817},
+ {0x0, 0, 1, 5818},
+ {0x0, 3, 4, 5819},
+ {0x0, 0, 1, 5820},
+ {0x0, 1, 8, 5821},
+ {0x1e56, 16, 16, 5828},
+ {0x1e54, 16, 16, 5828},
+ {0x0, 2, 9, 5828},
+ {0x2f83e, 16, 16, 5835},
+ {0x0, 0, 1, 5835},
+ {0x0, 0, 1, 5836},
+ {0x0, 3, 4, 5837},
+ {0x0, 4, 5, 5838},
+ {0x0, 5, 6, 5839},
+ {0x1fa2, 16, 16, 5840},
+ {0xf980, 16, 16, 5840},
+ {0x0, 10, 11, 5840},
+ {0x0, 7, 8, 5841},
+ {0x2f8f0, 16, 16, 5842},
+ {0x0, 14, 15, 5842},
+ {0xd4a, 16, 16, 5843},
+ {0x0, 6, 15, 5843},
+ {0x2f8ff, 16, 16, 5852},
+ {0x0, 0, 1, 5852},
+ {0x0, 0, 1, 5853},
+ {0x0, 3, 4, 5854},
+ {0x0, 0, 3, 5855},
+ {0x0, 3, 4, 5858},
+ {0x1e89, 16, 16, 5859},
+ {0x0, 0, 1, 5859},
+ {0x0, 0, 1, 5860},
+ {0x0, 9, 10, 5861},
+ {0x0, 3, 4, 5862},
+ {0x0, 12, 13, 5863},
+ {0x934, 16, 16, 5864},
+ {0x0, 2, 3, 5864},
+ {0x2f8ac, 16, 16, 5865},
+ {0x0, 4, 5, 5865},
+ {0x2f9ac, 16, 16, 5866},
+ {0x0, 11, 12, 5866},
+ {0x2f816, 16, 16, 5867},
+ {0x0, 14, 15, 5867},
+ {0x2f911, 16, 16, 5868},
+ {0x0, 8, 9, 5868},
+ {0x0, 6, 7, 5869},
+ {0x2f96b, 16, 16, 5870},
+ {0x1e15, 16, 16, 5870},
+ {0x0, 3, 4, 5870},
+ {0x1e05, 16, 16, 5871},
+ {0x0, 8, 9, 5871},
+ {0x2f93f, 16, 16, 5872},
+ {0x0, 8, 9, 5872},
+ {0x2f8d0, 16, 16, 5873},
+ {0x0, 0, 1, 5873},
+ {0x0, 0, 1, 5874},
+ {0x0, 6, 7, 5875},
+ {0x0, 5, 6, 5876},
+ {0x0, 4, 5, 5877},
+ {0x6d3, 16, 16, 5878},
+ {0x0, 1, 2, 5878},
+ {0x1e0e, 16, 16, 5879},
+ {0x0, 7, 10, 5879},
+ {0xfa33, 16, 16, 5882},
+ {0x0, 0, 1, 5882},
+ {0x0, 0, 1, 5883},
+ {0x0, 3, 4, 5884},
+ {0x0, 3, 4, 5885},
+ {0x0, 8, 9, 5886},
+ {0x2279, 16, 16, 5887},
+ {0x0, 2, 12, 5887},
+ {0x0, 1, 2, 5897},
+ {0x2f9b0, 16, 16, 5898},
+ {0x0, 0, 1, 5898},
+ {0xfa39, 16, 16, 5899},
+ {0x2f825, 16, 16, 5899},
+ {0x0, 3, 4, 5899},
+ {0x2f983, 16, 16, 5900},
+ {0xfa05, 16, 16, 5900},
+ {0x0, 9, 10, 5900},
+ {0xf916, 16, 16, 5901},
+ {0xf915, 16, 16, 5901},
+ {0x0, 12, 13, 5901},
+ {0xf908, 16, 16, 5902},
+ {0x0, 9, 13, 5902},
+ {0xf955, 16, 16, 5906},
+ {0x0, 14, 15, 5906},
+ {0xf9e1, 16, 16, 5907},
+ {0x2f8d3, 16, 16, 5907},
+ {0x0, 8, 9, 5907},
+ {0x2f93c, 16, 16, 5908},
+ {0x0, 0, 1, 5908},
+ {0x0, 0, 1, 5909},
+ {0x0, 3, 4, 5910},
+ {0x0, 0, 3, 5911},
+ {0x0, 2, 13, 5914},
+ {0x21e, 16, 16, 5925},
+ {0x0, 0, 1, 5925},
+ {0x0, 0, 1, 5926},
+ {0x0, 3, 4, 5927},
+ {0x0, 0, 1, 5928},
+ {0x0, 6, 9, 5929},
+ {0x4d0, 16, 16, 5932},
+ {0x0, 6, 7, 5932},
+ {0x0, 6, 7, 5933},
+ {0x2f9cc, 16, 16, 5934},
+ {0x0, 10, 11, 5934},
+ {0xf985, 16, 16, 5935},
+ {0x4d2, 16, 16, 5935},
+ {0x0, 3, 4, 5935},
+ {0x2f99a, 16, 16, 5936},
+ {0x1fd3, 16, 16, 5936},
+ {0x0, 4, 6, 5936},
+ {0x0, 0, 1, 5938},
+ {0x0, 0, 1, 5939},
+ {0x0, 3, 4, 5940},
+ {0x0, 0, 1, 5941},
+ {0x0, 15, 16, 5942},
+ {0x477, 16, 16, 5943},
+ {0x1e26, 16, 16, 5943},
+ {0x1e22, 16, 16, 5943},
+ {0x124, 16, 16, 5943},
+ {0xf979, 16, 16, 5943},
+ {0x0, 0, 1, 5943},
+ {0x2f93a, 16, 16, 5944},
+ {0xfa49, 16, 16, 5944},
+ {0x0, 8, 9, 5944},
+ {0xf900, 16, 16, 5945},
+ {0x0, 4, 5, 5945},
+ {0xf924, 16, 16, 5946},
+ {0x1f23, 16, 16, 5946},
+ {0x0, 5, 6, 5946},
+ {0x2f925, 16, 16, 5947},
+ {0x0, 4, 13, 5947},
+ {0x2f818, 16, 16, 5956},
+ {0x0, 10, 11, 5956},
+ {0x2f979, 16, 16, 5957},
+ {0x0, 0, 1, 5957},
+ {0x0, 0, 1, 5958},
+ {0x0, 3, 4, 5959},
+ {0x0, 0, 1, 5960},
+ {0x0, 2, 3, 5961},
+ {0x1ec6, 16, 16, 5962},
+ {0x0, 2, 3, 5962},
+ {0x2f895, 16, 16, 5963},
+ {0x0, 6, 7, 5963},
+ {0x0, 0, 1, 5964},
+ {0x0, 0, 1, 5965},
+ {0x0, 3, 4, 5966},
+ {0x0, 0, 1, 5967},
+ {0x0, 8, 9, 5968},
+ {0x407, 16, 16, 5969},
+ {0xf949, 16, 16, 5969},
+ {0x0, 0, 10, 5969},
+ {0x1eed, 16, 16, 5979},
+ {0x0, 5, 12, 5979},
+ {0x2f839, 16, 16, 5986},
+ {0x1eeb, 16, 16, 5986},
+ {0x1ee9, 16, 16, 5986},
+ {0x0, 3, 5, 5986},
+ {0x1f38, 16, 16, 5988},
+ {0x1eef, 16, 16, 5988},
+ {0x1f39, 16, 16, 5988},
+ {0x0, 0, 10, 5988},
+ {0x2f962, 16, 16, 5998},
+ {0xfa56, 16, 16, 5998},
+ {0x0, 3, 4, 5998},
+ {0x2f87c, 16, 16, 5999},
+ {0x2f963, 16, 16, 5999},
+ {0x0, 0, 1, 5999},
+ {0x0, 0, 1, 6000},
+ {0x0, 3, 4, 6001},
+ {0x0, 0, 1, 6002},
+ {0x0, 1, 5, 6003},
+ {0x1e2, 16, 16, 6007},
+ {0x1fc, 16, 16, 6007},
+ {0x0, 7, 8, 6007},
+ {0xf9f2, 16, 16, 6008},
+ {0xf906, 16, 16, 6008},
+ {0x0, 13, 14, 6008},
+ {0x2f886, 16, 16, 6009},
+ {0x0, 15, 16, 6009},
+ {0xf927, 16, 16, 6010},
+ {0x0, 12, 13, 6010},
+ {0x2f92a, 16, 16, 6011},
+ {0x0, 3, 5, 6011},
+ {0x1f40, 16, 16, 6013},
+ {0x1f41, 16, 16, 6013},
+ {0x0, 0, 16, 6013},
+ {0xfa, 16, 16, 6029},
+ {0xf9, 16, 16, 6029},
+ {0x169, 16, 16, 6029},
+ {0xfb, 16, 16, 6029},
+ {0x16b, 16, 16, 6029},
+ {0x0, 3, 14, 6029},
+ {0x1ee4, 16, 16, 6040},
+ {0x16d, 16, 16, 6040},
+ {0x1ee7, 16, 16, 6040},
+ {0xfc, 16, 16, 6040},
+ {0x0, 0, 1, 6040},
+ {0x0, 3, 4, 6041},
+ {0x0, 0, 1, 6042},
+ {0x0, 9, 10, 6043},
+ {0x0, 9, 10, 6044},
+ {0x3062, 16, 16, 6045},
+ {0x172, 16, 16, 6045},
+ {0x0, 0, 1, 6045},
+ {0x0, 0, 1, 6046},
+ {0x0, 3, 4, 6047},
+ {0x0, 0, 1, 6048},
+ {0x0, 7, 8, 6049},
+ {0x1e65, 16, 16, 6050},
+ {0x0, 1, 13, 6050},
+ {0x161, 16, 16, 6062},
+ {0x0, 9, 13, 6062},
+ {0x2f9a1, 16, 16, 6066},
+ {0x0, 0, 1, 6066},
+ {0x0, 0, 1, 6067},
+ {0x0, 3, 4, 6068},
+ {0x0, 0, 1, 6069},
+ {0x0, 0, 13, 6070},
+ {0x1da, 16, 16, 6083},
+ {0x0, 0, 1, 6083},
+ {0x0, 0, 1, 6084},
+ {0x0, 3, 4, 6085},
+ {0x0, 0, 4, 6086},
+ {0x0, 1, 13, 6090},
+ {0x13a, 16, 16, 6102},
+ {0x16f, 16, 16, 6102},
+ {0x1e76, 16, 16, 6102},
+ {0x0, 0, 1, 6102},
+ {0x0, 0, 1, 6103},
+ {0x0, 3, 4, 6104},
+ {0x0, 3, 4, 6105},
+ {0x0, 8, 9, 6106},
+ {0x219b, 16, 16, 6107},
+ {0x171, 16, 16, 6107},
+ {0x215, 16, 16, 6107},
+ {0x0, 0, 1, 6107},
+ {0x0, 3, 4, 6108},
+ {0x0, 0, 1, 6109},
+ {0x0, 9, 10, 6110},
+ {0x0, 9, 10, 6111},
+ {0x3050, 16, 16, 6112},
+ {0x0, 10, 11, 6112},
+ {0x0, 7, 8, 6113},
+ {0x2f95e, 16, 16, 6114},
+ {0x0, 2, 3, 6114},
+ {0x2f9ba, 16, 16, 6115},
+ {0x0, 14, 15, 6115},
+ {0xfa30, 16, 16, 6116},
+ {0x0, 10, 11, 6116},
+ {0x2f861, 16, 16, 6117},
+ {0x13e, 16, 16, 6117},
+ {0x1dc, 16, 16, 6117},
+ {0x1d8, 16, 16, 6117},
+ {0x1d6, 16, 16, 6117},
+ {0x0, 2, 3, 6117},
+ {0x1fd7, 16, 16, 6118},
+ {0x0, 1, 2, 6118},
+ {0x0, 4, 5, 6119},
+ {0x2f927, 16, 16, 6120},
+ {0x15d, 16, 16, 6120},
+ {0x15b, 16, 16, 6120},
+ {0x1e61, 16, 16, 6120},
+ {0x0, 3, 5, 6120},
+ {0x1f49, 16, 16, 6122},
+ {0x0, 0, 1, 6122},
+ {0x0, 3, 4, 6123},
+ {0x0, 0, 1, 6124},
+ {0x0, 9, 10, 6125},
+ {0x0, 9, 10, 6126},
+ {0x30c5, 16, 16, 6127},
+ {0xf93e, 16, 16, 6127},
+ {0x0, 0, 14, 6127},
+ {0x0, 4, 5, 6141},
+ {0x2f9d9, 16, 16, 6142},
+ {0x0, 13, 14, 6142},
+ {0x2f8b4, 16, 16, 6143},
+ {0x1f48, 16, 16, 6143},
+ {0x0, 8, 9, 6143},
+ {0xf9e2, 16, 16, 6144},
+ {0x0, 3, 9, 6144},
+ {0x1eca, 16, 16, 6150},
+ {0x12e, 16, 16, 6150},
+ {0x0, 0, 9, 6150},
+ {0x1f7a, 16, 16, 6159},
+ {0x3cd, 16, 16, 6159},
+ {0x1fe1, 16, 16, 6159},
+ {0x0, 1, 2, 6159},
+ {0x1e35, 16, 16, 6160},
+ {0x1fe0, 16, 16, 6160},
+ {0x0, 0, 1, 6160},
+ {0x0, 3, 4, 6161},
+ {0x0, 0, 1, 6162},
+ {0x0, 9, 10, 6163},
+ {0x0, 9, 11, 6164},
+ {0x3074, 16, 16, 6166},
+ {0x3cb, 16, 16, 6166},
+ {0x0, 3, 4, 6166},
+ {0xf99d, 16, 16, 6167},
+ {0x0, 0, 1, 6167},
+ {0x0, 0, 1, 6168},
+ {0x0, 3, 4, 6169},
+ {0x0, 0, 1, 6170},
+ {0x0, 8, 9, 6171},
+ {0x4e7, 16, 16, 6172},
+ {0x1f3b, 16, 16, 6172},
+ {0x0, 0, 1, 6172},
+ {0x0, 0, 1, 6173},
+ {0x0, 3, 4, 6174},
+ {0x0, 4, 5, 6175},
+ {0x0, 5, 6, 6176},
+ {0x1f92, 16, 16, 6177},
+ {0x0, 2, 4, 6177},
+ {0xfa42, 16, 16, 6179},
+ {0x0, 1, 2, 6179},
+ {0x1e5f, 16, 16, 6180},
+ {0x0, 0, 1, 6180},
+ {0x0, 0, 1, 6181},
+ {0x0, 3, 4, 6182},
+ {0x0, 3, 4, 6183},
+ {0x0, 8, 9, 6184},
+ {0x22ed, 16, 16, 6185},
+ {0x0, 2, 6, 6185},
+ {0x1ff6, 16, 16, 6189},
+ {0x1ff3, 16, 16, 6189},
+ {0x0, 9, 11, 6189},
+ {0xf92a, 16, 16, 6191},
+ {0x0, 0, 1, 6191},
+ {0x0, 0, 1, 6192},
+ {0x0, 3, 4, 6193},
+ {0x0, 0, 5, 6194},
+ {0x0, 2, 6, 6199},
+ {0x1fa0, 16, 16, 6203},
+ {0x0, 4, 5, 6203},
+ {0xf9b7, 16, 16, 6204},
+ {0x1f66, 16, 16, 6204},
+ {0x3073, 16, 16, 6204},
+ {0x0, 2, 8, 6204},
+ {0x2f823, 16, 16, 6210},
+ {0x0, 12, 13, 6210},
+ {0x2f862, 16, 16, 6211},
+ {0x2f822, 16, 16, 6211},
+ {0x0, 2, 3, 6211},
+ {0xf9e5, 16, 16, 6212},
+ {0x2f903, 16, 16, 6212},
+ {0x0, 11, 12, 6212},
+ {0x2f957, 16, 16, 6213},
+ {0x0, 11, 12, 6213},
+ {0xf98a, 16, 16, 6214},
+ {0x0, 9, 10, 6214},
+ {0x2f9bb, 16, 16, 6215},
+ {0x0, 0, 1, 6215},
+ {0x0, 0, 1, 6216},
+ {0x0, 3, 4, 6217},
+ {0x0, 0, 1, 6218},
+ {0x0, 15, 16, 6219},
+ {0x476, 16, 16, 6220},
+ {0x0, 0, 1, 6220},
+ {0x0, 0, 1, 6221},
+ {0x0, 3, 4, 6222},
+ {0x0, 0, 1, 6223},
+ {0x0, 8, 9, 6224},
+ {0x4eb, 16, 16, 6225},
+ {0x0, 1, 6, 6225},
+ {0xfa5b, 16, 16, 6230},
+ {0xf934, 16, 16, 6230},
+ {0x0, 0, 10, 6230},
+ {0x0, 0, 1, 6240},
+ {0x0, 0, 1, 6241},
+ {0x0, 3, 4, 6242},
+ {0x0, 0, 1, 6243},
+ {0x0, 0, 2, 6244},
+ {0x1f14, 16, 16, 6246},
+ {0x1f12, 16, 16, 6246},
+ {0x0, 3, 14, 6246},
+ {0x1e0c, 16, 16, 6257},
+ {0x1e10, 16, 16, 6257},
+ {0x1ffb, 16, 16, 6257},
+ {0x1feb, 16, 16, 6257},
+ {0x1ff9, 16, 16, 6257},
+ {0x1fdb, 16, 16, 6257},
+ {0x0, 3, 4, 6257},
+ {0x2f992, 16, 16, 6258},
+ {0x0, 0, 1, 6258},
+ {0x0, 3, 4, 6259},
+ {0x0, 0, 1, 6260},
+ {0x0, 9, 10, 6261},
+ {0x0, 9, 10, 6262},
+ {0x30b6, 16, 16, 6263},
+ {0x0, 0, 1, 6263},
+ {0x0, 0, 1, 6264},
+ {0x0, 3, 4, 6265},
+ {0x0, 0, 4, 6266},
+ {0x0, 3, 14, 6270},
+ {0x1e36, 16, 16, 6281},
+ {0x13b, 16, 16, 6281},
+ {0x1e12, 16, 16, 6281},
+ {0x0, 1, 2, 6281},
+ {0x0, 14, 15, 6282},
+ {0x2f906, 16, 16, 6283},
+ {0x0, 0, 1, 6283},
+ {0x0, 0, 1, 6284},
+ {0x0, 3, 4, 6285},
+ {0x0, 0, 1, 6286},
+ {0x0, 8, 9, 6287},
+ {0x4ed, 16, 16, 6288},
+ {0x2f8dc, 16, 16, 6288},
+ {0x0, 6, 7, 6288},
+ {0x0, 3, 4, 6289},
+ {0x2f91d, 16, 16, 6290},
+ {0x1e3c, 16, 16, 6290},
+ {0x1fbb, 16, 16, 6290},
+ {0x1fee, 16, 16, 6290},
+ {0x0, 14, 15, 6290},
+ {0x2fa08, 16, 16, 6291},
+ {0x1fc9, 16, 16, 6291},
+ {0x0, 0, 1, 6291},
+ {0x0, 0, 1, 6292},
+ {0x0, 13, 14, 6293},
+ {0x0, 3, 4, 6294},
+ {0x0, 14, 15, 6295},
+ {0xd4b, 16, 16, 6296},
+ {0x0, 6, 7, 6296},
+ {0x2fa1b, 16, 16, 6297},
+ {0x0, 7, 8, 6297},
+ {0x2f896, 16, 16, 6298},
+ {0xf97a, 16, 16, 6298},
+ {0x0, 1, 13, 6298},
+ {0x17d, 16, 16, 6310},
+ {0x0, 4, 5, 6310},
+ {0xfa57, 16, 16, 6311},
+ {0x0, 8, 9, 6311},
+ {0xf972, 16, 16, 6312},
+ {0x0, 0, 1, 6312},
+ {0x0, 0, 1, 6313},
+ {0x0, 3, 4, 6314},
+ {0x0, 3, 4, 6315},
+ {0x0, 8, 9, 6316},
+ {0x226f, 16, 16, 6317},
+ {0x0, 0, 1, 6317},
+ {0x0, 0, 1, 6318},
+ {0x0, 3, 4, 6319},
+ {0x0, 0, 1, 6320},
+ {0x0, 0, 13, 6321},
+ {0x1d5, 16, 16, 6334},
+ {0x0, 6, 7, 6334},
+ {0x0, 7, 8, 6335},
+ {0x2f9c5, 16, 16, 6336},
+ {0x0, 0, 1, 6336},
+ {0x0, 0, 1, 6337},
+ {0x0, 3, 4, 6338},
+ {0x0, 4, 5, 6339},
+ {0x0, 5, 6, 6340},
+ {0x1fb7, 16, 16, 6341},
+ {0x1db, 16, 16, 6341},
+ {0x1d7, 16, 16, 6341},
+ {0x0, 3, 14, 6341},
+ {0x1e71, 16, 16, 6352},
+ {0x0, 0, 1, 6352},
+ {0x2f924, 16, 16, 6353},
+ {0x0, 0, 1, 6353},
+ {0x0, 0, 1, 6354},
+ {0x0, 3, 4, 6355},
+ {0x0, 3, 4, 6356},
+ {0x0, 8, 9, 6357},
+ {0x2247, 16, 16, 6358},
+ {0x0, 5, 6, 6358},
+ {0x0, 6, 7, 6359},
+ {0x2fa16, 16, 16, 6360},
+ {0x0, 0, 1, 6360},
+ {0x0, 0, 1, 6361},
+ {0x0, 3, 4, 6362},
+ {0x0, 4, 5, 6363},
+ {0x0, 5, 6, 6364},
+ {0x1f8a, 16, 16, 6365},
+ {0x0, 14, 15, 6365},
+ {0x2fa0d, 16, 16, 6366},
+ {0x0, 1, 2, 6366},
+ {0x2f8a0, 16, 16, 6367},
+ {0x2f8e4, 16, 16, 6367},
+ {0x0, 9, 10, 6367},
+ {0x2f8cd, 16, 16, 6368},
+ {0x0, 5, 10, 6368},
+ {0x2f8d7, 16, 16, 6373},
+ {0x1e90, 16, 16, 6373},
+ {0x179, 16, 16, 6373},
+ {0x2f981, 16, 16, 6373},
+ {0x17b, 16, 16, 6373},
+ {0x21b, 16, 16, 6373},
+ {0x163, 16, 16, 6373},
+ {0xfa4c, 16, 16, 6373},
+ {0x1e6d, 16, 16, 6373},
+ {0x37e, 16, 16, 6373},
+ {0x1d9, 16, 16, 6373},
+ {0x0, 0, 1, 6373},
+ {0x0, 3, 4, 6374},
+ {0x0, 0, 1, 6375},
+ {0x0, 9, 10, 6376},
+ {0x0, 9, 11, 6377},
+ {0x30d7, 16, 16, 6379},
+ {0x0, 0, 1, 6379},
+ {0x0, 3, 4, 6380},
+ {0x0, 0, 1, 6381},
+ {0x0, 9, 10, 6382},
+ {0x0, 9, 10, 6383},
+ {0x3060, 16, 16, 6384},
+ {0x0, 2, 6, 6384},
+ {0x1f91, 16, 16, 6388},
+ {0x1e16, 16, 16, 6388},
+ {0x1f27, 16, 16, 6388},
+ {0x0, 7, 8, 6388},
+ {0x2f89e, 16, 16, 6389},
+ {0x0, 9, 10, 6389},
+ {0x2f8c3, 16, 16, 6390},
+ {0x0, 1, 2, 6390},
+ {0x2f83a, 16, 16, 6391},
+ {0x0, 12, 13, 6391},
+ {0x2f880, 16, 16, 6392},
+ {0x2f989, 16, 16, 6392},
+ {0xd1, 16, 16, 6392},
+ {0x1f8, 16, 16, 6392},
+ {0x143, 16, 16, 6392},
+ {0x1e44, 16, 16, 6392},
+ {0x0, 11, 12, 6392},
+ {0x2f98e, 16, 16, 6393},
+ {0x0, 11, 12, 6393},
+ {0x2f933, 16, 16, 6394},
+ {0x0, 10, 11, 6394},
+ {0xf99b, 16, 16, 6395},
+ {0x0, 0, 1, 6395},
+ {0x1e75, 16, 16, 6396},
+ {0x0, 0, 1, 6396},
+ {0x0, 0, 1, 6397},
+ {0x0, 3, 4, 6398},
+ {0x0, 4, 5, 6399},
+ {0x0, 5, 6, 6400},
+ {0x1f8d, 16, 16, 6401},
+ {0x30d6, 16, 16, 6401},
+ {0x1f2b, 16, 16, 6401},
+ {0x0, 2, 3, 6401},
+ {0xf9ad, 16, 16, 6402},
+ {0xf95d, 16, 16, 6402},
+ {0x0, 0, 1, 6402},
+ {0x0, 0, 1, 6403},
+ {0x0, 3, 4, 6404},
+ {0x0, 0, 3, 6405},
+ {0x0, 3, 4, 6408},
+ {0x1e7c, 16, 16, 6409},
+ {0x0, 3, 4, 6409},
+ {0x0, 14, 15, 6410},
+ {0x2f977, 16, 16, 6411},
+ {0x0, 0, 1, 6411},
+ {0x0, 3, 4, 6412},
+ {0x0, 0, 1, 6413},
+ {0x0, 9, 10, 6414},
+ {0x0, 9, 10, 6415},
+ {0x305e, 16, 16, 6416},
+ {0x0, 0, 1, 6416},
+ {0x2f842, 16, 16, 6417},
+ {0x0, 3, 4, 6417},
+ {0x2f90a, 16, 16, 6418},
+ {0x0, 0, 9, 6418},
+ {0x38e, 16, 16, 6427},
+ {0x0, 0, 1, 6427},
+ {0xf9ee, 16, 16, 6428},
+ {0x0, 15, 16, 6428},
+ {0x2f80b, 16, 16, 6429},
+ {0x0, 10, 11, 6429},
+ {0xf919, 16, 16, 6430},
+ {0xf912, 16, 16, 6430},
+ {0x0, 13, 14, 6430},
+ {0x0, 10, 11, 6431},
+ {0x2f898, 16, 16, 6432},
+ {0x211, 16, 16, 6432},
+ {0x159, 16, 16, 6432},
+ {0x0, 12, 13, 6432},
+ {0xfa2b, 16, 16, 6433},
+ {0x0, 10, 11, 6433},
+ {0xf9bb, 16, 16, 6434},
+ {0x0, 0, 1, 6434},
+ {0x0, 0, 1, 6435},
+ {0x0, 3, 4, 6436},
+ {0x0, 4, 5, 6437},
+ {0x0, 5, 6, 6438},
+ {0x1f83, 16, 16, 6439},
+ {0x1ff8, 16, 16, 6439},
+ {0x0, 11, 12, 6439},
+ {0x2f9d4, 16, 16, 6440},
+ {0x0, 1, 12, 6440},
+ {0x216, 16, 16, 6451},
+ {0x0, 0, 1, 6451},
+ {0x0, 0, 1, 6452},
+ {0x0, 3, 4, 6453},
+ {0x0, 0, 1, 6454},
+ {0x0, 4, 5, 6455},
+ {0x1e0, 16, 16, 6456},
+ {0x0, 0, 16, 6456},
+ {0x0, 6, 7, 6472},
+ {0xfa37, 16, 16, 6473},
+ {0x0, 0, 1, 6473},
+ {0x0, 0, 1, 6474},
+ {0x0, 3, 4, 6475},
+ {0x0, 3, 4, 6476},
+ {0x0, 8, 9, 6477},
+ {0x22e3, 16, 16, 6478},
+ {0x0, 0, 2, 6478},
+ {0x1f6a, 16, 16, 6480},
+ {0x1f6c, 16, 16, 6480},
+ {0x137, 16, 16, 6480},
+ {0x0, 3, 5, 6480},
+ {0x1f51, 16, 16, 6482},
+ {0x1f50, 16, 16, 6482},
+ {0x0, 1, 2, 6482},
+ {0x0, 5, 6, 6483},
+ {0x2f9ec, 16, 16, 6484},
+ {0x0, 14, 15, 6484},
+ {0x2f8c2, 16, 16, 6485},
+ {0x0, 13, 14, 6485},
+ {0x2f99d, 16, 16, 6486},
+ {0x1af, 16, 16, 6486},
+ {0x0, 9, 10, 6486},
+ {0xf9c7, 16, 16, 6487},
+ {0x1e59, 16, 16, 6487},
+ {0x4d3, 16, 16, 6487},
+ {0x0, 0, 1, 6487},
+ {0x0, 0, 1, 6488},
+ {0x0, 3, 4, 6489},
+ {0x0, 0, 1, 6490},
+ {0x0, 7, 8, 6491},
+ {0x1e1f, 16, 16, 6492},
+ {0x0, 7, 8, 6492},
+ {0x2f9bf, 16, 16, 6493},
+ {0x0, 2, 5, 6493},
+ {0xf73, 16, 16, 6496},
+ {0xf75, 16, 16, 6496},
+ {0x0, 8, 9, 6496},
+ {0x2f83f, 16, 16, 6497},
+ {0x0, 3, 5, 6497},
+ {0x1f30, 16, 16, 6499},
+ {0x1f31, 16, 16, 6499},
+ {0x0, 15, 16, 6499},
+ {0xf913, 16, 16, 6500},
+ {0x0, 0, 11, 6500},
+ {0x1e87, 16, 16, 6511},
+ {0x0, 0, 2, 6511},
+ {0x1fcd, 16, 16, 6513},
+ {0x1fce, 16, 16, 6513},
+ {0x175, 16, 16, 6513},
+ {0x1e83, 16, 16, 6513},
+ {0x1e81, 16, 16, 6513},
+ {0x0, 12, 13, 6513},
+ {0x2f8b8, 16, 16, 6514},
+ {0x0, 5, 6, 6514},
+ {0x1ffc, 16, 16, 6515},
+ {0xfa45, 16, 16, 6515},
+ {0x1e85, 16, 16, 6515},
+ {0x0, 3, 9, 6515},
+ {0x1ecc, 16, 16, 6521},
+ {0x0, 0, 1, 6521},
+ {0x0, 0, 1, 6522},
+ {0x0, 11, 12, 6523},
+ {0x0, 11, 12, 6524},
+ {0x0, 14, 15, 6525},
+ {0xbcb, 16, 16, 6526},
+ {0x1ea, 16, 16, 6526},
+ {0x0, 0, 1, 6526},
+ {0x0, 0, 1, 6527},
+ {0x0, 3, 4, 6528},
+ {0x0, 3, 4, 6529},
+ {0x0, 8, 9, 6530},
+ {0x22ac, 16, 16, 6531},
+ {0x0, 1, 2, 6531},
+ {0x0, 10, 11, 6532},
+ {0x2f9f7, 16, 16, 6533},
+ {0x0, 12, 13, 6533},
+ {0xf956, 16, 16, 6534},
+ {0x0, 0, 1, 6534},
+ {0x0, 0, 1, 6535},
+ {0x0, 3, 4, 6536},
+ {0x0, 0, 1, 6537},
+ {0x0, 8, 9, 6538},
+ {0x4f8, 16, 16, 6539},
+ {0x0, 12, 16, 6539},
+ {0xf9e9, 16, 16, 6543},
+ {0xf97e, 16, 16, 6543},
+ {0x0, 14, 15, 6543},
+ {0x2f8af, 16, 16, 6544},
+ {0x21f, 16, 16, 6544},
+ {0x1e98, 16, 16, 6544},
+ {0x0, 1, 2, 6544},
+ {0x1e3a, 16, 16, 6545},
+ {0x0, 7, 8, 6545},
+ {0x9cc, 16, 16, 6546},
+ {0x0, 3, 15, 6546},
+ {0x1e2a, 16, 16, 6558},
+ {0x0, 5, 16, 6558},
+ {0x2fa1a, 16, 16, 6569},
+ {0x2f81a, 16, 16, 6569},
+ {0x0, 7, 12, 6569},
+ {0x2f929, 16, 16, 6574},
+ {0x0, 2, 16, 6574},
+ {0xf94f, 16, 16, 6588},
+ {0x0, 14, 15, 6588},
+ {0xf920, 16, 16, 6589},
+ {0x0, 10, 11, 6589},
+ {0x0, 14, 15, 6590},
+ {0x2f9cb, 16, 16, 6591},
+ {0xf9a0, 16, 16, 6591},
+ {0x1e28, 16, 16, 6591},
+ {0x0, 1, 2, 6591},
+ {0x2f8da, 16, 16, 6592},
+ {0x1e24, 16, 16, 6592},
+ {0x2fa19, 16, 16, 6592},
+ {0xf9db, 16, 16, 6592},
+ {0x0, 0, 1, 6592},
+ {0x0, 0, 1, 6593},
+ {0x0, 3, 4, 6594},
+ {0x0, 0, 3, 6595},
+ {0x0, 7, 8, 6598},
+ {0x122, 16, 16, 6599},
+ {0x0, 0, 2, 6599},
+ {0x1f2a, 16, 16, 6601},
+ {0x1f2c, 16, 16, 6601},
+ {0x0, 0, 1, 6601},
+ {0x0, 0, 1, 6602},
+ {0x0, 3, 4, 6603},
+ {0x0, 4, 5, 6604},
+ {0x0, 5, 6, 6605},
+ {0x1f93, 16, 16, 6606},
+ {0x0, 14, 15, 6606},
+ {0xbca, 16, 16, 6607},
+ {0x0, 6, 7, 6607},
+ {0x2f912, 16, 16, 6608},
+ {0x0, 5, 6, 6608},
+ {0x2f9f6, 16, 16, 6609},
+ {0x0, 3, 4, 6609},
+ {0x2f8dd, 16, 16, 6610},
+ {0xf96a, 16, 16, 6610},
+ {0x0, 14, 15, 6610},
+ {0x2f90f, 16, 16, 6611},
+ {0x0, 9, 10, 6611},
+ {0x374, 16, 16, 6612},
+ {0x0, 6, 11, 6612},
+ {0xf998, 16, 16, 6617},
+ {0x0, 4, 5, 6617},
+ {0xfa3d, 16, 16, 6618},
+ {0x0, 2, 6, 6618},
+ {0x1f26, 16, 16, 6622},
+ {0x0, 7, 15, 6622},
+ {0x2f8c4, 16, 16, 6630},
+ {0x0, 0, 1, 6630},
+ {0x2f922, 16, 16, 6631},
+ {0x0, 1, 2, 6631},
+ {0xf96d, 16, 16, 6632},
+ {0x0, 1, 2, 6632},
+ {0x1e6f, 16, 16, 6633},
+ {0x0, 0, 1, 6633},
+ {0x0, 0, 1, 6634},
+ {0x0, 3, 4, 6635},
+ {0x0, 4, 5, 6636},
+ {0x0, 5, 6, 6637},
+ {0x1fa4, 16, 16, 6638},
+ {0x0, 0, 1, 6638},
+ {0x0, 0, 1, 6639},
+ {0x0, 3, 4, 6640},
+ {0x0, 0, 4, 6641},
+ {0x0, 1, 13, 6645},
+ {0x17e, 16, 16, 6657},
+ {0x1f90, 16, 16, 6657},
+ {0x0, 0, 2, 6657},
+ {0x1f5b, 16, 16, 6659},
+ {0x1f5d, 16, 16, 6659},
+ {0x0, 5, 6, 6659},
+ {0xfa04, 16, 16, 6660},
+ {0x1f6e, 16, 16, 6660},
+ {0x0, 0, 1, 6660},
+ {0x0, 0, 1, 6661},
+ {0x0, 3, 4, 6662},
+ {0x0, 0, 3, 6663},
+ {0x0, 1, 13, 6666},
+ {0x11f, 16, 16, 6678},
+ {0x121, 16, 16, 6678},
+ {0x1e21, 16, 16, 6678},
+ {0x11d, 16, 16, 6678},
+ {0x1f5, 16, 16, 6678},
+ {0x0, 3, 4, 6678},
+ {0x2f8bc, 16, 16, 6679},
+ {0x17c, 16, 16, 6679},
+ {0x17a, 16, 16, 6679},
+ {0x1e91, 16, 16, 6679},
+ {0x0, 1, 2, 6679},
+ {0x2f8b5, 16, 16, 6680},
+ {0xf9d7, 16, 16, 6680},
+ {0x2f8c6, 16, 16, 6680},
+ {0x1e7, 16, 16, 6680},
+ {0x0, 4, 5, 6680},
+ {0xf943, 16, 16, 6681},
+ {0x0, 0, 1, 6681},
+ {0x0, 0, 1, 6682},
+ {0x0, 3, 4, 6683},
+ {0x0, 0, 1, 6684},
+ {0x0, 0, 10, 6685},
+ {0x1ed7, 16, 16, 6695},
+ {0x0, 0, 1, 6695},
+ {0x0, 0, 1, 6696},
+ {0x0, 3, 4, 6697},
+ {0x0, 4, 5, 6698},
+ {0x0, 5, 6, 6699},
+ {0x1f8f, 16, 16, 6700},
+ {0x1ed1, 16, 16, 6700},
+ {0x1ed3, 16, 16, 6700},
+ {0x0, 2, 14, 6700},
+ {0xf95e, 16, 16, 6712},
+ {0x2f801, 16, 16, 6712},
+ {0x1ed5, 16, 16, 6712},
+ {0xf905, 16, 16, 6712},
+ {0x0, 0, 2, 6712},
+ {0x1f6d, 16, 16, 6714},
+ {0x1f6b, 16, 16, 6714},
+ {0x0, 10, 11, 6714},
+ {0x2f808, 16, 16, 6715},
+ {0x0, 15, 16, 6715},
+ {0x0, 0, 1, 6716},
+ {0x0, 0, 1, 6717},
+ {0x0, 12, 13, 6718},
+ {0x0, 13, 14, 6719},
+ {0x0, 5, 6, 6720},
+ {0xcc0, 16, 16, 6721},
+ {0x0, 0, 16, 6721},
+ {0x214, 16, 16, 6737},
+ {0x0, 11, 12, 6737},
+ {0xf953, 16, 16, 6738},
+ {0x1d3, 16, 16, 6738},
+ {0x170, 16, 16, 6738},
+ {0x16e, 16, 16, 6738},
+ {0x0, 3, 14, 6738},
+ {0x1e77, 16, 16, 6749},
+ {0x0, 3, 14, 6749},
+ {0x13c, 16, 16, 6760},
+ {0x1e37, 16, 16, 6760},
+ {0x0, 0, 1, 6760},
+ {0x0, 0, 1, 6761},
+ {0x0, 3, 4, 6762},
+ {0x0, 1, 2, 6763},
+ {0x0, 4, 5, 6764},
+ {0x1fec, 16, 16, 6765},
+ {0x0, 14, 15, 6765},
+ {0x0, 4, 5, 6766},
+ {0x2f859, 16, 16, 6767},
+ {0x2f800, 16, 16, 6767},
+ {0x1e3d, 16, 16, 6767},
+ {0x0, 0, 1, 6767},
+ {0x0, 3, 4, 6768},
+ {0x0, 0, 1, 6769},
+ {0x0, 9, 10, 6770},
+ {0x0, 9, 10, 6771},
+ {0x304e, 16, 16, 6772},
+ {0x0, 11, 15, 6772},
+ {0x2f87e, 16, 16, 6776},
+ {0x2f8cb, 16, 16, 6776},
+ {0x1e84, 16, 16, 6776},
+ {0x0, 0, 1, 6776},
+ {0x0, 0, 1, 6777},
+ {0x0, 3, 4, 6778},
+ {0x0, 0, 1, 6779},
+ {0x0, 1, 2, 6780},
+ {0x403, 16, 16, 6781},
+ {0x173, 16, 16, 6781},
+ {0x1ee6, 16, 16, 6781},
+ {0xdc, 16, 16, 6781},
+ {0x1ee5, 16, 16, 6781},
+ {0x16c, 16, 16, 6781},
+ {0x16a, 16, 16, 6781},
+ {0x168, 16, 16, 6781},
+ {0xdb, 16, 16, 6781},
+ {0x0, 8, 11, 6781},
+ {0x0, 0, 1, 6784},
+ {0x0, 0, 1, 6785},
+ {0x0, 6, 7, 6786},
+ {0x0, 5, 6, 6787},
+ {0x0, 4, 5, 6788},
+ {0x626, 16, 16, 6789},
+ {0x1e73, 16, 16, 6789},
+ {0x0, 5, 7, 6789},
+ {0xcc7, 16, 16, 6791},
+ {0x0, 0, 1, 6791},
+ {0x0, 0, 1, 6792},
+ {0x0, 3, 4, 6793},
+ {0x0, 0, 3, 6794},
+ {0x0, 0, 11, 6797},
+ {0x233, 16, 16, 6808},
+ {0x1e8f, 16, 16, 6808},
+ {0xcc8, 16, 16, 6808},
+ {0xfd, 16, 16, 6808},
+ {0x1ef3, 16, 16, 6808},
+ {0x1ef9, 16, 16, 6808},
+ {0x177, 16, 16, 6808},
+ {0x0, 12, 13, 6808},
+ {0x2f812, 16, 16, 6809},
+ {0x1ef7, 16, 16, 6809},
+ {0xff, 16, 16, 6809},
+ {0x1e80, 16, 16, 6809},
+ {0x0, 14, 15, 6809},
+ {0x2f83c, 16, 16, 6810},
+ {0x0, 2, 3, 6810},
+ {0x0, 0, 1, 6811},
+ {0x0, 0, 1, 6812},
+ {0x0, 11, 12, 6813},
+ {0x0, 13, 14, 6814},
+ {0x0, 7, 8, 6815},
+ {0xb94, 16, 16, 6816},
+ {0x0, 10, 11, 6816},
+ {0x0, 11, 12, 6817},
+ {0x2f961, 16, 16, 6818},
+ {0x0, 1, 2, 6818},
+ {0x213, 16, 16, 6819},
+ {0x0, 1, 12, 6819},
+ {0x1a0, 16, 16, 6830},
+ {0x0, 0, 9, 6830},
+ {0x3ca, 16, 16, 6839},
+ {0x0, 11, 12, 6839},
+ {0xf9f5, 16, 16, 6840},
+ {0x3af, 16, 16, 6840},
+ {0x1f76, 16, 16, 6840},
+ {0x1fd1, 16, 16, 6840},
+ {0x1fd0, 16, 16, 6840},
+ {0x1e99, 16, 16, 6840},
+ {0x0, 1, 2, 6840},
+ {0xf9ca, 16, 16, 6841},
+ {0x0, 1, 2, 6841},
+ {0x2f802, 16, 16, 6842},
+ {0x0, 0, 1, 6842},
+ {0x0, 0, 1, 6843},
+ {0x0, 6, 7, 6844},
+ {0x0, 5, 6, 6845},
+ {0x0, 4, 5, 6846},
+ {0x624, 16, 16, 6847},
+ {0x20e, 16, 16, 6847},
+ {0x0, 0, 1, 6847},
+ {0x0, 0, 1, 6848},
+ {0x0, 3, 4, 6849},
+ {0x0, 4, 5, 6850},
+ {0x0, 5, 6, 6851},
+ {0x1fae, 16, 16, 6852},
+ {0x0, 4, 5, 6852},
+ {0x2f8bd, 16, 16, 6853},
+ {0x0, 9, 10, 6853},
+ {0x2f949, 16, 16, 6854},
+ {0x0, 4, 5, 6854},
+ {0xf9a8, 16, 16, 6855},
+ {0x0, 3, 9, 6855},
+ {0x1e01, 16, 16, 6861},
+ {0x1ea1, 16, 16, 6861},
+ {0x1ef8, 16, 16, 6861},
+ {0x0, 0, 16, 6861},
+ {0x101, 16, 16, 6877},
+ {0x105, 16, 16, 6877},
+ {0x1f32, 16, 16, 6877},
+ {0x0, 0, 1, 6877},
+ {0x0, 3, 4, 6878},
+ {0x0, 0, 1, 6879},
+ {0x0, 9, 10, 6880},
+ {0x0, 9, 10, 6881},
+ {0x3069, 16, 16, 6882},
+ {0x0, 1, 13, 6882},
+ {0x139, 16, 16, 6894},
+ {0x0, 12, 13, 6894},
+ {0x2f9db, 16, 16, 6895},
+ {0x0, 9, 10, 6895},
+ {0xf96e, 16, 16, 6896},
+ {0x0, 3, 4, 6896},
+ {0x0, 0, 1, 6897},
+ {0x2fa09, 16, 16, 6898},
+ {0x0, 13, 14, 6898},
+ {0xf99e, 16, 16, 6899},
+ {0x0, 2, 3, 6899},
+ {0x2f85e, 16, 16, 6900},
+ {0x0, 13, 14, 6900},
+ {0xf91f, 16, 16, 6901},
+ {0x0, 13, 14, 6901},
+ {0x2f91a, 16, 16, 6902},
+ {0x13d, 16, 16, 6902},
+ {0x0, 0, 1, 6902},
+ {0x0, 3, 4, 6903},
+ {0x0, 0, 1, 6904},
+ {0x0, 9, 10, 6905},
+ {0x0, 9, 10, 6906},
+ {0x30f8, 16, 16, 6907},
+ {0x0, 5, 6, 6907},
+ {0x2f81d, 16, 16, 6908},
+ {0x2f945, 16, 16, 6908},
+ {0x0, 0, 1, 6908},
+ {0x0, 3, 4, 6909},
+ {0x0, 0, 1, 6910},
+ {0x0, 9, 10, 6911},
+ {0x0, 9, 10, 6912},
+ {0x30fa, 16, 16, 6913},
+ {0x0, 7, 12, 6913},
+ {0xf929, 16, 16, 6918},
+ {0x0, 14, 15, 6918},
+ {0xf917, 16, 16, 6919},
+ {0x0, 8, 12, 6919},
+ {0xfa07, 16, 16, 6923},
+ {0x0, 2, 6, 6923},
+ {0x1f0e, 16, 16, 6927},
+ {0x0, 0, 1, 6927},
+ {0x0, 0, 1, 6928},
+ {0x0, 3, 4, 6929},
+ {0x0, 0, 1, 6930},
+ {0x0, 1, 2, 6931},
+ {0x45c, 16, 16, 6932},
+ {0x1f88, 16, 16, 6932},
+ {0x0, 0, 1, 6932},
+ {0x0, 0, 1, 6933},
+ {0x0, 3, 4, 6934},
+ {0x0, 0, 1, 6935},
+ {0x0, 0, 2, 6936},
+ {0x1f4d, 16, 16, 6938},
+ {0x1f4b, 16, 16, 6938},
+ {0x0, 0, 1, 6938},
+ {0x0, 0, 1, 6939},
+ {0x0, 3, 4, 6940},
+ {0x0, 3, 4, 6941},
+ {0x0, 8, 9, 6942},
+ {0x22eb, 16, 16, 6943},
+ {0x0, 0, 1, 6943},
+ {0x0, 0, 1, 6944},
+ {0x0, 3, 4, 6945},
+ {0x0, 3, 4, 6946},
+ {0x0, 8, 9, 6947},
+ {0x226e, 16, 16, 6948},
+ {0x0, 0, 1, 6948},
+ {0xf9cf, 16, 16, 6949},
+ {0x0, 15, 16, 6949},
+ {0x2f8f4, 16, 16, 6950},
+ {0x0, 3, 5, 6950},
+ {0x1f11, 16, 16, 6952},
+ {0x1f10, 16, 16, 6952},
+ {0x0, 0, 1, 6952},
+ {0x0, 0, 1, 6953},
+ {0x0, 3, 4, 6954},
+ {0x0, 1, 2, 6955},
+ {0x0, 3, 5, 6956},
+ {0x1fe4, 16, 16, 6958},
+ {0x2f9df, 16, 16, 6958},
+ {0x1fe5, 16, 16, 6958},
+ {0x0, 0, 1, 6958},
+ {0x0, 3, 4, 6959},
+ {0x0, 0, 1, 6960},
+ {0x0, 9, 10, 6961},
+ {0x0, 9, 10, 6962},
+ {0x3067, 16, 16, 6963},
+ {0x1f4c, 16, 16, 6963},
+ {0x0, 6, 7, 6963},
+ {0x0, 10, 11, 6964},
+ {0xf987, 16, 16, 6965},
+ {0x2f87f, 16, 16, 6965},
+ {0x2f8d9, 16, 16, 6965},
+ {0x0, 0, 1, 6965},
+ {0xf990, 16, 16, 6966},
+ {0x0, 0, 1, 6966},
+ {0x2f879, 16, 16, 6967},
+ {0x1f73, 16, 16, 6967},
+ {0x0, 7, 8, 6967},
+ {0x2f9f0, 16, 16, 6968},
+ {0x1f77, 16, 16, 6968},
+ {0x1f71, 0, 1, 6968},
+ {0x0, 3, 4, 6969},
+ {0x0, 1, 2, 6970},
+ {0x2f892, 16, 16, 6971},
+ {0x0, 1, 2, 6971},
+ {0x1e95, 16, 16, 6972},
+ {0x0, 0, 1, 6972},
+ {0x0, 0, 1, 6973},
+ {0x0, 3, 4, 6974},
+ {0x0, 4, 5, 6975},
+ {0x0, 5, 6, 6976},
+ {0x1fa5, 16, 16, 6977},
+ {0x0, 0, 1, 6977},
+ {0x0, 3, 4, 6978},
+ {0x0, 4, 5, 6979},
+ {0x0, 5, 6, 6980},
+ {0x1fb4, 16, 16, 6981},
+ {0xf925, 16, 16, 6981},
+ {0xda, 16, 16, 6981},
+ {0x0, 6, 10, 6981},
+ {0xf9cc, 16, 16, 6985},
+ {0xf9e4, 16, 16, 6985},
+ {0x0, 3, 14, 6985},
+ {0x145, 16, 16, 6996},
+ {0x1e46, 16, 16, 6996},
+ {0x0, 3, 4, 6996},
+ {0x0, 5, 6, 6997},
+ {0x2f926, 16, 16, 6998},
+ {0x0, 2, 3, 6998},
+ {0x1fc1, 16, 16, 6999},
+ {0x0, 11, 12, 6999},
+ {0x2f9ff, 16, 16, 7000},
+ {0x0, 5, 6, 7000},
+ {0x2f955, 16, 16, 7001},
+ {0x0, 0, 1, 7001},
+ {0x0, 0, 1, 7002},
+ {0x0, 3, 4, 7003},
+ {0x0, 0, 1, 7004},
+ {0x0, 7, 8, 7005},
+ {0x1e66, 16, 16, 7006},
+ {0x0, 0, 1, 7006},
+ {0x0, 0, 1, 7007},
+ {0x0, 3, 4, 7008},
+ {0x0, 0, 1, 7009},
+ {0x0, 8, 9, 7010},
+ {0x4e6, 16, 16, 7011},
+ {0x0, 1, 2, 7011},
+ {0x1e3b, 16, 16, 7012},
+ {0x0, 7, 8, 7012},
+ {0x2f99e, 16, 16, 7013},
+ {0x1e4a, 16, 16, 7013},
+ {0xd9, 16, 16, 7013},
+ {0x0, 3, 4, 7013},
+ {0x1e7e, 16, 16, 7014},
+ {0x0, 0, 1, 7014},
+ {0x0, 0, 1, 7015},
+ {0x0, 3, 4, 7016},
+ {0x0, 0, 1, 7017},
+ {0x0, 1, 9, 7018},
+ {0x22d, 16, 16, 7026},
+ {0x0, 0, 1, 7026},
+ {0x0, 3, 4, 7027},
+ {0x0, 0, 1, 7028},
+ {0x0, 9, 10, 7029},
+ {0x0, 9, 10, 7030},
+ {0x30be, 16, 16, 7031},
+ {0x1e4d, 16, 16, 7031},
+ {0x1e4f, 16, 16, 7031},
+ {0x0, 0, 1, 7031},
+ {0x0, 0, 1, 7032},
+ {0x0, 3, 4, 7033},
+ {0x0, 3, 4, 7034},
+ {0x0, 8, 9, 7035},
+ {0x220c, 16, 16, 7036},
+ {0x0, 4, 5, 7036},
+ {0x2f84f, 16, 16, 7037},
+ {0x0, 3, 12, 7037},
+ {0xf931, 16, 16, 7046},
+ {0x0, 3, 4, 7046},
+ {0x2f849, 16, 16, 7047},
+ {0x0, 0, 1, 7047},
+ {0x0, 0, 1, 7048},
+ {0x0, 3, 4, 7049},
+ {0x0, 0, 1, 7050},
+ {0x0, 0, 2, 7051},
+ {0x1f1b, 16, 16, 7053},
+ {0x1f1d, 16, 16, 7053},
+ {0x0, 0, 1, 7053},
+ {0x0, 0, 1, 7054},
+ {0x0, 3, 4, 7055},
+ {0x0, 0, 1, 7056},
+ {0x0, 4, 5, 7057},
+ {0x22b, 16, 16, 7058},
+ {0x0, 8, 9, 7058},
+ {0xfa38, 16, 16, 7059},
+ {0x0, 7, 8, 7059},
+ {0xc7, 16, 16, 7060},
+ {0x0, 14, 15, 7060},
+ {0x2f936, 16, 16, 7061},
+ {0x0, 1, 9, 7061},
+ {0xf948, 16, 16, 7069},
+ {0x2f9d5, 16, 16, 7069},
+ {0x0, 12, 13, 7069},
+ {0x2f9a3, 16, 16, 7070},
+ {0xf903, 16, 16, 7070},
+ {0x2f8ed, 16, 16, 7070},
+ {0x0, 8, 9, 7070},
+ {0xf9b8, 16, 16, 7071},
+ {0x0, 11, 12, 7071},
+ {0x2f9da, 16, 16, 7072},
+ {0x0, 0, 11, 7072},
+ {0x2f9cf, 16, 16, 7083},
+ {0x0, 0, 1, 7083},
+ {0x0, 0, 1, 7084},
+ {0x0, 3, 4, 7085},
+ {0x0, 3, 4, 7086},
+ {0x0, 8, 9, 7087},
+ {0x2249, 16, 16, 7088},
+ {0x0, 6, 8, 7088},
+ {0x2f84b, 16, 16, 7090},
+ {0x2f84d, 16, 16, 7090},
+ {0x0, 6, 7, 7090},
+ {0x2f821, 16, 16, 7091},
+ {0x1ece, 16, 16, 7091},
+ {0xd6, 16, 16, 7091},
+ {0x22e, 16, 16, 7091},
+ {0x14e, 16, 16, 7091},
+ {0x14c, 16, 16, 7091},
+ {0x0, 13, 14, 7091},
+ {0x0, 10, 11, 7092},
+ {0x2f97b, 16, 16, 7093},
+ {0xd4, 16, 16, 7093},
+ {0xd3, 16, 16, 7093},
+ {0xd2, 16, 16, 7093},
+ {0x1eb3, 16, 16, 7093},
+ {0xfa40, 16, 16, 7093},
+ {0x1eb5, 16, 16, 7093},
+ {0x0, 13, 14, 7093},
+ {0x2f854, 16, 16, 7094},
+ {0x1eb1, 16, 16, 7094},
+ {0x0, 14, 15, 7094},
+ {0x2f890, 16, 16, 7095},
+ {0x0, 8, 9, 7095},
+ {0xfa67, 16, 16, 7096},
+ {0x0, 10, 16, 7096},
+ {0xdda, 16, 16, 7102},
+ {0x0, 8, 9, 7102},
+ {0xf9b4, 16, 16, 7103},
+ {0xddc, 16, 16, 7103},
+ {0xf9a1, 16, 16, 7103},
+ {0x0, 0, 1, 7103},
+ {0x0, 0, 1, 7104},
+ {0x0, 3, 4, 7105},
+ {0x0, 4, 5, 7106},
+ {0x0, 5, 6, 7107},
+ {0x1f8b, 16, 16, 7108},
+ {0x0, 3, 4, 7108},
+ {0x2f9f5, 16, 16, 7109},
+ {0x0, 14, 15, 7109},
+ {0x2f9b9, 16, 16, 7110},
+ {0x20c, 16, 16, 7110},
+ {0x0, 0, 1, 7110},
+ {0x0, 0, 1, 7111},
+ {0x0, 3, 4, 7112},
+ {0x0, 3, 4, 7113},
+ {0x0, 8, 9, 7114},
+ {0x2284, 16, 16, 7115},
+ {0x1d1, 16, 16, 7115},
+ {0x150, 16, 16, 7115},
+ {0x0, 7, 8, 7115},
+ {0xfa5f, 16, 16, 7116},
+ {0x0, 1, 13, 7116},
+ {0x1e6, 16, 16, 7128},
+ {0x0, 6, 7, 7128},
+ {0x2f9fd, 16, 16, 7129},
+ {0x0, 0, 1, 7129},
+ {0x0, 5, 6, 7130},
+ {0x2fa12, 16, 16, 7131},
+ {0x0, 8, 10, 7131},
+ {0x2fa04, 16, 16, 7133},
+ {0xfa2c, 16, 16, 7133},
+ {0x0, 15, 16, 7133},
+ {0xf940, 16, 16, 7134},
+ {0x0, 1, 2, 7134},
+ {0xfa4b, 16, 16, 7135},
+ {0x30d1, 16, 16, 7135},
+ {0x0, 2, 11, 7135},
+ {0x2f9f4, 16, 16, 7144},
+ {0x0, 15, 16, 7144},
+ {0xf94e, 16, 16, 7145},
+ {0x0, 0, 1, 7145},
+ {0x2f8d4, 16, 16, 7146},
+ {0x1f00, 16, 16, 7146},
+ {0x1f4, 16, 16, 7146},
+ {0x11c, 16, 16, 7146},
+ {0x1e20, 16, 16, 7146},
+ {0x11e, 16, 16, 7146},
+ {0x120, 16, 16, 7146},
+ {0x0, 3, 4, 7146},
+ {0x2f9f3, 16, 16, 7147},
+ {0x0, 9, 10, 7147},
+ {0xf9fb, 16, 16, 7148},
+ {0x1fef, 16, 16, 7148},
+ {0xf9ab, 16, 16, 7148},
+ {0x0, 3, 4, 7148},
+ {0xf94c, 16, 16, 7149},
+ {0x0, 0, 1, 7149},
+ {0x0, 0, 1, 7150},
+ {0x0, 3, 4, 7151},
+ {0x0, 4, 5, 7152},
+ {0x0, 5, 6, 7153},
+ {0x1f96, 16, 16, 7154},
+ {0x0, 0, 1, 7154},
+ {0x2f96a, 16, 16, 7155},
+ {0x1f72, 16, 16, 7155},
+ {0x0, 7, 12, 7155},
+ {0x2f90c, 16, 16, 7160},
+ {0x0, 0, 11, 7160},
+ {0x2f9d1, 16, 16, 7171},
+ {0x0, 0, 1, 7171},
+ {0x0, 0, 1, 7172},
+ {0x0, 3, 4, 7173},
+ {0x0, 0, 1, 7174},
+ {0x0, 1, 2, 7175},
+ {0x40c, 16, 16, 7176},
+ {0x0, 2, 12, 7176},
+ {0x2f89a, 16, 16, 7186},
+ {0x0, 7, 8, 7186},
+ {0x123, 16, 16, 7187},
+ {0x0, 5, 7, 7187},
+ {0xf974, 16, 16, 7189},
+ {0x2f996, 16, 16, 7189},
+ {0x0, 3, 4, 7189},
+ {0x1e93, 16, 16, 7190},
+ {0x0, 2, 3, 7190},
+ {0x1fe7, 16, 16, 7191},
+ {0x0, 2, 3, 7191},
+ {0x2f9fc, 16, 16, 7192},
+ {0x2f90b, 16, 16, 7192},
+ {0xf95a, 16, 16, 7192},
+ {0x0, 3, 5, 7192},
+ {0xfa02, 16, 16, 7194},
+ {0x2f8b6, 16, 16, 7194},
+ {0x0, 1, 2, 7194},
+ {0x1e48, 16, 16, 7195},
+ {0x4e4, 16, 16, 7195},
+ {0x4e2, 16, 16, 7195},
+ {0x0, 0, 1, 7195},
+ {0x0, 0, 1, 7196},
+ {0x0, 3, 4, 7197},
+ {0x0, 3, 4, 7198},
+ {0x0, 8, 9, 7199},
+ {0x2278, 16, 16, 7200},
+ {0x419, 16, 16, 7200},
+ {0x0, 1, 2, 7200},
+ {0x2f9c0, 16, 16, 7201},
+ {0x2f899, 16, 16, 7201},
+ {0x1e72, 16, 16, 7201},
+ {0x0, 4, 5, 7201},
+ {0xf98e, 16, 16, 7202},
+ {0x0, 5, 6, 7202},
+ {0x2f92b, 16, 16, 7203},
+ {0x0, 0, 1, 7203},
+ {0x2f9fa, 16, 16, 7204},
+ {0x0, 3, 14, 7204},
+ {0x1e0d, 16, 16, 7215},
+ {0x0, 6, 7, 7215},
+ {0x2f9f2, 16, 16, 7216},
+ {0x1e11, 16, 16, 7216},
+ {0x0, 14, 15, 7216},
+ {0x2f851, 16, 16, 7217},
+ {0x0, 6, 7, 7217},
+ {0x2f9f9, 16, 16, 7218},
+ {0x0, 2, 3, 7218},
+ {0xf9f9, 16, 16, 7219},
+ {0x0, 14, 15, 7219},
+ {0xf9a5, 16, 16, 7220},
+ {0x10f, 16, 16, 7220},
+ {0x0, 2, 6, 7220},
+ {0x1f0f, 16, 16, 7224},
+ {0x1f89, 16, 16, 7224},
+ {0x0, 15, 16, 7224},
+ {0x0, 0, 1, 7225},
+ {0x0, 0, 1, 7226},
+ {0x0, 3, 4, 7227},
+ {0x0, 0, 1, 7228},
+ {0x0, 7, 8, 7229},
+ {0x1e9b, 16, 16, 7230},
+ {0x1e13, 16, 16, 7230},
+ {0x0, 0, 3, 7230},
+ {0x2f84a, 16, 16, 7233},
+ {0xfa0d, 16, 16, 7233},
+ {0x0, 1, 2, 7233},
+ {0x2fa14, 16, 16, 7234},
+ {0x0, 12, 13, 7234},
+ {0x2f9ad, 16, 16, 7235},
+ {0x0, 10, 12, 7235},
+ {0xf9ff, 16, 16, 7237},
+ {0x2f820, 16, 16, 7237},
+ {0x0, 1, 2, 7237},
+ {0x2f84e, 16, 16, 7238},
+ {0x1fe8, 16, 16, 7238},
+ {0x1e58, 16, 16, 7238},
+ {0x1fe9, 16, 16, 7238},
+ {0x1fea, 16, 16, 7238},
+ {0x0, 13, 14, 7238},
+ {0x2f8f7, 16, 16, 7239},
+ {0x0, 0, 1, 7239},
+ {0x0, 0, 1, 7240},
+ {0x0, 3, 4, 7241},
+ {0x0, 4, 5, 7242},
+ {0x0, 5, 6, 7243},
+ {0x1f97, 16, 16, 7244},
+ {0x3ab, 16, 16, 7244},
+ {0x0, 3, 4, 7244},
+ {0xf9f1, 16, 16, 7245},
+ {0x210, 16, 16, 7245},
+ {0x2f9a2, 16, 16, 7245},
+ {0x158, 16, 16, 7245},
+ {0x0, 5, 6, 7245},
+ {0x2f9c8, 16, 16, 7246},
+ {0x0, 0, 2, 7246},
+ {0x1fc8, 16, 16, 7248},
+ {0x388, 16, 16, 7248},
+ {0x0, 12, 13, 7248},
+ {0xf9cb, 16, 16, 7249},
+ {0x0, 1, 2, 7249},
+ {0xfa62, 16, 16, 7250},
+ {0x0, 9, 10, 7250},
+ {0xf9a9, 16, 16, 7251},
+ {0x0, 14, 15, 7251},
+ {0xf9b6, 16, 16, 7252},
+ {0x0, 5, 6, 7252},
+ {0xf9e3, 16, 16, 7253},
+ {0x0, 11, 12, 7253},
+ {0xf9ce, 16, 16, 7254},
+ {0x0, 3, 4, 7254},
+ {0x1ef5, 16, 16, 7255},
+ {0x0, 1, 2, 7255},
+ {0x1e49, 16, 16, 7256},
+ {0x0, 0, 1, 7256},
+ {0x0, 0, 1, 7257},
+ {0x0, 3, 4, 7258},
+ {0x0, 0, 1, 7259},
+ {0x0, 0, 2, 7260},
+ {0x1f1c, 16, 16, 7262},
+ {0x1f1a, 16, 16, 7262},
+ {0x0, 3, 4, 7262},
+ {0xf99a, 16, 16, 7263},
+ {0xe4, 16, 16, 7263},
+ {0x1ea3, 16, 16, 7263},
+ {0x0, 0, 1, 7263},
+ {0x0, 3, 4, 7264},
+ {0x0, 0, 1, 7265},
+ {0x0, 9, 10, 7266},
+ {0x0, 9, 10, 7267},
+ {0x3054, 16, 16, 7268},
+ {0x0, 1, 3, 7268},
+ {0x2f856, 16, 16, 7270},
+ {0x2f857, 16, 16, 7270},
+ {0xe0, 16, 16, 7270},
+ {0xe1, 16, 16, 7270},
+ {0xe2, 16, 16, 7270},
+ {0xe3, 16, 16, 7270},
+ {0x0, 9, 10, 7270},
+ {0x2f82c, 16, 16, 7271},
+ {0x103, 16, 16, 7271},
+ {0x227, 16, 16, 7271},
+ {0x0, 0, 1, 7271},
+ {0x0, 0, 1, 7272},
+ {0x0, 3, 4, 7273},
+ {0x0, 0, 1, 7274},
+ {0x0, 0, 2, 7275},
+ {0x1f13, 16, 16, 7277},
+ {0x1f15, 16, 16, 7277},
+ {0x0, 1, 2, 7277},
+ {0x2f930, 16, 16, 7278},
+ {0x0, 0, 2, 7278},
+ {0x1f62, 16, 16, 7280},
+ {0x1f64, 16, 16, 7280},
+ {0x0, 2, 3, 7280},
+ {0xf938, 16, 16, 7281},
+ {0x0, 12, 13, 7281},
+ {0xf93b, 16, 16, 7282},
+ {0x0, 6, 7, 7282},
+ {0xf935, 16, 16, 7283},
+ {0x0, 0, 1, 7283},
+ {0x0, 0, 1, 7284},
+ {0x0, 3, 4, 7285},
+ {0x0, 4, 5, 7286},
+ {0x0, 5, 6, 7287},
+ {0x1f8c, 16, 16, 7288},
+ {0x0, 0, 1, 7288},
+ {0x0, 0, 1, 7289},
+ {0x0, 3, 4, 7290},
+ {0x0, 0, 1, 7291},
+ {0x0, 2, 3, 7292},
+ {0x1ed9, 16, 16, 7293},
+ {0xe5, 16, 16, 7293},
+ {0x1ce, 16, 16, 7293},
+ {0x0, 11, 12, 7293},
+ {0x2f9a7, 16, 16, 7294},
+ {0x201, 16, 16, 7294},
+ {0x0, 11, 12, 7294},
+ {0x2f990, 16, 16, 7295},
+ {0x0, 6, 7, 7295},
+ {0x2f85c, 16, 16, 7296},
+ {0x0, 0, 1, 7296},
+ {0x0, 0, 1, 7297},
+ {0x0, 3, 4, 7298},
+ {0x0, 4, 5, 7299},
+ {0x0, 5, 6, 7300},
+ {0x1fa3, 16, 16, 7301},
+ {0x0, 6, 7, 7301},
+ {0x2f9aa, 16, 16, 7302},
+ {0x0, 6, 7, 7302},
+ {0xf9b0, 16, 16, 7303},
+ {0x0, 1, 3, 7303},
+ {0x2f881, 16, 16, 7305},
+ {0x2f882, 16, 16, 7305},
+ {0x0, 2, 3, 7305},
+ {0xf9c1, 16, 16, 7306},
+ {0x0, 2, 7, 7306},
+ {0xfa03, 16, 16, 7311},
+ {0x0, 10, 11, 7311},
+ {0x2f932, 16, 16, 7312},
+ {0x2f966, 16, 16, 7312},
+ {0x0, 10, 11, 7312},
+ {0xf9ec, 16, 16, 7313},
+ {0x1e50, 16, 16, 7313},
+ {0x0, 6, 7, 7313},
+ {0xfa61, 16, 16, 7314},
+ {0x0, 1, 13, 7314},
+ {0x109, 16, 16, 7326},
+ {0x107, 16, 16, 7326},
+ {0x10b, 16, 16, 7326},
+ {0x0, 1, 2, 7326},
+ {0x0, 0, 1, 7327},
+ {0x0, 0, 1, 7328},
+ {0x0, 6, 7, 7329},
+ {0x0, 5, 6, 7330},
+ {0x0, 4, 5, 7331},
+ {0x6c2, 16, 16, 7332},
+ {0x0, 2, 3, 7332},
+ {0xf9bf, 16, 16, 7333},
+ {0x0, 0, 1, 7333},
+ {0x0, 0, 1, 7334},
+ {0x2fa1d, 16, 16, 7335},
+ {0x0, 3, 4, 7335},
+ {0x1ef4, 16, 16, 7336},
+ {0x0, 14, 15, 7336},
+ {0x2f9dd, 16, 16, 7337},
+ {0x0, 0, 4, 7337},
+ {0x2f9c4, 16, 16, 7341},
+ {0x0, 0, 1, 7341},
+ {0x0, 0, 1, 7342},
+ {0x0, 3, 4, 7343},
+ {0x0, 4, 5, 7344},
+ {0x0, 5, 6, 7345},
+ {0x1f87, 16, 16, 7346},
+ {0x2f9c3, 16, 16, 7346},
+ {0x0, 11, 12, 7346},
+ {0xf964, 16, 16, 7347},
+ {0x0, 12, 15, 7347},
+ {0xfa15, 16, 16, 7350},
+ {0xf954, 16, 16, 7350},
+ {0x0, 2, 3, 7350},
+ {0xf946, 16, 16, 7351},
+ {0x0, 0, 1, 7351},
+ {0x0, 0, 1, 7352},
+ {0x0, 3, 4, 7353},
+ {0x0, 3, 4, 7354},
+ {0x0, 8, 9, 7355},
+ {0x2226, 16, 16, 7356},
+ {0x1f79, 16, 16, 7356},
+ {0x0, 0, 1, 7356},
+ {0x0, 0, 1, 7357},
+ {0x0, 3, 4, 7358},
+ {0x0, 3, 4, 7359},
+ {0x0, 8, 9, 7360},
+ {0x21ce, 16, 16, 7361},
+ {0x1d4, 16, 16, 7361},
+ {0x1f7b, 16, 16, 7361},
+ {0x10d, 16, 16, 7361},
+ {0x0, 2, 10, 7361},
+ {0x2f96f, 16, 16, 7369},
+ {0xfa58, 16, 16, 7369},
+};
+
+const unsigned short _wind_canon_next_table[] = {
+ 1,
+ 0,
+ 46,
+ 29,
+ 15,
+ 73,
+ 64,
+ 11,
+ 6,
+ 24,
+ 38,
+ 2,
+ 42,
+ 722,
+ 2119,
+ 3,
+ 140,
+ 1467,
+ 221,
+ 325,
+ 285,
+ 682,
+ 360,
+ 729,
+ 1610,
+ 635,
+ 106,
+ 2045,
+ 510,
+ 2830,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 748,
+ 1101,
+ 4614,
+ 273,
+ 0,
+ 4,
+ 0,
+ 0,
+ 4440,
+ 5,
+ 0,
+ 10,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 97,
+ 224,
+ 1388,
+ 270,
+ 249,
+ 1440,
+ 550,
+ 3741,
+ 2040,
+ 7,
+ 419,
+ 54,
+ 109,
+ 883,
+ 1230,
+ 275,
+ 336,
+ 4348,
+ 0,
+ 0,
+ 4568,
+ 3216,
+ 2891,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1305,
+ 0,
+ 0,
+ 8,
+ 4480,
+ 937,
+ 112,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 9,
+ 1532,
+ 2106,
+ 1144,
+ 236,
+ 1215,
+ 1449,
+ 1624,
+ 0,
+ 0,
+ 12,
+ 194,
+ 1718,
+ 1680,
+ 3611,
+ 217,
+ 398,
+ 13,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4477,
+ 14,
+ 2316,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 328,
+ 16,
+ 553,
+ 3511,
+ 17,
+ 646,
+ 732,
+ 426,
+ 532,
+ 57,
+ 0,
+ 0,
+ 0,
+ 278,
+ 1790,
+ 0,
+ 0,
+ 658,
+ 695,
+ 2327,
+ 3451,
+ 3868,
+ 18,
+ 666,
+ 4417,
+ 4518,
+ 391,
+ 1640,
+ 1458,
+ 567,
+ 340,
+ 2209,
+ 2458,
+ 1747,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 1307,
+ 304,
+ 1254,
+ 227,
+ 750,
+ 51,
+ 1120,
+ 1576,
+ 467,
+ 1270,
+ 2751,
+ 25,
+ 1647,
+ 183,
+ 1785,
+ 363,
+ 1315,
+ 0,
+ 1982,
+ 0,
+ 0,
+ 2474,
+ 0,
+ 1656,
+ 0,
+ 4178,
+ 4486,
+ 26,
+ 28,
+ 27,
+ 132,
+ 82,
+ 346,
+ 186,
+ 98,
+ 0,
+ 30,
+ 0,
+ 0,
+ 1028,
+ 0,
+ 1050,
+ 739,
+ 113,
+ 0,
+ 2135,
+ 1415,
+ 0,
+ 4020,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4647,
+ 31,
+ 3197,
+ 0,
+ 0,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 354,
+ 809,
+ 436,
+ 1736,
+ 39,
+ 547,
+ 708,
+ 1945,
+ 850,
+ 367,
+ 594,
+ 1651,
+ 388,
+ 416,
+ 1251,
+ 705,
+ 4230,
+ 0,
+ 1894,
+ 0,
+ 886,
+ 424,
+ 40,
+ 4586,
+ 2250,
+ 1941,
+ 0,
+ 0,
+ 4635,
+ 41,
+ 1224,
+ 1391,
+ 813,
+ 1807,
+ 3757,
+ 308,
+ 442,
+ 43,
+ 439,
+ 121,
+ 4198,
+ 1596,
+ 1298,
+ 529,
+ 1244,
+ 1948,
+ 4367,
+ 4591,
+ 2500,
+ 2808,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4473,
+ 44,
+ 45,
+ 239,
+ 1073,
+ 1218,
+ 543,
+ 506,
+ 124,
+ 47,
+ 128,
+ 772,
+ 725,
+ 291,
+ 3715,
+ 357,
+ 3693,
+ 4339,
+ 759,
+ 0,
+ 2181,
+ 0,
+ 0,
+ 0,
+ 3076,
+ 48,
+ 2065,
+ 0,
+ 3213,
+ 49,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1375,
+ 50,
+ 1333,
+ 0,
+ 1993,
+ 1665,
+ 0,
+ 52,
+ 0,
+ 0,
+ 1352,
+ 0,
+ 3457,
+ 53,
+ 1249,
+ 55,
+ 0,
+ 0,
+ 0,
+ 1627,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1920,
+ 56,
+ 2143,
+ 0,
+ 0,
+ 0,
+ 58,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2970,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 65,
+ 0,
+ 0,
+ 0,
+ 1683,
+ 403,
+ 1593,
+ 1555,
+ 862,
+ 2420,
+ 151,
+ 259,
+ 1010,
+ 2377,
+ 2719,
+ 385,
+ 2542,
+ 0,
+ 0,
+ 0,
+ 826,
+ 894,
+ 66,
+ 610,
+ 0,
+ 2676,
+ 513,
+ 90,
+ 452,
+ 1152,
+ 1560,
+ 470,
+ 3342,
+ 0,
+ 0,
+ 67,
+ 0,
+ 4191,
+ 0,
+ 4103,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1443,
+ 68,
+ 69,
+ 70,
+ 71,
+ 72,
+ 539,
+ 985,
+ 74,
+ 1870,
+ 0,
+ 675,
+ 1542,
+ 75,
+ 0,
+ 1085,
+ 210,
+ 2259,
+ 2582,
+ 498,
+ 295,
+ 76,
+ 0,
+ 3605,
+ 0,
+ 0,
+ 4323,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1741,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 2790,
+ 587,
+ 0,
+ 0,
+ 978,
+ 1368,
+ 83,
+ 4492,
+ 0,
+ 0,
+ 161,
+ 2601,
+ 0,
+ 0,
+ 628,
+ 4245,
+ 2052,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2488,
+ 2098,
+ 1037,
+ 84,
+ 85,
+ 86,
+ 87,
+ 88,
+ 89,
+ 372,
+ 0,
+ 154,
+ 0,
+ 3528,
+ 0,
+ 1493,
+ 0,
+ 91,
+ 0,
+ 1275,
+ 0,
+ 4271,
+ 0,
+ 2079,
+ 92,
+ 93,
+ 94,
+ 95,
+ 96,
+ 3288,
+ 1345,
+ 1907,
+ 99,
+ 1176,
+ 2738,
+ 0,
+ 3255,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1615,
+ 2341,
+ 764,
+ 0,
+ 0,
+ 1103,
+ 0,
+ 1711,
+ 2982,
+ 100,
+ 143,
+ 0,
+ 4150,
+ 0,
+ 0,
+ 0,
+ 3444,
+ 101,
+ 102,
+ 103,
+ 104,
+ 105,
+ 527,
+ 881,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 107,
+ 0,
+ 0,
+ 0,
+ 4111,
+ 4319,
+ 0,
+ 2519,
+ 2853,
+ 108,
+ 1939,
+ 0,
+ 0,
+ 110,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3917,
+ 0,
+ 0,
+ 0,
+ 2192,
+ 1883,
+ 1470,
+ 1202,
+ 111,
+ 318,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 114,
+ 2770,
+ 0,
+ 0,
+ 115,
+ 116,
+ 117,
+ 118,
+ 119,
+ 120,
+ 4389,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2672,
+ 0,
+ 2002,
+ 0,
+ 0,
+ 122,
+ 123,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 179,
+ 925,
+ 125,
+ 0,
+ 0,
+ 1310,
+ 0,
+ 1686,
+ 0,
+ 0,
+ 1571,
+ 3387,
+ 4056,
+ 1539,
+ 0,
+ 0,
+ 3187,
+ 126,
+ 0,
+ 954,
+ 127,
+ 1047,
+ 0,
+ 0,
+ 1771,
+ 0,
+ 0,
+ 3590,
+ 0,
+ 3849,
+ 3246,
+ 0,
+ 0,
+ 129,
+ 0,
+ 0,
+ 433,
+ 130,
+ 131,
+ 3069,
+ 133,
+ 197,
+ 168,
+ 1797,
+ 0,
+ 0,
+ 579,
+ 1377,
+ 445,
+ 2552,
+ 460,
+ 2528,
+ 1957,
+ 1845,
+ 134,
+ 2847,
+ 901,
+ 1326,
+ 3859,
+ 3234,
+ 1193,
+ 993,
+ 753,
+ 3534,
+ 520,
+ 2171,
+ 2023,
+ 135,
+ 136,
+ 137,
+ 138,
+ 0,
+ 4306,
+ 181,
+ 182,
+ 0,
+ 0,
+ 0,
+ 0,
+ 180,
+ 0,
+ 0,
+ 0,
+ 0,
+ 139,
+ 842,
+ 1889,
+ 1537,
+ 0,
+ 2198,
+ 3252,
+ 0,
+ 0,
+ 0,
+ 2711,
+ 3762,
+ 3357,
+ 4313,
+ 4259,
+ 141,
+ 142,
+ 144,
+ 145,
+ 146,
+ 147,
+ 160,
+ 0,
+ 0,
+ 0,
+ 150,
+ 0,
+ 149,
+ 0,
+ 148,
+ 3760,
+ 0,
+ 0,
+ 0,
+ 152,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2861,
+ 153,
+ 155,
+ 156,
+ 157,
+ 158,
+ 159,
+ 1382,
+ 1759,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 162,
+ 163,
+ 164,
+ 165,
+ 166,
+ 0,
+ 958,
+ 799,
+ 167,
+ 0,
+ 175,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 177,
+ 4413,
+ 312,
+ 479,
+ 792,
+ 561,
+ 169,
+ 3769,
+ 3920,
+ 1487,
+ 230,
+ 1065,
+ 2427,
+ 3365,
+ 573,
+ 1452,
+ 204,
+ 170,
+ 171,
+ 172,
+ 962,
+ 1366,
+ 173,
+ 2855,
+ 174,
+ 0,
+ 0,
+ 0,
+ 176,
+ 178,
+ 0,
+ 0,
+ 0,
+ 0,
+ 220,
+ 3165,
+ 0,
+ 2515,
+ 4072,
+ 0,
+ 3470,
+ 2736,
+ 685,
+ 0,
+ 0,
+ 0,
+ 4065,
+ 956,
+ 1426,
+ 184,
+ 185,
+ 1529,
+ 1199,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1294,
+ 252,
+ 187,
+ 406,
+ 263,
+ 802,
+ 3985,
+ 0,
+ 0,
+ 0,
+ 188,
+ 0,
+ 0,
+ 0,
+ 2521,
+ 0,
+ 0,
+ 4211,
+ 4207,
+ 1549,
+ 4210,
+ 189,
+ 190,
+ 191,
+ 3706,
+ 192,
+ 193,
+ 195,
+ 4482,
+ 0,
+ 0,
+ 0,
+ 4447,
+ 196,
+ 3144,
+ 0,
+ 198,
+ 1689,
+ 1971,
+ 3023,
+ 3687,
+ 844,
+ 1257,
+ 816,
+ 2650,
+ 199,
+ 200,
+ 201,
+ 1569,
+ 202,
+ 623,
+ 1006,
+ 203,
+ 205,
+ 206,
+ 207,
+ 2194,
+ 208,
+ 2835,
+ 209,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1869,
+ 2545,
+ 2111,
+ 0,
+ 0,
+ 4458,
+ 3207,
+ 0,
+ 0,
+ 3111,
+ 491,
+ 243,
+ 211,
+ 212,
+ 213,
+ 214,
+ 215,
+ 216,
+ 218,
+ 0,
+ 0,
+ 3956,
+ 4074,
+ 0,
+ 0,
+ 0,
+ 2374,
+ 0,
+ 2864,
+ 0,
+ 2217,
+ 0,
+ 4093,
+ 219,
+ 4624,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3181,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1313,
+ 0,
+ 0,
+ 222,
+ 223,
+ 225,
+ 0,
+ 960,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3964,
+ 0,
+ 2070,
+ 0,
+ 0,
+ 3710,
+ 3722,
+ 1821,
+ 226,
+ 228,
+ 0,
+ 2337,
+ 2010,
+ 1739,
+ 3930,
+ 0,
+ 2844,
+ 0,
+ 2205,
+ 0,
+ 4089,
+ 229,
+ 231,
+ 232,
+ 233,
+ 234,
+ 2125,
+ 1147,
+ 1504,
+ 1852,
+ 1853,
+ 1854,
+ 1855,
+ 1856,
+ 0,
+ 1857,
+ 0,
+ 1858,
+ 1859,
+ 0,
+ 0,
+ 235,
+ 0,
+ 0,
+ 1893,
+ 2151,
+ 0,
+ 0,
+ 2478,
+ 0,
+ 237,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3627,
+ 238,
+ 3084,
+ 0,
+ 0,
+ 0,
+ 240,
+ 3098,
+ 0,
+ 3417,
+ 0,
+ 2733,
+ 288,
+ 4042,
+ 241,
+ 0,
+ 3183,
+ 242,
+ 244,
+ 245,
+ 246,
+ 247,
+ 248,
+ 1464,
+ 1829,
+ 0,
+ 2409,
+ 4575,
+ 250,
+ 0,
+ 1026,
+ 0,
+ 0,
+ 0,
+ 0,
+ 422,
+ 3040,
+ 3298,
+ 3659,
+ 311,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 251,
+ 3254,
+ 1774,
+ 0,
+ 0,
+ 0,
+ 253,
+ 0,
+ 378,
+ 0,
+ 2976,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2353,
+ 254,
+ 255,
+ 256,
+ 4532,
+ 257,
+ 262,
+ 258,
+ 3195,
+ 260,
+ 0,
+ 0,
+ 2060,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3061,
+ 261,
+ 4183,
+ 0,
+ 0,
+ 0,
+ 2127,
+ 0,
+ 0,
+ 0,
+ 1703,
+ 2090,
+ 1263,
+ 4685,
+ 4693,
+ 264,
+ 265,
+ 266,
+ 267,
+ 268,
+ 269,
+ 1017,
+ 644,
+ 271,
+ 4507,
+ 4332,
+ 0,
+ 0,
+ 3482,
+ 3765,
+ 3492,
+ 3442,
+ 3526,
+ 3205,
+ 2857,
+ 2559,
+ 701,
+ 272,
+ 307,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 274,
+ 2989,
+ 3322,
+ 0,
+ 0,
+ 1608,
+ 4469,
+ 0,
+ 0,
+ 2068,
+ 302,
+ 1380,
+ 276,
+ 626,
+ 4351,
+ 277,
+ 3593,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 279,
+ 280,
+ 281,
+ 282,
+ 3789,
+ 0,
+ 0,
+ 0,
+ 283,
+ 284,
+ 4369,
+ 0,
+ 286,
+ 0,
+ 0,
+ 0,
+ 3021,
+ 3494,
+ 1812,
+ 0,
+ 0,
+ 2284,
+ 0,
+ 0,
+ 4465,
+ 287,
+ 289,
+ 290,
+ 1317,
+ 4386,
+ 2437,
+ 292,
+ 0,
+ 0,
+ 4656,
+ 293,
+ 294,
+ 2033,
+ 4164,
+ 296,
+ 3461,
+ 297,
+ 298,
+ 299,
+ 300,
+ 301,
+ 1015,
+ 0,
+ 0,
+ 1016,
+ 0,
+ 0,
+ 303,
+ 1905,
+ 0,
+ 2597,
+ 2301,
+ 305,
+ 2348,
+ 2104,
+ 3179,
+ 0,
+ 3830,
+ 0,
+ 2359,
+ 306,
+ 309,
+ 0,
+ 477,
+ 4208,
+ 310,
+ 313,
+ 314,
+ 315,
+ 4099,
+ 316,
+ 4095,
+ 317,
+ 319,
+ 3561,
+ 320,
+ 321,
+ 322,
+ 3163,
+ 0,
+ 323,
+ 324,
+ 4595,
+ 326,
+ 4122,
+ 2012,
+ 0,
+ 1788,
+ 719,
+ 0,
+ 2058,
+ 0,
+ 2075,
+ 0,
+ 0,
+ 0,
+ 3390,
+ 327,
+ 1058,
+ 0,
+ 712,
+ 408,
+ 0,
+ 0,
+ 0,
+ 329,
+ 1629,
+ 1110,
+ 330,
+ 2162,
+ 331,
+ 332,
+ 333,
+ 334,
+ 335,
+ 0,
+ 0,
+ 0,
+ 339,
+ 3940,
+ 0,
+ 3286,
+ 0,
+ 0,
+ 337,
+ 4436,
+ 0,
+ 1343,
+ 871,
+ 1287,
+ 0,
+ 1301,
+ 3655,
+ 0,
+ 2995,
+ 338,
+ 341,
+ 342,
+ 343,
+ 344,
+ 345,
+ 347,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3013,
+ 0,
+ 3885,
+ 3735,
+ 2293,
+ 919,
+ 348,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1396,
+ 2223,
+ 349,
+ 350,
+ 351,
+ 352,
+ 353,
+ 2502,
+ 0,
+ 2168,
+ 1591,
+ 0,
+ 0,
+ 355,
+ 0,
+ 4411,
+ 4124,
+ 0,
+ 1008,
+ 3222,
+ 402,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 401,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 356,
+ 3038,
+ 0,
+ 2386,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 358,
+ 359,
+ 2866,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3271,
+ 0,
+ 361,
+ 4641,
+ 362,
+ 4399,
+ 0,
+ 364,
+ 0,
+ 0,
+ 0,
+ 3883,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3876,
+ 0,
+ 1922,
+ 2314,
+ 366,
+ 365,
+ 3249,
+ 1663,
+ 1241,
+ 1558,
+ 1903,
+ 2215,
+ 368,
+ 0,
+ 4541,
+ 0,
+ 687,
+ 0,
+ 3490,
+ 370,
+ 369,
+ 371,
+ 373,
+ 374,
+ 375,
+ 376,
+ 377,
+ 379,
+ 380,
+ 381,
+ 382,
+ 865,
+ 0,
+ 0,
+ 1924,
+ 383,
+ 384,
+ 3670,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 386,
+ 387,
+ 1408,
+ 0,
+ 0,
+ 2423,
+ 0,
+ 0,
+ 4484,
+ 0,
+ 2946,
+ 0,
+ 4633,
+ 389,
+ 1864,
+ 0,
+ 0,
+ 0,
+ 1879,
+ 390,
+ 392,
+ 393,
+ 394,
+ 3865,
+ 0,
+ 0,
+ 0,
+ 395,
+ 396,
+ 0,
+ 0,
+ 397,
+ 399,
+ 0,
+ 1969,
+ 0,
+ 3392,
+ 2333,
+ 400,
+ 404,
+ 405,
+ 407,
+ 1019,
+ 0,
+ 0,
+ 0,
+ 2745,
+ 0,
+ 1136,
+ 0,
+ 415,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2949,
+ 835,
+ 409,
+ 410,
+ 411,
+ 412,
+ 413,
+ 414,
+ 653,
+ 4423,
+ 4176,
+ 3845,
+ 0,
+ 0,
+ 0,
+ 417,
+ 0,
+ 0,
+ 0,
+ 2599,
+ 2291,
+ 1934,
+ 0,
+ 0,
+ 3574,
+ 418,
+ 4616,
+ 420,
+ 4120,
+ 0,
+ 1510,
+ 1862,
+ 762,
+ 1191,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3095,
+ 3484,
+ 421,
+ 505,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 423,
+ 425,
+ 999,
+ 597,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 427,
+ 428,
+ 429,
+ 430,
+ 3914,
+ 0,
+ 0,
+ 0,
+ 431,
+ 432,
+ 434,
+ 435,
+ 437,
+ 1581,
+ 1239,
+ 0,
+ 3895,
+ 4677,
+ 0,
+ 3603,
+ 3274,
+ 0,
+ 0,
+ 1507,
+ 0,
+ 0,
+ 3082,
+ 438,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1726,
+ 4241,
+ 4357,
+ 703,
+ 440,
+ 0,
+ 1043,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2797,
+ 3720,
+ 441,
+ 2824,
+ 0,
+ 2177,
+ 0,
+ 0,
+ 1092,
+ 1434,
+ 0,
+ 4525,
+ 4317,
+ 4409,
+ 0,
+ 443,
+ 3123,
+ 459,
+ 444,
+ 1512,
+ 0,
+ 855,
+ 446,
+ 3312,
+ 970,
+ 0,
+ 0,
+ 2722,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1838,
+ 447,
+ 448,
+ 449,
+ 450,
+ 451,
+ 1523,
+ 0,
+ 0,
+ 3410,
+ 0,
+ 689,
+ 0,
+ 453,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 875,
+ 454,
+ 455,
+ 456,
+ 457,
+ 458,
+ 1727,
+ 0,
+ 2305,
+ 928,
+ 485,
+ 461,
+ 0,
+ 0,
+ 2278,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1823,
+ 462,
+ 463,
+ 464,
+ 465,
+ 466,
+ 1932,
+ 0,
+ 0,
+ 0,
+ 468,
+ 0,
+ 0,
+ 1303,
+ 0,
+ 3423,
+ 469,
+ 4127,
+ 471,
+ 4136,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2464,
+ 472,
+ 473,
+ 474,
+ 475,
+ 476,
+ 478,
+ 480,
+ 481,
+ 482,
+ 483,
+ 0,
+ 3191,
+ 873,
+ 484,
+ 486,
+ 487,
+ 488,
+ 489,
+ 490,
+ 0,
+ 0,
+ 497,
+ 492,
+ 493,
+ 494,
+ 495,
+ 496,
+ 3810,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 604,
+ 2380,
+ 0,
+ 499,
+ 500,
+ 501,
+ 502,
+ 503,
+ 504,
+ 3552,
+ 1954,
+ 0,
+ 0,
+ 951,
+ 4236,
+ 3402,
+ 0,
+ 0,
+ 0,
+ 507,
+ 0,
+ 0,
+ 2868,
+ 2608,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 508,
+ 509,
+ 3887,
+ 4146,
+ 0,
+ 0,
+ 511,
+ 0,
+ 0,
+ 2252,
+ 0,
+ 2122,
+ 512,
+ 3117,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1695,
+ 0,
+ 888,
+ 0,
+ 514,
+ 515,
+ 516,
+ 517,
+ 518,
+ 519,
+ 521,
+ 522,
+ 523,
+ 524,
+ 0,
+ 1296,
+ 525,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 526,
+ 528,
+ 2580,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1991,
+ 0,
+ 0,
+ 0,
+ 530,
+ 531,
+ 3472,
+ 786,
+ 3153,
+ 4618,
+ 3901,
+ 4217,
+ 2388,
+ 3042,
+ 2452,
+ 2697,
+ 533,
+ 2908,
+ 2873,
+ 1753,
+ 4083,
+ 1402,
+ 534,
+ 535,
+ 536,
+ 537,
+ 538,
+ 540,
+ 542,
+ 541,
+ 2449,
+ 0,
+ 544,
+ 1667,
+ 934,
+ 0,
+ 2403,
+ 0,
+ 3160,
+ 0,
+ 868,
+ 0,
+ 1133,
+ 3542,
+ 2266,
+ 2186,
+ 545,
+ 546,
+ 548,
+ 4308,
+ 0,
+ 1670,
+ 1967,
+ 2289,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3487,
+ 549,
+ 3702,
+ 0,
+ 0,
+ 0,
+ 2401,
+ 1428,
+ 0,
+ 672,
+ 1045,
+ 551,
+ 4289,
+ 4500,
+ 552,
+ 941,
+ 554,
+ 1337,
+ 3724,
+ 2535,
+ 2509,
+ 1599,
+ 4665,
+ 779,
+ 1355,
+ 3614,
+ 4361,
+ 4597,
+ 3676,
+ 638,
+ 3948,
+ 555,
+ 556,
+ 557,
+ 1979,
+ 0,
+ 0,
+ 0,
+ 558,
+ 559,
+ 0,
+ 0,
+ 560,
+ 562,
+ 563,
+ 564,
+ 565,
+ 0,
+ 4475,
+ 1430,
+ 566,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4488,
+ 568,
+ 569,
+ 570,
+ 571,
+ 572,
+ 574,
+ 575,
+ 576,
+ 1804,
+ 0,
+ 577,
+ 578,
+ 580,
+ 581,
+ 582,
+ 583,
+ 584,
+ 0,
+ 0,
+ 0,
+ 4239,
+ 585,
+ 586,
+ 1815,
+ 588,
+ 589,
+ 590,
+ 591,
+ 592,
+ 3190,
+ 593,
+ 3819,
+ 0,
+ 0,
+ 2153,
+ 0,
+ 0,
+ 0,
+ 770,
+ 0,
+ 0,
+ 0,
+ 2688,
+ 0,
+ 595,
+ 596,
+ 598,
+ 599,
+ 600,
+ 601,
+ 0,
+ 0,
+ 0,
+ 2004,
+ 602,
+ 603,
+ 605,
+ 606,
+ 607,
+ 608,
+ 609,
+ 3435,
+ 0,
+ 0,
+ 1585,
+ 0,
+ 0,
+ 611,
+ 0,
+ 0,
+ 617,
+ 612,
+ 613,
+ 614,
+ 615,
+ 616,
+ 950,
+ 618,
+ 619,
+ 620,
+ 621,
+ 940,
+ 622,
+ 624,
+ 0,
+ 0,
+ 0,
+ 625,
+ 627,
+ 629,
+ 1208,
+ 630,
+ 631,
+ 632,
+ 633,
+ 634,
+ 3269,
+ 2006,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3731,
+ 0,
+ 4310,
+ 636,
+ 637,
+ 639,
+ 640,
+ 641,
+ 642,
+ 643,
+ 645,
+ 1170,
+ 1320,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1832,
+ 647,
+ 648,
+ 649,
+ 650,
+ 651,
+ 0,
+ 0,
+ 0,
+ 2133,
+ 3450,
+ 652,
+ 654,
+ 655,
+ 4063,
+ 3782,
+ 0,
+ 0,
+ 656,
+ 657,
+ 2885,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 659,
+ 660,
+ 661,
+ 662,
+ 663,
+ 0,
+ 0,
+ 0,
+ 2063,
+ 665,
+ 664,
+ 667,
+ 668,
+ 669,
+ 670,
+ 671,
+ 674,
+ 0,
+ 0,
+ 673,
+ 676,
+ 0,
+ 4679,
+ 677,
+ 678,
+ 679,
+ 680,
+ 681,
+ 2966,
+ 3324,
+ 0,
+ 0,
+ 683,
+ 0,
+ 4663,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1117,
+ 1149,
+ 1567,
+ 1865,
+ 684,
+ 686,
+ 688,
+ 690,
+ 691,
+ 692,
+ 693,
+ 694,
+ 696,
+ 697,
+ 698,
+ 699,
+ 0,
+ 0,
+ 0,
+ 3891,
+ 700,
+ 2696,
+ 702,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2247,
+ 704,
+ 706,
+ 1228,
+ 800,
+ 0,
+ 2859,
+ 0,
+ 0,
+ 0,
+ 3278,
+ 711,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 707,
+ 747,
+ 3266,
+ 0,
+ 0,
+ 4631,
+ 0,
+ 777,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 709,
+ 0,
+ 1574,
+ 2565,
+ 710,
+ 1673,
+ 713,
+ 714,
+ 715,
+ 716,
+ 717,
+ 718,
+ 720,
+ 0,
+ 721,
+ 3508,
+ 0,
+ 0,
+ 0,
+ 4626,
+ 0,
+ 723,
+ 1205,
+ 3975,
+ 0,
+ 1965,
+ 2339,
+ 776,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 724,
+ 2072,
+ 3816,
+ 0,
+ 2900,
+ 726,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4115,
+ 727,
+ 728,
+ 4321,
+ 0,
+ 0,
+ 1499,
+ 1071,
+ 730,
+ 731,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3686,
+ 2394,
+ 2643,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 733,
+ 4157,
+ 734,
+ 735,
+ 736,
+ 737,
+ 738,
+ 4197,
+ 740,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3966,
+ 1159,
+ 741,
+ 742,
+ 743,
+ 744,
+ 745,
+ 746,
+ 749,
+ 2517,
+ 0,
+ 0,
+ 0,
+ 3657,
+ 3893,
+ 0,
+ 1363,
+ 0,
+ 0,
+ 751,
+ 752,
+ 754,
+ 755,
+ 756,
+ 1867,
+ 0,
+ 1168,
+ 757,
+ 758,
+ 760,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2623,
+ 761,
+ 763,
+ 765,
+ 766,
+ 767,
+ 768,
+ 769,
+ 0,
+ 3768,
+ 771,
+ 2350,
+ 0,
+ 1289,
+ 0,
+ 0,
+ 0,
+ 773,
+ 0,
+ 2914,
+ 774,
+ 775,
+ 778,
+ 780,
+ 781,
+ 782,
+ 783,
+ 0,
+ 0,
+ 0,
+ 4148,
+ 784,
+ 785,
+ 787,
+ 788,
+ 789,
+ 2219,
+ 0,
+ 0,
+ 0,
+ 790,
+ 791,
+ 0,
+ 0,
+ 798,
+ 793,
+ 794,
+ 795,
+ 4643,
+ 0,
+ 796,
+ 797,
+ 801,
+ 0,
+ 0,
+ 0,
+ 0,
+ 861,
+ 803,
+ 804,
+ 805,
+ 806,
+ 807,
+ 812,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 808,
+ 1914,
+ 0,
+ 2611,
+ 0,
+ 0,
+ 810,
+ 0,
+ 0,
+ 1432,
+ 3708,
+ 811,
+ 1166,
+ 0,
+ 0,
+ 0,
+ 1769,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 814,
+ 841,
+ 815,
+ 817,
+ 818,
+ 819,
+ 820,
+ 0,
+ 4659,
+ 823,
+ 822,
+ 821,
+ 4098,
+ 825,
+ 0,
+ 0,
+ 824,
+ 834,
+ 833,
+ 827,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2482,
+ 0,
+ 3996,
+ 0,
+ 3381,
+ 828,
+ 829,
+ 830,
+ 831,
+ 832,
+ 836,
+ 837,
+ 838,
+ 839,
+ 840,
+ 843,
+ 845,
+ 846,
+ 847,
+ 848,
+ 0,
+ 1583,
+ 4046,
+ 849,
+ 853,
+ 0,
+ 0,
+ 0,
+ 0,
+ 854,
+ 4005,
+ 851,
+ 0,
+ 4545,
+ 0,
+ 4593,
+ 4394,
+ 0,
+ 0,
+ 2882,
+ 0,
+ 0,
+ 4672,
+ 852,
+ 856,
+ 857,
+ 858,
+ 859,
+ 860,
+ 1124,
+ 0,
+ 0,
+ 0,
+ 2433,
+ 2048,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3569,
+ 0,
+ 863,
+ 864,
+ 866,
+ 867,
+ 4516,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 869,
+ 870,
+ 872,
+ 874,
+ 876,
+ 877,
+ 878,
+ 879,
+ 880,
+ 4396,
+ 882,
+ 1658,
+ 0,
+ 2361,
+ 2656,
+ 0,
+ 0,
+ 884,
+ 0,
+ 1410,
+ 0,
+ 0,
+ 0,
+ 4205,
+ 916,
+ 0,
+ 915,
+ 0,
+ 918,
+ 917,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 885,
+ 887,
+ 889,
+ 890,
+ 891,
+ 892,
+ 893,
+ 2837,
+ 0,
+ 4562,
+ 0,
+ 1926,
+ 0,
+ 895,
+ 0,
+ 3048,
+ 0,
+ 2627,
+ 0,
+ 3696,
+ 0,
+ 3645,
+ 896,
+ 897,
+ 898,
+ 899,
+ 900,
+ 902,
+ 903,
+ 904,
+ 905,
+ 1292,
+ 1638,
+ 1952,
+ 910,
+ 911,
+ 908,
+ 909,
+ 914,
+ 0,
+ 912,
+ 913,
+ 906,
+ 907,
+ 0,
+ 0,
+ 947,
+ 0,
+ 0,
+ 948,
+ 920,
+ 921,
+ 922,
+ 923,
+ 924,
+ 926,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2229,
+ 927,
+ 929,
+ 930,
+ 931,
+ 932,
+ 933,
+ 935,
+ 936,
+ 939,
+ 0,
+ 0,
+ 0,
+ 0,
+ 938,
+ 942,
+ 943,
+ 944,
+ 2311,
+ 0,
+ 0,
+ 0,
+ 945,
+ 946,
+ 0,
+ 0,
+ 949,
+ 952,
+ 953,
+ 955,
+ 957,
+ 959,
+ 961,
+ 966,
+ 967,
+ 968,
+ 969,
+ 963,
+ 0,
+ 964,
+ 965,
+ 976,
+ 977,
+ 0,
+ 0,
+ 1014,
+ 0,
+ 0,
+ 1013,
+ 971,
+ 972,
+ 973,
+ 974,
+ 975,
+ 979,
+ 2660,
+ 980,
+ 981,
+ 982,
+ 983,
+ 4640,
+ 984,
+ 1126,
+ 0,
+ 0,
+ 0,
+ 986,
+ 1472,
+ 0,
+ 987,
+ 0,
+ 4686,
+ 988,
+ 989,
+ 990,
+ 991,
+ 992,
+ 994,
+ 995,
+ 996,
+ 997,
+ 998,
+ 1000,
+ 1001,
+ 1002,
+ 1003,
+ 0,
+ 0,
+ 0,
+ 2368,
+ 1005,
+ 1004,
+ 1007,
+ 1009,
+ 2233,
+ 0,
+ 0,
+ 1011,
+ 1012,
+ 1018,
+ 0,
+ 0,
+ 0,
+ 1025,
+ 1020,
+ 1021,
+ 1022,
+ 1412,
+ 1023,
+ 0,
+ 0,
+ 2799,
+ 4403,
+ 1024,
+ 1123,
+ 0,
+ 1119,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1027,
+ 0,
+ 1036,
+ 2442,
+ 1029,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1078,
+ 1030,
+ 0,
+ 0,
+ 3173,
+ 1031,
+ 1032,
+ 1033,
+ 1034,
+ 1035,
+ 1038,
+ 1039,
+ 1040,
+ 1041,
+ 1042,
+ 1044,
+ 1046,
+ 0,
+ 0,
+ 0,
+ 1094,
+ 1048,
+ 1049,
+ 1051,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4049,
+ 0,
+ 0,
+ 1184,
+ 1052,
+ 1053,
+ 1054,
+ 1055,
+ 1056,
+ 0,
+ 3108,
+ 1057,
+ 1281,
+ 1059,
+ 1060,
+ 1061,
+ 1062,
+ 1063,
+ 1064,
+ 1066,
+ 1067,
+ 1068,
+ 1069,
+ 1070,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1142,
+ 1072,
+ 3991,
+ 0,
+ 1987,
+ 0,
+ 0,
+ 2577,
+ 0,
+ 2879,
+ 0,
+ 1074,
+ 1709,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1075,
+ 1077,
+ 0,
+ 1076,
+ 1079,
+ 1080,
+ 1081,
+ 1082,
+ 1083,
+ 0,
+ 3836,
+ 1084,
+ 1478,
+ 0,
+ 0,
+ 1086,
+ 1095,
+ 1087,
+ 1088,
+ 1089,
+ 1090,
+ 1091,
+ 1093,
+ 0,
+ 0,
+ 1109,
+ 1096,
+ 1097,
+ 1098,
+ 1099,
+ 1100,
+ 1102,
+ 1104,
+ 1105,
+ 1106,
+ 1107,
+ 1108,
+ 1111,
+ 4603,
+ 1112,
+ 1113,
+ 1114,
+ 1115,
+ 1116,
+ 3852,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1118,
+ 2021,
+ 0,
+ 0,
+ 3625,
+ 0,
+ 0,
+ 2625,
+ 2303,
+ 2658,
+ 0,
+ 2589,
+ 2904,
+ 0,
+ 0,
+ 1121,
+ 1122,
+ 0,
+ 0,
+ 0,
+ 1207,
+ 1125,
+ 2923,
+ 0,
+ 3373,
+ 0,
+ 1127,
+ 1128,
+ 1129,
+ 1130,
+ 1131,
+ 1132,
+ 1134,
+ 1135,
+ 1137,
+ 1138,
+ 1139,
+ 1484,
+ 1140,
+ 0,
+ 0,
+ 2785,
+ 1143,
+ 1141,
+ 2440,
+ 0,
+ 1810,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1145,
+ 1146,
+ 1151,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1148,
+ 1222,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1150,
+ 2414,
+ 0,
+ 0,
+ 3639,
+ 0,
+ 0,
+ 2494,
+ 0,
+ 0,
+ 1153,
+ 1154,
+ 1155,
+ 1156,
+ 1157,
+ 1158,
+ 1214,
+ 3089,
+ 0,
+ 0,
+ 0,
+ 1160,
+ 1161,
+ 1162,
+ 1163,
+ 1164,
+ 1165,
+ 1204,
+ 0,
+ 0,
+ 0,
+ 1167,
+ 1169,
+ 0,
+ 0,
+ 0,
+ 1183,
+ 1171,
+ 1172,
+ 1173,
+ 2506,
+ 0,
+ 0,
+ 0,
+ 1174,
+ 1175,
+ 1177,
+ 0,
+ 0,
+ 0,
+ 3127,
+ 0,
+ 0,
+ 0,
+ 1233,
+ 0,
+ 3545,
+ 1178,
+ 1179,
+ 1180,
+ 1181,
+ 2768,
+ 0,
+ 1182,
+ 0,
+ 2776,
+ 0,
+ 0,
+ 2818,
+ 1185,
+ 3803,
+ 1186,
+ 1187,
+ 1188,
+ 3874,
+ 0,
+ 1189,
+ 1190,
+ 1192,
+ 1194,
+ 1195,
+ 1196,
+ 1197,
+ 3087,
+ 3425,
+ 2425,
+ 2781,
+ 2782,
+ 2779,
+ 2780,
+ 2778,
+ 0,
+ 1201,
+ 2777,
+ 2769,
+ 1198,
+ 0,
+ 0,
+ 2823,
+ 0,
+ 0,
+ 2820,
+ 1200,
+ 1203,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1223,
+ 1206,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1227,
+ 1209,
+ 1210,
+ 1211,
+ 1212,
+ 1213,
+ 1216,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3668,
+ 1217,
+ 2275,
+ 0,
+ 4212,
+ 0,
+ 0,
+ 1219,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1660,
+ 1220,
+ 1221,
+ 4558,
+ 4353,
+ 0,
+ 0,
+ 0,
+ 1225,
+ 3785,
+ 1885,
+ 0,
+ 0,
+ 1520,
+ 0,
+ 0,
+ 3067,
+ 1226,
+ 1229,
+ 1701,
+ 0,
+ 0,
+ 3309,
+ 2997,
+ 4002,
+ 3661,
+ 0,
+ 0,
+ 0,
+ 4397,
+ 0,
+ 0,
+ 4628,
+ 1231,
+ 1232,
+ 1234,
+ 1235,
+ 1236,
+ 1237,
+ 1238,
+ 1240,
+ 1243,
+ 1242,
+ 3847,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4392,
+ 0,
+ 1247,
+ 0,
+ 1245,
+ 1654,
+ 0,
+ 0,
+ 2575,
+ 1246,
+ 1248,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1273,
+ 1250,
+ 4695,
+ 0,
+ 0,
+ 1252,
+ 1605,
+ 1253,
+ 4203,
+ 2043,
+ 2363,
+ 0,
+ 0,
+ 3420,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3935,
+ 1255,
+ 4451,
+ 0,
+ 2077,
+ 4228,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1256,
+ 1258,
+ 1259,
+ 1260,
+ 1261,
+ 1262,
+ 1274,
+ 1264,
+ 1265,
+ 1266,
+ 1267,
+ 0,
+ 0,
+ 0,
+ 4445,
+ 1269,
+ 1268,
+ 2906,
+ 0,
+ 0,
+ 1271,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1535,
+ 0,
+ 0,
+ 0,
+ 2783,
+ 1272,
+ 1276,
+ 1277,
+ 1278,
+ 1279,
+ 1280,
+ 1282,
+ 1283,
+ 1284,
+ 1285,
+ 1286,
+ 1288,
+ 1290,
+ 1291,
+ 1293,
+ 3557,
+ 3556,
+ 0,
+ 3560,
+ 1295,
+ 3525,
+ 0,
+ 3524,
+ 0,
+ 3523,
+ 3522,
+ 1297,
+ 1299,
+ 3319,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1394,
+ 1300,
+ 1302,
+ 3571,
+ 0,
+ 0,
+ 0,
+ 1304,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3624,
+ 1306,
+ 0,
+ 0,
+ 0,
+ 1336,
+ 1308,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3622,
+ 3889,
+ 0,
+ 0,
+ 2269,
+ 0,
+ 1622,
+ 1309,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1335,
+ 1311,
+ 1312,
+ 1314,
+ 1316,
+ 1318,
+ 1319,
+ 1321,
+ 1322,
+ 1323,
+ 1324,
+ 0,
+ 0,
+ 0,
+ 2810,
+ 1325,
+ 1332,
+ 1327,
+ 1328,
+ 1329,
+ 1330,
+ 1331,
+ 1334,
+ 1338,
+ 1339,
+ 1340,
+ 1341,
+ 1342,
+ 1344,
+ 3240,
+ 0,
+ 0,
+ 4006,
+ 0,
+ 1346,
+ 2690,
+ 2940,
+ 3138,
+ 0,
+ 4430,
+ 0,
+ 0,
+ 0,
+ 4251,
+ 1347,
+ 1348,
+ 1349,
+ 1350,
+ 1354,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1351,
+ 0,
+ 1362,
+ 1353,
+ 1356,
+ 1357,
+ 1358,
+ 1359,
+ 0,
+ 0,
+ 0,
+ 4489,
+ 1361,
+ 1360,
+ 1365,
+ 0,
+ 0,
+ 1364,
+ 1367,
+ 1369,
+ 3349,
+ 1370,
+ 1371,
+ 1372,
+ 1373,
+ 1374,
+ 1376,
+ 1379,
+ 0,
+ 0,
+ 1378,
+ 1425,
+ 1381,
+ 1383,
+ 1384,
+ 1385,
+ 2029,
+ 0,
+ 1386,
+ 1387,
+ 2050,
+ 2435,
+ 1389,
+ 1782,
+ 2812,
+ 3101,
+ 3276,
+ 2109,
+ 3227,
+ 4674,
+ 0,
+ 4133,
+ 1436,
+ 0,
+ 0,
+ 1437,
+ 0,
+ 1438,
+ 0,
+ 0,
+ 0,
+ 1390,
+ 1392,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3712,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3478,
+ 3827,
+ 2821,
+ 1439,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1393,
+ 1395,
+ 1397,
+ 1398,
+ 1399,
+ 1400,
+ 1401,
+ 1403,
+ 1404,
+ 1405,
+ 1406,
+ 1407,
+ 1409,
+ 1411,
+ 1414,
+ 1413,
+ 0,
+ 0,
+ 1423,
+ 0,
+ 1424,
+ 1416,
+ 1417,
+ 1418,
+ 1419,
+ 1420,
+ 2413,
+ 1421,
+ 1422,
+ 1427,
+ 1429,
+ 1431,
+ 1433,
+ 1435,
+ 1860,
+ 1441,
+ 0,
+ 2179,
+ 3151,
+ 0,
+ 3780,
+ 0,
+ 0,
+ 4047,
+ 2683,
+ 4118,
+ 0,
+ 0,
+ 0,
+ 2207,
+ 1442,
+ 1444,
+ 1445,
+ 1446,
+ 1447,
+ 1509,
+ 1448,
+ 4611,
+ 0,
+ 0,
+ 1765,
+ 1450,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3775,
+ 0,
+ 3134,
+ 1451,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1506,
+ 1453,
+ 1454,
+ 1455,
+ 2117,
+ 0,
+ 1456,
+ 4549,
+ 1502,
+ 0,
+ 0,
+ 0,
+ 1503,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1457,
+ 1459,
+ 1460,
+ 1461,
+ 1462,
+ 1463,
+ 1465,
+ 1466,
+ 1877,
+ 4113,
+ 4380,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1468,
+ 1880,
+ 1469,
+ 3012,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1471,
+ 1473,
+ 1474,
+ 1475,
+ 1476,
+ 1477,
+ 1479,
+ 1480,
+ 1481,
+ 1482,
+ 1483,
+ 1486,
+ 1485,
+ 1488,
+ 1489,
+ 1490,
+ 2470,
+ 0,
+ 1767,
+ 1491,
+ 1492,
+ 1494,
+ 1495,
+ 1496,
+ 1497,
+ 1498,
+ 1500,
+ 0,
+ 0,
+ 0,
+ 1501,
+ 1505,
+ 1508,
+ 1511,
+ 1513,
+ 1514,
+ 1515,
+ 1516,
+ 1517,
+ 1518,
+ 0,
+ 1519,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1522,
+ 1521,
+ 1524,
+ 1525,
+ 1526,
+ 1527,
+ 1528,
+ 1530,
+ 1531,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2637,
+ 3193,
+ 0,
+ 0,
+ 4091,
+ 1891,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1533,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2184,
+ 1534,
+ 1536,
+ 1538,
+ 1540,
+ 1541,
+ 1543,
+ 1544,
+ 1545,
+ 1546,
+ 1547,
+ 1548,
+ 1550,
+ 1551,
+ 1552,
+ 1553,
+ 1554,
+ 1556,
+ 1557,
+ 1580,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1579,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3060,
+ 1559,
+ 1561,
+ 1562,
+ 1563,
+ 1564,
+ 1565,
+ 1566,
+ 1568,
+ 1570,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4513,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4529,
+ 0,
+ 0,
+ 4527,
+ 1572,
+ 1573,
+ 1575,
+ 4401,
+ 4142,
+ 3854,
+ 0,
+ 3229,
+ 2960,
+ 0,
+ 2287,
+ 1943,
+ 1613,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1577,
+ 1722,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1578,
+ 1582,
+ 0,
+ 0,
+ 3268,
+ 1584,
+ 1586,
+ 1587,
+ 1588,
+ 1589,
+ 3081,
+ 1590,
+ 1592,
+ 1636,
+ 1594,
+ 1595,
+ 1597,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2613,
+ 1598,
+ 1600,
+ 1601,
+ 1602,
+ 1603,
+ 1604,
+ 1606,
+ 0,
+ 0,
+ 0,
+ 1607,
+ 1609,
+ 4537,
+ 0,
+ 0,
+ 2254,
+ 0,
+ 1611,
+ 0,
+ 0,
+ 4428,
+ 1612,
+ 1614,
+ 1616,
+ 1897,
+ 1617,
+ 1618,
+ 1619,
+ 1620,
+ 1621,
+ 1623,
+ 4530,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1625,
+ 1984,
+ 1626,
+ 1628,
+ 3280,
+ 1630,
+ 1631,
+ 1632,
+ 1633,
+ 1634,
+ 1635,
+ 1637,
+ 1650,
+ 0,
+ 0,
+ 0,
+ 1646,
+ 1639,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1672,
+ 1641,
+ 1642,
+ 1643,
+ 1644,
+ 0,
+ 0,
+ 0,
+ 2937,
+ 3683,
+ 1645,
+ 2324,
+ 0,
+ 1648,
+ 0,
+ 3576,
+ 0,
+ 0,
+ 3058,
+ 2816,
+ 0,
+ 4543,
+ 1649,
+ 1652,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3306,
+ 1653,
+ 1655,
+ 1657,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1679,
+ 1659,
+ 3795,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1661,
+ 1662,
+ 1664,
+ 0,
+ 3635,
+ 1666,
+ 2248,
+ 0,
+ 0,
+ 0,
+ 1668,
+ 0,
+ 0,
+ 3880,
+ 3663,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1669,
+ 1671,
+ 1674,
+ 1675,
+ 1676,
+ 1677,
+ 1678,
+ 3620,
+ 0,
+ 1681,
+ 2621,
+ 1682,
+ 2245,
+ 0,
+ 2273,
+ 0,
+ 1684,
+ 1685,
+ 1687,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2633,
+ 0,
+ 0,
+ 4243,
+ 1688,
+ 1690,
+ 1691,
+ 1692,
+ 1693,
+ 0,
+ 2370,
+ 1724,
+ 1725,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1723,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1694,
+ 1696,
+ 1697,
+ 1698,
+ 1699,
+ 1700,
+ 1702,
+ 1704,
+ 1705,
+ 1706,
+ 1707,
+ 2476,
+ 0,
+ 0,
+ 3467,
+ 2062,
+ 1708,
+ 1710,
+ 1712,
+ 1713,
+ 1714,
+ 1715,
+ 1717,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1721,
+ 0,
+ 1716,
+ 1719,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3558,
+ 1720,
+ 1728,
+ 1729,
+ 1730,
+ 1731,
+ 1733,
+ 1734,
+ 0,
+ 1732,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1735,
+ 1737,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2271,
+ 3843,
+ 0,
+ 4471,
+ 3684,
+ 0,
+ 4144,
+ 1738,
+ 1740,
+ 1742,
+ 1743,
+ 1744,
+ 1745,
+ 1746,
+ 1748,
+ 1749,
+ 1750,
+ 1751,
+ 1752,
+ 1754,
+ 1755,
+ 1756,
+ 1757,
+ 1758,
+ 1760,
+ 1761,
+ 1762,
+ 2406,
+ 0,
+ 1763,
+ 1764,
+ 1766,
+ 1851,
+ 0,
+ 0,
+ 0,
+ 1844,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1768,
+ 1770,
+ 1772,
+ 1773,
+ 1775,
+ 1776,
+ 1777,
+ 1778,
+ 2085,
+ 0,
+ 0,
+ 3063,
+ 1779,
+ 1780,
+ 0,
+ 0,
+ 1784,
+ 0,
+ 1781,
+ 1783,
+ 2190,
+ 3056,
+ 0,
+ 0,
+ 0,
+ 1786,
+ 0,
+ 0,
+ 4535,
+ 0,
+ 4638,
+ 4426,
+ 2962,
+ 1787,
+ 1831,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1789,
+ 1791,
+ 1792,
+ 1793,
+ 1794,
+ 1795,
+ 1796,
+ 2014,
+ 0,
+ 2591,
+ 2754,
+ 2931,
+ 3006,
+ 2239,
+ 3167,
+ 1798,
+ 4030,
+ 3907,
+ 1799,
+ 1800,
+ 1801,
+ 1802,
+ 1803,
+ 1814,
+ 1805,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1806,
+ 1808,
+ 0,
+ 0,
+ 0,
+ 3672,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2159,
+ 1809,
+ 1811,
+ 1813,
+ 1816,
+ 1817,
+ 1818,
+ 1819,
+ 1820,
+ 3653,
+ 1822,
+ 1824,
+ 1825,
+ 1826,
+ 1827,
+ 1828,
+ 1830,
+ 1833,
+ 1834,
+ 1835,
+ 3105,
+ 0,
+ 0,
+ 0,
+ 1836,
+ 1837,
+ 1839,
+ 1840,
+ 1841,
+ 1842,
+ 1843,
+ 1846,
+ 1847,
+ 1848,
+ 2787,
+ 0,
+ 2149,
+ 1849,
+ 1850,
+ 1861,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1887,
+ 1863,
+ 3714,
+ 0,
+ 1866,
+ 1868,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1888,
+ 2713,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1871,
+ 0,
+ 0,
+ 4279,
+ 1872,
+ 1873,
+ 1874,
+ 1875,
+ 1876,
+ 1878,
+ 1882,
+ 0,
+ 1881,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1896,
+ 1884,
+ 1886,
+ 1890,
+ 1892,
+ 1895,
+ 1898,
+ 1899,
+ 1900,
+ 1901,
+ 1902,
+ 1904,
+ 1936,
+ 0,
+ 0,
+ 0,
+ 1938,
+ 0,
+ 0,
+ 0,
+ 1906,
+ 0,
+ 1916,
+ 1908,
+ 0,
+ 0,
+ 0,
+ 2801,
+ 0,
+ 0,
+ 0,
+ 3821,
+ 0,
+ 2893,
+ 1909,
+ 1910,
+ 1911,
+ 1912,
+ 1919,
+ 0,
+ 1918,
+ 0,
+ 1913,
+ 0,
+ 0,
+ 1937,
+ 1917,
+ 0,
+ 0,
+ 0,
+ 1915,
+ 1921,
+ 1923,
+ 1925,
+ 1927,
+ 1928,
+ 1929,
+ 1930,
+ 1931,
+ 1933,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1951,
+ 1935,
+ 1940,
+ 1942,
+ 1944,
+ 3897,
+ 2257,
+ 0,
+ 0,
+ 2685,
+ 0,
+ 0,
+ 0,
+ 1946,
+ 1947,
+ 3840,
+ 3567,
+ 0,
+ 2958,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1949,
+ 3225,
+ 1950,
+ 1953,
+ 1955,
+ 1956,
+ 1958,
+ 1959,
+ 1960,
+ 1961,
+ 2335,
+ 2669,
+ 2000,
+ 2001,
+ 1998,
+ 1999,
+ 1997,
+ 0,
+ 1995,
+ 1996,
+ 2008,
+ 2009,
+ 1964,
+ 0,
+ 1963,
+ 0,
+ 0,
+ 1962,
+ 1966,
+ 1968,
+ 1986,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1970,
+ 1972,
+ 1973,
+ 1974,
+ 2635,
+ 0,
+ 1975,
+ 2299,
+ 1978,
+ 0,
+ 0,
+ 1976,
+ 1977,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1990,
+ 1981,
+ 1980,
+ 1983,
+ 1985,
+ 1988,
+ 0,
+ 0,
+ 0,
+ 3394,
+ 1989,
+ 1992,
+ 1994,
+ 2003,
+ 2005,
+ 2007,
+ 2011,
+ 2013,
+ 2015,
+ 2016,
+ 2017,
+ 2018,
+ 2020,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2019,
+ 2022,
+ 2024,
+ 2025,
+ 2026,
+ 2027,
+ 4061,
+ 3801,
+ 4344,
+ 4343,
+ 4342,
+ 2028,
+ 4338,
+ 0,
+ 4337,
+ 4336,
+ 4335,
+ 4334,
+ 0,
+ 4379,
+ 4378,
+ 0,
+ 0,
+ 4371,
+ 2032,
+ 2031,
+ 0,
+ 2030,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2039,
+ 2034,
+ 2035,
+ 2036,
+ 2037,
+ 2038,
+ 4329,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2814,
+ 0,
+ 0,
+ 0,
+ 2041,
+ 0,
+ 0,
+ 3079,
+ 2042,
+ 2044,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2087,
+ 2365,
+ 2046,
+ 2047,
+ 2049,
+ 2097,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2051,
+ 2053,
+ 2054,
+ 2055,
+ 2056,
+ 2057,
+ 2059,
+ 2061,
+ 2064,
+ 2066,
+ 2067,
+ 2069,
+ 2071,
+ 3878,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2073,
+ 2074,
+ 2076,
+ 2089,
+ 0,
+ 2078,
+ 2080,
+ 2081,
+ 2082,
+ 2083,
+ 2084,
+ 2086,
+ 2088,
+ 2091,
+ 2092,
+ 2093,
+ 2094,
+ 0,
+ 0,
+ 0,
+ 3400,
+ 2095,
+ 2096,
+ 2099,
+ 2100,
+ 2101,
+ 2102,
+ 2103,
+ 2105,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2222,
+ 2107,
+ 2108,
+ 2110,
+ 0,
+ 2929,
+ 2112,
+ 2113,
+ 2114,
+ 2115,
+ 2116,
+ 2157,
+ 2158,
+ 0,
+ 2161,
+ 0,
+ 0,
+ 0,
+ 2156,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2118,
+ 3219,
+ 0,
+ 0,
+ 2120,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2833,
+ 2504,
+ 2121,
+ 2124,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2123,
+ 2126,
+ 2128,
+ 2129,
+ 2130,
+ 3428,
+ 3754,
+ 0,
+ 0,
+ 2131,
+ 2132,
+ 2134,
+ 2136,
+ 2137,
+ 2138,
+ 2139,
+ 2140,
+ 3777,
+ 2141,
+ 2142,
+ 2144,
+ 2145,
+ 2146,
+ 2147,
+ 2148,
+ 2150,
+ 2152,
+ 2189,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2155,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2154,
+ 2160,
+ 2163,
+ 2164,
+ 2165,
+ 2166,
+ 2167,
+ 0,
+ 0,
+ 0,
+ 2170,
+ 2169,
+ 2172,
+ 2173,
+ 2174,
+ 2175,
+ 0,
+ 4233,
+ 4454,
+ 3665,
+ 3666,
+ 0,
+ 3664,
+ 0,
+ 0,
+ 0,
+ 3667,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2176,
+ 2232,
+ 0,
+ 2178,
+ 2180,
+ 2182,
+ 3136,
+ 2183,
+ 2185,
+ 2187,
+ 0,
+ 0,
+ 3185,
+ 2188,
+ 2191,
+ 2193,
+ 2202,
+ 2201,
+ 2204,
+ 2203,
+ 2197,
+ 0,
+ 2200,
+ 2367,
+ 2196,
+ 2195,
+ 0,
+ 2238,
+ 2237,
+ 0,
+ 0,
+ 2236,
+ 2199,
+ 2206,
+ 2208,
+ 2210,
+ 2211,
+ 2212,
+ 2213,
+ 2214,
+ 2216,
+ 2218,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2235,
+ 2221,
+ 2220,
+ 2224,
+ 2225,
+ 2226,
+ 2227,
+ 2228,
+ 2230,
+ 2231,
+ 2234,
+ 2240,
+ 2241,
+ 2242,
+ 2871,
+ 0,
+ 2243,
+ 2244,
+ 2246,
+ 2249,
+ 2251,
+ 0,
+ 0,
+ 0,
+ 2256,
+ 2253,
+ 2255,
+ 4135,
+ 2258,
+ 4372,
+ 2762,
+ 0,
+ 0,
+ 3000,
+ 2260,
+ 2261,
+ 2262,
+ 2263,
+ 2264,
+ 2265,
+ 2267,
+ 2268,
+ 2270,
+ 2272,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2286,
+ 2274,
+ 0,
+ 2326,
+ 2667,
+ 2276,
+ 2277,
+ 2279,
+ 2280,
+ 2281,
+ 2282,
+ 2283,
+ 2957,
+ 0,
+ 2956,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2948,
+ 2285,
+ 2288,
+ 2290,
+ 2292,
+ 2294,
+ 2295,
+ 2296,
+ 2297,
+ 2298,
+ 2300,
+ 2302,
+ 2304,
+ 2306,
+ 2307,
+ 2308,
+ 2309,
+ 2310,
+ 2312,
+ 2313,
+ 2315,
+ 2317,
+ 2318,
+ 2319,
+ 2320,
+ 2321,
+ 2322,
+ 2323,
+ 2325,
+ 2328,
+ 2329,
+ 2330,
+ 2331,
+ 0,
+ 0,
+ 0,
+ 3651,
+ 3273,
+ 2332,
+ 2334,
+ 0,
+ 0,
+ 0,
+ 2930,
+ 2336,
+ 2338,
+ 2340,
+ 2342,
+ 3502,
+ 2343,
+ 2344,
+ 2345,
+ 2346,
+ 2347,
+ 2349,
+ 2731,
+ 2351,
+ 2352,
+ 2354,
+ 2355,
+ 2356,
+ 2357,
+ 3408,
+ 3730,
+ 2358,
+ 4346,
+ 0,
+ 0,
+ 0,
+ 2360,
+ 2362,
+ 2364,
+ 2366,
+ 2369,
+ 2373,
+ 0,
+ 0,
+ 2372,
+ 2371,
+ 2376,
+ 0,
+ 0,
+ 0,
+ 2375,
+ 3704,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2378,
+ 2379,
+ 2381,
+ 2382,
+ 2383,
+ 2384,
+ 2385,
+ 2387,
+ 2389,
+ 2390,
+ 2391,
+ 2392,
+ 2393,
+ 2395,
+ 2396,
+ 2397,
+ 2398,
+ 2399,
+ 2400,
+ 2402,
+ 2404,
+ 2405,
+ 2407,
+ 2408,
+ 0,
+ 2411,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2412,
+ 2410,
+ 2415,
+ 2416,
+ 2417,
+ 2418,
+ 2419,
+ 2480,
+ 2421,
+ 0,
+ 3065,
+ 2422,
+ 2424,
+ 2426,
+ 2428,
+ 2429,
+ 2430,
+ 3054,
+ 0,
+ 2431,
+ 3432,
+ 2432,
+ 0,
+ 0,
+ 0,
+ 3753,
+ 2434,
+ 2436,
+ 2438,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4503,
+ 2439,
+ 2441,
+ 2443,
+ 2444,
+ 2445,
+ 2446,
+ 2447,
+ 2448,
+ 2450,
+ 2451,
+ 2453,
+ 2454,
+ 2455,
+ 3750,
+ 0,
+ 0,
+ 0,
+ 2456,
+ 3919,
+ 0,
+ 0,
+ 2457,
+ 2459,
+ 2460,
+ 2461,
+ 2462,
+ 2463,
+ 2465,
+ 2466,
+ 2467,
+ 2468,
+ 2469,
+ 2473,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2472,
+ 2471,
+ 0,
+ 0,
+ 0,
+ 3832,
+ 2475,
+ 2477,
+ 2481,
+ 2479,
+ 2483,
+ 2484,
+ 2485,
+ 2486,
+ 2487,
+ 2489,
+ 2490,
+ 2491,
+ 2492,
+ 2493,
+ 2495,
+ 2496,
+ 2497,
+ 2498,
+ 2499,
+ 2551,
+ 2501,
+ 2508,
+ 0,
+ 0,
+ 2503,
+ 2541,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2505,
+ 4102,
+ 2507,
+ 2510,
+ 2511,
+ 2512,
+ 2513,
+ 2514,
+ 2516,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2564,
+ 2518,
+ 2520,
+ 2522,
+ 2523,
+ 2524,
+ 2525,
+ 2827,
+ 0,
+ 0,
+ 3797,
+ 2526,
+ 2527,
+ 3942,
+ 4265,
+ 4298,
+ 0,
+ 2529,
+ 0,
+ 0,
+ 0,
+ 3359,
+ 2530,
+ 2531,
+ 2532,
+ 2533,
+ 2534,
+ 2536,
+ 2537,
+ 2538,
+ 2539,
+ 2540,
+ 2543,
+ 2544,
+ 2546,
+ 2547,
+ 2548,
+ 2549,
+ 2550,
+ 2553,
+ 2567,
+ 2917,
+ 0,
+ 2704,
+ 0,
+ 0,
+ 0,
+ 3584,
+ 2554,
+ 2555,
+ 2556,
+ 2557,
+ 2562,
+ 2561,
+ 0,
+ 2563,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2558,
+ 2560,
+ 2566,
+ 2568,
+ 2569,
+ 2570,
+ 2571,
+ 2573,
+ 0,
+ 0,
+ 2574,
+ 0,
+ 0,
+ 0,
+ 2572,
+ 2610,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2576,
+ 2578,
+ 2579,
+ 2581,
+ 2583,
+ 3744,
+ 2584,
+ 2585,
+ 2586,
+ 2587,
+ 2588,
+ 2590,
+ 2592,
+ 2593,
+ 2594,
+ 2595,
+ 4059,
+ 3125,
+ 3459,
+ 2596,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3767,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3719,
+ 0,
+ 0,
+ 3718,
+ 2598,
+ 2600,
+ 2602,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2615,
+ 2603,
+ 2604,
+ 2605,
+ 3296,
+ 0,
+ 2606,
+ 2607,
+ 2609,
+ 2612,
+ 2614,
+ 2616,
+ 2617,
+ 2618,
+ 2619,
+ 2620,
+ 2622,
+ 2624,
+ 2626,
+ 2628,
+ 2629,
+ 2630,
+ 2631,
+ 2632,
+ 2634,
+ 2636,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2671,
+ 2638,
+ 2639,
+ 2640,
+ 2641,
+ 2642,
+ 2644,
+ 2645,
+ 2646,
+ 2647,
+ 2649,
+ 2648,
+ 2651,
+ 2652,
+ 2653,
+ 3572,
+ 0,
+ 2964,
+ 2654,
+ 2655,
+ 2657,
+ 2659,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2687,
+ 2661,
+ 2662,
+ 2663,
+ 2664,
+ 2665,
+ 2666,
+ 2668,
+ 2674,
+ 0,
+ 2675,
+ 0,
+ 0,
+ 2670,
+ 2673,
+ 2677,
+ 2678,
+ 2679,
+ 2680,
+ 2681,
+ 2682,
+ 2684,
+ 2686,
+ 2689,
+ 2691,
+ 2692,
+ 2693,
+ 2694,
+ 2695,
+ 0,
+ 2703,
+ 2698,
+ 2699,
+ 2700,
+ 3961,
+ 0,
+ 0,
+ 0,
+ 2701,
+ 2702,
+ 0,
+ 0,
+ 2710,
+ 2705,
+ 2706,
+ 2707,
+ 2708,
+ 2709,
+ 2712,
+ 2714,
+ 2715,
+ 2716,
+ 2717,
+ 2718,
+ 3326,
+ 2720,
+ 2721,
+ 2723,
+ 2724,
+ 2725,
+ 2726,
+ 2729,
+ 2728,
+ 0,
+ 2730,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2727,
+ 2732,
+ 2734,
+ 2735,
+ 3799,
+ 2737,
+ 2739,
+ 2740,
+ 2741,
+ 2742,
+ 2743,
+ 2744,
+ 2746,
+ 2747,
+ 2748,
+ 2749,
+ 4180,
+ 4425,
+ 2750,
+ 4654,
+ 4415,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2752,
+ 0,
+ 0,
+ 4287,
+ 2753,
+ 2755,
+ 2756,
+ 2757,
+ 3355,
+ 0,
+ 2758,
+ 2759,
+ 0,
+ 0,
+ 2761,
+ 2760,
+ 2763,
+ 2764,
+ 2765,
+ 2766,
+ 2767,
+ 2771,
+ 2772,
+ 2773,
+ 4355,
+ 2774,
+ 2775,
+ 2784,
+ 2789,
+ 0,
+ 0,
+ 2786,
+ 2788,
+ 3029,
+ 2791,
+ 2792,
+ 2793,
+ 2794,
+ 2795,
+ 4350,
+ 2796,
+ 0,
+ 4347,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4345,
+ 2798,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2826,
+ 2807,
+ 0,
+ 0,
+ 2800,
+ 2802,
+ 2803,
+ 2804,
+ 2805,
+ 2806,
+ 2809,
+ 2811,
+ 2813,
+ 2815,
+ 2819,
+ 2817,
+ 2822,
+ 2825,
+ 2828,
+ 2829,
+ 2832,
+ 0,
+ 0,
+ 2831,
+ 2834,
+ 2836,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2843,
+ 2838,
+ 2839,
+ 2840,
+ 2841,
+ 2842,
+ 2845,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2846,
+ 2848,
+ 2849,
+ 2850,
+ 2851,
+ 0,
+ 3519,
+ 3203,
+ 2852,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2863,
+ 2854,
+ 2856,
+ 2858,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2903,
+ 2860,
+ 2862,
+ 2865,
+ 2867,
+ 2869,
+ 3232,
+ 2870,
+ 2872,
+ 2874,
+ 2875,
+ 2876,
+ 2877,
+ 2878,
+ 2880,
+ 2881,
+ 2883,
+ 0,
+ 2884,
+ 2886,
+ 2887,
+ 2888,
+ 2889,
+ 2890,
+ 2899,
+ 0,
+ 0,
+ 0,
+ 2892,
+ 2894,
+ 2895,
+ 2896,
+ 2897,
+ 2898,
+ 2901,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4384,
+ 2902,
+ 2905,
+ 2907,
+ 2909,
+ 2910,
+ 2911,
+ 2912,
+ 2913,
+ 2915,
+ 2916,
+ 2918,
+ 2919,
+ 2920,
+ 2921,
+ 2922,
+ 2924,
+ 2925,
+ 2926,
+ 2927,
+ 2928,
+ 2932,
+ 2933,
+ 2934,
+ 2935,
+ 0,
+ 3601,
+ 3899,
+ 2968,
+ 2969,
+ 0,
+ 0,
+ 0,
+ 2936,
+ 2939,
+ 0,
+ 0,
+ 2938,
+ 2941,
+ 2942,
+ 2943,
+ 2944,
+ 2945,
+ 2947,
+ 2950,
+ 2951,
+ 2952,
+ 2953,
+ 3328,
+ 2954,
+ 2955,
+ 2959,
+ 3551,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2961,
+ 2963,
+ 2965,
+ 2967,
+ 2971,
+ 2972,
+ 2973,
+ 2974,
+ 2975,
+ 2977,
+ 2978,
+ 2979,
+ 2980,
+ 3302,
+ 2991,
+ 2992,
+ 0,
+ 0,
+ 2994,
+ 0,
+ 2993,
+ 0,
+ 2981,
+ 2983,
+ 2984,
+ 2985,
+ 2986,
+ 2987,
+ 0,
+ 2988,
+ 2990,
+ 2996,
+ 0,
+ 0,
+ 0,
+ 2999,
+ 2998,
+ 3001,
+ 3002,
+ 3003,
+ 3004,
+ 3005,
+ 3007,
+ 3008,
+ 3009,
+ 3331,
+ 3010,
+ 3980,
+ 3674,
+ 3020,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3011,
+ 3014,
+ 3015,
+ 3016,
+ 3017,
+ 3018,
+ 3019,
+ 3022,
+ 3024,
+ 3025,
+ 3026,
+ 3973,
+ 3733,
+ 3337,
+ 3027,
+ 3028,
+ 3030,
+ 3031,
+ 3032,
+ 3033,
+ 3034,
+ 3035,
+ 0,
+ 3036,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3037,
+ 3039,
+ 3041,
+ 3043,
+ 3044,
+ 3045,
+ 3046,
+ 3047,
+ 3049,
+ 3050,
+ 3051,
+ 3052,
+ 3053,
+ 3097,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3055,
+ 3057,
+ 3059,
+ 3062,
+ 3064,
+ 3066,
+ 3104,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3068,
+ 3637,
+ 4170,
+ 3070,
+ 3578,
+ 3071,
+ 3072,
+ 3073,
+ 3074,
+ 3075,
+ 3077,
+ 3078,
+ 3080,
+ 3083,
+ 3085,
+ 3086,
+ 3088,
+ 3090,
+ 3091,
+ 3092,
+ 3093,
+ 4028,
+ 3094,
+ 3096,
+ 3099,
+ 3100,
+ 3103,
+ 0,
+ 0,
+ 3231,
+ 0,
+ 3102,
+ 3107,
+ 3106,
+ 3109,
+ 3110,
+ 3112,
+ 3113,
+ 3114,
+ 3115,
+ 3116,
+ 3118,
+ 3119,
+ 3120,
+ 3121,
+ 3122,
+ 3124,
+ 3295,
+ 3126,
+ 0,
+ 0,
+ 0,
+ 3133,
+ 3128,
+ 3129,
+ 3130,
+ 3131,
+ 3132,
+ 3135,
+ 3137,
+ 3139,
+ 3140,
+ 3141,
+ 3142,
+ 3143,
+ 0,
+ 0,
+ 0,
+ 4457,
+ 0,
+ 4464,
+ 0,
+ 4456,
+ 3145,
+ 3146,
+ 3147,
+ 3148,
+ 3150,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3149,
+ 3159,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3152,
+ 3154,
+ 3155,
+ 3156,
+ 3157,
+ 3158,
+ 3161,
+ 3162,
+ 3164,
+ 3166,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3224,
+ 0,
+ 0,
+ 3221,
+ 3168,
+ 3169,
+ 3170,
+ 3787,
+ 0,
+ 3171,
+ 3172,
+ 3174,
+ 3175,
+ 3176,
+ 3177,
+ 3178,
+ 3180,
+ 3182,
+ 3184,
+ 3186,
+ 3188,
+ 3189,
+ 3192,
+ 3194,
+ 3196,
+ 3198,
+ 3199,
+ 3200,
+ 3201,
+ 3202,
+ 3204,
+ 3218,
+ 0,
+ 3206,
+ 3208,
+ 3209,
+ 3210,
+ 3211,
+ 3212,
+ 4505,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3214,
+ 3215,
+ 3217,
+ 3220,
+ 3223,
+ 3226,
+ 3265,
+ 0,
+ 0,
+ 3228,
+ 3230,
+ 3233,
+ 3235,
+ 3236,
+ 3237,
+ 3238,
+ 0,
+ 3838,
+ 3264,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3263,
+ 3262,
+ 0,
+ 0,
+ 0,
+ 3239,
+ 3241,
+ 3242,
+ 3243,
+ 3244,
+ 3245,
+ 0,
+ 3251,
+ 3247,
+ 3248,
+ 3250,
+ 3253,
+ 3496,
+ 3256,
+ 3257,
+ 3258,
+ 3259,
+ 3260,
+ 3261,
+ 3267,
+ 3270,
+ 3272,
+ 3275,
+ 3277,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3842,
+ 3279,
+ 3281,
+ 3282,
+ 3283,
+ 3284,
+ 3285,
+ 3287,
+ 3289,
+ 3290,
+ 3291,
+ 3292,
+ 3293,
+ 3294,
+ 3300,
+ 3301,
+ 0,
+ 3304,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3297,
+ 3321,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3299,
+ 3303,
+ 3305,
+ 3308,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3307,
+ 0,
+ 0,
+ 3311,
+ 3310,
+ 3313,
+ 3314,
+ 3315,
+ 3316,
+ 3318,
+ 0,
+ 0,
+ 3317,
+ 3320,
+ 3323,
+ 3325,
+ 3327,
+ 3329,
+ 3330,
+ 3333,
+ 3332,
+ 3335,
+ 3334,
+ 3336,
+ 0,
+ 3339,
+ 0,
+ 3341,
+ 3340,
+ 3371,
+ 3379,
+ 4692,
+ 0,
+ 0,
+ 3380,
+ 3338,
+ 4468,
+ 0,
+ 0,
+ 0,
+ 3348,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3372,
+ 3343,
+ 3344,
+ 3345,
+ 3346,
+ 3347,
+ 3350,
+ 3351,
+ 3352,
+ 3353,
+ 3354,
+ 3406,
+ 3405,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3407,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3356,
+ 3416,
+ 3358,
+ 0,
+ 4528,
+ 3360,
+ 3361,
+ 3362,
+ 3363,
+ 3397,
+ 3398,
+ 0,
+ 0,
+ 3399,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3364,
+ 3366,
+ 3367,
+ 3368,
+ 3369,
+ 0,
+ 3982,
+ 4257,
+ 3370,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3396,
+ 3374,
+ 3375,
+ 3376,
+ 3377,
+ 3378,
+ 3382,
+ 3383,
+ 3384,
+ 3385,
+ 3386,
+ 3388,
+ 3389,
+ 3391,
+ 3393,
+ 3395,
+ 3401,
+ 3403,
+ 3404,
+ 3422,
+ 3409,
+ 3411,
+ 3412,
+ 3413,
+ 3414,
+ 3415,
+ 3418,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4661,
+ 3419,
+ 3421,
+ 3424,
+ 3426,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3427,
+ 3429,
+ 3430,
+ 0,
+ 0,
+ 3431,
+ 0,
+ 3434,
+ 0,
+ 3441,
+ 3433,
+ 3436,
+ 3437,
+ 3438,
+ 3439,
+ 3481,
+ 3440,
+ 3443,
+ 3445,
+ 3446,
+ 3447,
+ 3448,
+ 3449,
+ 3452,
+ 3453,
+ 3454,
+ 3455,
+ 3456,
+ 3458,
+ 4004,
+ 3460,
+ 3462,
+ 3463,
+ 3464,
+ 3465,
+ 3466,
+ 3468,
+ 0,
+ 0,
+ 3469,
+ 3489,
+ 3471,
+ 3473,
+ 3474,
+ 3475,
+ 4588,
+ 0,
+ 0,
+ 0,
+ 3476,
+ 3480,
+ 0,
+ 0,
+ 3477,
+ 3479,
+ 3486,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3483,
+ 3485,
+ 3488,
+ 3491,
+ 3493,
+ 3495,
+ 3497,
+ 3498,
+ 3499,
+ 3500,
+ 3501,
+ 3503,
+ 3504,
+ 3505,
+ 3506,
+ 3507,
+ 3510,
+ 0,
+ 0,
+ 0,
+ 3509,
+ 3512,
+ 4579,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4551,
+ 4291,
+ 3513,
+ 3514,
+ 3515,
+ 3516,
+ 3518,
+ 3517,
+ 3520,
+ 0,
+ 0,
+ 0,
+ 3521,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3541,
+ 3527,
+ 3529,
+ 3530,
+ 3531,
+ 3532,
+ 3533,
+ 3535,
+ 3536,
+ 3537,
+ 4109,
+ 0,
+ 3538,
+ 3834,
+ 3539,
+ 0,
+ 0,
+ 0,
+ 3540,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3555,
+ 3543,
+ 3544,
+ 3546,
+ 3547,
+ 3548,
+ 3549,
+ 3550,
+ 3553,
+ 3554,
+ 3559,
+ 3562,
+ 3563,
+ 3564,
+ 3565,
+ 3566,
+ 3568,
+ 3570,
+ 3630,
+ 3629,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3632,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3573,
+ 3575,
+ 3577,
+ 3579,
+ 3580,
+ 3581,
+ 3582,
+ 3583,
+ 3585,
+ 3586,
+ 3587,
+ 3588,
+ 3599,
+ 3600,
+ 0,
+ 0,
+ 3589,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3638,
+ 3591,
+ 3592,
+ 3594,
+ 3595,
+ 3596,
+ 3597,
+ 3598,
+ 3636,
+ 0,
+ 0,
+ 3633,
+ 3634,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3602,
+ 3604,
+ 3606,
+ 3607,
+ 3608,
+ 3609,
+ 3610,
+ 3612,
+ 3613,
+ 3615,
+ 3616,
+ 3617,
+ 3618,
+ 3619,
+ 3621,
+ 3623,
+ 3626,
+ 3631,
+ 0,
+ 0,
+ 0,
+ 3628,
+ 3640,
+ 3641,
+ 3642,
+ 3643,
+ 3682,
+ 3644,
+ 3646,
+ 3647,
+ 3648,
+ 3649,
+ 3650,
+ 3654,
+ 0,
+ 0,
+ 3652,
+ 3656,
+ 3658,
+ 3660,
+ 3662,
+ 3669,
+ 3671,
+ 3673,
+ 3675,
+ 3677,
+ 3678,
+ 3679,
+ 3680,
+ 3681,
+ 3685,
+ 3688,
+ 3689,
+ 3690,
+ 3691,
+ 0,
+ 4263,
+ 3692,
+ 3694,
+ 3695,
+ 3697,
+ 3698,
+ 3699,
+ 3700,
+ 3701,
+ 3703,
+ 3705,
+ 4515,
+ 3707,
+ 0,
+ 0,
+ 4514,
+ 0,
+ 4512,
+ 0,
+ 4524,
+ 3709,
+ 3711,
+ 3713,
+ 3716,
+ 3717,
+ 3721,
+ 3723,
+ 3725,
+ 3726,
+ 3727,
+ 3728,
+ 3729,
+ 3732,
+ 3734,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3764,
+ 3736,
+ 3737,
+ 3738,
+ 3739,
+ 3740,
+ 3742,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4510,
+ 4304,
+ 4285,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4539,
+ 3743,
+ 3745,
+ 3746,
+ 3747,
+ 3748,
+ 3749,
+ 3751,
+ 3752,
+ 3756,
+ 3755,
+ 3758,
+ 3759,
+ 3761,
+ 3763,
+ 3766,
+ 3770,
+ 3771,
+ 3772,
+ 3773,
+ 3774,
+ 3776,
+ 3778,
+ 0,
+ 3779,
+ 3781,
+ 3783,
+ 3784,
+ 3786,
+ 3794,
+ 3793,
+ 3792,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3788,
+ 3800,
+ 0,
+ 3833,
+ 3790,
+ 3791,
+ 3796,
+ 3798,
+ 3802,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3809,
+ 3804,
+ 3805,
+ 3806,
+ 3807,
+ 3808,
+ 3811,
+ 3812,
+ 3813,
+ 3814,
+ 3815,
+ 3817,
+ 3818,
+ 3820,
+ 3822,
+ 3823,
+ 3824,
+ 3825,
+ 3826,
+ 3828,
+ 0,
+ 0,
+ 3829,
+ 3831,
+ 3835,
+ 3837,
+ 3856,
+ 0,
+ 0,
+ 0,
+ 3853,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3839,
+ 3857,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3841,
+ 3858,
+ 0,
+ 0,
+ 0,
+ 3844,
+ 3882,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3846,
+ 3848,
+ 3850,
+ 3851,
+ 3855,
+ 3860,
+ 3861,
+ 3862,
+ 4382,
+ 0,
+ 3863,
+ 3864,
+ 3866,
+ 3867,
+ 3869,
+ 3870,
+ 3871,
+ 3872,
+ 3873,
+ 3875,
+ 3877,
+ 3879,
+ 3881,
+ 3884,
+ 3886,
+ 3888,
+ 0,
+ 0,
+ 0,
+ 3937,
+ 3890,
+ 3892,
+ 0,
+ 0,
+ 3913,
+ 3938,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3894,
+ 3896,
+ 3898,
+ 3900,
+ 3902,
+ 3903,
+ 3904,
+ 3905,
+ 3906,
+ 3908,
+ 3909,
+ 3910,
+ 3911,
+ 0,
+ 4443,
+ 4215,
+ 3933,
+ 3934,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3932,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3912,
+ 3915,
+ 3916,
+ 3918,
+ 3921,
+ 3922,
+ 3923,
+ 3924,
+ 0,
+ 4438,
+ 3929,
+ 3928,
+ 0,
+ 3927,
+ 0,
+ 3925,
+ 3926,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3939,
+ 3931,
+ 3936,
+ 3941,
+ 3943,
+ 3944,
+ 3945,
+ 3946,
+ 3955,
+ 3954,
+ 0,
+ 3947,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3959,
+ 3949,
+ 3950,
+ 3951,
+ 3952,
+ 3953,
+ 3960,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3958,
+ 3957,
+ 0,
+ 0,
+ 0,
+ 3994,
+ 3963,
+ 3962,
+ 3965,
+ 3967,
+ 3968,
+ 3969,
+ 3970,
+ 3971,
+ 3972,
+ 4262,
+ 4229,
+ 4019,
+ 4018,
+ 4017,
+ 0,
+ 4016,
+ 0,
+ 4014,
+ 4013,
+ 3979,
+ 3978,
+ 3977,
+ 0,
+ 0,
+ 3974,
+ 3976,
+ 4015,
+ 4027,
+ 0,
+ 0,
+ 0,
+ 4012,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3981,
+ 3984,
+ 0,
+ 0,
+ 0,
+ 3983,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3995,
+ 3986,
+ 3987,
+ 3988,
+ 3989,
+ 3990,
+ 3992,
+ 3993,
+ 3997,
+ 3998,
+ 3999,
+ 4000,
+ 4001,
+ 4201,
+ 0,
+ 0,
+ 4003,
+ 4007,
+ 4008,
+ 4009,
+ 4010,
+ 4011,
+ 4076,
+ 0,
+ 4021,
+ 4022,
+ 4023,
+ 4024,
+ 4025,
+ 4026,
+ 4029,
+ 4037,
+ 4031,
+ 4032,
+ 4033,
+ 4034,
+ 0,
+ 4547,
+ 4039,
+ 4038,
+ 4041,
+ 4040,
+ 4035,
+ 0,
+ 0,
+ 4036,
+ 4045,
+ 4044,
+ 4071,
+ 4043,
+ 4048,
+ 4050,
+ 4051,
+ 4052,
+ 4053,
+ 4054,
+ 4055,
+ 4057,
+ 4058,
+ 4060,
+ 4082,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4062,
+ 4068,
+ 4067,
+ 0,
+ 0,
+ 4069,
+ 0,
+ 4070,
+ 0,
+ 4064,
+ 4066,
+ 4073,
+ 4075,
+ 4077,
+ 4078,
+ 4079,
+ 4080,
+ 4081,
+ 4084,
+ 4085,
+ 4086,
+ 4087,
+ 4088,
+ 4090,
+ 4092,
+ 4094,
+ 4097,
+ 0,
+ 4096,
+ 0,
+ 0,
+ 4101,
+ 4571,
+ 4572,
+ 4573,
+ 4574,
+ 4100,
+ 0,
+ 4577,
+ 4578,
+ 4560,
+ 4561,
+ 4609,
+ 0,
+ 4610,
+ 0,
+ 0,
+ 4613,
+ 4104,
+ 4105,
+ 4106,
+ 4107,
+ 4108,
+ 4110,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4126,
+ 4112,
+ 4114,
+ 4116,
+ 4117,
+ 4119,
+ 4121,
+ 4123,
+ 4125,
+ 4128,
+ 4129,
+ 4130,
+ 4131,
+ 4132,
+ 4134,
+ 4137,
+ 4138,
+ 4139,
+ 4140,
+ 4141,
+ 4143,
+ 0,
+ 0,
+ 0,
+ 4202,
+ 4145,
+ 4189,
+ 0,
+ 0,
+ 4147,
+ 4149,
+ 0,
+ 0,
+ 4156,
+ 4151,
+ 4152,
+ 4153,
+ 4154,
+ 4155,
+ 4158,
+ 4159,
+ 4160,
+ 4161,
+ 4163,
+ 4162,
+ 4165,
+ 4166,
+ 4167,
+ 4168,
+ 4169,
+ 4171,
+ 4172,
+ 4173,
+ 4174,
+ 4175,
+ 4177,
+ 4179,
+ 4182,
+ 4181,
+ 4184,
+ 4185,
+ 4186,
+ 4187,
+ 4188,
+ 4190,
+ 4192,
+ 4193,
+ 4194,
+ 4195,
+ 4196,
+ 4199,
+ 4200,
+ 4204,
+ 4206,
+ 4209,
+ 4223,
+ 4213,
+ 4214,
+ 4216,
+ 4218,
+ 4219,
+ 4220,
+ 4221,
+ 4222,
+ 4224,
+ 4225,
+ 4226,
+ 4227,
+ 4232,
+ 0,
+ 0,
+ 4231,
+ 4235,
+ 0,
+ 0,
+ 0,
+ 4234,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4261,
+ 4237,
+ 4238,
+ 4240,
+ 4242,
+ 4244,
+ 4246,
+ 4247,
+ 4248,
+ 4249,
+ 4250,
+ 4252,
+ 4253,
+ 4254,
+ 4255,
+ 4256,
+ 4258,
+ 4260,
+ 4264,
+ 4266,
+ 4267,
+ 4268,
+ 4269,
+ 4277,
+ 0,
+ 0,
+ 4270,
+ 0,
+ 0,
+ 0,
+ 4278,
+ 4272,
+ 4273,
+ 4274,
+ 4275,
+ 4276,
+ 4280,
+ 4281,
+ 4282,
+ 4283,
+ 4284,
+ 4286,
+ 4288,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4316,
+ 4290,
+ 4292,
+ 4293,
+ 4294,
+ 4295,
+ 4296,
+ 4297,
+ 4299,
+ 4300,
+ 4301,
+ 4302,
+ 4303,
+ 4305,
+ 4307,
+ 4309,
+ 4312,
+ 4311,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4315,
+ 4314,
+ 4318,
+ 4320,
+ 4322,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4360,
+ 4324,
+ 4325,
+ 4326,
+ 4327,
+ 4328,
+ 4330,
+ 4331,
+ 4333,
+ 4340,
+ 4341,
+ 4349,
+ 4352,
+ 4354,
+ 4356,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4359,
+ 4358,
+ 4362,
+ 4363,
+ 4364,
+ 4365,
+ 4366,
+ 4368,
+ 4370,
+ 4373,
+ 4374,
+ 4375,
+ 4376,
+ 4377,
+ 4381,
+ 4404,
+ 4405,
+ 0,
+ 4406,
+ 0,
+ 4407,
+ 4408,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4383,
+ 4385,
+ 4387,
+ 4388,
+ 4391,
+ 4390,
+ 4393,
+ 4395,
+ 4398,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4414,
+ 4400,
+ 4402,
+ 4410,
+ 4412,
+ 4416,
+ 4418,
+ 4419,
+ 4420,
+ 4421,
+ 4422,
+ 4424,
+ 4427,
+ 0,
+ 0,
+ 0,
+ 4449,
+ 4450,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4429,
+ 4431,
+ 4432,
+ 4433,
+ 4434,
+ 4435,
+ 4467,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4437,
+ 4439,
+ 4441,
+ 4442,
+ 4444,
+ 4446,
+ 4448,
+ 4452,
+ 4453,
+ 4455,
+ 4459,
+ 4460,
+ 4461,
+ 4462,
+ 4463,
+ 4466,
+ 4470,
+ 4472,
+ 4474,
+ 4476,
+ 0,
+ 0,
+ 0,
+ 4479,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4499,
+ 4478,
+ 4481,
+ 4483,
+ 4485,
+ 4487,
+ 4490,
+ 0,
+ 0,
+ 4491,
+ 4493,
+ 4494,
+ 4495,
+ 4496,
+ 4497,
+ 4498,
+ 4502,
+ 0,
+ 4501,
+ 4504,
+ 4506,
+ 4508,
+ 4509,
+ 4511,
+ 4517,
+ 4519,
+ 4520,
+ 4521,
+ 4522,
+ 4523,
+ 4526,
+ 4531,
+ 4533,
+ 4534,
+ 4536,
+ 4538,
+ 4540,
+ 4542,
+ 4544,
+ 4546,
+ 4548,
+ 4550,
+ 4552,
+ 4553,
+ 4554,
+ 4555,
+ 4557,
+ 4556,
+ 4559,
+ 4563,
+ 4564,
+ 4565,
+ 4566,
+ 4567,
+ 4570,
+ 4569,
+ 4576,
+ 4580,
+ 4581,
+ 4582,
+ 4583,
+ 4584,
+ 4585,
+ 4587,
+ 4589,
+ 4590,
+ 4592,
+ 4594,
+ 4596,
+ 4598,
+ 4599,
+ 4600,
+ 4601,
+ 4602,
+ 4604,
+ 4605,
+ 4606,
+ 4607,
+ 4608,
+ 4612,
+ 4615,
+ 4617,
+ 4619,
+ 4620,
+ 4621,
+ 4622,
+ 4623,
+ 4625,
+ 4627,
+ 4629,
+ 4630,
+ 4632,
+ 4637,
+ 0,
+ 0,
+ 0,
+ 4634,
+ 4636,
+ 4639,
+ 4642,
+ 4645,
+ 4644,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4646,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4694,
+ 4648,
+ 4649,
+ 4650,
+ 4651,
+ 4652,
+ 4653,
+ 4655,
+ 4657,
+ 4658,
+ 4660,
+ 4662,
+ 4671,
+ 0,
+ 0,
+ 4664,
+ 4666,
+ 4667,
+ 4668,
+ 4669,
+ 4670,
+ 4673,
+ 4676,
+ 0,
+ 4675,
+ 4678,
+ 4680,
+ 4681,
+ 4682,
+ 4683,
+ 4684,
+ 4687,
+ 4688,
+ 4689,
+ 4690,
+ 4691,
+ 4696,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4697,
+};
+
diff --git a/source4/heimdal/lib/wind/normalize_table.h b/source4/heimdal/lib/wind/normalize_table.h
new file mode 100644
index 0000000000..90b62e645d
--- /dev/null
+++ b/source4/heimdal/lib/wind/normalize_table.h
@@ -0,0 +1,34 @@
+/* normalize_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.923674 */
+
+#ifndef NORMALIZE_TABLE_H
+#define NORMALIZE_TABLE_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MAX_LENGTH_CANON 18
+
+struct translation {
+ uint32_t key;
+ unsigned short val_len;
+ unsigned short val_offset;
+};
+
+extern const struct translation _wind_normalize_table[];
+
+extern const uint32_t _wind_normalize_val_table[];
+
+extern const size_t _wind_normalize_table_size;
+
+struct canon_node {
+ uint32_t val;
+ unsigned char next_start;
+ unsigned char next_end;
+ unsigned short next_offset;
+};
+
+extern const struct canon_node _wind_canon_table[];
+
+extern const unsigned short _wind_canon_next_table[];
+#endif /* NORMALIZE_TABLE_H */
diff --git a/source4/heimdal/lib/wind/stringprep.c b/source4/heimdal/lib/wind/stringprep.c
new file mode 100644
index 0000000000..0beba76384
--- /dev/null
+++ b/source4/heimdal/lib/wind/stringprep.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2004, 2006, 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+
+RCSID("$Id: stringprep.c 22593 2008-02-12 11:58:01Z lha $");
+
+/**
+ * Process a input UCS4 string according a string-prep profile.
+ *
+ * @param in input UCS4 string to process
+ * @param in_len length of the input string
+ * @param out output UCS4 string
+ * @param out_len length of the output string.
+ * @param flags stringprep profile.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_stringprep(const uint32_t *in, size_t in_len,
+ uint32_t *out, size_t *out_len,
+ wind_profile_flags flags)
+{
+ size_t tmp_len = in_len * 3;
+ uint32_t *tmp = malloc(tmp_len * sizeof(uint32_t));
+ int ret;
+ size_t olen;
+
+ if (tmp == NULL)
+ return ENOMEM;
+
+ ret = _wind_stringprep_map(in, in_len, tmp, &tmp_len, flags);
+ if (ret) {
+ free(tmp);
+ return ret;
+ }
+
+ olen = *out_len;
+ ret = _wind_stringprep_normalize(tmp, tmp_len, tmp, &olen);
+ if (ret) {
+ free(tmp);
+ return ret;
+ }
+ ret = _wind_stringprep_prohibited(tmp, olen, flags);
+ if (ret) {
+ free(tmp);
+ return ret;
+ }
+ ret = _wind_stringprep_testbidi(tmp, olen, flags);
+ if (ret) {
+ free(tmp);
+ return ret;
+ }
+
+ /* Insignificant Character Handling for ldap-prep */
+ if (flags & WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE) {
+ ret = _wind_ldap_case_exact_attribute(tmp, olen, out, out_len);
+#if 0
+ } else if (flags & WIND_PROFILE_LDAP_CASE_EXACT_ASSERTION) {
+ } else if (flags & WIND_PROFILE_LDAP_NUMERIC) {
+ } else if (flags & WIND_PROFILE_LDAP_TELEPHONE) {
+#endif
+ } else {
+ memcpy(out, tmp, sizeof(out[0]) * olen);
+ *out_len = olen;
+ }
+ free(tmp);
+
+ return ret;
+}
+
+static struct {
+ const char *name;
+ wind_profile_flags flags;
+} profiles[] = {
+ { "nameprep", WIND_PROFILE_NAME },
+ { "saslprep", WIND_PROFILE_SASL },
+ { "ldapprep", WIND_PROFILE_LDAP }
+};
+
+/**
+ * Try to find the profile given a name.
+ *
+ * @param name name of the profile.
+ * @param flags the resulting profile.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_profile(const char *name, wind_profile_flags *flags)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(profiles)/sizeof(profiles[0]); i++) {
+ if (strcasecmp(profiles[i].name, name) == 0) {
+ *flags = profiles[i].flags;
+ return 0;
+ }
+ }
+ return WIND_ERR_NO_PROFILE;
+}
diff --git a/source4/heimdal/lib/wind/utf8.c b/source4/heimdal/lib/wind/utf8.c
new file mode 100644
index 0000000000..c49e80522e
--- /dev/null
+++ b/source4/heimdal/lib/wind/utf8.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2004, 2006, 2007, 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+
+RCSID("$Id: utf8.c 22572 2008-02-05 20:22:39Z lha $");
+
+/**
+ * Convert an UTF-8 string to an UCS4 string.
+ *
+ * @param in an UTF-8 string to convert.
+ * @param out the resulting UCS4 strint, must be at least
+ * wind_utf8ucs4_length() long. If out is NULL, the function will
+ * calculate the needed space for the out variable (just like
+ * wind_utf8ucs4_length()).
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_utf8ucs4(const char *in, uint32_t *out, size_t *out_len)
+{
+ const unsigned char *p;
+ size_t o = 0;
+
+ for (p = (const unsigned char *)in; *p != '\0'; ++p) {
+ unsigned c = *p;
+ uint32_t u;
+
+ if (c & 0x80) {
+ if ((c & 0xE0) == 0xC0) {
+ const unsigned c2 = *++p;
+ if ((c2 & 0xC0) == 0x80) {
+ u = ((c & 0x1F) << 6)
+ | (c2 & 0x3F);
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else if ((c & 0xF0) == 0xE0) {
+ const unsigned c2 = *++p;
+ if ((c2 & 0xC0) == 0x80) {
+ const unsigned c3 = *++p;
+ if ((c3 & 0xC0) == 0x80) {
+ u = ((c & 0x0F) << 12)
+ | ((c2 & 0x3F) << 6)
+ | (c3 & 0x3F);
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else if ((c & 0xF8) == 0xF0) {
+ const unsigned c2 = *++p;
+ if ((c2 & 0xC0) == 0x80) {
+ const unsigned c3 = *++p;
+ if ((c3 & 0xC0) == 0x80) {
+ const unsigned c4 = *++p;
+ if ((c4 & 0xC0) == 0x80) {
+ u = ((c & 0x07) << 18)
+ | ((c2 & 0x3F) << 12)
+ | ((c3 & 0x3F) << 6)
+ | (c4 & 0x3F);
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else {
+ return WIND_ERR_INVALID_UTF8;
+ }
+ } else {
+ u = c;
+ }
+ if (out) {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ out[o] = u;
+ }
+ o++;
+ }
+ *out_len = o;
+ return 0;
+}
+
+/**
+ * Calculate the length of from converting a UTF-8 string to a UCS4
+ * string.
+ *
+ * @param in an UTF-8 string to convert.
+ * @param out_len the length of the resulting UCS4 string.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_utf8ucs4_length(const char *in, size_t *out_len)
+{
+ return wind_utf8ucs4(in, NULL, out_len);
+}
+
+static const char first_char[4] =
+ { 0x00, 0xC0, 0xE0, 0xF0 };
+
+/**
+ * Convert an UCS4 string to a UTF-8 string.
+ *
+ * @param in an UCS4 string to convert.
+ * @param in_len the length input array.
+
+ * @param out the resulting UTF-8 strint, must be at least
+ * wind_ucs4utf8_length() + 1 long (the extra char for the NUL). If
+ * out is NULL, the function will calculate the needed space for the
+ * out variable (just like wind_ucs4utf8_length()).
+
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs4utf8(const uint32_t *in, size_t in_len, char *out, size_t *out_len)
+{
+ uint32_t ch;
+ size_t i, len, o;
+
+ for (o = 0, i = 0; i < in_len; i++) {
+ ch = in[i];
+
+ if (ch < 0x80) {
+ len = 1;
+ } else if (ch < 0x800) {
+ len = 2;
+ } else if (ch < 0x10000) {
+ len = 3;
+ } else if (ch <= 0x10FFFF) {
+ len = 4;
+ } else
+ return WIND_ERR_INVALID_UTF32;
+
+ o += len;
+
+ if (out) {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+
+ switch(len) {
+ case 4:
+ out[3] = (ch | 0x80) & 0xbf;
+ ch = ch << 6;
+ case 3:
+ out[2] = (ch | 0x80) & 0xbf;
+ ch = ch << 6;
+ case 2:
+ out[1] = (ch | 0x80) & 0xbf;
+ ch = ch << 6;
+ case 1:
+ out[0] = ch | first_char[len - 1];
+ }
+ }
+ out += len;
+ }
+ if (out) {
+ if (o + 1 >= *out_len)
+ return WIND_ERR_OVERRUN;
+ *out = '\0';
+ }
+ *out_len = o;
+ return 0;
+}
+
+/**
+ * Calculate the length of from converting a UCS4 string to an UTF-8 string.
+ *
+ * @param in an UCS4 string to convert.
+ * @param in_len the length of UCS4 string to convert.
+ * @param out_len the length of the resulting UTF-8 string.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs4utf8_length(const uint32_t *in, size_t in_len, size_t *out_len)
+{
+ return wind_ucs4utf8(in, in_len, NULL, out_len);
+}
+
+/**
+ * Read in an UCS2 from a buffer.
+ *
+ * @param ptr The input buffer to read from.
+ * @param len the length of the input buffer.
+ * @param flags Flags to control the behavior of the function.
+ * @param out the output UCS2, the array must be at least out/2 long.
+ * @param out_len the output length
+ *
+ * @return returns 0 on success, an wind error code otherwise.
+ * @ingroup wind
+ */
+
+int
+wind_ucs2read(const void *ptr, size_t len, unsigned int *flags,
+ uint16_t *out, size_t *out_len)
+{
+ const unsigned char *p = ptr;
+ int little = ((*flags) & WIND_RW_LE);
+ size_t olen = *out_len;
+
+ /** if len is zero, flags are unchanged */
+ if (len == 0) {
+ *out_len = 0;
+ return 0;
+ }
+
+ /** if len is odd, WIND_ERR_LENGTH_NOT_MOD2 is returned */
+ if (len & 1)
+ return WIND_ERR_LENGTH_NOT_MOD2;
+
+ /**
+ * If the flags WIND_RW_BOM is set, check for BOM. If not BOM is
+ * found, check is LE/BE flag is already and use that otherwise
+ * fail with WIND_ERR_NO_BOM. When done, clear WIND_RW_BOM and
+ * the LE/BE flag and set the resulting LE/BE flag.
+ */
+ if ((*flags) & WIND_RW_BOM) {
+ uint16_t bom = (p[0] << 8) + p[1];
+ if (bom == 0xfffe || bom == 0xfeff) {
+ little = (bom == 0xfffe);
+ p += 2;
+ len -= 2;
+ } else if (((*flags) & (WIND_RW_LE|WIND_RW_BE)) != 0) {
+ /* little already set */
+ } else
+ return WIND_ERR_NO_BOM;
+ *flags = ((*flags) & ~(WIND_RW_BOM|WIND_RW_LE|WIND_RW_BE));
+ *flags |= little ? WIND_RW_LE : WIND_RW_BE;
+ }
+
+ while (len) {
+ if (olen < 1)
+ return WIND_ERR_OVERRUN;
+ if (little)
+ *out = (p[1] << 8) + p[0];
+ else
+ *out = (p[0] << 8) + p[1];
+ out++; p += 2; len -= 2; olen--;
+ }
+ *out_len -= olen;
+ return 0;
+}
+
+/**
+ * Write an UCS2 string to a buffer.
+ *
+ * @param in The input UCS2 string.
+ * @param in_len the length of the input buffer.
+ * @param flags Flags to control the behavior of the function.
+ * @param ptr The input buffer to write to, the array must be at least
+ * (in + 1) * 2 bytes long.
+ * @param out_len the output length
+ *
+ * @return returns 0 on success, an wind error code otherwise.
+ * @ingroup wind
+ */
+
+int
+wind_ucs2write(const uint16_t *in, size_t in_len, unsigned int *flags,
+ void *ptr, size_t *out_len)
+{
+ unsigned char *p = ptr;
+ size_t len = *out_len;
+
+ /** If in buffer is not of length be mod 2, WIND_ERR_LENGTH_NOT_MOD2 is returned*/
+ if (len & 1)
+ return WIND_ERR_LENGTH_NOT_MOD2;
+
+ /** On zero input length, flags are preserved */
+ if (in_len == 0) {
+ *out_len = 0;
+ return 0;
+ }
+ /** If flags have WIND_RW_BOM set, the byte order mark is written
+ * first to the output data */
+ if ((*flags) & WIND_RW_BOM) {
+ uint16_t bom = 0xfffe;
+
+ if (len < 2)
+ return WIND_ERR_OVERRUN;
+
+ if ((*flags) & WIND_RW_LE) {
+ p[0] = (bom >> 8) & 0xff;
+ p[1] = (bom ) & 0xff;
+ } else {
+ p[1] = (bom ) & 0xff;
+ p[0] = (bom >> 8) & 0xff;
+ }
+ len -= 2;
+ }
+
+ while (in_len) {
+ /** If the output wont fit into out_len, WIND_ERR_OVERRUN is returned */
+ if (len < 2)
+ return WIND_ERR_OVERRUN;
+ if ((*flags) & WIND_RW_LE) {
+ p[0] = (in[0] >> 8) & 0xff;
+ p[1] = (in[0] ) & 0xff;
+ } else {
+ p[1] = (in[0] ) & 0xff;
+ p[0] = (in[0] >> 8) & 0xff;
+ }
+ len -= 2;
+ in_len--;
+ p += 2;
+ in++;
+ }
+ *out_len -= len;
+ return 0;
+}
+
+
+/**
+ * Convert an UCS2 string to a UTF-8 string.
+ *
+ * @param in an UCS2 string to convert.
+ * @param in_len the length of the in UCS2 string.
+ * @param out the resulting UTF-8 strint, must be at least
+ * wind_ucs2utf8_length() long. If out is NULL, the function will
+ * calculate the needed space for the out variable (just like
+ * wind_ucs2utf8_length()).
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs2utf8(const uint16_t *in, size_t in_len, char *out, size_t *out_len)
+{
+ uint16_t ch;
+ size_t i, len, o;
+
+ for (o = 0, i = 0; i < in_len; i++) {
+ ch = in[i];
+
+ if (ch < 0x80) {
+ len = 1;
+ } else if (ch < 0x800) {
+ len = 2;
+ } else
+ len = 3;
+
+ o += len;
+
+ if (out) {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+
+ switch(len) {
+ case 3:
+ out[2] = (ch | 0x80) & 0xbf;
+ ch = ch << 6;
+ case 2:
+ out[1] = (ch | 0x80) & 0xbf;
+ ch = ch << 6;
+ case 1:
+ out[0] = ch | first_char[len - 1];
+ }
+ out += len;
+ }
+ }
+ if (out) {
+ if (o >= *out_len)
+ return WIND_ERR_OVERRUN;
+ *out = '\0';
+ }
+ *out_len = o;
+ return 0;
+}
+
+/**
+ * Calculate the length of from converting a UCS2 string to an UTF-8 string.
+ *
+ * @param in an UCS2 string to convert.
+ * @param in_len an UCS2 string length to convert.
+ * @param out_len the length of the resulting UTF-8 string.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs2utf8_length(const uint16_t *in, size_t in_len, size_t *out_len)
+{
+ return wind_ucs2utf8(in, in_len, NULL, out_len);
+}
diff --git a/source4/heimdal/lib/wind/wind.h b/source4/heimdal/lib/wind/wind.h
new file mode 100644
index 0000000000..6921b619f5
--- /dev/null
+++ b/source4/heimdal/lib/wind/wind.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: wind.h 22595 2008-02-12 11:59:05Z lha $ */
+
+#ifndef _WIND_H_
+#define _WIND_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <wind_err.h>
+
+typedef unsigned int wind_profile_flags;
+
+#define WIND_PROFILE_NAME 0x00000001
+#define WIND_PROFILE_SASL 0x00000002
+#define WIND_PROFILE_LDAP 0x00000004
+
+#define WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE 0x00010000
+#define WIND_PROFILE_LDAP_CASE_EXACT_ASSERTION 0x00020000
+#define WIND_PROFILE_LDAP_NUMERIC 0x00040000
+#define WIND_PROFILE_LDAP_TELEPHONE 0x00080000
+
+
+/* flags to wind_ucs2read/wind_ucs2write */
+#define WIND_RW_LE 1
+#define WIND_RW_BE 2
+#define WIND_RW_BOM 4
+
+int wind_stringprep(const unsigned *in, size_t in_len,
+ unsigned *out, size_t *out_len,
+ wind_profile_flags flags);
+int wind_profile(const char *, wind_profile_flags *);
+
+int wind_punycode_label_toascii(const uint32_t *, size_t,
+ char *, size_t *);
+
+int wind_utf8ucs4(const char *, uint32_t *, size_t *);
+int wind_utf8ucs4_length(const char *, size_t *);
+
+int wind_ucs4utf8(const uint32_t *, size_t, char *, size_t *);
+int wind_ucs4utf8_length(const uint32_t *, size_t, size_t *);
+
+int wind_ucs2utf8(const uint16_t *, size_t, char *, size_t *);
+int wind_ucs2utf8_length(const uint16_t *, size_t, size_t *);
+
+
+int wind_ucs2read(const void *, size_t, unsigned int *, uint16_t *, size_t *);
+int wind_ucs2write(const uint16_t *, size_t, unsigned int *, void *, size_t *);
+
+#endif /* _WIND_H_ */
diff --git a/source4/heimdal/lib/wind/wind_err.et b/source4/heimdal/lib/wind/wind_err.et
new file mode 100644
index 0000000000..025c402790
--- /dev/null
+++ b/source4/heimdal/lib/wind/wind_err.et
@@ -0,0 +1,22 @@
+#
+# Error messages for the wind library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: wind_err.et 22559 2008-02-03 16:35:07Z lha $"
+
+error_table wind
+
+prefix WIND_ERR
+error_code NONE, "No error"
+error_code NO_PROFILE, "No such profile"
+error_code OVERRUN, "Buffer overrun"
+error_code UNDERUN, "Buffer underrun"
+error_code LENGTH_NOT_MOD2, "Lenght not mod2"
+error_code LENGTH_NOT_MOD4, "Lenght not mod4"
+error_code INVALID_UTF8, "Invalid UTF-8 combination in string"
+error_code INVALID_UTF16, "Invalid UTF-16 combination in string"
+error_code INVALID_UTF32, "Invalid UTF-32 combination in string"
+error_code NO_BOM, "No byte order mark (BOM) in string"
+
+end
diff --git a/source4/heimdal/lib/wind/windlocl.h b/source4/heimdal/lib/wind/windlocl.h
new file mode 100644
index 0000000000..02e8c46481
--- /dev/null
+++ b/source4/heimdal/lib/wind/windlocl.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: windlocl.h 22582 2008-02-11 20:43:50Z lha $ */
+
+#ifndef _WINDLOCL_H_
+#define _WINDLOCL_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "wind.h"
+#include "wind_err.h"
+
+int _wind_combining_class(uint32_t);
+
+int _wind_stringprep_testbidi(const uint32_t *, size_t, wind_profile_flags);
+
+int _wind_stringprep_error(const uint32_t, wind_profile_flags);
+
+int _wind_stringprep_prohibited(const uint32_t *, size_t, wind_profile_flags);
+
+int _wind_stringprep_map(const uint32_t *, size_t,
+ uint32_t *, size_t *,
+ wind_profile_flags);
+
+int _wind_stringprep_normalize(const uint32_t *, size_t, uint32_t *, size_t *);
+
+int _wind_ldap_case_exact_attribute(const uint32_t *, size_t,
+ uint32_t *, size_t *);
+
+
+#endif /* _WINDLOCL_H_ */
diff --git a/source4/heimdal_build/config.h b/source4/heimdal_build/config.h
index 7a51def3c6..e2c735a65f 100644
--- a/source4/heimdal_build/config.h
+++ b/source4/heimdal_build/config.h
@@ -19,4 +19,6 @@
#define SIGRETURN(x) return (RETSIGTYPE)(x)
#endif
+#define HDB_DB_DIR ""
+
#endif
diff --git a/source4/heimdal_build/config.mk b/source4/heimdal_build/config.mk
index d3d87f7a70..d58d06f909 100644
--- a/source4/heimdal_build/config.mk
+++ b/source4/heimdal_build/config.mk
@@ -46,6 +46,7 @@ PRIVATE_DEPENDENCIES = HDB_LDB HEIMDAL_KRB5 HEIMDAL_HDB_KEYS HEIMDAL_ROKEN HEIMD
HEIMDAL_HDB_OBJ_FILES = \
./heimdal/lib/hdb/db.o \
+ ./heimdal/lib/hdb/dbinfo.o \
./heimdal/lib/hdb/hdb.o \
./heimdal/lib/hdb/ext.o \
./heimdal/lib/hdb/keytab.o \
@@ -175,7 +176,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
# Start SUBSYSTEM HEIMDAL_KRB5
[SUBSYSTEM::HEIMDAL_KRB5]
CFLAGS = -Iheimdal_build -Iheimdal/lib/krb5
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1
+PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1 HEIMDAL_WIND
PUBLIC_DEPENDENCIES = HEIMDAL_KRB5_ASN1 HEIMDAL_GLUE HEIMDAL_HX509 HEIMDAL_HCRYPTO
# End SUBSYSTEM HEIMDAL_KRB5
#######################
@@ -334,8 +335,9 @@ HEIMDAL_HCRYPTO_OBJ_FILES = \
./heimdal/lib/hcrypto/rand-unix.o \
./heimdal/lib/hcrypto/rand-fortuna.o \
./heimdal/lib/hcrypto/rand-timer.o \
- ./heimdal/lib/hcrypto/hmac.o
-
+ ./heimdal/lib/hcrypto/hmac.o \
+ ./heimdal/lib/hcrypto/camellia.o \
+ ./heimdal/lib/hcrypto/camellia-ntt.o
#######################
# Start SUBSYSTEM HEIMDAL_HX509
@@ -347,7 +349,8 @@ PRIVATE_DEPENDENCIES = \
HEIMDAL_CMS_ASN1 HEIMDAL_RFC2459_ASN1 \
HEIMDAL_OCSP_ASN1 HEIMDAL_PKCS8_ASN1 \
HEIMDAL_PKCS9_ASN1 HEIMDAL_PKCS12_ASN1 \
- HEIMDAL_PKINIT_ASN1 HEIMDAL_PKCS10_ASN1
+ HEIMDAL_PKINIT_ASN1 HEIMDAL_PKCS10_ASN1 \
+ HEIMDAL_WIND
# End SUBSYSTEM HEIMDAL_HX509
#######################
@@ -376,6 +379,31 @@ HEIMDAL_HX509_OBJ_FILES = \
./heimdal/lib/hx509/revoke.o \
./heimdal/lib/hx509/hx509_err.o
+#######################
+# Start SUBSYSTEM HEIMDAL_WIND
+[SUBSYSTEM::HEIMDAL_WIND]
+CFLAGS = -Iheimdal_build -Iheimdal/lib/wind
+PRIVATE_DEPENDENCIES = \
+ HEIMDAL_ROKEN HEIMDAL_COM_ERR
+
+HEIMDAL_WIND_OBJ_FILES = \
+ ./heimdal/lib/wind/wind_err.o \
+ ./heimdal/lib/wind/stringprep.o \
+ ./heimdal/lib/wind/errorlist.o \
+ ./heimdal/lib/wind/errorlist_table.o \
+ ./heimdal/lib/wind/normalize.o \
+ ./heimdal/lib/wind/normalize_table.o \
+ ./heimdal/lib/wind/combining.o \
+ ./heimdal/lib/wind/combining_table.o \
+ ./heimdal/lib/wind/utf8.o \
+ ./heimdal/lib/wind/bidi.o \
+ ./heimdal/lib/wind/bidi_table.o \
+ ./heimdal/lib/wind/ldap.o \
+ ./heimdal/lib/wind/map.o \
+ ./heimdal/lib/wind/map_table.o
+# End SUBSYSTEM HEIMDAL_WIND
+#######################
+
[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME]
CFLAGS = -Iheimdal_build -Iheimdal/lib/roken -Ilib/socket_wrapper
@@ -399,7 +427,7 @@ PUBLIC_DEPENDENCIES = \
HEIMDAL_ROKEN_GETPROGNAME \
HEIMDAL_ROKEN_CLOSEFROM \
RESOLV \
- EXT_SOCKET
+ LIBREPLACE_NETWORK
# End SUBSYSTEM HEIMDAL_ROKEN
#######################
@@ -470,7 +498,7 @@ HEIMDAL_ASN1_COMPILE_LEX_OBJ_FILES = ./heimdal/lib/asn1/lex.ho
[BINARY::asn1_compile]
CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
USE_HOSTCC = YES
-PRIVATE_DEPENDENCIES = HEIMDAL_ASN1_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = HEIMDAL_ASN1_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H LIBREPLACE_NETWORK
asn1_compile_OBJ_FILES = \
./heimdal/lib/asn1/main.ho \
@@ -513,7 +541,7 @@ HEIMDAL_COM_ERR_COMPILE_LEX_OBJ_FILES = ./heimdal/lib/com_err/lex.ho
[BINARY::compile_et]
CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
USE_HOSTCC = YES
-PRIVATE_DEPENDENCIES = HEIMDAL_COM_ERR_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = HEIMDAL_COM_ERR_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H LIBREPLACE_NETWORK
# End BINARY compile_et
#######################
@@ -554,6 +582,7 @@ mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/krb_err.et heimdal/li
mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/krb5_err.et heimdal/lib/krb5|
mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/gssapi/krb5/gkrb5_err.et heimdal/lib/gssapi|
mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/hx509/hx509_err.et heimdal/lib/hx509|
+mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/wind/wind_err.et heimdal/lib/wind|
clean::
@-rm -f bin/compile_et bin/asn1_compile
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index bc5a45ae2b..d983b77b40 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -510,7 +510,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.valid_start = NULL;
- acct_expiry = samdb_result_account_expires(msg, 0);
+ acct_expiry = samdb_result_account_expires(msg);
if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {
entry_ex->entry.valid_end = NULL;
} else {
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 92a5dc26e0..72b5bb14a9 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -639,9 +639,9 @@ static void kdc_task_init(struct task_server *task)
}
/* Registar WinDC hooks */
- ret = _krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
- PLUGIN_TYPE_DATA, "windc",
- &windc_plugin_table);
+ ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
+ PLUGIN_TYPE_DATA, "windc",
+ &windc_plugin_table);
if(ret) {
task_server_terminate(task, "kdc: failed to register hdb keytab");
return;
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
index 66f36af870..1c68d4c37d 100644
--- a/source4/kdc/pac-glue.c
+++ b/source4/kdc/pac-glue.c
@@ -220,13 +220,47 @@ krb5_error_code samba_kdc_reget_pac(void *priv, krb5_context context,
return ret;
}
+static void samba_kdc_build_edata_reply(TALLOC_CTX *tmp_ctx, krb5_data *e_data,
+ NTSTATUS nt_status)
+{
+ PA_DATA pa;
+ unsigned char *buf;
+ size_t len;
+ krb5_error_code ret = 0;
+
+ if (!e_data)
+ return;
+
+ pa.padata_type = KRB5_PADATA_PW_SALT;
+ pa.padata_value.length = 12;
+ pa.padata_value.data = malloc(pa.padata_value.length);
+ if (!pa.padata_value.data) {
+ e_data->length = 0;
+ e_data->data = NULL;
+ return;
+ }
+
+ SIVAL(pa.padata_value.data, 0, NT_STATUS_V(nt_status));
+ SIVAL(pa.padata_value.data, 4, 0);
+ SIVAL(pa.padata_value.data, 8, 1);
+
+ ASN1_MALLOC_ENCODE(PA_DATA, buf, len, &pa, &len, ret);
+ free(pa.padata_value.data);
+
+ e_data->data = buf;
+ e_data->length = len;
+
+ return;
+}
+
/* Given an hdb entry (and in particular it's private member), consult
* the account_ok routine in auth/auth_sam.c for consistancy */
krb5_error_code samba_kdc_check_client_access(void *priv,
krb5_context context, hdb_entry_ex *entry_ex,
- KDC_REQ *req)
+ KDC_REQ *req,
+ krb5_data *e_data)
{
krb5_error_code ret;
NTSTATUS nt_status;
@@ -274,30 +308,28 @@ krb5_error_code samba_kdc_check_client_access(void *priv,
name);
free(name);
- /* TODO: Need a more complete mapping of NTSTATUS to krb5kdc errors */
-
- /* TODO: Also need to add the appropriate e-data struct of type
- * PA-PW-SALT (3) that includes the NT_STATUS code, which gives Windows
- * the information it needs to display the appropriate dialog. */
+ if (NT_STATUS_IS_OK(nt_status))
+ return 0;
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_MUST_CHANGE))
- return KRB5KDC_ERR_KEY_EXPIRED;
+ ret = KRB5KDC_ERR_KEY_EXPIRED;
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED))
- return KRB5KDC_ERR_KEY_EXPIRED;
+ ret = KRB5KDC_ERR_KEY_EXPIRED;
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_EXPIRED))
- return KRB5KDC_ERR_CLIENT_REVOKED;
+ ret = KRB5KDC_ERR_CLIENT_REVOKED;
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED))
- return KRB5KDC_ERR_CLIENT_REVOKED;
+ ret = KRB5KDC_ERR_CLIENT_REVOKED;
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_LOGON_HOURS))
- return KRB5KDC_ERR_CLIENT_REVOKED;
+ ret = KRB5KDC_ERR_CLIENT_REVOKED;
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_LOCKED_OUT))
- return KRB5KDC_ERR_CLIENT_REVOKED;
+ ret = KRB5KDC_ERR_CLIENT_REVOKED;
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_WORKSTATION))
- return KRB5KDC_ERR_POLICY;
- else if (!NT_STATUS_IS_OK(nt_status)) {
- return KRB5KDC_ERR_POLICY;
- }
+ ret = KRB5KDC_ERR_POLICY;
+ else
+ ret = KRB5KDC_ERR_POLICY;
- return 0;
+ samba_kdc_build_edata_reply(tmp_ctx, e_data, nt_status);
+
+ return ret;
}
diff --git a/source4/lib/events/events_signal.c b/source4/lib/events/events_signal.c
index aec34339c3..c0771cbe01 100644
--- a/source4/lib/events/events_signal.c
+++ b/source4/lib/events/events_signal.c
@@ -257,7 +257,7 @@ int common_event_check_signal(struct event_context *ev)
for (j=0;j<count;j++) {
/* note the use of the sig_info array as a
ring buffer */
- int ofs = (counter.count + j) % SA_INFO_QUEUE_COUNT;
+ int ofs = ((count-1) + j) % SA_INFO_QUEUE_COUNT;
se->handler(ev, se, i, 1,
(void*)&sig_state->sig_info[i][ofs],
se->private_data);
diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in
index d88f82b726..a53c5542da 100644
--- a/source4/lib/ldb/Makefile.in
+++ b/source4/lib/ldb/Makefile.in
@@ -121,7 +121,7 @@ distclean:: clean
rm -f Makefile
realdistclean:: distclean
- rm -f configure.in include/config.h.in
+ rm -f configure include/config.h.in
check:: test @PYTHON_CHECK_TARGET@
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index 3c9ef3ff69..b51c288993 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -65,7 +65,7 @@ static struct backends_list_entry {
#ifdef HAVE_LDB_LDAP
#define LDAP_INIT &ldb_ldap_backend_ops, \
- &ldb_ildap_backend_ops, \
+ &ldb_ldapi_backend_ops, \
&ldb_ldaps_backend_ops,
#else
#define LDAP_INIT
diff --git a/source4/lib/ldb/include/ldb_includes.h b/source4/lib/ldb/include/ldb_includes.h
index e2bcca2b04..cc9b46ac1f 100644
--- a/source4/lib/ldb/include/ldb_includes.h
+++ b/source4/lib/ldb/include/ldb_includes.h
@@ -18,7 +18,6 @@
#include "replace.h"
#include "system/filesys.h"
-#include "system/network.h"
#include "system/time.h"
#include "talloc.h"
#include "ldb.h"
diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h
index 880aafd593..ea8533bc38 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -200,7 +200,7 @@ extern const struct ldb_module_ops ldb_ranged_results_module_ops;
extern const struct ldb_backend_ops ldb_tdb_backend_ops;
extern const struct ldb_backend_ops ldb_sqlite3_backend_ops;
extern const struct ldb_backend_ops ldb_ldap_backend_ops;
-extern const struct ldb_backend_ops ldb_ildap_backend_ops;
+extern const struct ldb_backend_ops ldb_ldapi_backend_ops;
extern const struct ldb_backend_ops ldb_ldaps_backend_ops;
int ldb_match_msg(struct ldb_context *ldb,
diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i
index 0d9679d21e..e01a1107d2 100644
--- a/source4/lib/ldb/ldb.i
+++ b/source4/lib/ldb/ldb.i
@@ -257,12 +257,19 @@ int ldb_dn_from_pyobject(TALLOC_CTX *mem_ctx, PyObject *object,
int ret;
struct ldb_dn *odn;
if (ldb_ctx != NULL && PyString_Check(object)) {
- *dn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
+ odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
+ if (!odn) {
+ return SWIG_ERROR;
+ }
+ *dn = odn;
return 0;
}
ret = SWIG_ConvertPtr(object, (void **)&odn, SWIGTYPE_p_ldb_dn,
SWIG_POINTER_EXCEPTION);
*dn = ldb_dn_copy(mem_ctx, odn);
+ if (odn && !*dn) {
+ return SWIG_ERROR;
+ }
return ret;
}
@@ -462,6 +469,8 @@ typedef struct ldb_ldif ldb_ldif;
#ifdef SWIGPYTHON
%{
+static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
+
static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
{
char *text;
@@ -557,22 +566,29 @@ PyObject *PyExc_LdbError;
};
%typemap(in,numinputs=1) ldb_msg *add_msg {
- int dict_pos, msg_pos;
- PyObject *key, *value;
+ Py_ssize_t dict_pos, msg_pos;
ldb_msg_element *msgel;
+ PyObject *key, *value;
if (PyDict_Check($input)) {
+ PyObject *dn_value = PyDict_GetItemString($input, "dn");
$1 = ldb_msg_new(NULL);
$1->elements = talloc_zero_array($1, struct ldb_message_element, PyDict_Size($input));
msg_pos = dict_pos = 0;
- while (PyDict_Next($input, &dict_pos, &key, &value)) {
- if (!strcmp(PyString_AsString(key), "dn")) {
- /* using argp0 (magic SWIG value) here is a hack */
- if (ldb_dn_from_pyobject($1, value, argp1, &$1->dn) != 0) {
+ if (dn_value) {
+ /* using argp1 (magic SWIG value) here is a hack */
+ if (ldb_dn_from_pyobject($1, dn_value, argp1, &$1->dn) != 0) {
SWIG_exception(SWIG_TypeError, "unable to import dn object");
}
- } else {
- msgel = ldb_msg_element_from_pyobject($1->elements, value, 0, PyString_AsString(key));
+ if ($1->dn == NULL) {
+ SWIG_exception(SWIG_TypeError, "dn set but not found");
+ }
+ }
+
+ while (PyDict_Next($input, &dict_pos, &key, &value)) {
+ char *key_str = PyString_AsString(key);
+ if (strcmp(key_str, "dn") != 0) {
+ msgel = ldb_msg_element_from_pyobject($1->elements, value, 0, key_str);
if (msgel == NULL) {
SWIG_exception(SWIG_TypeError, "unable to import element");
}
diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
index 3f6ff3fd5b..a4534c549a 100644
--- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c
+++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
@@ -826,17 +826,17 @@ failed:
return -1;
}
-_PUBLIC_ struct ldb_backend_ops ldb_ldap_backend_ops = {
+const struct ldb_backend_ops ldb_ldap_backend_ops = {
.name = "ldap",
.connect_fn = lldb_connect
};
-_PUBLIC_ struct ldb_backend_ops ldb_ldapi_backend_ops = {
+const struct ldb_backend_ops ldb_ldapi_backend_ops = {
.name = "ldapi",
.connect_fn = lldb_connect
};
-_PUBLIC_ struct ldb_backend_ops ldb_ldaps_backend_ops = {
+const struct ldb_backend_ops ldb_ldaps_backend_ops = {
.name = "ldaps",
.connect_fn = lldb_connect
};
diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c
index cf05048b02..082c6d9cad 100644
--- a/source4/lib/ldb/ldb_wrap.c
+++ b/source4/lib/ldb/ldb_wrap.c
@@ -2471,7 +2471,7 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags)
#define SWIGTYPE_p_ldb_module_ops swig_types[9]
#define SWIGTYPE_p_ldb_result swig_types[10]
#define SWIGTYPE_p_ldb_val swig_types[11]
-#define SWIGTYPE_p_long_long swig_types[12]
+#define SWIGTYPE_p_long swig_types[12]
#define SWIGTYPE_p_p_char swig_types[13]
#define SWIGTYPE_p_p_ldb_control swig_types[14]
#define SWIGTYPE_p_p_ldb_result swig_types[15]
@@ -2480,11 +2480,10 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags)
#define SWIGTYPE_p_unsigned_char swig_types[18]
#define SWIGTYPE_p_unsigned_int swig_types[19]
#define SWIGTYPE_p_unsigned_long swig_types[20]
-#define SWIGTYPE_p_unsigned_long_long swig_types[21]
-#define SWIGTYPE_p_unsigned_short swig_types[22]
-#define SWIGTYPE_p_void swig_types[23]
-static swig_type_info *swig_types[25];
-static swig_module_info swig_module = {swig_types, 24, 0, 0, 0, 0};
+#define SWIGTYPE_p_unsigned_short swig_types[21]
+#define SWIGTYPE_p_void swig_types[22]
+static swig_type_info *swig_types[24];
+static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0};
#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
@@ -2713,12 +2712,19 @@ int ldb_dn_from_pyobject(TALLOC_CTX *mem_ctx, PyObject *object,
int ret;
struct ldb_dn *odn;
if (ldb_ctx != NULL && PyString_Check(object)) {
- *dn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
+ odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
+ if (!odn) {
+ return SWIG_ERROR;
+ }
+ *dn = odn;
return 0;
}
ret = SWIG_ConvertPtr(object, (void **)&odn, SWIGTYPE_p_ldb_dn,
SWIG_POINTER_EXCEPTION);
*dn = ldb_dn_copy(mem_ctx, odn);
+ if (odn && !*dn) {
+ return SWIG_ERROR;
+ }
return ret;
}
@@ -2992,6 +2998,8 @@ SWIGINTERN PyObject *ldb_msg___iter__(ldb_msg *self){
return PyObject_GetIter(ldb_msg_list_elements(self));
}
+static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
+
static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
{
char *text;
@@ -4708,22 +4716,29 @@ SWIGINTERN PyObject *_wrap_Ldb_add(PyObject *SWIGUNUSEDPARM(self), PyObject *arg
}
arg1 = (ldb *)(argp1);
{
- int dict_pos, msg_pos;
- PyObject *key, *value;
+ Py_ssize_t dict_pos, msg_pos;
ldb_msg_element *msgel;
+ PyObject *key, *value;
if (PyDict_Check(obj1)) {
+ PyObject *dn_value = PyDict_GetItemString(obj1, "dn");
arg2 = ldb_msg_new(NULL);
arg2->elements = talloc_zero_array(arg2, struct ldb_message_element, PyDict_Size(obj1));
msg_pos = dict_pos = 0;
+ if (dn_value) {
+ /* using argp1 (magic SWIG value) here is a hack */
+ if (ldb_dn_from_pyobject(arg2, dn_value, argp1, &arg2->dn) != 0) {
+ SWIG_exception(SWIG_TypeError, "unable to import dn object");
+ }
+ if (arg2->dn == NULL) {
+ SWIG_exception(SWIG_TypeError, "dn set but not found");
+ }
+ }
+
while (PyDict_Next(obj1, &dict_pos, &key, &value)) {
- if (!strcmp(PyString_AsString(key), "dn")) {
- /* using argp0 (magic SWIG value) here is a hack */
- if (ldb_dn_from_pyobject(arg2, value, argp1, &arg2->dn) != 0) {
- SWIG_exception(SWIG_TypeError, "unable to import dn object");
- }
- } else {
- msgel = ldb_msg_element_from_pyobject(arg2->elements, value, 0, PyString_AsString(key));
+ char *key_str = PyString_AsString(key);
+ if (strcmp(key_str, "dn") != 0) {
+ msgel = ldb_msg_element_from_pyobject(arg2->elements, value, 0, key_str);
if (msgel == NULL) {
SWIG_exception(SWIG_TypeError, "unable to import element");
}
@@ -5696,7 +5711,7 @@ static PyMethodDef SwigMethods[] = {
static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_f_p_void_enum_ldb_debug_level_p_q_const__char_va_list__void = {"_p_f_p_void_enum_ldb_debug_level_p_q_const__char_va_list__void", "void (*)(void *,enum ldb_debug_level,char const *,va_list)", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_int = {"_p_int", "int *|int_least32_t *|int32_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_context = {"_p_ldb_context", "struct ldb_context *|ldb *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_ldif = {"_p_ldb_ldif", "struct ldb_ldif *|ldb_ldif *", 0, 0, (void*)0, 0};
@@ -5705,16 +5720,15 @@ static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element",
static swig_type_info _swigt__p_ldb_module_ops = {"_p_ldb_module_ops", "struct ldb_module_ops *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_val = {"_p_ldb_val", "struct ldb_val *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_long = {"_p_long", "intptr_t *|int_least64_t *|int_fast32_t *|int_fast64_t *|int64_t *|long *|int_fast16_t *|intmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_ldb_control = {"_p_p_ldb_control", "struct ldb_control **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_ldb_result = {"_p_p_ldb_result", "struct ldb_result **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_unsigned_long = {"_p_unsigned_long", "unsigned long *|time_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uint_least32_t *|uint32_t *|unsigned int *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_unsigned_long = {"_p_unsigned_long", "uintptr_t *|uint_least64_t *|uint_fast32_t *|uint_fast64_t *|uint64_t *|unsigned long *|time_t *|uint_fast16_t *|uintmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0};
@@ -5731,7 +5745,7 @@ static swig_type_info *swig_type_initial[] = {
&_swigt__p_ldb_module_ops,
&_swigt__p_ldb_result,
&_swigt__p_ldb_val,
- &_swigt__p_long_long,
+ &_swigt__p_long,
&_swigt__p_p_char,
&_swigt__p_p_ldb_control,
&_swigt__p_p_ldb_result,
@@ -5740,7 +5754,6 @@ static swig_type_info *swig_type_initial[] = {
&_swigt__p_unsigned_char,
&_swigt__p_unsigned_int,
&_swigt__p_unsigned_long,
- &_swigt__p_unsigned_long_long,
&_swigt__p_unsigned_short,
&_swigt__p_void,
};
@@ -5757,7 +5770,7 @@ static swig_cast_info _swigc__p_ldb_message_element[] = { {&_swigt__p_ldb_messa
static swig_cast_info _swigc__p_ldb_module_ops[] = { {&_swigt__p_ldb_module_ops, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_result[] = { {&_swigt__p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_val[] = { {&_swigt__p_ldb_val, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_long[] = { {&_swigt__p_long, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_ldb_control[] = { {&_swigt__p_p_ldb_control, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_ldb_result[] = { {&_swigt__p_p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
@@ -5766,7 +5779,6 @@ static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0
static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_long[] = { {&_swigt__p_unsigned_long, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}};
@@ -5783,7 +5795,7 @@ static swig_cast_info *swig_cast_initial[] = {
_swigc__p_ldb_module_ops,
_swigc__p_ldb_result,
_swigc__p_ldb_val,
- _swigc__p_long_long,
+ _swigc__p_long,
_swigc__p_p_char,
_swigc__p_p_ldb_control,
_swigc__p_p_ldb_result,
@@ -5792,7 +5804,6 @@ static swig_cast_info *swig_cast_initial[] = {
_swigc__p_unsigned_char,
_swigc__p_unsigned_int,
_swigc__p_unsigned_long,
- _swigc__p_unsigned_long_long,
_swigc__p_unsigned_short,
_swigc__p_void,
};
diff --git a/source4/lib/ldb/rules.mk b/source4/lib/ldb/rules.mk
index 534ba016ab..ff5dc02742 100644
--- a/source4/lib/ldb/rules.mk
+++ b/source4/lib/ldb/rules.mk
@@ -7,7 +7,7 @@ ctags:
.SUFFIXES: _wrap.c .i
.i_wrap.c:
- [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -python -keyword $<
+ [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -python -keyword $<
.SUFFIXES: .1 .1.xml .3 .3.xml .xml .html .c .o
diff --git a/source4/lib/ldb/tests/sample_module.c b/source4/lib/ldb/tests/sample_module.c
index 98d8e865dd..1a9e72c907 100644
--- a/source4/lib/ldb/tests/sample_module.c
+++ b/source4/lib/ldb/tests/sample_module.c
@@ -32,7 +32,7 @@ int sample_add(struct ldb_module *mod, struct ldb_request *req)
return ldb_next_request(mod, req);
}
-_PUBLIC_ const struct ldb_module_ops ldb_sample_module_ops = {
+const struct ldb_module_ops ldb_sample_module_ops = {
.name = "sample",
.add = sample_add,
};
diff --git a/source4/lib/ldb/tests/test-soloading.sh b/source4/lib/ldb/tests/test-soloading.sh
index c42c9b22ba..da6d57541e 100755
--- a/source4/lib/ldb/tests/test-soloading.sh
+++ b/source4/lib/ldb/tests/test-soloading.sh
@@ -19,7 +19,7 @@ fi
cat <<EOF | $VALGRIND ldbadd || exit 1
dn: @MODULES
-@LIST: sample_module
+@LIST: sample
EOF
cat <<EOF | $VALGRIND ldbadd || exit 1
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 6a879ab962..29d6e00247 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -462,6 +462,8 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server,
rec->retries = 0;
rec->msg = msg;
rec->header = (struct messaging_header *)rec->packet.data;
+ /* zero padding */
+ ZERO_STRUCTP(rec->header);
rec->header->version = MESSAGING_VERSION;
rec->header->msg_type = msg_type;
rec->header->from = msg->server_id;
diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c
index c5741b7e2c..51c255e9f7 100644
--- a/source4/lib/registry/registry_wrap.c
+++ b/source4/lib/registry/registry_wrap.c
@@ -2950,7 +2950,7 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
}
result = reg_open_local(arg1,arg2,arg3,arg4);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3001,7 +3001,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA
arg3 = (struct registry_key **)(argp3);
result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3044,7 +3044,7 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj
arg2 = (char *)(buf2);
result = reg_key_del_abs(arg1,(char const *)arg2);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3095,7 +3095,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self)
arg3 = (struct registry_key **)(argp3);
result = reg_get_predefined_key(arg1,arg2,arg3);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3136,7 +3136,7 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje
arg2 = (char *)(buf2);
result = reg_diff_apply(arg1,(char const *)arg2);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3194,7 +3194,7 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO
}
result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3260,7 +3260,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self)
}
result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3373,7 +3373,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self)
arg3 = (char *)(buf3);
result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3524,7 +3524,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
}
result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3601,7 +3601,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
}
result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3642,7 +3642,7 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *
arg2 = (char *)(buf2);
result = reg_create_directory(arg1,(char const *)arg2,arg3);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3683,7 +3683,7 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
arg2 = (char *)(buf2);
result = reg_open_directory(arg1,(char const *)arg2,arg3);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3750,7 +3750,7 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *
}
result = reg_open_samba(arg1,arg2,arg3,arg4,arg5);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
diff --git a/source4/lib/replace/README b/source4/lib/replace/README
index 268a1b15cf..43f7b08572 100644
--- a/source4/lib/replace/README
+++ b/source4/lib/replace/README
@@ -15,7 +15,6 @@ rename
initgroups
memmove
strdup
-inet_ntoa
setlinebuf
vsyslog
timegm
@@ -52,6 +51,7 @@ readline (the library)
inet_ntoa
inet_ntop
inet_pton
+inet_aton
strtoll
strtoull
socketpair
diff --git a/source4/lib/replace/configure.ac b/source4/lib/replace/configure.ac
index f5e054f476..02dc08bf72 100644
--- a/source4/lib/replace/configure.ac
+++ b/source4/lib/replace/configure.ac
@@ -21,6 +21,9 @@ if test "$ac_cv_prog_gcc" = yes; then
CFLAGS="$CFLAGS -Wno-format-y2k"
fi
+LIBS="${LIBREPLACE_NETWORK_LIBS}"
+AC_SUBST(LIBS)
+
AC_SUBST(LDFLAGS)
AC_OUTPUT(Makefile)
diff --git a/source4/lib/replace/getifaddrs.m4 b/source4/lib/replace/getifaddrs.m4
index 6cca155de3..927bc677db 100644
--- a/source4/lib/replace/getifaddrs.m4
+++ b/source4/lib/replace/getifaddrs.m4
@@ -34,10 +34,12 @@ fi
##################
# look for a method of finding the list of network interfaces
#
-# This tests need LIBS="$NSL_LIBS $SOCKET_LIBS"
+# This tests need LIBS="${LIBREPLACE_NETWORK_LIBS}"
#
old_LIBS=$LIBS
-LIBS="$NSL_LIBS $SOCKET_LIBS"
+LIBS="${LIBREPLACE_NETWORK_LIBS}"
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I$libreplacedir"
iface=no;
##################
# look for a method of finding the list of network interfaces
@@ -79,7 +81,6 @@ AC_TRY_RUN([
libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)])
if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then
iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available])
- old_LIBS="$old_LIBS $LIBS"
fi
fi
@@ -100,7 +101,6 @@ AC_TRY_RUN([
libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)])
if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then
iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available])
- old_LIBS="$old_LIBS $LIBS"
fi
fi
@@ -120,8 +120,9 @@ AC_TRY_RUN([
libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)])
if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then
iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available])
- old_LIBS="$old_LIBS $LIBS"
fi
fi
LIBS=$old_LIBS
+CPPFLAGS="$SAVE_CPPFLAGS"
+
diff --git a/source4/lib/replace/getpass.c b/source4/lib/replace/getpass.c
index d91d029f6a..73333b9021 100644
--- a/source4/lib/replace/getpass.c
+++ b/source4/lib/replace/getpass.c
@@ -185,7 +185,13 @@ char *rep_getpass(const char *prompt)
buf[0] = 0;
if (!gotintr) {
in_fd = fileno(in);
- fgets(buf, bufsize, in);
+ if (fgets(buf, bufsize, in) == NULL) {
+ buf[0] = 0;
+ if (in && in != stdin) {
+ fclose(in);
+ }
+ return buf;
+ }
}
nread = strlen(buf);
if (nread) {
diff --git a/source4/lib/replace/inet_aton.c b/source4/lib/replace/inet_aton.c
new file mode 100644
index 0000000000..c6b3bb11a7
--- /dev/null
+++ b/source4/lib/replace/inet_aton.c
@@ -0,0 +1,33 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * replacement functions
+ * Copyright (C) Michael Adam <obnox@samba.org> 2008
+ *
+ * ** NOTE! The following LGPL license applies to the replace
+ * ** library. This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+/**
+ * We know that we have inet_pton from earlier libreplace checks.
+ */
+int rep_inet_aton(const char *src, struct in_addr *dst)
+{
+ return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0;
+}
diff --git a/source4/lib/replace/inet_aton.m4 b/source4/lib/replace/inet_aton.m4
new file mode 100644
index 0000000000..853688ef6b
--- /dev/null
+++ b/source4/lib/replace/inet_aton.m4
@@ -0,0 +1 @@
+AC_CHECK_FUNCS(inet_aton,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_aton.o"])
diff --git a/source4/lib/replace/inet_ntoa.c b/source4/lib/replace/inet_ntoa.c
new file mode 100644
index 0000000000..e3b80ebef8
--- /dev/null
+++ b/source4/lib/replace/inet_ntoa.c
@@ -0,0 +1,39 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * replacement routines for broken systems
+ * Copyright (C) Andrew Tridgell 2003
+ * Copyright (C) Michael Adam 2008
+ *
+ * ** NOTE! The following LGPL license applies to the replace
+ * ** library. This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+/**
+ * NOTE: this is not thread safe, but it can't be, either
+ * since it returns a pointer to static memory.
+ */
+char *rep_inet_ntoa(struct in_addr ip)
+{
+ uint8_t *p = (uint8_t *)&ip.s_addr;
+ static char buf[18];
+ slprintf(buf, 17, "%d.%d.%d.%d",
+ (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
+ return buf;
+}
diff --git a/source4/lib/replace/inet_ntoa.m4 b/source4/lib/replace/inet_ntoa.m4
new file mode 100644
index 0000000000..5aaa9350c5
--- /dev/null
+++ b/source4/lib/replace/inet_ntoa.m4
@@ -0,0 +1,19 @@
+AC_CHECK_FUNCS(inet_ntoa,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_ntoa.o"])
+
+AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[
+AC_TRY_RUN([
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+main() { struct in_addr ip; ip.s_addr = 0x12345678;
+if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
+ strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
+exit(1);}],
+ libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)])
+if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then
+ AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
+fi
diff --git a/source4/lib/replace/libreplace.m4 b/source4/lib/replace/libreplace.m4
index e0cc57f4c8..8e17258918 100644
--- a/source4/lib/replace/libreplace.m4
+++ b/source4/lib/replace/libreplace.m4
@@ -120,24 +120,6 @@ if test x"$libreplace_cv_USABLE_NET_IF_H" = x"yes";then
AC_DEFINE(HAVE_NET_IF_H, 1, usability of net/if.h)
fi
-AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[
-AC_TRY_RUN([
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-main() { struct in_addr ip; ip.s_addr = 0x12345678;
-if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
- strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
-exit(1);}],
- libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)])
-if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then
- AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
-fi
-
AC_HAVE_TYPE([socklen_t],[#include <sys/socket.h>])
AC_HAVE_TYPE([sa_family_t],[#include <sys/socket.h>])
AC_HAVE_TYPE([struct addrinfo], [#include <netdb.h>])
@@ -176,7 +158,7 @@ fi
AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup)
-AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp socketpair)
+AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp)
AC_CHECK_FUNCS(isatty)
AC_HAVE_DECL(setresuid, [#include <unistd.h>])
AC_HAVE_DECL(setresgid, [#include <unistd.h>])
@@ -347,9 +329,12 @@ m4_include(timegm.m4)
m4_include(socket.m4)
m4_include(inet_ntop.m4)
m4_include(inet_pton.m4)
+m4_include(inet_aton.m4)
+m4_include(inet_ntoa.m4)
m4_include(getaddrinfo.m4)
m4_include(repdir.m4)
m4_include(getifaddrs.m4)
+m4_include(socketpair.m4)
AC_CHECK_FUNCS([syslog printf memset memcpy],,[AC_MSG_ERROR([Required function not found])])
diff --git a/source4/lib/replace/replace.c b/source4/lib/replace/replace.c
index b2a240e8ab..6930f9b079 100644
--- a/source4/lib/replace/replace.c
+++ b/source4/lib/replace/replace.c
@@ -27,7 +27,6 @@
#include "system/time.h"
#include "system/passwd.h"
#include "system/syslog.h"
-#include "system/network.h"
#include "system/locale.h"
#include "system/wait.h"
@@ -295,20 +294,6 @@ char *rep_strdup(const char *s)
}
#endif /* HAVE_STRDUP */
-#ifndef WITH_PTHREADS
-/* REWRITE: not thread safe */
-#ifdef REPLACE_INET_NTOA
-char *rep_inet_ntoa(struct in_addr ip)
-{
- uint8_t *p = (uint8_t *)&ip.s_addr;
- static char buf[18];
- slprintf(buf, 17, "%d.%d.%d.%d",
- (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
- return buf;
-}
-#endif /* REPLACE_INET_NTOA */
-#endif
-
#ifndef HAVE_SETLINEBUF
void rep_setlinebuf(FILE *stream)
{
@@ -599,25 +584,3 @@ int rep_unsetenv(const char *name)
return 0;
}
#endif
-
-#ifndef HAVE_SOCKETPAIR
-int rep_socketpair(int d, int type, int protocol, int sv[2])
-{
- if (d != AF_UNIX) {
- errno = EAFNOSUPPORT;
- return -1;
- }
-
- if (protocol != 0) {
- errno = EPROTONOSUPPORT;
- return -1;
- }
-
- if (type != SOCK_STREAM) {
- errno = EOPNOTSUPP;
- return -1;
- }
-
- return pipe(sv);
-}
-#endif
diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h
index 0d16f4ffd0..5fe79394eb 100644
--- a/source4/lib/replace/replace.h
+++ b/source4/lib/replace/replace.h
@@ -212,7 +212,7 @@ int rep_dlclose(void *handle);
#ifndef HAVE_SOCKETPAIR
#define socketpair rep_socketpair
-int rep_socketpair(int d, int type, int protocol, int sv[2]);
+/* prototype is in system/network.h */
#endif
#ifndef PRINTF_ATTRIBUTE
@@ -325,7 +325,7 @@ ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset);
ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset);
#endif
-#ifdef REPLACE_INET_NTOA
+#if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA)
#define inet_ntoa rep_inet_ntoa
/* prototype is in "system/network.h" */
#endif
@@ -340,6 +340,11 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
/* prototype is in "system/network.h" */
#endif
+#ifndef HAVE_INET_ATON
+#define inet_aton rep_inet_aton
+/* prototype is in "system/network.h" */
+#endif
+
#ifndef HAVE_CONNECT
#define connect rep_connect
/* prototype is in "system/network.h" */
diff --git a/source4/lib/replace/samba.m4 b/source4/lib/replace/samba.m4
index a2e04f53b1..e62c3d3cd1 100644
--- a/source4/lib/replace/samba.m4
+++ b/source4/lib/replace/samba.m4
@@ -3,6 +3,9 @@ AC_LIBREPLACE_BROKEN_CHECKS
SMB_EXT_LIB(LIBREPLACE_EXT, [${LIBDL}])
SMB_ENABLE(LIBREPLACE_EXT)
+SMB_EXT_LIB(LIBREPLACE_NETWORK, [${LIBREPLACE_NETWORK_LIBS}])
+SMB_ENABLE(LIBREPLACE_NETWORK)
+
# remove leading ./
LIBREPLACE_DIR=`echo ${libreplacedir} |sed -e 's/^\.\///g'`
diff --git a/source4/lib/replace/snprintf.c b/source4/lib/replace/snprintf.c
index 9f8a7657e5..a174dcffed 100644
--- a/source4/lib/replace/snprintf.c
+++ b/source4/lib/replace/snprintf.c
@@ -1264,7 +1264,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
VA_COPY(ap2, ap);
ret = vsnprintf(NULL, 0, format, ap2);
va_end(ap2);
- if (ret <= 0) return ret;
+ if (ret < 0) return ret;
(*ptr) = (char *)malloc(ret+1);
if (!*ptr) return -1;
diff --git a/source4/lib/replace/socket.m4 b/source4/lib/replace/socket.m4
index c0c8f93e81..984f81f15f 100644
--- a/source4/lib/replace/socket.m4
+++ b/source4/lib/replace/socket.m4
@@ -7,10 +7,10 @@ dnl only looks in /etc/hosts), so we only look for -lsocket if we need
dnl it.
AC_CHECK_FUNCS(connect)
if test x"$ac_cv_func_connect" = x"no"; then
- AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect)
- AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect)
- AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect)
- AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect)
+ AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, connect)
+ AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, connect)
+ AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, connect)
+ AC_CHECK_LIB_EXT(inet, LIBREPLACE_NETWORK_LIBS, connect)
dnl We can't just call AC_CHECK_FUNCS(connect) here,
dnl because the value has been cached.
if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" ||
@@ -24,9 +24,9 @@ fi
AC_CHECK_FUNCS(gethostbyname)
if test x"$ac_cv_func_gethostbyname" = x"no"; then
- AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname)
- AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname)
- AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname)
+ AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, gethostbyname)
+ AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, gethostbyname)
+ AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, gethostbyname)
dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here,
dnl because the value has been cached.
if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" ||
@@ -37,4 +37,3 @@ if test x"$ac_cv_func_gethostbyname" = x"no"; then
[Whether the system has gethostbyname()])
fi
fi
-
diff --git a/source4/lib/replace/socketpair.c b/source4/lib/replace/socketpair.c
new file mode 100644
index 0000000000..c775730952
--- /dev/null
+++ b/source4/lib/replace/socketpair.c
@@ -0,0 +1,46 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * replacement routines for broken systems
+ * Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2006
+ * Copyright (C) Michael Adam <obnox@samba.org> 2008
+ *
+ * ** NOTE! The following LGPL license applies to the replace
+ * ** library. This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+int rep_socketpair(int d, int type, int protocol, int sv[2])
+{
+ if (d != AF_UNIX) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (protocol != 0) {
+ errno = EPROTONOSUPPORT;
+ return -1;
+ }
+
+ if (type != SOCK_STREAM) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ return pipe(sv);
+}
diff --git a/source4/lib/replace/socketpair.m4 b/source4/lib/replace/socketpair.m4
new file mode 100644
index 0000000000..7088334cda
--- /dev/null
+++ b/source4/lib/replace/socketpair.m4
@@ -0,0 +1 @@
+AC_CHECK_FUNCS(socketpair,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} socketpair.o"])
diff --git a/source4/lib/replace/system/network.h b/source4/lib/replace/system/network.h
index 410c6d7cca..a5fb813aa1 100644
--- a/source4/lib/replace/system/network.h
+++ b/source4/lib/replace/system/network.h
@@ -88,7 +88,7 @@
typedef int socklen_t;
#endif
-#ifdef REPLACE_INET_NTOA
+#if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA)
/* define is in "replace.h" */
char *rep_inet_ntoa(struct in_addr ip);
#endif
@@ -103,6 +103,11 @@ int rep_inet_pton(int af, const char *src, void *dst);
const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size);
#endif
+#ifndef HAVE_INET_ATON
+/* define is in "replace.h" */
+int rep_inet_aton(const char *src, struct in_addr *dst);
+#endif
+
#ifndef HAVE_CONNECT
/* define is in "replace.h" */
int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
@@ -138,6 +143,11 @@ int rep_getifaddrs(struct ifaddrs **);
void rep_freeifaddrs(struct ifaddrs *);
#endif
+#ifndef HAVE_SOCKETPAIR
+/* define is in "replace.h" */
+int rep_socketpair(int d, int type, int protocol, int sv[2]);
+#endif
+
/*
* Some systems have getaddrinfo but not the
* defines needed to use it.
@@ -305,7 +315,7 @@ struct addrinfo {
/* Needed for some systems that don't define it (Solaris). */
#ifndef ifr_netmask
-#define ifr_netmask ifr_addrs
+#define ifr_netmask ifr_addr
#endif
#ifdef SOCKET_WRAPPER
diff --git a/source4/lib/replace/test/os2_delete.c b/source4/lib/replace/test/os2_delete.c
index c6ef180017..b45c135355 100644
--- a/source4/lib/replace/test/os2_delete.c
+++ b/source4/lib/replace/test/os2_delete.c
@@ -39,8 +39,15 @@ static void create_files(void)
int i;
for (i=0;i<NUM_FILES;i++) {
char fname[40];
+ int fd;
sprintf(fname, TESTDIR "/test%u.txt", i);
- close(open(fname, O_CREAT|O_RDWR, 0600)) == 0 || FAILED("close");
+ fd = open(fname, O_CREAT|O_RDWR, 0600);
+ if (fd < 0) {
+ FAILED("open");
+ }
+ if (close(fd) != 0) {
+ FAILED("close");
+ }
}
}
diff --git a/source4/lib/socket/config.m4 b/source4/lib/socket/config.m4
index a713090c6d..b40002b321 100644
--- a/source4/lib/socket/config.m4
+++ b/source4/lib/socket/config.m4
@@ -11,50 +11,6 @@ if test x"$samba_cv_HAVE_SOCK_SIN_LEN" = x"yes"; then
AC_DEFINE(HAVE_SOCK_SIN_LEN,1,[Whether the sockaddr_in struct has a sin_len property])
fi
-# The following test taken from the cvs sources
-# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
-# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
-# libsocket.so which has a bad implementation of gethostbyname (it
-# only looks in /etc/hosts), so we only look for -lsocket if we need
-# it.
-AC_CHECK_FUNCS(connect)
-if test x"$ac_cv_func_connect" = x"no"; then
- AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect)
- AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect)
- AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect)
- AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect)
- SMB_ENABLE(EXT_SOCKET,YES)
- dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
- dnl has been cached.
- if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" ||
- test x"$ac_cv_lib_ext_nsl_connect" = x"yes" ||
- test x"$ac_cv_lib_ext_socket_connect" = x"yes" ||
- test x"$ac_cv_lib_ext_inet_connect" = x"yes"; then
- AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()])
- else
- AC_MSG_ERROR([no connect() function available!])
- fi
-fi
-
-SMB_EXT_LIB(EXT_SOCKET,[${SOCKET_LIBS}],[${SOCKET_CFLAGS}],[${SOCKET_CPPFLAGS}],[${SOCKET_LDFLAGS}])
-
-AC_CHECK_FUNCS(gethostbyname)
-if test x"$ac_cv_func_gethostbyname" = x"no"; then
- AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname)
- AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname)
- AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname)
- SMB_ENABLE(EXT_NSL,YES)
- dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, because the value
- dnl has been cached.
- if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" != x"yes" &&
- test x"$ac_cv_lib_ext_nsl_gethostbyname" != x"yes" &&
- test x"$ac_cv_lib_ext_socket_gethostbyname" != x"yes"; then
- AC_MSG_ERROR([no gethostbyname() function available!])
- fi
-fi
-
-SMB_EXT_LIB(EXT_NSL,[${NSL_LIBS}],[],[],[])
-
############################################
# check for unix domain sockets
AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [
diff --git a/source4/lib/socket/config.mk b/source4/lib/socket/config.mk
index 354b1b5198..2400190175 100644
--- a/source4/lib/socket/config.mk
+++ b/source4/lib/socket/config.mk
@@ -2,7 +2,7 @@
# Start SUBSYSTEM LIBNETIF
[SUBSYSTEM::LIBNETIF]
PRIVATE_PROTO_HEADER = netif_proto.h
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBREPLACE_NETWORK
# End SUBSYSTEM LIBNETIF
##############################
@@ -13,7 +13,7 @@ LIBNETIF_OBJ_FILES = $(addprefix lib/socket/, interface.o netif.o)
[MODULE::socket_ip]
SUBSYSTEM = samba-socket
OUTPUT_TYPE = MERGED_OBJ
-PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL LIBSAMBA-ERRORS
+PRIVATE_DEPENDENCIES = LIBSAMBA-ERRORS LIBREPLACE_NETWORK
# End MODULE socket_ip
################################################
@@ -24,7 +24,7 @@ socket_ip_OBJ_FILES = lib/socket/socket_ip.o
[MODULE::socket_unix]
SUBSYSTEM = samba-socket
OUTPUT_TYPE = MERGED_OBJ
-PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
# End MODULE socket_unix
################################################
diff --git a/source4/lib/socket_wrapper/config.mk b/source4/lib/socket_wrapper/config.mk
index f7e874d8e2..75d3ade28b 100644
--- a/source4/lib/socket_wrapper/config.mk
+++ b/source4/lib/socket_wrapper/config.mk
@@ -1,7 +1,7 @@
##############################
# Start SUBSYSTEM SOCKET_WRAPPER
[SUBSYSTEM::SOCKET_WRAPPER]
-PRIVATE_DEPENDENCIES = EXT_SOCKET
+PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
# End SUBSYSTEM SOCKET_WRAPPER
##############################
diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c
index 644365a665..86d9f7a312 100644
--- a/source4/lib/socket_wrapper/socket_wrapper.c
+++ b/source4/lib/socket_wrapper/socket_wrapper.c
@@ -64,6 +64,7 @@
#include <unistd.h>
#include <string.h>
#include <stdio.h>
+#include <stdint.h>
#endif
@@ -624,67 +625,67 @@ enum swrap_packet_type {
};
struct swrap_file_hdr {
- unsigned long magic;
- unsigned short version_major;
- unsigned short version_minor;
- long timezone;
- unsigned long sigfigs;
- unsigned long frame_max_len;
+ uint32_t magic;
+ uint16_t version_major;
+ uint16_t version_minor;
+ int32_t timezone;
+ uint32_t sigfigs;
+ uint32_t frame_max_len;
#define SWRAP_FRAME_LENGTH_MAX 0xFFFF
- unsigned long link_type;
+ uint32_t link_type;
};
#define SWRAP_FILE_HDR_SIZE 24
struct swrap_packet {
struct {
- unsigned long seconds;
- unsigned long micro_seconds;
- unsigned long recorded_length;
- unsigned long full_length;
+ uint32_t seconds;
+ uint32_t micro_seconds;
+ uint32_t recorded_length;
+ uint32_t full_length;
} frame;
#define SWRAP_PACKET__FRAME_SIZE 16
struct {
struct {
- unsigned char ver_hdrlen;
- unsigned char tos;
- unsigned short packet_length;
- unsigned short identification;
- unsigned char flags;
- unsigned char fragment;
- unsigned char ttl;
- unsigned char protocol;
- unsigned short hdr_checksum;
- unsigned long src_addr;
- unsigned long dest_addr;
+ uint8_t ver_hdrlen;
+ uint8_t tos;
+ uint16_t packet_length;
+ uint16_t identification;
+ uint8_t flags;
+ uint8_t fragment;
+ uint8_t ttl;
+ uint8_t protocol;
+ uint16_t hdr_checksum;
+ uint32_t src_addr;
+ uint32_t dest_addr;
} hdr;
#define SWRAP_PACKET__IP_HDR_SIZE 20
union {
struct {
- unsigned short source_port;
- unsigned short dest_port;
- unsigned long seq_num;
- unsigned long ack_num;
- unsigned char hdr_length;
- unsigned char control;
- unsigned short window;
- unsigned short checksum;
- unsigned short urg;
+ uint16_t source_port;
+ uint16_t dest_port;
+ uint32_t seq_num;
+ uint32_t ack_num;
+ uint8_t hdr_length;
+ uint8_t control;
+ uint16_t window;
+ uint16_t checksum;
+ uint16_t urg;
} tcp;
#define SWRAP_PACKET__IP_P_TCP_SIZE 20
struct {
- unsigned short source_port;
- unsigned short dest_port;
- unsigned short length;
- unsigned short checksum;
+ uint16_t source_port;
+ uint16_t dest_port;
+ uint16_t length;
+ uint16_t checksum;
} udp;
#define SWRAP_PACKET__IP_P_UDP_SIZE 8
struct {
- unsigned char type;
- unsigned char code;
- unsigned short checksum;
- unsigned long unused;
+ uint8_t type;
+ uint8_t code;
+ uint16_t checksum;
+ uint32_t unused;
} icmp;
#define SWRAP_PACKET__IP_P_ICMP_SIZE 8
} p;
diff --git a/source4/lib/util/config.mk b/source4/lib/util/config.mk
index b0978ca5f5..3afe398a8f 100644
--- a/source4/lib/util/config.mk
+++ b/source4/lib/util/config.mk
@@ -2,7 +2,8 @@
PUBLIC_DEPENDENCIES = \
LIBTALLOC LIBCRYPTO \
SOCKET_WRAPPER EXT_NSL \
- CHARSET EXECINFO DYNCONFIG
+ CHARSET EXECINFO DYNCONFIG \
+ LIBREPLACE_NETWORK
LIBSAMBA-UTIL_OBJ_FILES = $(addprefix lib/util/, \
xfile.o \
@@ -37,7 +38,6 @@ PUBLIC_HEADERS += $(addprefix lib/util/, util.h \
[SUBSYSTEM::ASN1_UTIL]
PRIVATE_PROTO_HEADER = asn1_proto.h
-
ASN1_UTIL_OBJ_FILES = lib/util/asn1.o
PUBLIC_HEADERS += lib/util/asn1.h
diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c
index aab7487a42..26169e7838 100644
--- a/source4/libcli/composite/composite.c
+++ b/source4/libcli/composite/composite.c
@@ -1,6 +1,7 @@
/*
Unix SMB/CIFS implementation.
+ Copyright (C) Volker Lendecke 2005
Copyright (C) Andrew Tridgell 2005
This program is free software; you can redistribute it and/or modify
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 24e8ad4afc..3965c58204 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -175,7 +175,7 @@ struct smb_rmdir {
};
/* struct used in rename() call */
-enum smb_rename_level {RAW_RENAME_RENAME, RAW_RENAME_NTRENAME};
+enum smb_rename_level {RAW_RENAME_RENAME, RAW_RENAME_NTRENAME, RAW_RENAME_NTTRANS};
union smb_rename {
struct {
@@ -206,6 +206,17 @@ union smb_rename {
const char *new_name;
} in;
} ntrename;
+
+ /* NT TRANS rename interface */
+ struct {
+ enum smb_rename_level level;
+
+ struct {
+ union smb_handle file;
+ uint16_t flags;/* see RENAME_REPLACE_IF_EXISTS */
+ const char *new_name;
+ } in;
+ } nttrans;
};
enum smb_tcon_level {
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index d9383401b7..725034c3a9 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -36,6 +36,8 @@ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree,
union smb_rename *parms)
{
struct smbcli_request *req = NULL;
+ struct smb_nttrans nt;
+ TALLOC_CTX *mem_ctx;
switch (parms->generic.level) {
case RAW_RENAME_RENAME:
@@ -53,6 +55,30 @@ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree,
smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE);
smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE);
break;
+
+ case RAW_RENAME_NTTRANS:
+
+ mem_ctx = talloc_new(tree);
+
+ nt.in.max_setup = 0;
+ nt.in.max_param = 0;
+ nt.in.max_data = 0;
+ nt.in.setup_count = 0;
+ nt.in.setup = NULL;
+ nt.in.function = NT_TRANSACT_RENAME;
+ nt.in.params = data_blob_talloc(mem_ctx, NULL, 4);
+ nt.in.data = data_blob(NULL, 0);
+
+ SSVAL(nt.in.params.data, VWV(0), parms->nttrans.in.file.fnum);
+ SSVAL(nt.in.params.data, VWV(1), parms->nttrans.in.flags);
+
+ smbcli_blob_append_string(tree->session, mem_ctx,
+ &nt.in.params, parms->nttrans.in.new_name,
+ STR_TERMINATE);
+
+ req = smb_raw_nttrans_send(tree, &nt);
+ talloc_free(mem_ctx);
+ return req;
}
if (!smbcli_request_send(req)) {
diff --git a/source4/libcli/security/security.h b/source4/libcli/security/security.h
index d9485c825f..c7f2a09311 100644
--- a/source4/libcli/security/security.h
+++ b/source4/libcli/security/security.h
@@ -18,4 +18,12 @@
*/
#include "librpc/gen_ndr/security.h"
+
+enum security_user_level {
+ SECURITY_ANONYMOUS,
+ SECURITY_USER,
+ SECURITY_ADMINISTRATOR,
+ SECURITY_SYSTEM
+};
+
#include "libcli/security/proto.h"
diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c
index e126340c46..0680c54258 100644
--- a/source4/libcli/security/security_token.c
+++ b/source4/libcli/security/security_token.c
@@ -23,6 +23,7 @@
#include "includes.h"
#include "dsdb/samdb/samdb.h"
#include "libcli/security/security.h"
+#include "auth/session.h"
/*
return a blank security token
@@ -141,3 +142,29 @@ bool security_token_has_nt_authenticated_users(const struct security_token *toke
{
return security_token_has_sid_string(token, SID_NT_AUTHENTICATED_USERS);
}
+
+enum security_user_level security_session_user_level(struct auth_session_info *session_info)
+{
+ if (!session_info) {
+ return SECURITY_ANONYMOUS;
+ }
+
+ if (security_token_is_system(session_info->security_token)) {
+ return SECURITY_SYSTEM;
+ }
+
+ if (security_token_is_anonymous(session_info->security_token)) {
+ return SECURITY_ANONYMOUS;
+ }
+
+ if (security_token_has_builtin_administrators(session_info->security_token)) {
+ return SECURITY_ADMINISTRATOR;
+ }
+
+ if (security_token_has_nt_authenticated_users(session_info->security_token)) {
+ return SECURITY_USER;
+ }
+
+ return SECURITY_ANONYMOUS;
+}
+
diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c
index 72118b2359..eb9e4c45d9 100644
--- a/source4/libcli/security/security_wrap.c
+++ b/source4/libcli/security/security_wrap.c
@@ -3116,7 +3116,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM
arg2 = (struct security_ace *)(argp2);
result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3156,7 +3156,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM
arg2 = (struct security_ace *)(argp2);
result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3196,7 +3196,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM
arg2 = (struct dom_sid *)(argp2);
result = security_descriptor_dacl_del(arg1,(struct dom_sid const *)arg2);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3236,7 +3236,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM
arg2 = (struct dom_sid *)(argp2);
result = security_descriptor_sacl_del(arg1,(struct dom_sid const *)arg2);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c
index f67e6dd0e3..e0bdb27cfc 100644
--- a/source4/libcli/swig/libcli_nbt_wrap.c
+++ b/source4/libcli/swig/libcli_nbt_wrap.c
@@ -4065,7 +4065,7 @@ SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct nbt_name_query *)(argp3);
result = do_nbt_name_query(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
diff --git a/source4/libcli/util/errors.i b/source4/libcli/util/errors.i
index ede536a995..17efcbf62a 100644
--- a/source4/libcli/util/errors.i
+++ b/source4/libcli/util/errors.i
@@ -20,7 +20,7 @@
#ifdef SWIGPYTHON
%typemap(out,noblock=1) WERROR {
if (!W_ERROR_IS_OK($1)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, win_errstr($1));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V($1), win_errstr($1));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if ($result == NULL) {
@@ -30,7 +30,7 @@
%typemap(out,noblock=1) NTSTATUS {
if (NT_STATUS_IS_ERR($1)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, nt_errstr($1));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V($1), nt_errstr($1));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if ($result == NULL) {
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index 667f54c447..50cc1145d2 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -867,8 +867,11 @@ static NTSTATUS libnet_RpcConnectDCInfo_recv(struct composite_context *c, struct
} else {
if (s->r.out.error_string) {
r->out.error_string = talloc_steal(mem_ctx, s->r.out.error_string);
- } else {
+ } else if (r->in.binding == NULL) {
r->out.error_string = talloc_asprintf(mem_ctx, "Connection to DC failed: %s", nt_errstr(status));
+ } else {
+ r->out.error_string = talloc_asprintf(mem_ctx, "Connection to DC %s failed: %s",
+ r->in.binding, nt_errstr(status));
}
}
diff --git a/source4/libnet/net_wrap.c b/source4/libnet/net_wrap.c
index a4e27c151c..29b30a87c2 100644
--- a/source4/libnet/net_wrap.c
+++ b/source4/libnet/net_wrap.c
@@ -2679,7 +2679,7 @@ SWIGINTERN PyObject *_wrap_libnet_samsync_ldb(PyObject *SWIGUNUSEDPARM(self), Py
arg3 = (struct libnet_samsync_ldb *)(argp3);
result = libnet_samsync_ldb(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2721,7 +2721,7 @@ SWIGINTERN PyObject *_wrap_libnet_DomainList(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_DomainList *)(argp3);
result = libnet_DomainList(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2763,7 +2763,7 @@ SWIGINTERN PyObject *_wrap_libnet_DomainClose(PyObject *SWIGUNUSEDPARM(self), Py
arg3 = (struct libnet_DomainClose *)(argp3);
result = libnet_DomainClose(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2805,7 +2805,7 @@ SWIGINTERN PyObject *_wrap_libnet_DomainOpen(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_DomainOpen *)(argp3);
result = libnet_DomainOpen(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2847,7 +2847,7 @@ SWIGINTERN PyObject *_wrap_libnet_LookupName(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_LookupName *)(argp3);
result = libnet_LookupName(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2889,7 +2889,7 @@ SWIGINTERN PyObject *_wrap_libnet_LookupDCs(PyObject *SWIGUNUSEDPARM(self), PyOb
arg3 = (struct libnet_LookupDCs *)(argp3);
result = libnet_LookupDCs(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2931,7 +2931,7 @@ SWIGINTERN PyObject *_wrap_libnet_LookupHost(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_Lookup *)(argp3);
result = libnet_LookupHost(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -2973,7 +2973,7 @@ SWIGINTERN PyObject *_wrap_libnet_Lookup(PyObject *SWIGUNUSEDPARM(self), PyObjec
arg3 = (struct libnet_Lookup *)(argp3);
result = libnet_Lookup(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3015,7 +3015,7 @@ SWIGINTERN PyObject *_wrap_libnet_ListShares(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_ListShares *)(argp3);
result = libnet_ListShares(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3057,7 +3057,7 @@ SWIGINTERN PyObject *_wrap_libnet_AddShare(PyObject *SWIGUNUSEDPARM(self), PyObj
arg3 = (struct libnet_AddShare *)(argp3);
result = libnet_AddShare(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3099,7 +3099,7 @@ SWIGINTERN PyObject *_wrap_libnet_DelShare(PyObject *SWIGUNUSEDPARM(self), PyObj
arg3 = (struct libnet_DelShare *)(argp3);
result = libnet_DelShare(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3141,7 +3141,7 @@ SWIGINTERN PyObject *_wrap_libnet_GroupList(PyObject *SWIGUNUSEDPARM(self), PyOb
arg3 = (struct libnet_GroupList *)(argp3);
result = libnet_GroupList(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3183,7 +3183,7 @@ SWIGINTERN PyObject *_wrap_libnet_GroupInfo(PyObject *SWIGUNUSEDPARM(self), PyOb
arg3 = (struct libnet_GroupInfo *)(argp3);
result = libnet_GroupInfo(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3225,7 +3225,7 @@ SWIGINTERN PyObject *_wrap_libnet_UserList(PyObject *SWIGUNUSEDPARM(self), PyObj
arg3 = (struct libnet_UserList *)(argp3);
result = libnet_UserList(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3267,7 +3267,7 @@ SWIGINTERN PyObject *_wrap_libnet_UserInfo(PyObject *SWIGUNUSEDPARM(self), PyObj
arg3 = (struct libnet_UserInfo *)(argp3);
result = libnet_UserInfo(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3309,7 +3309,7 @@ SWIGINTERN PyObject *_wrap_libnet_ModifyUser(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_ModifyUser *)(argp3);
result = libnet_ModifyUser(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3351,7 +3351,7 @@ SWIGINTERN PyObject *_wrap_libnet_DeleteUser(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_DeleteUser *)(argp3);
result = libnet_DeleteUser(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3393,7 +3393,7 @@ SWIGINTERN PyObject *_wrap_libnet_CreateUser(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_CreateUser *)(argp3);
result = libnet_CreateUser(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3435,7 +3435,7 @@ SWIGINTERN PyObject *_wrap_libnet_SamDump_keytab(PyObject *SWIGUNUSEDPARM(self),
arg3 = (struct libnet_SamDump_keytab *)(argp3);
result = libnet_SamDump_keytab(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3477,7 +3477,7 @@ SWIGINTERN PyObject *_wrap_libnet_SamDump(PyObject *SWIGUNUSEDPARM(self), PyObje
arg3 = (struct libnet_SamDump *)(argp3);
result = libnet_SamDump(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3519,7 +3519,7 @@ SWIGINTERN PyObject *_wrap_libnet_SamSync_netlogon(PyObject *SWIGUNUSEDPARM(self
arg3 = (struct libnet_SamSync *)(argp3);
result = libnet_SamSync_netlogon(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3561,7 +3561,7 @@ SWIGINTERN PyObject *_wrap_libnet_UnbecomeDC(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_UnbecomeDC *)(argp3);
result = libnet_UnbecomeDC(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3603,7 +3603,7 @@ SWIGINTERN PyObject *_wrap_libnet_BecomeDC(PyObject *SWIGUNUSEDPARM(self), PyObj
arg3 = (struct libnet_BecomeDC *)(argp3);
result = libnet_BecomeDC(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3652,7 +3652,7 @@ SWIGINTERN PyObject *_wrap_libnet_JoinSite(PyObject *SWIGUNUSEDPARM(self), PyObj
arg3 = (struct libnet_JoinDomain *)(argp3);
result = libnet_JoinSite(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3694,7 +3694,7 @@ SWIGINTERN PyObject *_wrap_libnet_JoinDomain(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_JoinDomain *)(argp3);
result = libnet_JoinDomain(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3736,7 +3736,7 @@ SWIGINTERN PyObject *_wrap_libnet_Join(PyObject *SWIGUNUSEDPARM(self), PyObject
arg3 = (struct libnet_Join *)(argp3);
result = libnet_Join(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3778,7 +3778,7 @@ SWIGINTERN PyObject *_wrap_libnet_RpcConnect(PyObject *SWIGUNUSEDPARM(self), PyO
arg3 = (struct libnet_RpcConnect *)(argp3);
result = libnet_RpcConnect(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3820,7 +3820,7 @@ SWIGINTERN PyObject *_wrap_libnet_RemoteTOD(PyObject *SWIGUNUSEDPARM(self), PyOb
arg3 = (union libnet_RemoteTOD *)(argp3);
result = libnet_RemoteTOD(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3862,7 +3862,7 @@ SWIGINTERN PyObject *_wrap_libnet_ChangePassword(PyObject *SWIGUNUSEDPARM(self),
arg3 = (union libnet_ChangePassword *)(argp3);
result = libnet_ChangePassword(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
@@ -3904,7 +3904,7 @@ SWIGINTERN PyObject *_wrap_libnet_SetPassword(PyObject *SWIGUNUSEDPARM(self), Py
arg3 = (union libnet_SetPassword *)(argp3);
result = libnet_SetPassword(arg1,arg2,arg3);
if (NT_STATUS_IS_ERR(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 682a3b81cd..bb81888d12 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -2,7 +2,7 @@
# Start SUBSYSTEM LIBNDR
[LIBRARY::LIBNDR]
PRIVATE_PROTO_HEADER = ndr/libndr_proto.h
-PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET EXT_NSL \
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET \
LIBSAMBA-CONFIG
LIBNDR_OBJ_FILES = $(addprefix librpc/ndr/, ndr.o ndr_basic.o ndr_string.o uuid.o)
diff --git a/source4/librpc/idl/opendb.idl b/source4/librpc/idl/opendb.idl
index e3bc2d0f17..72bf23a9b4 100644
--- a/source4/librpc/idl/opendb.idl
+++ b/source4/librpc/idl/opendb.idl
@@ -20,6 +20,7 @@ interface opendb
uint32 share_access;
uint32 access_mask;
pointer file_handle;
+ pointer fd;
/* we need a per-entry delete on close, as well as a per-file
one, to cope with strange semantics on open */
boolean8 delete_on_close;
diff --git a/source4/nsswitch/config.m4 b/source4/nsswitch/config.m4
index a3b7412841..207b7fa53f 100644
--- a/source4/nsswitch/config.m4
+++ b/source4/nsswitch/config.m4
@@ -4,8 +4,7 @@ case "$host_os" in
*linux*)
SMB_LIBRARY(nss_winbind,
[nsswitch/winbind_nss_linux.o],
- [LIBWINBIND-CLIENT],
- [2],[2])
+ [LIBWINBIND-CLIENT])
;;
*)
;;
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index 58183b5e60..3c090b5f5c 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -595,6 +595,13 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs,
SETUP_PID;
+ if (ren->nttrans.level == RAW_RENAME_NTTRANS) {
+ struct cvfs_file *f;
+ f = ntvfs_handle_get_backend_data(ren->nttrans.in.file.ntvfs, ntvfs);
+ if (!f) return NT_STATUS_INVALID_HANDLE;
+ ren->nttrans.in.file.fnum = f->fnum;
+ }
+
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
return smb_raw_rename(private->tree, ren);
}
diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk
index 356f6465c3..c66257b73f 100644
--- a/source4/ntvfs/common/config.mk
+++ b/source4/ntvfs/common/config.mk
@@ -2,7 +2,7 @@
# Start LIBRARY ntvfs_common
[SUBSYSTEM::ntvfs_common]
PRIVATE_PROTO_HEADER = proto.h
-PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share LIBDBWRAP
+PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify sys_lease share LIBDBWRAP
PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb
# End LIBRARY ntvfs_common
################################################
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index 1cc077137c..676706e03f 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -97,11 +97,11 @@ _PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
*/
_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck,
void *file_handle, const char *path,
- bool allow_level_II_oplock,
+ int *fd, bool allow_level_II_oplock,
uint32_t oplock_level, uint32_t *oplock_granted)
{
return ops->odb_open_file(lck, file_handle, path,
- allow_level_II_oplock,
+ fd, allow_level_II_oplock,
oplock_level, oplock_granted);
}
diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h
index fb3223aea9..045476337a 100644
--- a/source4/ntvfs/common/opendb.h
+++ b/source4/ntvfs/common/opendb.h
@@ -27,7 +27,7 @@ struct opendb_ops {
DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck);
NTSTATUS (*odb_open_file)(struct odb_lock *lck,
void *file_handle, const char *path,
- bool allow_level_II_oplock,
+ int *fd, bool allow_level_II_oplock,
uint32_t oplock_level, uint32_t *oplock_granted);
NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private);
NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle,
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 17fcdfbbb4..fc05b342a8 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -49,11 +49,13 @@
#include "ntvfs/common/ntvfs_common.h"
#include "cluster/cluster.h"
#include "param/param.h"
+#include "ntvfs/sysdep/sys_lease.h"
struct odb_context {
struct tdb_wrap *w;
struct ntvfs_context *ntvfs_ctx;
bool oplocks;
+ struct sys_lease_context *lease_ctx;
};
/*
@@ -72,6 +74,10 @@ struct odb_lock {
} can_open;
};
+static NTSTATUS odb_oplock_break_send(struct messaging_context *msg_ctx,
+ struct opendb_entry *e,
+ uint8_t level);
+
/*
Open up the openfiles.tdb database. Close it down using
talloc_free(). We need the messaging_ctx to allow for pending open
@@ -96,7 +102,12 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx,
odb->ntvfs_ctx = ntvfs_ctx;
/* leave oplocks disabled by default until the code is working */
- odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", false);
+ odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", true);
+
+ odb->lease_ctx = sys_lease_context_create(ntvfs_ctx->config, odb,
+ ntvfs_ctx->event_ctx,
+ ntvfs_ctx->msg_ctx,
+ odb_oplock_break_send);
return odb;
}
@@ -442,7 +453,7 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
*/
static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
void *file_handle, const char *path,
- bool allow_level_II_oplock,
+ int *fd, bool allow_level_II_oplock,
uint32_t oplock_level, uint32_t *oplock_granted)
{
struct odb_context *odb = lck->odb;
@@ -491,22 +502,29 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
oplock_level = OPLOCK_NONE;
}
+ lck->can_open.e->file_handle = file_handle;
+ lck->can_open.e->fd = fd;
+ lck->can_open.e->allow_level_II_oplock = allow_level_II_oplock;
+ lck->can_open.e->oplock_level = oplock_level;
+
+ if (odb->lease_ctx && fd) {
+ NTSTATUS status;
+ status = sys_lease_setup(odb->lease_ctx, lck->can_open.e);
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
+
if (oplock_granted) {
- if (oplock_level == OPLOCK_EXCLUSIVE) {
+ if (lck->can_open.e->oplock_level == OPLOCK_EXCLUSIVE) {
*oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
- } else if (oplock_level == OPLOCK_BATCH) {
+ } else if (lck->can_open.e->oplock_level == OPLOCK_BATCH) {
*oplock_granted = BATCH_OPLOCK_RETURN;
- } else if (oplock_level == OPLOCK_LEVEL_II) {
+ } else if (lck->can_open.e->oplock_level == OPLOCK_LEVEL_II) {
*oplock_granted = LEVEL_II_OPLOCK_RETURN;
} else {
*oplock_granted = NO_OPLOCK_RETURN;
}
}
- lck->can_open.e->file_handle = file_handle;
- lck->can_open.e->allow_level_II_oplock = allow_level_II_oplock;
- lck->can_open.e->oplock_level = oplock_level;
-
/* it doesn't conflict, so add it to the end */
lck->file.entries = talloc_realloc(lck, lck->file.entries,
struct opendb_entry,
@@ -569,6 +587,11 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle,
if (lck->file.entries[i].delete_on_close) {
lck->file.delete_on_close = true;
}
+ if (odb->lease_ctx && lck->file.entries[i].fd) {
+ NTSTATUS status;
+ status = sys_lease_remove(odb->lease_ctx, &lck->file.entries[i]);
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
if (i < lck->file.num_entries-1) {
memmove(lck->file.entries+i, lck->file.entries+i+1,
(lck->file.num_entries - (i+1)) *
@@ -622,6 +645,13 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle,
if (file_handle == lck->file.entries[i].file_handle &&
cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.entries[i].server)) {
lck->file.entries[i].oplock_level = oplock_level;
+
+ if (odb->lease_ctx && lck->file.entries[i].fd) {
+ NTSTATUS status;
+ status = sys_lease_update(odb->lease_ctx, &lck->file.entries[i]);
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
+
break;
}
}
@@ -800,6 +830,7 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
lck->can_open.e->server = odb->ntvfs_ctx->server_id;
lck->can_open.e->file_handle = NULL;
+ lck->can_open.e->fd = NULL;
lck->can_open.e->stream_id = stream_id;
lck->can_open.e->share_access = share_access;
lck->can_open.e->access_mask = access_mask;
@@ -831,5 +862,6 @@ static const struct opendb_ops opendb_tdb_ops = {
void odb_tdb_init_ops(void)
{
+ sys_lease_init();
odb_set_ops(&opendb_tdb_ops);
}
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 2e757e1742..6e77cb7c75 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -300,7 +300,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
/* now really mark the file as open */
status = odb_open_file(lck, f->handle, name->full_name,
- false, OPLOCK_NONE, NULL);
+ NULL, false, OPLOCK_NONE, NULL);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(lck);
@@ -360,7 +360,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
}
status = odb_open_file(lck, f->handle, name->full_name,
- false, OPLOCK_NONE, NULL);
+ NULL, false, OPLOCK_NONE, NULL);
if (!NT_STATUS_IS_OK(status)) {
goto cleanup_delete;
@@ -600,7 +600,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
mode = pvfs_fileperms(pvfs, attrib);
/* create the file */
- fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode);
+ fd = open(name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode);
if (fd == -1) {
return pvfs_map_errno(pvfs, errno);
}
@@ -688,19 +688,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
return status;
}
- status = odb_open_file(lck, f->handle, name->full_name,
- allow_level_II_oplock,
- oplock_level, &oplock_granted);
- talloc_free(lck);
- if (!NT_STATUS_IS_OK(status)) {
- /* bad news, we must have hit a race - we don't delete the file
- here as the most likely scenario is that someone else created
- the file at the same time */
- close(fd);
- return status;
- }
-
-
f->ntvfs = h;
f->pvfs = pvfs;
f->pending_list = NULL;
@@ -723,6 +710,18 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
f->handle->sticky_write_time = false;
f->handle->open_completed = false;
+ status = odb_open_file(lck, f->handle, name->full_name,
+ &f->handle->fd, allow_level_II_oplock,
+ oplock_level, &oplock_granted);
+ talloc_free(lck);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* bad news, we must have hit a race - we don't delete the file
+ here as the most likely scenario is that someone else created
+ the file at the same time */
+ close(fd);
+ return status;
+ }
+
DLIST_ADD(pvfs->files.list, f);
/* setup a destructor to avoid file descriptor leaks on
@@ -859,7 +858,13 @@ NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs,
/* setup a pending lock */
status = odb_open_file_pending(lck, r);
- if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND,status)) {
+ /*
+ * maybe only a unix application
+ * has the file open
+ */
+ data_blob_free(&r->odb_locking_key);
+ } else if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -876,8 +881,6 @@ NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs,
talloc_steal(r, wait_handle);
- talloc_steal(pvfs, r);
-
return NT_STATUS_OK;
}
@@ -892,8 +895,14 @@ static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r,
enum pvfs_wait_notice reason)
{
union smb_open *io = talloc_get_type(_io, union smb_open);
+ struct timeval *final_timeout = NULL;
NTSTATUS status;
+ if (private_data) {
+ final_timeout = talloc_get_type(private_data,
+ struct timeval);
+ }
+
/* w2k3 ignores SMBntcancel for outstanding open requests. It's probably
just a bug in their server, but we better do the same */
if (reason == PVFS_WAIT_CANCEL) {
@@ -901,6 +910,16 @@ static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r,
}
if (reason == PVFS_WAIT_TIMEOUT) {
+ if (final_timeout &&
+ !timeval_expired(final_timeout)) {
+ /*
+ * we need to retry periodictly
+ * after an EAGAIN as there's
+ * no way the kernel tell us
+ * an oplock is released.
+ */
+ goto retry;
+ }
/* if it timed out, then give the failure
immediately */
talloc_free(r);
@@ -909,6 +928,7 @@ static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r,
return;
}
+retry:
talloc_free(r);
/* try the open again, which could trigger another retry setup
@@ -1028,6 +1048,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
struct pvfs_state *pvfs = ntvfs->private_data;
NTSTATUS status;
struct timeval end_time;
+ struct timeval *final_timeout = NULL;
if (io->generic.in.create_options &
(NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
@@ -1048,12 +1069,28 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
} else if (NT_STATUS_EQUAL(parent_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
end_time = timeval_add(&req->statistics.request_time,
pvfs->oplock_break_timeout, 0);
+ } else if (NT_STATUS_EQUAL(parent_status, STATUS_MORE_ENTRIES)) {
+ /*
+ * we got EAGAIN which means a unix application
+ * has an oplock or share mode
+ *
+ * we retry every 4/5 of the sharing violation delay
+ * to see if the unix application
+ * has released the oplock or share mode.
+ */
+ final_timeout = talloc(req, struct timeval);
+ NT_STATUS_HAVE_NO_MEMORY(final_timeout);
+ *final_timeout = timeval_add(&req->statistics.request_time,
+ pvfs->oplock_break_timeout,
+ 0);
+ end_time = timeval_current_ofs(0, (pvfs->sharing_violation_delay*4)/5);
+ end_time = timeval_min(final_timeout, &end_time);
} else {
return NT_STATUS_INTERNAL_ERROR;
}
- return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL,
- pvfs_retry_open_sharing);
+ return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io,
+ final_timeout, pvfs_retry_open_sharing);
}
/*
@@ -1297,9 +1334,34 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return status;
}
+ if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) {
+ flags |= O_RDWR;
+ } else {
+ flags |= O_RDONLY;
+ }
+
+ /* do the actual open */
+ fd = open(f->handle->name->full_name, flags | O_NONBLOCK);
+ if (fd == -1) {
+ status = pvfs_map_errno(f->pvfs, errno);
+
+ /*
+ * STATUS_MORE_ENTRIES is EAGAIN or EWOULDBLOCK
+ */
+ if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
+ (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+ return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status);
+ }
+
+ talloc_free(lck);
+ return status;
+ }
+
+ f->handle->fd = fd;
+
/* now really mark the file as open */
status = odb_open_file(lck, f->handle, name->full_name,
- allow_level_II_oplock,
+ &f->handle->fd, allow_level_II_oplock,
oplock_level, &oplock_granted);
if (!NT_STATUS_IS_OK(status)) {
@@ -1307,6 +1369,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return status;
}
+ f->handle->have_opendb_entry = true;
+
if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
oplock_granted = OPLOCK_BATCH;
} else if (oplock_granted != OPLOCK_NONE) {
@@ -1317,23 +1381,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
}
}
- f->handle->have_opendb_entry = true;
-
- if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) {
- flags |= O_RDWR;
- } else {
- flags |= O_RDONLY;
- }
-
- /* do the actual open */
- fd = open(f->handle->name->full_name, flags);
- if (fd == -1) {
- talloc_free(lck);
- return pvfs_map_errno(f->pvfs, errno);
- }
-
- f->handle->fd = fd;
-
stream_existed = name->stream_exists;
/* if this was a stream create then create the stream as well */
diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c
index 29b2d03005..5c2a627084 100644
--- a/source4/ntvfs/posix/pvfs_rename.c
+++ b/source4/ntvfs/posix/pvfs_rename.c
@@ -568,6 +568,9 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_rename *ren)
{
+ struct pvfs_state *pvfs = ntvfs->private_data;
+ struct pvfs_file *f;
+
switch (ren->generic.level) {
case RAW_RENAME_RENAME:
return pvfs_rename_mv(ntvfs, req, ren);
@@ -575,6 +578,15 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs,
case RAW_RENAME_NTRENAME:
return pvfs_rename_nt(ntvfs, req, ren);
+ case RAW_RENAME_NTTRANS:
+ f = pvfs_find_fd(pvfs, req, ren->nttrans.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* wk23 ignores the request */
+ return NT_STATUS_OK;
+
default:
break;
}
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index 7a2d964b9d..4cb47a4f1f 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -219,6 +219,12 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
return pvfs_unlink_one(pvfs, req, unl, name);
}
+ /*
+ * disable async requests in the wildcard case
+ * untill we have proper tests for this
+ */
+ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
+
/* get list of matching files */
status = pvfs_list_start(pvfs, name, req, &dir);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/ntvfs/sysdep/config.m4 b/source4/ntvfs/sysdep/config.m4
index f70cac5e64..6de75a4294 100644
--- a/source4/ntvfs/sysdep/config.m4
+++ b/source4/ntvfs/sysdep/config.m4
@@ -11,3 +11,13 @@ fi
if test x"$ac_cv_header_linux_inotify_h" = x"yes" -a x"$ac_cv_have___NR_inotify_init_decl" = x"yes"; then
SMB_ENABLE(sys_notify_inotify, YES)
fi
+
+AC_HAVE_DECL(F_SETLEASE, [#include <fcntl.h>])
+AC_HAVE_DECL(SA_SIGINFO, [#include <signal.h>])
+
+SMB_ENABLE(sys_lease_linux, NO)
+
+if test x"$ac_cv_have_F_SETLEASE_decl" = x"yes" \
+ -a x"$ac_cv_have_SA_SIGINFO_decl" = x"yes"; then
+ SMB_ENABLE(sys_lease_linux, YES)
+fi
diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk
index 6cd5d88aca..68be660049 100644
--- a/source4/ntvfs/sysdep/config.mk
+++ b/source4/ntvfs/sysdep/config.mk
@@ -15,3 +15,11 @@ sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o
################################################
sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o
+
+[SUBSYSTEM::sys_lease_linux]
+
+sys_lease_linux_OBJ_FILES = ntvfs/sysdep/sys_lease_linux.o
+
+[SUBSYSTEM::sys_lease]
+
+sys_lease_OBJ_FILES = ntvfs/sysdep/sys_lease.o
diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c
new file mode 100644
index 0000000000..28dd27a708
--- /dev/null
+++ b/source4/ntvfs/sysdep/sys_lease.c
@@ -0,0 +1,142 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Stefan Metzmacher 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ abstract the various kernel interfaces to leases (oplocks) into a
+ single Samba friendly interface
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "ntvfs/sysdep/sys_lease.h"
+#include "lib/events/events.h"
+#include "lib/util/dlinklist.h"
+#include "param/param.h"
+#include "build.h"
+
+/* list of registered backends */
+static struct sys_lease_ops *backends;
+static uint32_t num_backends;
+
+#define LEASE_BACKEND "lease:backend"
+
+/*
+ initialise a system change notify backend
+*/
+_PUBLIC_ struct sys_lease_context *sys_lease_context_create(struct share_config *scfg,
+ TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct messaging_context *msg,
+ sys_lease_send_break_fn break_send)
+{
+ struct sys_lease_context *ctx;
+ const char *bname;
+ int i;
+ NTSTATUS status;
+
+ if (num_backends == 0) {
+ return NULL;
+ }
+
+ if (ev == NULL) {
+ ev = event_context_find(mem_ctx);
+ }
+
+ ctx = talloc_zero(mem_ctx, struct sys_lease_context);
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ ctx->event_ctx = ev;
+ ctx->msg_ctx = msg;
+ ctx->break_send = break_send;
+
+ bname = share_string_option(scfg, LEASE_BACKEND, NULL);
+ if (!bname) {
+ talloc_free(ctx);
+ return NULL;
+ }
+
+ for (i=0;i<num_backends;i++) {
+ if (strcasecmp(backends[i].name, bname) == 0) {
+ ctx->ops = &backends[i];
+ break;
+ }
+ }
+
+ if (!ctx->ops) {
+ talloc_free(ctx);
+ return NULL;
+ }
+
+ status = ctx->ops->init(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+/*
+ register a lease backend
+*/
+_PUBLIC_ NTSTATUS sys_lease_register(const struct sys_lease_ops *backend)
+{
+ struct sys_lease_ops *b;
+ b = talloc_realloc(talloc_autofree_context(), backends,
+ struct sys_lease_ops, num_backends+1);
+ NT_STATUS_HAVE_NO_MEMORY(b);
+ backends = b;
+ backends[num_backends] = *backend;
+ num_backends++;
+ return NT_STATUS_OK;
+}
+
+_PUBLIC_ NTSTATUS sys_lease_init(void)
+{
+ static bool initialized = false;
+
+ init_module_fn static_init[] = { STATIC_sys_lease_MODULES };
+
+ if (initialized) return NT_STATUS_OK;
+ initialized = true;
+
+ run_init_functions(static_init);
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS sys_lease_setup(struct sys_lease_context *ctx,
+ struct opendb_entry *e)
+{
+ return ctx->ops->setup(ctx, e);
+}
+
+NTSTATUS sys_lease_update(struct sys_lease_context *ctx,
+ struct opendb_entry *e)
+{
+ return ctx->ops->update(ctx, e);
+}
+
+NTSTATUS sys_lease_remove(struct sys_lease_context *ctx,
+ struct opendb_entry *e)
+{
+ return ctx->ops->remove(ctx, e);
+}
diff --git a/source4/ntvfs/sysdep/sys_lease.h b/source4/ntvfs/sysdep/sys_lease.h
new file mode 100644
index 0000000000..e53760fb1e
--- /dev/null
+++ b/source4/ntvfs/sysdep/sys_lease.h
@@ -0,0 +1,65 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Stefan Metzmacher 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "param/share.h"
+
+struct sys_lease_context;
+struct opendb_entry;
+struct messaging_context;
+
+typedef NTSTATUS (*sys_lease_send_break_fn)(struct messaging_context *,
+ struct opendb_entry *,
+ uint8_t level);
+
+struct sys_lease_ops {
+ const char *name;
+ NTSTATUS (*init)(struct sys_lease_context *ctx);
+ NTSTATUS (*setup)(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
+ NTSTATUS (*update)(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
+ NTSTATUS (*remove)(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
+};
+
+struct sys_lease_context {
+ struct event_context *event_ctx;
+ struct messaging_context *msg_ctx;
+ sys_lease_send_break_fn break_send;
+ void *private_data; /* for use of backend */
+ const struct sys_lease_ops *ops;
+};
+
+NTSTATUS sys_lease_register(const struct sys_lease_ops *ops);
+NTSTATUS sys_lease_init(void);
+
+struct sys_lease_context *sys_lease_context_create(struct share_config *scfg,
+ TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct messaging_context *msg_ctx,
+ sys_lease_send_break_fn break_send);
+
+NTSTATUS sys_lease_setup(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
+
+NTSTATUS sys_lease_update(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
+
+NTSTATUS sys_lease_remove(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
diff --git a/source4/ntvfs/sysdep/sys_lease_linux.c b/source4/ntvfs/sysdep/sys_lease_linux.c
new file mode 100644
index 0000000000..0727eed212
--- /dev/null
+++ b/source4/ntvfs/sysdep/sys_lease_linux.c
@@ -0,0 +1,213 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Stefan Metzmacher 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ lease (oplock) implementation using fcntl F_SETLEASE on linux
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "lib/events/events.h"
+#include "ntvfs/sysdep/sys_lease.h"
+#include "ntvfs/ntvfs.h"
+#include "librpc/gen_ndr/ndr_opendb.h"
+#include "lib/util/dlinklist.h"
+#include "cluster/cluster.h"
+
+#define LINUX_LEASE_RT_SIGNAL (SIGRTMIN+1)
+
+struct linux_lease_pending {
+ struct linux_lease_pending *prev, *next;
+ struct sys_lease_context *ctx;
+ struct opendb_entry e;
+};
+
+/* the global linked list of pending leases */
+static struct linux_lease_pending *leases;
+
+static void linux_lease_signal_handler(struct event_context *ev_ctx,
+ struct signal_event *se,
+ int signum, int count,
+ void *_info, void *private_data)
+{
+ struct sys_lease_context *ctx = talloc_get_type(private_data,
+ struct sys_lease_context);
+ siginfo_t *info = (siginfo_t *)_info;
+ struct linux_lease_pending *c;
+ int got_fd = info->si_fd;
+
+ for (c = leases; c; c = c->next) {
+ int *fd = (int *)c->e.fd;
+
+ if (got_fd == *fd) {
+ break;
+ }
+ }
+
+ if (!c) {
+ return;
+ }
+
+ ctx->break_send(ctx->msg_ctx, &c->e, OPLOCK_BREAK_TO_NONE);
+}
+
+static int linux_lease_pending_destructor(struct linux_lease_pending *p)
+{
+ int ret;
+ int *fd = (int *)p->e.fd;
+
+ DLIST_REMOVE(leases, p);
+
+ if (*fd == -1) {
+ return 0;
+ }
+
+ ret = fcntl(*fd, F_SETLEASE, F_UNLCK);
+ if (ret == -1) {
+ DEBUG(0,("%s: failed to remove oplock: %s\n",
+ __FUNCTION__, strerror(errno)));
+ }
+
+ return 0;
+}
+
+static NTSTATUS linux_lease_init(struct sys_lease_context *ctx)
+{
+ struct signal_event *se;
+
+ se = event_add_signal(ctx->event_ctx, ctx,
+ LINUX_LEASE_RT_SIGNAL, SA_SIGINFO,
+ linux_lease_signal_handler, ctx);
+ NT_STATUS_HAVE_NO_MEMORY(se);
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS linux_lease_setup(struct sys_lease_context *ctx,
+ struct opendb_entry *e)
+{
+ int ret;
+ int *fd = (int *)e->fd;
+ struct linux_lease_pending *p;
+
+ if (e->oplock_level == OPLOCK_NONE) {
+ e->fd = NULL;
+ return NT_STATUS_OK;
+ } else if (e->oplock_level == OPLOCK_LEVEL_II) {
+ /*
+ * the linux kernel doesn't support level2 oplocks
+ * so fix up the granted oplock level
+ */
+ e->oplock_level = OPLOCK_NONE;
+ e->allow_level_II_oplock = false;
+ e->fd = NULL;
+ return NT_STATUS_OK;
+ }
+
+ p = talloc(ctx, struct linux_lease_pending);
+ NT_STATUS_HAVE_NO_MEMORY(p);
+
+ p->ctx = ctx;
+ p->e = *e;
+
+ ret = fcntl(*fd, F_SETSIG, LINUX_LEASE_RT_SIGNAL);
+ if (ret == -1) {
+ talloc_free(p);
+ return map_nt_error_from_unix(errno);
+ }
+
+ ret = fcntl(*fd, F_SETLEASE, F_WRLCK);
+ if (ret == -1) {
+ talloc_free(p);
+ return map_nt_error_from_unix(errno);
+ }
+
+ DLIST_ADD(leases, p);
+
+ talloc_set_destructor(p, linux_lease_pending_destructor);
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS linux_lease_remove(struct sys_lease_context *ctx,
+ struct opendb_entry *e);
+
+static NTSTATUS linux_lease_update(struct sys_lease_context *ctx,
+ struct opendb_entry *e)
+{
+ struct linux_lease_pending *c;
+
+ for (c = leases; c; c = c->next) {
+ if (c->e.fd == e->fd) {
+ break;
+ }
+ }
+
+ if (!c) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /*
+ * set the fd pointer to NULL so that the caller
+ * will not call the remove function as the oplock
+ * is already removed
+ */
+ e->fd = NULL;
+
+ talloc_free(c);
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS linux_lease_remove(struct sys_lease_context *ctx,
+ struct opendb_entry *e)
+{
+ struct linux_lease_pending *c;
+
+ for (c = leases; c; c = c->next) {
+ if (c->e.fd == e->fd) {
+ break;
+ }
+ }
+
+ if (!c) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ talloc_free(c);
+
+ return NT_STATUS_OK;
+}
+
+static struct sys_lease_ops linux_lease_ops = {
+ .name = "linux",
+ .init = linux_lease_init,
+ .setup = linux_lease_setup,
+ .update = linux_lease_update,
+ .remove = linux_lease_remove
+};
+
+/*
+ initialialise the linux lease module
+ */
+NTSTATUS sys_lease_linux_init(void)
+{
+ /* register ourselves as a system lease module */
+ return sys_lease_register(&linux_lease_ops);
+}
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index 86b8951026..7a2575b897 100644
--- a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -44,6 +44,36 @@ sub new($)
bless($self, $class);
}
+sub ElementDirection($)
+{
+ my ($e) = @_;
+
+ return "[in,out]" if (has_property($e, "in") and has_property($e, "out"));
+ return "[in]" if (has_property($e, "in"));
+ return "[out]" if (has_property($e, "out"));
+ return "[in,out]";
+}
+
+sub HeaderProperties($$)
+{
+ my($props,$ignores) = @_;
+ my $ret = "";
+
+ foreach my $d (keys %{$props}) {
+ next if (grep(/^$d$/, @$ignores));
+ if($props->{$d} ne "1") {
+ $ret.= "$d($props->{$d}),";
+ } else {
+ $ret.="$d,";
+ }
+ }
+
+ if ($ret) {
+ return "[" . substr($ret, 0, -1) . "]";
+ }
+}
+
+
sub ParseFunction($$$)
{
my ($self, $if, $fn) = @_;
@@ -57,7 +87,9 @@ sub ParseFunction($$$)
$fn_args .= "struct rpc_pipe_client *cli,\n" . $pad . "TALLOC_CTX *mem_ctx";
foreach (@{$fn->{ELEMENTS}}) {
- $fn_args .= ",\n" . $pad . DeclLong($_);
+ my $dir = ElementDirection($_);
+ my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
+ $fn_args .= ",\n" . $pad . DeclLong($_) . " /* $dir $prop */";
}
if (defined($fn->{RETURN_TYPE}) && ($fn->{RETURN_TYPE} eq "WERROR")) {
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 4375088e17..429c413b98 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -99,8 +99,21 @@ static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX
int ret;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
+
if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
struct lsa_secret_state *secret_state = h->data;
+
+ /* Ensure user is permitted to delete this... */
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed delete things */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
ret = ldb_delete(secret_state->sam_ldb,
secret_state->secret_dn);
talloc_free(h);
@@ -446,6 +459,8 @@ static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TAL
/*
lsa_CreateAccount
+
+ This call does not seem to have any long-term effects, hence no database operations
*/
static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_CreateAccount *r)
@@ -644,9 +659,26 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_cal
/* create the trusted_domain */
ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
- ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ switch (ret) {
+ case LDB_SUCCESS:
+ break;
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ return NT_STATUS_DOMAIN_EXISTS;
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ return NT_STATUS_ACCESS_DENIED;
+ default:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create user record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -1656,6 +1688,16 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
ZERO_STRUCTP(r->out.sec_handle);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed create secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
policy_state = policy_handle->data;
if (!r->in.name.string) {
@@ -1802,6 +1844,16 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
return NT_STATUS_INVALID_PARAMETER;
}
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed to access secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
secret_state = talloc(mem_ctx, struct lsa_secret_state);
if (!secret_state) {
return NT_STATUS_NO_MEMORY;
@@ -1833,10 +1885,10 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
}
} else {
+ secret_state->global = false;
secret_state->sam_ldb = talloc_reference(secret_state,
secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
- secret_state->global = false;
name = r->in.name.string;
if (strlen(name) < 1) {
return NT_STATUS_INVALID_PARAMETER;
@@ -2068,6 +2120,17 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO
DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
+ /* Ensure user is permitted to read this... */
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed to read secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
secret_state = h->data;
/* pull all the user attributes */
diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c
index bcc2af97a7..e01efa8233 100644
--- a/source4/rpc_server/lsa/lsa_lookup.c
+++ b/source4/rpc_server/lsa/lsa_lookup.c
@@ -220,6 +220,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
} else if (strchr_m(name, '@')) {
status = crack_name_to_nt4_name(mem_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status)));
return status;
}
} else {
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 8193e0a882..0aa4d65d8c 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -324,11 +324,11 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
struct samr_connect_state *c_state;
struct dcesrv_handle *h;
struct samr_SamArray *array;
- int count, i, start_i;
+ int i, start_i, ret;
const char * const dom_attrs[] = { "cn", NULL};
const char * const ref_attrs[] = { "nETBIOSName", NULL};
- struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
+ struct ldb_result *dom_res;
+ struct ldb_result *ref_res;
struct ldb_dn *partitions_basedn;
*r->out.resume_handle = 0;
@@ -341,19 +341,18 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
- count = gendb_search(c_state->sam_ctx,
- mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(objectClass=domain)");
- if (count == -1) {
- DEBUG(0,("samdb: no domains found in EnumDomains\n"));
+ ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &dom_res, ldb_get_default_basedn(c_state->sam_ctx),
+ LDB_SCOPE_SUBTREE, dom_attrs, "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- *r->out.resume_handle = count;
+ *r->out.resume_handle = dom_res->count;
start_i = *r->in.resume_handle;
- if (start_i >= count) {
+ if (start_i >= dom_res->count) {
/* search past end of list is not an error for this call */
return NT_STATUS_OK;
}
@@ -366,23 +365,27 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
array->count = 0;
array->entries = NULL;
- array->entries = talloc_array(mem_ctx, struct samr_SamEntry, count - start_i);
+ array->entries = talloc_array(mem_ctx, struct samr_SamEntry, dom_res->count - start_i);
if (array->entries == NULL) {
return NT_STATUS_NO_MEMORY;
}
- for (i=0;i<count-start_i;i++) {
- int ret;
+ for (i=0;i<dom_res->count-start_i;i++) {
array->entries[i].idx = start_i + i;
/* try and find the domain */
- ret = gendb_search(c_state->sam_ctx, mem_ctx, partitions_basedn,
- &ref_msgs, ref_attrs,
- "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(dom_msgs[i]->dn));
- if (ret == 1) {
- array->entries[i].name.string = samdb_result_string(ref_msgs[0], "nETBIOSName", NULL);
+ ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &ref_res, partitions_basedn,
+ LDB_SCOPE_SUBTREE, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))",
+ ldb_dn_get_linearized(dom_res->msgs[i]->dn));
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (ref_res->count == 1) {
+ array->entries[i].name.string = samdb_result_string(ref_res->msgs[0], "nETBIOSName", NULL);
} else {
- array->entries[i].name.string = samdb_result_string(dom_msgs[i], "cn", NULL);
+ array->entries[i].name.string = samdb_result_string(dom_res->msgs[i], "cn", NULL);
}
}
@@ -425,7 +428,7 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
ret = gendb_search(c_state->sam_ctx,
mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(&(objectSid=%s)(&(|(objectclass=domain)(objectClass=builtinDomain))))",
+ "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
if (ret == 0) {
return NT_STATUS_NO_SUCH_DOMAIN;
@@ -472,6 +475,14 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
}
d_state->access_mask = r->in.access_mask;
+ if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+ d_state->builtin = true;
+ } else {
+ d_state->builtin = false;
+ }
+
+ d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+
h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);
if (!h_domain) {
talloc_free(d_state);
@@ -520,6 +531,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo2(struct samr_domain_state *state,
string */
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, dom_msgs[0], "fSMORoleOwner");
+ if (!info->primary.string) {
+ info->primary.string = lp_netbios_name(state->lp_ctx);
+ }
+
info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff",
0x8000000000000000LL);
@@ -614,6 +629,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo6(struct samr_domain_state *state,
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx,
dom_msgs[0], "fSMORoleOwner");
+ if (!info->primary.string) {
+ info->primary.string = lp_netbios_name(state->lp_ctx);
+ }
+
return NT_STATUS_OK;
}
@@ -1004,6 +1023,11 @@ static NTSTATUS dcesrv_samr_CreateDomainGroup(struct dcesrv_call_state *dce_call
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a domain group in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
groupname = r->in.name->string;
if (groupname == NULL) {
@@ -1130,9 +1154,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
if (ldb_cnt == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (ldb_cnt == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to SamEntry format */
entries = talloc_array(mem_ctx, struct samr_SamEntry, ldb_cnt);
@@ -1166,10 +1187,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
first<count && entries[first].idx <= *r->in.resume_handle;
first++) ;
- if (first == count) {
- return NT_STATUS_OK;
- }
-
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
r->out.num_entries = count - first;
@@ -1234,6 +1251,10 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a user in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
account_name = r->in.account_name->string;
if (account_name == NULL) {
@@ -1318,15 +1339,16 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
/* create the user */
ret = ldb_add(d_state->sam_ctx, msg);
switch (ret) {
- case LDB_SUCCESS:
+ case LDB_SUCCESS:
break;
- case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_USER_EXISTS;
- case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ case LDB_ERR_UNWILLING_TO_PERFORM:
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
@@ -1466,8 +1488,8 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
- struct ldb_message **res;
- int count, num_filtered_entries, i, first;
+ struct ldb_result *res;
+ int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
@@ -1479,32 +1501,30 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
d_state = h->data;
- /* search for all users in this domain. This could possibly be cached and
- resumed based on resume_key */
- count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
- "objectclass=user");
- if (count == -1) {
+ /* don't have to worry about users in the builtin domain, as there are none */
+ ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=user");
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(3, ("Failed to search for Domain Users in %s: %s\n",
+ ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (count == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to SamEntry format */
- entries = talloc_array(mem_ctx, struct samr_SamEntry, count);
+ entries = talloc_array(mem_ctx, struct samr_SamEntry, res->count);
if (!entries) {
return NT_STATUS_NO_MEMORY;
}
num_filtered_entries = 0;
- for (i=0;i<count;i++) {
+ for (i=0;i<res->count;i++) {
/* Check if a mask has been requested */
if (r->in.acct_flags
- && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res[i],
+ && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res->msgs[i],
d_state->domain_dn) & r->in.acct_flags) == 0)) {
continue;
}
- entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
- entries[num_filtered_entries].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+ entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res->msgs[i], "objectSid", 0);
+ entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", "");
num_filtered_entries++;
}
@@ -1566,6 +1586,11 @@ static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, T
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a domain alias in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
alias_name = r->in.alias_name->string;
if (alias_name == NULL) {
@@ -2073,7 +2098,8 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
{
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- struct ldb_message *msg, **res;
+ struct ldb_message *msg;
+ struct ldb_result *res;
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
@@ -2083,14 +2109,22 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
a_state = h->data;
+
+ ret = ldb_search_exp_fmt(a_state->sam_ctx, mem_ctx, &res, a_state->account_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=*");
+
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ return NT_STATUS_NO_SUCH_GROUP;
+ } else if (ret != LDB_SUCCESS) {
+ DEBUG(2, ("Error reading group info: %s\n", ldb_errstring(a_state->sam_ctx)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
- /* pull all the group attributes */
- ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- a_state->account_dn, &res, attrs);
- if (ret != 1) {
+ if (res->count != 1) {
+ DEBUG(2, ("Error finding group info, got %d entries\n", res->count));
+
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- msg = res[0];
+ msg = res->msgs[0];
/* allocate the info structure */
r->out.info = talloc(mem_ctx, union samr_GroupInfo);
diff --git a/source4/rpc_server/samr/dcesrv_samr.h b/source4/rpc_server/samr/dcesrv_samr.h
index 7a6978344b..a28a4bec43 100644
--- a/source4/rpc_server/samr/dcesrv_samr.h
+++ b/source4/rpc_server/samr/dcesrv_samr.h
@@ -52,6 +52,8 @@ struct samr_domain_state {
const char *domain_name;
struct ldb_dn *domain_dn;
enum server_role role;
+ bool builtin;
+ struct loadparm_context *lp_ctx;
};
/*
diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c
index 681e3b918f..9993dc14c1 100644
--- a/source4/rpc_server/winreg/rpc_winreg.c
+++ b/source4/rpc_server/winreg/rpc_winreg.c
@@ -26,6 +26,7 @@
#include "rpc_server/common/common.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "param/param.h"
+#include "libcli/security/security.h"
enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
@@ -120,32 +121,39 @@ static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
- /* the security descriptor is optional */
- if (r->in.secdesc != NULL) {
- DATA_BLOB sdblob;
- enum ndr_err_code ndr_err;
- sdblob.data = r->in.secdesc->sd.data;
- sdblob.length = r->in.secdesc->sd.len;
- if (sdblob.data == NULL) {
- return WERR_INVALID_PARAM;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ /* the security descriptor is optional */
+ if (r->in.secdesc != NULL) {
+ DATA_BLOB sdblob;
+ enum ndr_err_code ndr_err;
+ sdblob.data = r->in.secdesc->sd.data;
+ sdblob.length = r->in.secdesc->sd.len;
+ if (sdblob.data == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+ ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
+ (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_INVALID_PARAM;
+ }
}
- ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
- (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- return WERR_INVALID_PARAM;
+
+ error = reg_key_add_name(newh, (struct registry_key *)h->data,
+ r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
+ (struct registry_key **)&newh->data);
+ if (W_ERROR_IS_OK(error)) {
+ r->out.new_handle = &newh->wire_handle;
+ } else {
+ talloc_free(newh);
}
+
+ return error;
+ default:
+ return WERR_ACCESS_DENIED;
}
-
- error = reg_key_add_name(newh, (struct registry_key *)h->data,
- r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
- (struct registry_key **)&newh->data);
- if (W_ERROR_IS_OK(error)) {
- r->out.new_handle = &newh->wire_handle;
- } else {
- talloc_free(newh);
- }
-
- return error;
}
@@ -160,7 +168,14 @@ static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- return reg_key_del((struct registry_key *)h->data, r->in.key.name);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ return reg_key_del((struct registry_key *)h->data, r->in.key.name);
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -176,9 +191,16 @@ static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- key = h->data;
-
- return reg_del_value(key, r->in.value.name);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ key = h->data;
+
+ return reg_del_value(key, r->in.value.name);
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -289,7 +311,14 @@ static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- return reg_key_flush(h->data);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ return reg_key_flush(h->data);
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -342,23 +371,31 @@ static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
- if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
- newh = talloc_reference(dce_call->context, h);
- result = WERR_OK;
- } else {
- newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
- result = reg_open_key(newh, (struct registry_key *)h->data,
- r->in.keyname.name,
- (struct registry_key **)&newh->data);
- }
-
- if (W_ERROR_IS_OK(result)) {
- r->out.handle = &newh->wire_handle;
- } else {
- talloc_free(newh);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ case SECURITY_USER:
+ if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
+ newh = talloc_reference(dce_call->context, h);
+ result = WERR_OK;
+ } else {
+ newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
+ result = reg_open_key(newh, (struct registry_key *)h->data,
+ r->in.keyname.name,
+ (struct registry_key **)&newh->data);
+ }
+
+ if (W_ERROR_IS_OK(result)) {
+ r->out.handle = &newh->wire_handle;
+ } else {
+ talloc_free(newh);
+ }
+ return result;
+ default:
+ return WERR_ACCESS_DENIED;
}
- return result;
}
@@ -376,17 +413,25 @@ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- k = h->data;
-
- ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
- r->out.num_values, r->out.last_changed_time,
- r->out.max_subkeylen, r->out.max_valnamelen,
- r->out.max_valbufsize);
-
- if (r->out.classname != NULL)
- r->out.classname->name = classname;
-
- return ret;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ case SECURITY_USER:
+ k = h->data;
+
+ ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
+ r->out.num_values, r->out.last_changed_time,
+ r->out.max_subkeylen, r->out.max_valnamelen,
+ r->out.max_valbufsize);
+
+ if (r->out.classname != NULL)
+ r->out.classname->name = classname;
+
+ return ret;
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -405,35 +450,43 @@ static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- key = h->data;
-
- result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name.name,
- &value_type, &value_data);
-
- if (!W_ERROR_IS_OK(result)) {
- return result;
- }
-
- /* Just asking for the size of the buffer */
- r->out.type = talloc(mem_ctx, uint32_t);
- if (!r->out.type) {
- return WERR_NOMEM;
- }
- *r->out.type = value_type;
- r->out.length = talloc(mem_ctx, uint32_t);
- if (!r->out.length) {
- return WERR_NOMEM;
- }
- *r->out.length = value_data.length;
- if (r->in.data == NULL) {
- r->out.size = talloc(mem_ctx, uint32_t);
- *r->out.size = value_data.length;
- } else {
- r->out.size = r->in.size;
- r->out.data = value_data.data;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ case SECURITY_USER:
+ key = h->data;
+
+ result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name.name,
+ &value_type, &value_data);
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ /* Just asking for the size of the buffer */
+ r->out.type = talloc(mem_ctx, uint32_t);
+ if (!r->out.type) {
+ return WERR_NOMEM;
+ }
+ *r->out.type = value_type;
+ r->out.length = talloc(mem_ctx, uint32_t);
+ if (!r->out.length) {
+ return WERR_NOMEM;
+ }
+ *r->out.length = value_data.length;
+ if (r->in.data == NULL) {
+ r->out.size = talloc(mem_ctx, uint32_t);
+ *r->out.size = value_data.length;
+ } else {
+ r->out.size = r->in.size;
+ r->out.data = value_data.data;
+ }
+
+ return WERR_OK;
+ default:
+ return WERR_ACCESS_DENIED;
}
-
- return WERR_OK;
}
@@ -497,11 +550,17 @@ static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call,
key = h->data;
- data.data = r->in.data;
- data.length = r->in.size;
- result = reg_val_set(key, r->in.name.name, r->in.type, data);
-
- return result;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ data.data = r->in.data;
+ data.length = r->in.size;
+ result = reg_val_set(key, r->in.name.name, r->in.type, data);
+ return result;
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
diff --git a/source4/script/valgrind_run b/source4/script/valgrind_run
index 45361c22b1..5171d171a7 100755
--- a/source4/script/valgrind_run
+++ b/source4/script/valgrind_run
@@ -4,4 +4,6 @@ ENV="$1"
shift 1
-$ENV valgrind -q --db-attach=yes --num-callers=30 $@
+CMD="$ENV valgrind -q --db-attach=yes --num-callers=30 $@"
+echo $CMD
+eval $CMD
diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4
index 2142cd9abd..3790071ba8 100644
--- a/source4/scripting/python/config.m4
+++ b/source4/scripting/python/config.m4
@@ -22,8 +22,8 @@ AC_DEFUN([TRY_LINK_PYTHON],
CFLAGS="$CFLAGS $2"
AC_TRY_LINK([
+ /* we have our own configure tests */
#include <Python.h>
- #include <stdlib.h>
],[
Py_InitModule(NULL, NULL);
],[
diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c
index f467f851bd..cf85e91e1e 100644
--- a/source4/scripting/python/misc_wrap.c
+++ b/source4/scripting/python/misc_wrap.c
@@ -3027,7 +3027,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE
"ldb context must be non-NULL");
result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3);
if (!W_ERROR_IS_OK(result)) {
- PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+ PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
PyErr_SetObject(PyExc_RuntimeError, obj);
SWIG_fail;
} else if (resultobj == NULL) {
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index ebca1f8e40..e97ce694b4 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -51,7 +51,6 @@ class InvalidNetbiosName(Exception):
class ProvisionPaths:
def __init__(self):
- self.smbconf = None
self.shareconf = None
self.hklm = None
self.hkcu = None
@@ -67,7 +66,27 @@ class ProvisionPaths:
self.dns = None
self.winsdb = None
self.private_dir = None
-
+ self.ldapdir = None
+ self.slapdconf = None
+ self.modulesconf = None
+ self.memberofconf = None
+ self.fedoradsinf = None
+ self.fedoradspartitions = None
+
+class ProvisionNames:
+ def __init__(self):
+ self.rootdn = None
+ self.domaindn = None
+ self.configdn = None
+ self.schemadn = None
+ self.ldapmanagerdn = None
+ self.dnsdomain = None
+ self.realm = None
+ self.netbiosname = None
+ self.domain = None
+ self.hostname = None
+ self.sitename = None
+
class ProvisionResult:
def __init__(self):
self.paths = None
@@ -217,9 +236,20 @@ def provision_paths_from_lp(lp, dnsdomain):
paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
- paths.smbconf = os.path.join(paths.private_dir, "smb.conf")
paths.phpldapadminconfig = os.path.join(paths.private_dir,
"phpldapadmin-config.php")
+ paths.ldapdir = os.path.join(paths.private_dir,
+ "ldap")
+ paths.slapdconf = os.path.join(paths.ldapdir,
+ "slapd.conf")
+ paths.modulesconf = os.path.join(paths.ldapdir,
+ "modules.conf")
+ paths.memberofconf = os.path.join(paths.ldapdir,
+ "memberof.conf")
+ paths.fedoradsinf = os.path.join(paths.ldapdir,
+ "fedorads.inf")
+ paths.fedoradspartitions = os.path.join(paths.ldapdir,
+ "fedorads-partitions.ldif")
paths.hklm = "hklm.ldb"
paths.hkcr = "hkcr.ldb"
paths.hkcu = "hkcu.ldb"
@@ -227,16 +257,145 @@ def provision_paths_from_lp(lp, dnsdomain):
paths.hkpd = "hkpd.ldb"
paths.hkpt = "hkpt.ldb"
- paths.sysvol = lp.get("sysvol", "path")
- if paths.sysvol is None:
- paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol")
+ paths.sysvol = lp.get("path", "sysvol")
- paths.netlogon = lp.get("netlogon", "path")
- if paths.netlogon is None:
- paths.netlogon = os.path.join(os.path.join(paths.sysvol, "scripts"))
+ paths.netlogon = lp.get("path", "netlogon")
return paths
+def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None,
+ rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None):
+
+ if hostname is None:
+ hostname = gethostname().split(".")[0].lower()
+
+ netbiosname = hostname.upper()
+ if not valid_netbios_name(netbiosname):
+ raise InvalidNetbiosName(netbiosname)
+
+ hostname = hostname.lower()
+
+ if dnsdomain is None:
+ dnsdomain = lp.get("realm")
+
+ if serverrole is None:
+ serverrole = lp.get("server role")
+
+ assert dnsdomain is not None
+ realm = dnsdomain.upper()
+
+ if lp.get("realm").upper() != realm:
+ raise Exception("realm '%s' in %s must match chosen realm '%s'" %
+ (lp.get("realm"), smbconf, realm))
+
+ dnsdomain = dnsdomain.lower()
+
+ if (serverrole == "domain controller"):
+ if domain is None:
+ domain = lp.get("workgroup")
+ if domaindn is None:
+ domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
+ if lp.get("workgroup").upper() != domain.upper():
+ raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'",
+ lp.get("workgroup"), domain)
+ else:
+ domain = netbiosname
+ if domaindn is None:
+ domaindn = "CN=" + netbiosname
+
+ assert domain is not None
+ domain = domain.upper()
+ if not valid_netbios_name(domain):
+ raise InvalidNetbiosName(domain)
+
+ if rootdn is None:
+ rootdn = domaindn
+
+ if configdn is None:
+ configdn = "CN=Configuration," + rootdn
+ if schemadn is None:
+ schemadn = "CN=Schema," + configdn
+
+ if sitename is None:
+ sitename=DEFAULTSITE
+
+ names = ProvisionNames()
+ names.rootdn = rootdn
+ names.domaindn = domaindn
+ names.configdn = configdn
+ names.schemadn = schemadn
+ names.ldapmanagerdn = "CN=Manager," + rootdn
+ names.dnsdomain = dnsdomain
+ names.domain = domain
+ names.realm = realm
+ names.netbiosname = netbiosname
+ names.hostname = hostname
+ names.sitename = sitename
+
+ return names
+
+
+def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir):
+ if targetdir is not None:
+ if not os.path.exists(targetdir):
+ os.mkdir(targetdir)
+ if not os.path.exists(os.path.join(targetdir, "etc")):
+ os.mkdir(os.path.join(targetdir, "etc"))
+
+ smbconf = os.path.join(targetdir, "etc", "smb.conf")
+
+ # only install a new smb.conf if there isn't one there already
+
+ if not os.path.exists(smbconf):
+ if hostname is None:
+ hostname = gethostname().split(".")[0].lower()
+
+ if serverrole is None:
+ serverrole = "standalone"
+
+ assert serverrole in ("domain controller", "member server", "standalone")
+ if serverrole == "domain controller":
+ smbconfsuffix = "dc"
+ elif serverrole == "member server":
+ smbconfsuffix = "member"
+ elif serverrole == "standalone":
+ smbconfsuffix = "standalone"
+
+ assert domain is not None
+ assert realm is not None
+
+ default_lp = param.LoadParm()
+ #Load non-existant file
+ default_lp.load(smbconf)
+
+ if targetdir is not None:
+ privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private"))
+ lockdir_line = "lock dir = " + os.path.abspath(targetdir)
+
+ default_lp.set("lock dir", os.path.abspath(targetdir))
+ else:
+ privatedir_line = "private_dir = " + default_lp.get("private dir")
+ lockdir_line = "lock dir = " + default_lp.get("lock dir")
+
+ sysvol = os.path.join(default_lp.get("lock dir"), "sysvol")
+ netlogon = os.path.join(sysvol, realm.lower(), "scripts")
+
+ setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
+ smbconf, {
+ "HOSTNAME": hostname,
+ "DOMAIN": domain,
+ "REALM": realm,
+ "SERVERROLE": serverrole,
+ "NETLOGONPATH": netlogon,
+ "SYSVOLPATH": sysvol,
+ "PRIVATEDIR_LINE": privatedir_line,
+ "LOCKDIR_LINE": lockdir_line
+ })
+
+ lp = param.LoadParm()
+ lp.load(smbconf)
+
+ return lp
def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
wheel, backup):
@@ -279,9 +438,8 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
- credentials, configdn, schemadn, domaindn,
- hostname, netbiosname, dnsdomain, realm,
- rootdn, serverrole, sitename, ldap_backend=None,
+ credentials, names,
+ serverrole, ldap_backend=None,
ldap_backend_type=None, erase=False):
"""Setup the partitions for the SAM database.
@@ -368,12 +526,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
samdb.transaction_start()
try:
setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), {
- "SCHEMADN": schemadn,
+ "SCHEMADN": names.schemadn,
"SCHEMADN_LDB": schemadn_ldb,
"SCHEMADN_MOD2": ",objectguid",
- "CONFIGDN": configdn,
+ "CONFIGDN": names.configdn,
"CONFIGDN_LDB": configdn_ldb,
- "DOMAINDN": domaindn,
+ "DOMAINDN": names.domaindn,
"DOMAINDN_LDB": domaindn_ldb,
"SCHEMADN_MOD": "schema_fsmo,instancetype",
"CONFIGDN_MOD": "naming_fsmo,instancetype",
@@ -399,9 +557,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
message("Setting up sam.ldb rootDSE")
- setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
- dnsdomain, realm, rootdn, configdn, netbiosname,
- sitename)
+ setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname,
+ names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname,
+ names.sitename)
if erase:
message("Erasing data from partitions")
@@ -534,10 +692,10 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
})
-def setup_self_join(samdb, configdn, schemadn, domaindn,
- netbiosname, hostname, dnsdomain, machinepass, dnspass,
- realm, domainname, domainsid, invocationid, setup_path,
- policyguid, sitename, hostguid=None):
+def setup_self_join(samdb, names,
+ machinepass, dnspass,
+ domainsid, invocationid, setup_path,
+ policyguid, hostguid=None):
"""Join a host to its own domain."""
if hostguid is not None:
hostguid_add = "objectGUID: %s" % hostguid
@@ -545,33 +703,32 @@ def setup_self_join(samdb, configdn, schemadn, domaindn,
hostguid_add = ""
setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
- "CONFIGDN": configdn,
- "SCHEMADN": schemadn,
- "DOMAINDN": domaindn,
+ "CONFIGDN": names.configdn,
+ "SCHEMADN": names.schemadn,
+ "DOMAINDN": names.domaindn,
"INVOCATIONID": invocationid,
- "NETBIOSNAME": netbiosname,
- "DEFAULTSITE": sitename,
- "DNSNAME": "%s.%s" % (hostname, dnsdomain),
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain),
"MACHINEPASS_B64": b64encode(machinepass),
"DNSPASS_B64": b64encode(dnspass),
- "REALM": realm,
- "DOMAIN": domainname,
+ "REALM": names.realm,
+ "DOMAIN": names.domain,
"HOSTGUID_ADD": hostguid_add,
- "DNSDOMAIN": dnsdomain})
+ "DNSDOMAIN": names.dnsdomain})
setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), {
"POLICYGUID": policyguid,
- "DNSDOMAIN": dnsdomain,
+ "DNSDOMAIN": names.dnsdomain,
"DOMAINSID": str(domainsid),
- "DOMAINDN": domaindn})
+ "DOMAINDN": names.domaindn})
def setup_samdb(path, setup_path, session_info, credentials, lp,
- schemadn, configdn, domaindn, dnsdomain, realm,
- netbiosname, message, hostname, rootdn,
+ names, message,
domainsid, aci, domainguid, policyguid,
- domainname, fill, adminpass, krbtgtpass,
+ fill, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass,
- serverrole, sitename, ldap_backend=None,
+ serverrole, ldap_backend=None,
ldap_backend_type=None):
"""Setup a complete SAM Database.
@@ -581,14 +738,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
erase = (fill != FILL_DRS)
# Also wipes the database
- setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn,
- domaindn=domaindn, message=message, lp=lp,
+ setup_samdb_partitions(path, setup_path, message=message, lp=lp,
credentials=credentials, session_info=session_info,
- hostname=hostname, netbiosname=netbiosname,
- dnsdomain=dnsdomain, realm=realm, rootdn=rootdn,
+ names=names,
ldap_backend=ldap_backend, serverrole=serverrole,
- ldap_backend_type=ldap_backend_type, erase=erase,
- sitename=sitename)
+ ldap_backend_type=ldap_backend_type, erase=erase)
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
@@ -606,18 +760,24 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
if serverrole == "domain controller":
samdb.set_invocation_id(invocationid)
- load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename)
+ load_schema(setup_path, samdb, names.schemadn, names.netbiosname, names.configdn, names.sitename)
samdb.transaction_start()
try:
- message("Adding DomainDN: %s (permitted to fail)" % domaindn)
+ message("Adding DomainDN: %s (permitted to fail)" % names.domaindn)
+ if serverrole == "domain controller":
+ domain_oc = "domainDNS"
+ else:
+ domain_oc = "samba4LocalDomain"
+
setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
- "DOMAINDN": domaindn,
+ "DOMAINDN": names.domaindn,
"ACI": aci,
+ "DOMAIN_OC": domain_oc
})
- message("Modifying DomainDN: " + domaindn + "")
+ message("Modifying DomainDN: " + names.domaindn + "")
if domainguid is not None:
domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % domainguid
else:
@@ -626,104 +786,102 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), {
"LDAPTIME": timestring(int(time.time())),
"DOMAINSID": str(domainsid),
- "SCHEMADN": schemadn,
- "NETBIOSNAME": netbiosname,
- "DEFAULTSITE": sitename,
- "CONFIGDN": configdn,
+ "SCHEMADN": names.schemadn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "CONFIGDN": names.configdn,
"POLICYGUID": policyguid,
- "DOMAINDN": domaindn,
+ "DOMAINDN": names.domaindn,
"DOMAINGUID_MOD": domainguid_mod,
})
message("Adding configuration container (permitted to fail)")
setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), {
- "CONFIGDN": configdn,
+ "CONFIGDN": names.configdn,
"ACI": aci,
"EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb",
})
message("Modifying configuration container")
setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), {
- "CONFIGDN": configdn,
- "SCHEMADN": schemadn,
+ "CONFIGDN": names.configdn,
+ "SCHEMADN": names.schemadn,
})
message("Adding schema container (permitted to fail)")
setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), {
- "SCHEMADN": schemadn,
+ "SCHEMADN": names.schemadn,
"ACI": aci,
"EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb"
})
message("Modifying schema container")
setup_modify_ldif(samdb,
setup_path("provision_schema_basedn_modify.ldif"), {
- "SCHEMADN": schemadn,
- "NETBIOSNAME": netbiosname,
- "DEFAULTSITE": sitename,
- "CONFIGDN": configdn,
+ "SCHEMADN": names.schemadn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "CONFIGDN": names.configdn,
})
message("Setting up sam.ldb Samba4 schema")
setup_add_ldif(samdb, setup_path("schema_samba4.ldif"),
- {"SCHEMADN": schemadn })
+ {"SCHEMADN": names.schemadn })
message("Setting up sam.ldb AD schema")
setup_add_ldif(samdb, setup_path("schema.ldif"),
- {"SCHEMADN": schemadn})
+ {"SCHEMADN": names.schemadn})
message("Setting up sam.ldb configuration data")
setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
- "CONFIGDN": configdn,
- "NETBIOSNAME": netbiosname,
- "DEFAULTSITE": sitename,
- "DNSDOMAIN": dnsdomain,
- "DOMAIN": domainname,
- "SCHEMADN": schemadn,
- "DOMAINDN": domaindn,
+ "CONFIGDN": names.configdn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "DNSDOMAIN": names.dnsdomain,
+ "DOMAIN": names.domain,
+ "SCHEMADN": names.schemadn,
+ "DOMAINDN": names.domaindn,
})
message("Setting up display specifiers")
setup_add_ldif(samdb, setup_path("display_specifiers.ldif"),
- {"CONFIGDN": configdn})
+ {"CONFIGDN": names.configdn})
message("Adding users container (permitted to fail)")
setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), {
- "DOMAINDN": domaindn})
+ "DOMAINDN": names.domaindn})
message("Modifying users container")
setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), {
- "DOMAINDN": domaindn})
+ "DOMAINDN": names.domaindn})
message("Adding computers container (permitted to fail)")
setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), {
- "DOMAINDN": domaindn})
+ "DOMAINDN": names.domaindn})
message("Modifying computers container")
setup_modify_ldif(samdb, setup_path("provision_computers_modify.ldif"), {
- "DOMAINDN": domaindn})
+ "DOMAINDN": names.domaindn})
message("Setting up sam.ldb data")
setup_add_ldif(samdb, setup_path("provision.ldif"), {
- "DOMAINDN": domaindn,
- "NETBIOSNAME": netbiosname,
- "DEFAULTSITE": sitename,
- "CONFIGDN": configdn,
+ "DOMAINDN": names.domaindn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": names.sitename,
+ "CONFIGDN": names.configdn,
})
if fill == FILL_FULL:
message("Setting up sam.ldb users and groups")
setup_add_ldif(samdb, setup_path("provision_users.ldif"), {
- "DOMAINDN": domaindn,
+ "DOMAINDN": names.domaindn,
"DOMAINSID": str(domainsid),
- "CONFIGDN": configdn,
+ "CONFIGDN": names.configdn,
"ADMINPASS_B64": b64encode(adminpass),
"KRBTGTPASS_B64": b64encode(krbtgtpass),
})
if serverrole == "domain controller":
message("Setting up self join")
- setup_self_join(samdb, configdn=configdn, schemadn=schemadn,
- domaindn=domaindn, invocationid=invocationid,
- dnspass=dnspass, netbiosname=netbiosname,
- dnsdomain=dnsdomain, realm=realm,
- machinepass=machinepass, domainname=domainname,
+ setup_self_join(samdb, names=names, invocationid=invocationid,
+ dnspass=dnspass,
+ machinepass=machinepass,
domainsid=domainsid, policyguid=policyguid,
- hostname=hostname, hostguid=hostguid,
- setup_path=setup_path, sitename=sitename)
+ hostguid=hostguid,
+ setup_path=setup_path)
#We want to setup the index last, as adds are faster unindexed
message("Setting up sam.ldb index")
@@ -748,7 +906,7 @@ def provision(setup_dir, message, session_info,
policyguid=None, invocationid=None, machinepass=None,
dnspass=None, root=None, nobody=None, nogroup=None, users=None,
wheel=None, backup=None, aci=None, serverrole=None,
- ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
+ ldap_backend=None, ldap_backend_type=None, sitename=None):
"""Provision samba4
:note: caution, this wipes all existing data!
@@ -759,6 +917,9 @@ def provision(setup_dir, message, session_info,
if domainsid is None:
domainsid = security.random_sid()
+ else:
+ domainsid = security.Sid(domainsid)
+
if policyguid is None:
policyguid = uuid.random()
if adminpass is None:
@@ -784,129 +945,37 @@ def provision(setup_dir, message, session_info,
backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0]
if aci is None:
aci = "# no aci for local ldb"
- if hostname is None:
- hostname = gethostname().split(".")[0].lower()
-
- if hostip is None:
- hostip = gethostbyname(hostname)
-
- netbiosname = hostname.upper()
- if not valid_netbios_name(netbiosname):
- raise InvalidNetbiosName(netbiosname)
- if targetdir is not None:
- if not os.path.exists(targetdir):
- os.mkdir(targetdir)
- if not os.path.exists(os.path.join(targetdir, "etc")):
- os.mkdir(os.path.join(targetdir, "etc"))
-
- smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf"))
-
- # only install a new smb.conf if there isn't one there already
-
- if not os.path.exists(smbconf):
- message("Setting up smb.conf")
- if serverrole is None:
- serverrole = "standalone"
-
- assert serverrole in ("domain controller", "member server", "standalone")
- if serverrole == "domain controller":
- smbconfsuffix = "dc"
- elif serverrole == "member server":
- smbconfsuffix = "member"
- elif serverrole == "standalone":
- smbconfsuffix = "standalone"
+ lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir)
- assert domain is not None
- assert realm is not None
+ names = guess_names(lp=lp, hostname=hostname, domain=domain,
+ dnsdomain=realm, serverrole=serverrole, sitename=sitename,
+ rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn)
- default_lp = param.LoadParm()
- #Load non-existant file
- default_lp.load(smbconf)
-
- if targetdir is not None:
- privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private"))
- lockdir_line = "lock dir = " + os.path.abspath(targetdir)
+ paths = provision_paths_from_lp(lp, names.dnsdomain)
- default_lp.set("lock dir", os.path.abspath(targetdir))
-
- sysvol = os.path.join(default_lp.get("lock dir"), "sysvol")
- netlogon = os.path.join(os.path.join(sysvol, "scripts"))
-
- setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
- smbconf, {
- "HOSTNAME": hostname,
- "DOMAIN": domain,
- "REALM": realm,
- "SERVERROLE": serverrole,
- "NETLOGONPATH": netlogon,
- "SYSVOLPATH": sysvol,
- "PRIVATEDIR_LINE": privatedir_line,
- "LOCKDIR_LINE": lockdir_line
- })
-
- lp = param.LoadParm()
- lp.load(smbconf)
+ if hostip is None:
+ hostip = gethostbyname(names.hostname)
if serverrole is None:
serverrole = lp.get("server role")
+
assert serverrole in ("domain controller", "member server", "standalone")
if invocationid is None and serverrole == "domain controller":
invocationid = uuid.random()
- if realm is None:
- realm = lp.get("realm")
-
- assert realm is not None
- realm = realm.upper()
-
- if lp.get("realm").upper() != realm.upper():
- raise Exception("realm '%s' in %s must match chosen realm '%s'" %
- (lp.get("realm"), smbconf, realm))
-
- dnsdomain = realm.lower()
-
- paths = provision_paths_from_lp(lp, dnsdomain)
-
- if targetdir is not None:
- if not os.path.exists(paths.private_dir):
- os.mkdir(paths.private_dir)
+ if not os.path.exists(paths.private_dir):
+ os.mkdir(paths.private_dir)
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
- if ldap_backend == "ldapi":
- # provision-backend will set this path suggested slapd command line / fedorads.inf
- ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="")
-
- if serverrole == "domain controller":
- if domaindn is None:
- domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
- if domain is None:
- domain = lp.get("workgroup")
-
- if lp.get("workgroup").upper() != domain.upper():
- raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'",
- lp.get("workgroup"), domain)
-
- assert domain is not None
- domain = domain.upper()
- if not valid_netbios_name(domain):
- raise InvalidNetbiosName(domain)
- else:
- if domaindn is None:
- domaindn = "CN=" + netbiosname
- domain = netbiosname
-
- if rootdn is None:
- rootdn = domaindn
-
- if configdn is None:
- configdn = "CN=Configuration," + rootdn
- if schemadn is None:
- schemadn = "CN=Schema," + configdn
-
+ if ldap_backend is not None:
+ if ldap_backend == "ldapi":
+ # provision-backend will set this path suggested slapd command line / fedorads.inf
+ ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="")
+
message("set DOMAIN SID: %s" % str(domainsid))
- message("Provisioning for %s in realm %s" % (domain, realm))
+ message("Provisioning for %s in realm %s" % (names.domain, realm))
message("Using administrator password: %s" % adminpass)
# only install a new shares config db if there is none
@@ -935,21 +1004,19 @@ def provision(setup_dir, message, session_info,
credentials=credentials, lp=lp)
samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info,
- credentials=credentials, lp=lp, schemadn=schemadn,
- configdn=configdn, domaindn=domaindn,
- dnsdomain=dnsdomain, netbiosname=netbiosname,
- realm=realm, message=message, hostname=hostname,
- rootdn=rootdn, domainsid=domainsid,
+ credentials=credentials, lp=lp, names=names,
+ message=message,
+ domainsid=domainsid,
aci=aci, domainguid=domainguid, policyguid=policyguid,
- domainname=domain, fill=samdb_fill,
+ fill=samdb_fill,
adminpass=adminpass, krbtgtpass=krbtgtpass,
hostguid=hostguid, invocationid=invocationid,
machinepass=machinepass, dnspass=dnspass,
serverrole=serverrole, ldap_backend=ldap_backend,
- ldap_backend_type=ldap_backend_type, sitename=sitename)
+ ldap_backend_type=ldap_backend_type)
if lp.get("server role") == "domain controller":
- policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies",
+ policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies",
"{" + policyguid + "}")
os.makedirs(policy_path, 0755)
os.makedirs(os.path.join(policy_path, "Machine"), 0755)
@@ -958,14 +1025,14 @@ def provision(setup_dir, message, session_info,
os.makedirs(paths.netlogon, 0755)
secrets_ldb = Ldb(paths.secrets, session_info=session_info,
credentials=credentials, lp=lp)
- secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm,
- netbiosname=netbiosname, domainsid=domainsid,
+ secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm,
+ netbiosname=names.netbiosname, domainsid=domainsid,
keytab_path=paths.keytab, samdb_url=paths.samdb,
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
- machinepass=machinepass, dnsdomain=dnsdomain)
+ machinepass=machinepass, dnsdomain=names.dnsdomain)
if samdb_fill == FILL_FULL:
- setup_name_mappings(samdb, str(domainsid), domaindn, root=root,
+ setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root,
nobody=nobody, nogroup=nogroup, wheel=wheel,
users=users, backup=backup)
@@ -980,14 +1047,14 @@ def provision(setup_dir, message, session_info,
domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
assert isinstance(domainguid, str)
hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID",
- expression="(&(objectClass=computer)(cn=%s))" % hostname,
+ expression="(&(objectClass=computer)(cn=%s))" % names.hostname,
scope=SCOPE_SUBTREE)
assert isinstance(hostguid, str)
- message("Setting up DNS zone: %s" % dnsdomain)
+ message("Setting up DNS zone: %s" % names.dnsdomain)
create_zone_file(paths.dns, setup_path, samdb,
- hostname=hostname, hostip=hostip, dnsdomain=dnsdomain,
- domaindn=domaindn, dnspass=dnspass, realm=realm,
+ hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain,
+ domaindn=names.domaindn, dnspass=dnspass, realm=names.realm,
domainguid=domainguid, hostguid=hostguid)
message("Please install the zone located in %s into your DNS server" % paths.dns)
@@ -1024,6 +1091,149 @@ def provision_become_dc(setup_dir=None,
domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename);
+def setup_db_config(setup_path, file, dbdir):
+ if not os.path.isdir(os.path.join(dbdir, "bdb-logs")):
+ os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700);
+ if not os.path.isdir(os.path.join(dbdir, "tmp")):
+ os.makedirs(os.path.join(dbdir, "tmp"), 0700);
+
+ setup_file(setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"),
+ {"LDAPDBDIR": dbdir})
+
+
+
+def provision_backend(setup_dir=None, message=None,
+ smbconf=None, targetdir=None, realm=None,
+ rootdn=None, domaindn=None, schemadn=None, configdn=None,
+ domain=None, hostname=None, adminpass=None, root=None, serverrole=None,
+ ldap_backend_type=None):
+
+ def setup_path(file):
+ return os.path.join(setup_dir, file)
+
+ if hostname is None:
+ hostname = gethostname().split(".")[0].lower()
+
+ if root is None:
+ root = findnss(pwd.getpwnam, ["root"])[0]
+
+ lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir)
+
+ names = guess_names(lp=lp, hostname=hostname, domain=domain,
+ dnsdomain=realm, serverrole=serverrole,
+ rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn)
+
+ paths = provision_paths_from_lp(lp, names.dnsdomain)
+
+ if not os.path.isdir(paths.ldapdir):
+ os.makedirs(paths.ldapdir)
+ schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb")
+ try:
+ os.unlink(schemadb_path)
+ except:
+ pass
+
+ schemadb = Ldb(schemadb_path, lp=lp)
+
+ setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"),
+ {"SCHEMADN": names.schemadn,
+ "ACI": "#",
+ "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb"
+ })
+ setup_modify_ldif(schemadb,
+ setup_path("provision_schema_basedn_modify.ldif"), \
+ {"SCHEMADN": names.schemadn,
+ "NETBIOSNAME": names.netbiosname,
+ "DEFAULTSITE": DEFAULTSITE,
+ "CONFIGDN": names.configdn,
+ })
+
+ setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"),
+ {"SCHEMADN": names.schemadn })
+ setup_add_ldif(schemadb, setup_path("schema.ldif"),
+ {"SCHEMADN": names.schemadn})
+
+ if ldap_backend_type == "fedora-ds":
+ setup_file(setup_path("fedora-ds.inf"), paths.fedoradsinf,
+ {"ROOT": root,
+ "HOSTNAME": hostname,
+ "DNSDOMAIN": names.dnsdomain,
+ "LDAPDIR": paths.ldapdir,
+ "DOMAINDN": names.domaindn,
+ "LDAPMANAGERDN": names.ldapmanagerdn,
+ "LDAPMANAGERPASS": adminpass,
+ "SERVERPORT": ""})
+
+ setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions,
+ {"CONFIGDN": names.configdn,
+ "SCHEMADN": names.schemadn,
+ })
+
+ setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions,
+ {"CONFIGDN": names.configdn,
+ "SCHEMADN": names.schemadn,
+ })
+ mapping = "schema-map-fedora-ds-1.0"
+ backend_schema = "99_ad.ldif"
+ elif ldap_backend_type == "openldap":
+ attrs = ["linkID", "lDAPDisplayName"]
+ res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs);
+
+ memberof_config = "# Generated from schema in " + schemadb_path + "\n";
+ refint_attributes = "";
+ for i in range (0, len(res)):
+ linkid = res[i]["linkID"][0]
+ linkid = str(int(linkid) + 1)
+ expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))"
+ target = schemadb.searchone(basedn=names.schemadn,
+ expression=expression,
+ attribute="lDAPDisplayName",
+ scope=SCOPE_SUBTREE);
+ if target is not None:
+ refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0];
+ memberof_config = memberof_config + """overlay memberof
+memberof-dangling error
+memberof-refint TRUE
+memberof-group-oc top
+memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """
+memberof-memberof-ad """ + target + """
+memberof-dangling-error 32
+
+""";
+
+ memberof_config = memberof_config + """
+overlay refint
+refint_attributes""" + refint_attributes + "\n";
+
+ setup_file(setup_path("slapd.conf"), paths.slapdconf,
+ {"DNSDOMAIN": names.dnsdomain,
+ "LDAPDIR": paths.ldapdir,
+ "DOMAINDN": names.domaindn,
+ "CONFIGDN": names.configdn,
+ "SCHEMADN": names.schemadn,
+ "LDAPMANAGERDN": names.ldapmanagerdn,
+ "LDAPMANAGERPASS": adminpass,
+ "MEMBEROF_CONFIG": memberof_config})
+ setup_file(setup_path("modules.conf"), paths.modulesconf,
+ {"REALM": names.realm})
+
+ setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user"))
+ setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config"))
+ setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema"))
+ mapping = "schema-map-openldap-2.3"
+ backend_schema = "backend-schema.schema"
+
+
+ ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="")
+ message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri)
+
+
+ schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema);
+
+ os.system(schema_command)
+
+
+
def create_phpldapadmin_config(path, setup_path, ldapi_uri):
"""Create a PHP LDAP admin configuration file.
diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c
index e05b286dd0..cd9a1cb4d5 100644
--- a/source4/scripting/python/uuidmodule.c
+++ b/source4/scripting/python/uuidmodule.c
@@ -24,6 +24,7 @@
static PyObject *uuid_random(PyObject *self, PyObject *args)
{
struct GUID guid;
+ PyObject *pyobj;
char *str;
if (!PyArg_ParseTuple(args, (char *)""))
@@ -37,9 +38,11 @@ static PyObject *uuid_random(PyObject *self, PyObject *args)
return NULL;
}
+ pyobj = PyString_FromString(str);
+
talloc_free(str);
- return PyString_FromString(str);
+ return pyobj;
}
static PyMethodDef methods[] = {
diff --git a/source4/selftest/output/plain.pm b/source4/selftest/output/plain.pm
index e491a999ab..25ff74792e 100644
--- a/source4/selftest/output/plain.pm
+++ b/source4/selftest/output/plain.pm
@@ -7,8 +7,6 @@ use Exporter;
use FindBin qw($RealBin);
use lib "$RealBin/..";
-use Subunit qw(parse_results);
-
use strict;
sub new($$$$$$$) {
@@ -62,7 +60,9 @@ sub output_msg($$)
my ($self, $output) = @_;
if ($self->{verbose}) {
+ require FileHandle;
print $output;
+ STDOUT->flush();
} else {
$self->{test_output}->{$self->{NAME}} .= $output;
}
diff --git a/source4/selftest/selftest.pl b/source4/selftest/selftest.pl
index 73d03f3d4c..39a1b5a450 100755
--- a/source4/selftest/selftest.pl
+++ b/source4/selftest/selftest.pl
@@ -584,7 +584,7 @@ push (@torture_options, "--configfile=$conffile");
push (@torture_options, "--maximum-runtime=$torture_maxtime");
push (@torture_options, "--target=$opt_target");
push (@torture_options, "--basedir=$prefix_abs");
-push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
+push (@torture_options, "--option=torture:progress=no") unless ($opt_verbose);
push (@torture_options, "--format=subunit");
push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
diff --git a/source4/selftest/target/Samba4.pm b/source4/selftest/target/Samba4.pm
index 48fda17599..262c8035f6 100644
--- a/source4/selftest/target/Samba4.pm
+++ b/source4/selftest/target/Samba4.pm
@@ -544,7 +544,7 @@ sub provision($$$$$$)
my $localbasedn = $basedn;
- $localbasedn = "DC=$netbiosname" if $server_role eq "member server";
+ $localbasedn = "CN=$netbiosname" if $server_role eq "member server";
open(CONFFILE, ">$conffile");
print CONFFILE "
@@ -577,9 +577,6 @@ sub provision($$$$$$)
gensec:require_pac = true
log level = $smbd_loglevel
- # this is a global option
- opendb:oplocks = yes
-
[tmp]
path = $tmpdir
read only = no
@@ -617,6 +614,14 @@ sub provision($$$$$$)
read only = no
ntvfs handler = simple
+[sysvol]
+ path = $lockdir/sysvol
+ read only = yes
+
+[netlogon]
+ path = $lockdir/sysvol/$dnsname/scripts
+ read only = no
+
[cifsposix]
copy = simple
ntvfs handler = cifsposix
@@ -746,7 +751,7 @@ nogroup:x:65534:nobody
if (defined($self->{ldap})) {
push (@provision_options, "--ldap-backend=$ldap_uri");
- system("$self->{bindir}/smbscript $self->{setupdir}/provision-backend $configuration --ldap-manager-pass=$password --root=$unix_name --realm=$realm --host-name=$netbiosname --ldap-backend-type=$self->{ldap}>&2") == 0 or die("backend provision failed");
+ system("$self->{bindir}/smbpython $self->{setupdir}/provision-backend $configuration --ldap-manager-pass=$password --root=$unix_name --realm=$realm --domain=$domain --host-name=$netbiosname --ldap-backend-type=$self->{ldap}>&2") == 0 or die("backend provision failed");
if ($self->{ldap} eq "openldap") {
($ret->{SLAPD_CONF}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ldapdir, $configuration) or die("Unable to create openldap directories");
diff --git a/source4/setup/newuser b/source4/setup/newuser
index 7c80e9e8de..03ae4e5ffb 100755
--- a/source4/setup/newuser
+++ b/source4/setup/newuser
@@ -1,80 +1,61 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-/*
- add a new user to a Samba4 server
- Copyright Andrew Tridgell 2005
- Released under the GNU GPL v2 or later
-*/
-
-options = GetOptions(ARGV,
- "POPT_AUTOHELP",
- 'username=s',
- 'unixname=s',
- 'password=s',
- "POPT_COMMON_SAMBA",
- "POPT_COMMON_VERSION",
- "POPT_COMMON_CREDENTIALS",
- 'quiet');
-
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-libinclude("base.js");
-libinclude("provision.js");
-
-/*
- print a message if quiet is not set
-*/
-function message()
-{
- if (options["quiet"] == undefined) {
- print(vsprintf(arguments));
- }
-}
-
-/*
- show some help
-*/
-function ShowHelp()
-{
- print("
-Samba4 newuser
-
-newuser [options]
- --username USERNAME choose new username
- --unixname USERNAME choose unix name of new user
- --password PASSWORD set password
-
-You must provide at least a username
-");
- exit(1);
-}
-
-if (options['username'] == undefined) {
- ShowHelp();
-}
-
-if (options['password'] == undefined) {
- random_init(local);
- options.password = randpass(12);
- printf("chose random password %s\n", options.password);
-}
-if (options['unixname'] == undefined) {
- options.unixname = options.username;
-}
-
-var nss = nss_init();
-if (nss.getpwnam(options.unixname) == undefined) {
- printf("ERROR: Unix user '%s' does not exist\n", options.unixname);
- exit(1);
-}
-
-var creds = options.get_credentials();
-var system_session = system_session();
-
-
-newuser(options.username, options.unixname, options.password, message, system_session, creds);
-
-return 0;
+#!/usr/bin/python
+#
+# add a new user to a Samba4 server
+# Copyright Andrew Tridgell 2005
+# Copyright Jelmer Vernooij 2008
+# Released under the GNU GPL v2 or later
+#
+
+import samba.getopt as options
+import optparse
+import pwd
+import sys
+
+from auth import system_session
+from samba.samdb import SamDB
+
+parser = optparse.OptionParser("newuser [options] <username> [<password>]")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option("--quiet", help="Be quiet", action="store_true")
+parser.add_option("--unixname", help="Unix Username", type=str)
+
+opts, args = parser.parse_args()
+
+#
+# print a message if quiet is not set
+#
+def message(text):
+ if not opts.quiet:
+ print text
+
+if len(args) == 0:
+ parser.print_usage()
+ sys.exit(1)
+
+username = args[0]
+if len(args) > 1:
+ password = args[1]
+else:
+ random_init(local)
+ options.password = randpass(12)
+ print "chose random password %s\n" % password
+
+if opts.unixname is None:
+ opts.unixname = username
+
+try:
+ pwd.getpwnam(opts.unixname)
+except KeyError:
+ print "ERROR: Unix user '%s' does not exist" % opts.unixname
+ sys.exit(1)
+
+creds = credopts.get_credentials()
+
+lp = sambaopts.get_loadparm()
+samdb = SamDB(url=lp.get("sam database"), session_info=system_session(),
+ credentials=creds, lp=lp)
+samdb.newuser(username, opts.unixname, password)
diff --git a/source4/setup/newuser.py b/source4/setup/newuser.py
deleted file mode 100755
index 03ae4e5ffb..0000000000
--- a/source4/setup/newuser.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/python
-#
-# add a new user to a Samba4 server
-# Copyright Andrew Tridgell 2005
-# Copyright Jelmer Vernooij 2008
-# Released under the GNU GPL v2 or later
-#
-
-import samba.getopt as options
-import optparse
-import pwd
-import sys
-
-from auth import system_session
-from samba.samdb import SamDB
-
-parser = optparse.OptionParser("newuser [options] <username> [<password>]")
-sambaopts = options.SambaOptions(parser)
-parser.add_option_group(sambaopts)
-parser.add_option_group(options.VersionOptions(parser))
-credopts = options.CredentialsOptions(parser)
-parser.add_option_group(credopts)
-parser.add_option("--quiet", help="Be quiet", action="store_true")
-parser.add_option("--unixname", help="Unix Username", type=str)
-
-opts, args = parser.parse_args()
-
-#
-# print a message if quiet is not set
-#
-def message(text):
- if not opts.quiet:
- print text
-
-if len(args) == 0:
- parser.print_usage()
- sys.exit(1)
-
-username = args[0]
-if len(args) > 1:
- password = args[1]
-else:
- random_init(local)
- options.password = randpass(12)
- print "chose random password %s\n" % password
-
-if opts.unixname is None:
- opts.unixname = username
-
-try:
- pwd.getpwnam(opts.unixname)
-except KeyError:
- print "ERROR: Unix user '%s' does not exist" % opts.unixname
- sys.exit(1)
-
-creds = credopts.get_credentials()
-
-lp = sambaopts.get_loadparm()
-samdb = SamDB(url=lp.get("sam database"), session_info=system_session(),
- credentials=creds, lp=lp)
-samdb.newuser(username, opts.unixname, password)
diff --git a/source4/setup/provision b/source4/setup/provision
index 629bfa10e0..b0363d8a8f 100755
--- a/source4/setup/provision
+++ b/source4/setup/provision
@@ -27,6 +27,7 @@ import optparse
import os, sys
import samba
+import param
from auth import system_session
import samba.getopt as options
@@ -110,7 +111,7 @@ if opts.realm is None or opts.domain is None:
parser.print_usage()
sys.exit(1)
-smbconf = sambaopts.get_loadparm_path()
+smbconf = sambaopts.get_loadparm().configfile()
if opts.aci is not None:
print "set ACI: %s" % opts.aci
diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend
index abd1b9a875..ada6dcef8d 100755
--- a/source4/setup/provision-backend
+++ b/source4/setup/provision-backend
@@ -1,189 +1,98 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-/*
- provision a Samba4 server
- Copyright Andrew Tridgell 2005
- Released under the GNU GPL v2 or later
-*/
-
-options = GetOptions(ARGV,
- "POPT_AUTOHELP",
- "POPT_COMMON_SAMBA",
- "POPT_COMMON_VERSION",
- "POPT_COMMON_CREDENTIALS",
- 'realm=s',
- 'host-name=s',
- 'ldap-manager-pass=s',
- 'root=s',
- 'quiet',
- 'ldap-backend-type=s',
- 'ldap-backend-port=i');
-
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-sys = sys_init();
-
-libinclude("base.js");
-libinclude("provision.js");
-
-/*
- print a message if quiet is not set
-*/
-function message()
-{
- if (options["quiet"] == undefined) {
- print(vsprintf(arguments));
- }
-}
-
-/*
- show some help
-*/
-function ShowHelp()
-{
- print("
-Samba4 provisioning
-
-provision [options]
- --realm REALM set realm
- --host-name HOSTNAME set hostname
- --ldap-manager-pass PASSWORD choose LDAP Manager password (otherwise random)
- --root USERNAME choose 'root' unix username
- --quiet Be quiet
- --ldap-backend-type LDAPSERVER Select either \"openldap\" or \"fedora-ds\" as a target to configure
- --ldap-backend-port PORT Select the TCP port (if any) that the LDAP backend should listen on (Fedora DS only)
-You must provide at least a realm and ldap-backend-type
-
-");
- exit(1);
-}
-
-if (options['host-name'] == undefined) {
- options['host-name'] = hostname();
-}
-
-/*
- main program
-*/
-if (options["realm"] == undefined ||
- options["ldap-backend-type"] == undefined ||
- options["host-name"] == undefined) {
- ShowHelp();
-}
-
-/* cope with an initially blank smb.conf */
-var lp = loadparm_init();
-lp.set("realm", options.realm);
-lp.reload();
-
-var subobj = provision_guess();
-for (r in options) {
- var key = strupper(join("", split("-", r)));
- subobj[key] = options[r];
-}
-
-
-
-var paths = provision_default_paths(subobj);
-provision_fix_subobj(subobj, paths);
-message("Provisioning LDAP backend for %s in realm %s into %s\n", subobj.HOSTNAME, subobj.REALM, subobj.LDAPDIR);
-message("Using %s password: %s\n", subobj.LDAPMANAGERDN, subobj.LDAPMANAGERPASS);
-var tmp_schema_ldb = subobj.LDAPDIR + "/schema-tmp.ldb";
-sys.mkdir(subobj.LDAPDIR, 0700);
-
-provision_schema(subobj, message, tmp_schema_ldb, paths);
-
-var mapping;
-var backend_schema;
-var slapd_command;
-if (options["ldap-backend-type"] == "fedora-ds") {
- mapping = "schema-map-fedora-ds-1.0";
- backend_schema = "99_ad.ldif";
- if (options["ldap-backend-port"] != undefined) {
- message("Will listen on TCP port " + options["ldap-backend-port"] + "\n");
- subobj.SERVERPORT="ServerPort = " + options["ldap-backend-port"];
- } else {
- message("Will listen on LDAPI only\n");
- subobj.SERVERPORT="";
- }
- setup_file("fedorads.inf", message, subobj.LDAPDIR + "/fedorads.inf", subobj);
- setup_file("fedorads-partitions.ldif", message, subobj.LDAPDIR + "/fedorads-partitions.ldif", subobj);
-
- slapd_command = "(see documentation)";
-} else if (options["ldap-backend-type"] == "openldap") {
- mapping = "schema-map-openldap-2.3";
- backend_schema = "backend-schema.schema";
- setup_file("slapd.conf", message, subobj.LDAPDIR + "/slapd.conf", subobj);
- setup_file("modules.conf", message, subobj.LDAPDIR + "/modules.conf", subobj);
- sys.mkdir(subobj.LDAPDIR + "/db", 0700);
- subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/user";
- sys.mkdir(subobj.LDAPDBDIR, 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
- setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
- subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/config";
- sys.mkdir(subobj.LDAPDBDIR, 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
- setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
- subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/schema";
- sys.mkdir(subobj.LDAPDBDIR, 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
- sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
- setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
- if (options["ldap-backend-port"] != undefined) {
- message("\nStart slapd with: \n");
- slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h \"ldap://0.0.0.0:" + options["ldap-backend-port"] + " " + subobj.LDAPI_URI "\"";
- } else {
- slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h " + subobj.LDAPI_URI;
- }
-
- var ldb = ldb_init();
- ldb.filename = tmp_schema_ldb;
-
- var connect_ok = ldb.connect(ldb.filename);
- assert(connect_ok);
- var attrs = new Array("linkID", "lDAPDisplayName");
- var res = ldb.search("(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", subobj.SCHEMADN, ldb.SCOPE_SUBTREE, attrs);
- assert(res.error == 0);
- var memberof_config = "";
- var refint_attributes = "";
- for (i=0; i < res.msgs.length; i++) {
-searchone(ldb, subobj.DOMAINDN, "(&(objectClass=computer)(cn=" + subobj.NETBIOSNAME + "))", "objectGUID");
- var target = searchone(ldb, subobj.SCHEMADN, "(&(objectclass=attributeSchema)(linkID=" + (res.msgs[i].linkID + 1) + "))", "lDAPDisplayName");
- if (target != undefined) {
- refint_attributes = refint_attributes + " " + target + " " + res.msgs[i].lDAPDisplayName;
- memberof_config = memberof_config + "overlay memberof
-memberof-dangling error
-memberof-refint TRUE
-memberof-group-oc top
-memberof-member-ad " + res.msgs[i].lDAPDisplayName + "
-memberof-memberof-ad " + target + "
-memberof-dangling-error 32
-
-";
- }
- }
-
- memberof_config = memberof_config + "
-overlay refint
-refint_attributes" + refint_attributes + "
-";
-
- ok = sys.file_save(subobj.LDAPDIR + "/memberof.conf", memberof_config);
- if (!ok) {
- message("failed to create file: " + f + "\n");
- assert(ok);
- }
-
-}
-var schema_command = "ad2oLschema --option=convert:target=" + options["ldap-backend-type"] + " -I " + lp.get("setup directory") + "/" + mapping + " -H tdb://" + tmp_schema_ldb + " -O " + subobj.LDAPDIR + "/" + backend_schema;
-
-message("\nCreate a suitable schema file with:\n%s\n", schema_command);
-message("\nStart slapd with: \n%s\n", slapd_command);
-
-message("All OK\n");
-return 0;
+#!/usr/bin/python
+#
+# Unix SMB/CIFS implementation.
+# provision a Samba4 server
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+#
+# Based on the original in EJS:
+# Copyright (C) Andrew Tridgell 2005
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import getopt
+import optparse
+import os, sys
+
+import samba
+import param
+
+from auth import system_session
+import samba.getopt as options
+from samba.provision import (provision_backend)
+
+parser = optparse.OptionParser("provision [options]")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option("--setupdir", type="string", metavar="DIR",
+ help="directory with setup files")
+parser.add_option("--realm", type="string", metavar="REALM", help="set realm")
+parser.add_option("--domain", type="string", metavar="DOMAIN",
+ help="set domain")
+parser.add_option("--host-name", type="string", metavar="HOSTNAME",
+ help="set hostname")
+parser.add_option("--ldap-manager-pass", type="string", metavar="PASSWORD",
+ help="choose LDAP manager password (otherwise random)")
+parser.add_option("--root", type="string", metavar="USERNAME",
+ help="choose 'root' unix username")
+parser.add_option("--quiet", help="Be quiet", action="store_true")
+parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TYPE",
+ help="LDB mapping module to use for the LDAP backend",
+ choices=["fedora-ds", "openldap"])
+parser.add_option("--server-role", type="choice", metavar="ROLE",
+ choices=["domain controller", "dc", "member server", "member", "standalone"],
+ help="Set server role to provision for (default standalone)")
+parser.add_option("--targetdir", type="string", metavar="DIR",
+ help="Set target directory")
+
+opts = parser.parse_args()[0]
+
+def message(text):
+ """print a message if quiet is not set."""
+ if not opts.quiet:
+ print text
+
+if opts.realm is None or opts.domain is None:
+ if opts.realm is None:
+ print >>sys.stderr, "No realm set"
+ if opts.domain is None:
+ print >>sys.stderr, "No domain set"
+ parser.print_usage()
+ sys.exit(1)
+
+smbconf = sambaopts.get_loadparm().configfile()
+
+if opts.server_role == "dc":
+ server_role = "domain controller"
+elif opts.server_role == "member":
+ server_role = "member server"
+else:
+ server_role = opts.server_role
+
+setup_dir = opts.setupdir
+if setup_dir is None:
+ setup_dir = "setup"
+
+provision_backend(setup_dir=setup_dir, message=message, smbconf=smbconf, targetdir=opts.targetdir,
+ realm=opts.realm, domain=opts.domain,
+ hostname=opts.host_name,
+ adminpass=opts.ldap_manager_pass,
+ root=opts.root, serverrole=server_role,
+ ldap_backend_type=opts.ldap_backend_type)
+
+message("All OK")
diff --git a/source4/setup/provision-backend.js b/source4/setup/provision-backend.js
new file mode 100644
index 0000000000..edc09907a8
--- /dev/null
+++ b/source4/setup/provision-backend.js
@@ -0,0 +1,188 @@
+#!/bin/sh
+exec smbscript "$0" ${1+"$@"}
+/*
+ provision a Samba4 server
+ Copyright Andrew Tridgell 2005
+ Released under the GNU GPL v2 or later
+*/
+
+options = GetOptions(ARGV,
+ "POPT_AUTOHELP",
+ "POPT_COMMON_SAMBA",
+ "POPT_COMMON_VERSION",
+ "POPT_COMMON_CREDENTIALS",
+ 'realm=s',
+ 'host-name=s',
+ 'ldap-manager-pass=s',
+ 'root=s',
+ 'quiet',
+ 'ldap-backend-type=s',
+ 'ldap-backend-port=i');
+
+if (options == undefined) {
+ println("Failed to parse options");
+ return -1;
+}
+
+sys = sys_init();
+
+libinclude("base.js");
+libinclude("provision.js");
+
+/*
+ print a message if quiet is not set
+*/
+function message()
+{
+ if (options["quiet"] == undefined) {
+ print(vsprintf(arguments));
+ }
+}
+
+/*
+ show some help
+*/
+function ShowHelp()
+{
+ print("
+Samba4 provisioning
+
+provision [options]
+ --realm REALM set realm
+ --host-name HOSTNAME set hostname
+ --ldap-manager-pass PASSWORD choose LDAP Manager password (otherwise random)
+ --root USERNAME choose 'root' unix username
+ --quiet Be quiet
+ --ldap-backend-type LDAPSERVER Select either \"openldap\" or \"fedora-ds\" as a target to configure
+ --ldap-backend-port PORT Select the TCP port (if any) that the LDAP backend should listen on (Fedora DS only)
+You must provide at least a realm and ldap-backend-type
+
+");
+ exit(1);
+}
+
+if (options['host-name'] == undefined) {
+ options['host-name'] = hostname();
+}
+
+/*
+ main program
+*/
+if (options["realm"] == undefined ||
+ options["ldap-backend-type"] == undefined ||
+ options["host-name"] == undefined) {
+ ShowHelp();
+}
+
+/* cope with an initially blank smb.conf */
+var lp = loadparm_init();
+lp.set("realm", options.realm);
+lp.reload();
+
+var subobj = provision_guess();
+for (r in options) {
+ var key = strupper(join("", split("-", r)));
+ subobj[key] = options[r];
+}
+
+
+
+var paths = provision_default_paths(subobj);
+provision_fix_subobj(subobj, paths);
+message("Provisioning LDAP backend for %s in realm %s into %s\n", subobj.HOSTNAME, subobj.REALM, subobj.LDAPDIR);
+message("Using %s password: %s\n", subobj.LDAPMANAGERDN, subobj.LDAPMANAGERPASS);
+var tmp_schema_ldb = subobj.LDAPDIR + "/schema-tmp.ldb";
+sys.mkdir(subobj.LDAPDIR, 0700);
+
+provision_schema(subobj, message, tmp_schema_ldb, paths);
+
+var mapping;
+var backend_schema;
+var slapd_command;
+if (options["ldap-backend-type"] == "fedora-ds") {
+ mapping = "schema-map-fedora-ds-1.0";
+ backend_schema = "99_ad.ldif";
+ if (options["ldap-backend-port"] != undefined) {
+ message("Will listen on TCP port " + options["ldap-backend-port"] + "\n");
+ subobj.SERVERPORT="ServerPort = " + options["ldap-backend-port"];
+ } else {
+ message("Will listen on LDAPI only\n");
+ subobj.SERVERPORT="";
+ }
+ setup_file("fedorads.inf", message, subobj.LDAPDIR + "/fedorads.inf", subobj);
+ setup_file("fedorads-partitions.ldif", message, subobj.LDAPDIR + "/fedorads-partitions.ldif", subobj);
+
+ slapd_command = "(see documentation)";
+} else if (options["ldap-backend-type"] == "openldap") {
+ mapping = "schema-map-openldap-2.3";
+ backend_schema = "backend-schema.schema";
+ setup_file("slapd.conf", message, subobj.LDAPDIR + "/slapd.conf", subobj);
+ setup_file("modules.conf", message, subobj.LDAPDIR + "/modules.conf", subobj);
+ sys.mkdir(subobj.LDAPDIR + "/db", 0700);
+ subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/user";
+ sys.mkdir(subobj.LDAPDBDIR, 0700);
+ sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
+ sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
+ setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
+ subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/config";
+ sys.mkdir(subobj.LDAPDBDIR, 0700);
+ sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
+ sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
+ setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
+ subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/schema";
+ sys.mkdir(subobj.LDAPDBDIR, 0700);
+ sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700);
+ sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700);
+ setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj);
+ if (options["ldap-backend-port"] != undefined) {
+ message("\nStart slapd with: \n");
+ slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h \"ldap://0.0.0.0:" + options["ldap-backend-port"] + " " + subobj.LDAPI_URI "\"";
+ } else {
+ slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h " + subobj.LDAPI_URI;
+ }
+
+ var ldb = ldb_init();
+ ldb.filename = tmp_schema_ldb;
+
+ var connect_ok = ldb.connect(ldb.filename);
+ assert(connect_ok);
+ var attrs = new Array("linkID", "lDAPDisplayName");
+ var res = ldb.search("(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", subobj.SCHEMADN, ldb.SCOPE_SUBTREE, attrs);
+ assert(res.error == 0);
+ var memberof_config = "";
+ var refint_attributes = "";
+ for (i=0; i < res.msgs.length; i++) {
+ var target = searchone(ldb, subobj.SCHEMADN, "(&(objectclass=attributeSchema)(linkID=" + (res.msgs[i].linkID + 1) + "))", "lDAPDisplayName");
+ if (target != undefined) {
+ refint_attributes = refint_attributes + " " + target + " " + res.msgs[i].lDAPDisplayName;
+ memberof_config = memberof_config + "overlay memberof
+memberof-dangling error
+memberof-refint TRUE
+memberof-group-oc top
+memberof-member-ad " + res.msgs[i].lDAPDisplayName + "
+memberof-memberof-ad " + target + "
+memberof-dangling-error 32
+
+";
+ }
+ }
+
+ memberof_config = memberof_config + "
+overlay refint
+refint_attributes" + refint_attributes + "
+";
+
+ ok = sys.file_save(subobj.LDAPDIR + "/memberof.conf", memberof_config);
+ if (!ok) {
+ message("failed to create file: " + f + "\n");
+ assert(ok);
+ }
+
+}
+var schema_command = "ad2oLschema --option=convert:target=" + options["ldap-backend-type"] + " -I " + lp.get("setup directory") + "/" + mapping + " -H tdb://" + tmp_schema_ldb + " -O " + subobj.LDAPDIR + "/" + backend_schema;
+
+message("\nCreate a suitable schema file with:\n%s\n", schema_command);
+message("\nStart slapd with: \n%s\n", slapd_command);
+
+message("All OK\n");
+return 0;
diff --git a/source4/setup/provision.js b/source4/setup/provision.js
deleted file mode 100755
index 328754fd9c..0000000000
--- a/source4/setup/provision.js
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-/*
- provision a Samba4 server
- Copyright Andrew Tridgell 2005
- Released under the GNU GPL v2 or later
-*/
-
-options = GetOptions(ARGV,
- "POPT_AUTOHELP",
- "POPT_COMMON_SAMBA",
- "POPT_COMMON_VERSION",
- "POPT_COMMON_CREDENTIALS",
- 'realm=s',
- 'domain=s',
- 'domain-guid=s',
- 'domain-sid=s',
- 'policy-guid=s',
- 'host-name=s',
- 'host-ip=s',
- 'host-guid=s',
- 'invocationid=s',
- 'adminpass=s',
- 'krbtgtpass=s',
- 'machinepass=s',
- 'dnspass=s',
- 'root=s',
- 'nobody=s',
- 'nogroup=s',
- 'wheel=s',
- 'users=s',
- 'quiet',
- 'blank',
- 'server-role=s',
- 'partitions-only',
- 'ldap-base',
- 'ldap-backend=s',
- 'ldap-backend-type=s',
- 'aci=s');
-
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-libinclude("base.js");
-libinclude("provision.js");
-
-/*
- print a message if quiet is not set
-*/
-function message()
-{
- if (options["quiet"] == undefined) {
- print(vsprintf(arguments));
- }
-}
-
-/*
- show some help
-*/
-function ShowHelp()
-{
- print("
-Samba4 provisioning
-
-provision [options]
- --realm REALM set realm
- --domain DOMAIN set domain
- --domain-guid GUID set domainguid (otherwise random)
- --domain-sid SID set domainsid (otherwise random)
- --host-name HOSTNAME set hostname
- --host-ip IPADDRESS set ipaddress
- --host-guid GUID set hostguid (otherwise random)
- --policy-guid GUID set group policy guid (otherwise random)
- --invocationid GUID set invocationid (otherwise random)
- --adminpass PASSWORD choose admin password (otherwise random)
- --krbtgtpass PASSWORD choose krbtgt password (otherwise random)
- --machinepass PASSWORD choose machine password (otherwise random)
- --root USERNAME choose 'root' unix username
- --nobody USERNAME choose 'nobody' user
- --nogroup GROUPNAME choose 'nogroup' group
- --wheel GROUPNAME choose 'wheel' privileged group
- --users GROUPNAME choose 'users' group
- --quiet Be quiet
- --blank do not add users or groups, just the structure
- --server-role ROLE Set server role to provision for (default standalone)
- --partitions-only Configure Samba's partitions, but do not modify them (ie, join a BDC)
- --ldap-base output only an LDIF file, suitable for creating an LDAP baseDN
- --ldap-backend LDAPSERVER LDAP server to use for this provision
- --ldap-backend-type TYPE OpenLDAP or Fedora DS
- --aci ACI An arbitary LDIF fragment, particularly useful to loading a backend ACI value into a target LDAP server
-You must provide at least a realm and domain
-
-");
- exit(1);
-}
-
-if (options['host-name'] == undefined) {
- options['host-name'] = hostname();
-}
-
-/*
- main program
-*/
-if (options["realm"] == undefined ||
- options["domain"] == undefined ||
- options["host-name"] == undefined) {
- ShowHelp();
-}
-
-/* cope with an initially blank smb.conf */
-var lp = loadparm_init();
-lp.set("realm", options.realm);
-lp.set("workgroup", options.domain);
-lp.set("server role", options["server-role"]);
-lp.reload();
-
-var subobj = provision_guess();
-for (r in options) {
- var key = strupper(join("", split("-", r)));
- subobj[key] = options[r];
-}
-
-var blank = (options["blank"] != undefined);
-var ldapbackend = (options["ldap-backend"] != undefined);
-var ldapbackendtype = options["ldap-backend-type"];
-var partitions_only = (options["partitions-only"] != undefined);
-var paths = provision_default_paths(subobj);
-if (options["aci"] != undefined) {
- message("set ACI: %s\n", subobj["ACI"]);
-}
-
-message("set DOMAIN SID: %s\n", subobj["DOMAINSID"]);
-
-provision_fix_subobj(subobj, paths);
-
-if (ldapbackend) {
- if (options["ldap-backend"] == "ldapi") {
- subobj.LDAPBACKEND = subobj.LDAPI_URI;
- }
- if (ldapbackendtype == undefined) {
-
- } else if (ldapbackendtype == "openldap") {
- subobj.LDAPMODULE = "normalise,entryuuid";
- subobj.TDB_MODULES_LIST = "";
- } else if (ldapbackendtype == "fedora-ds") {
- subobj.LDAPMODULE = "nsuniqueid";
- }
- subobj.BACKEND_MOD = subobj.LDAPMODULE + ",paged_searches";
- subobj.DOMAINDN_LDB = subobj.LDAPBACKEND;
- subobj.CONFIGDN_LDB = subobj.LDAPBACKEND;
- subobj.SCHEMADN_LDB = subobj.LDAPBACKEND;
- message("LDAP module: %s on backend: %s\n", subobj.LDAPMODULE, subobj.LDAPBACKEND);
-}
-
-if (!provision_validate(subobj, message)) {
- return -1;
-}
-
-var system_session = system_session();
-var creds = options.get_credentials();
-message("Provisioning for %s in realm %s\n", subobj.DOMAIN, subobj.REALM);
-message("Using administrator password: %s\n", subobj.ADMINPASS);
-if (partitions_only) {
- provision_become_dc(subobj, message, false, paths, system_session);
-} else {
- provision(subobj, message, blank, paths, system_session, creds, ldapbackend);
- provision_dns(subobj, message, paths, system_session, creds);
- message("To reproduce this provision, run with:\n");
-/* There has to be a better way than this... */
- message("--realm='%s' --domain='%s' \\\n", subobj.REALM_CONF, subobj.DOMAIN_CONF);
- if (subobj.DOMAINGUID != undefined) {
- message("--domain-guid='%s' \\\n", subobj.DOMAINGUID);
- }
- if (subobj.HOSTGUID != undefined) {
- message("--host-guid='%s' \\\n", subobj.HOSTGUID);
- }
- message("--policy-guid='%s' --host-name='%s' --host-ip='%s' \\\n", subobj.POLICYGUID, subobj.HOSTNAME, subobj.HOSTIP);
- if (subobj.INVOCATIONID != undefined) {
- message("--invocationid='%s' \\\n", subobj.INVOCATIONID);
- }
- message("--adminpass='%s' --krbtgtpass='%s' \\\n", subobj.ADMINPASS, subobj.KRBTGTPASS);
- message("--machinepass='%s' --dnspass='%s' \\\n", subobj.MACHINEPASS, subobj.DNSPASS);
- message("--root='%s' --nobody='%s' --nogroup='%s' \\\n", subobj.ROOT, subobj.NOBODY, subobj.NOGROUP);
- message("--wheel='%s' --users='%s' --server-role='%s' \\\n", subobj.WHEEL, subobj.USERS, subobj.SERVERROLE);
- if (ldapbackend) {
- message("--ldap-backend='%s' \\\n", subobj.LDAPBACKEND);
- }
- if (ldapbackendtype != undefined) {
- message("--ldap-backend-type='%s' \\\n", + ldapbackendtype);
- }
- message("--aci='" + subobj.ACI + "' \\\n")
-}
-
-
-message("All OK\n");
-return 0;
diff --git a/source4/setup/provision_basedn.ldif b/source4/setup/provision_basedn.ldif
index 11eb0593e8..7fdecfa3c0 100644
--- a/source4/setup/provision_basedn.ldif
+++ b/source4/setup/provision_basedn.ldif
@@ -3,7 +3,6 @@
################################
dn: ${DOMAINDN}
objectClass: top
-objectClass: domain
-objectClass: domainDNS
+objectClass: ${DOMAIN_OC}
${ACI}
diff --git a/source4/setup/schema-map-openldap-2.3 b/source4/setup/schema-map-openldap-2.3
index 0bce95afba..3f07a9d50f 100644
--- a/source4/setup/schema-map-openldap-2.3
+++ b/source4/setup/schema-map-openldap-2.3
@@ -11,6 +11,7 @@ distinguishedName
description
cn
top
+#The memberOf plugin provides this attribute
memberOf
#This shouldn't make it to the ldap server
sambaPassword
diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif
index 8bd1705468..7146091c8e 100644
--- a/source4/setup/schema_samba4.ldif
+++ b/source4/setup/schema_samba4.ldif
@@ -194,3 +194,41 @@ attributeID: 1.3.6.1.4.1.7165.4.1.11
attributeSyntax: 2.5.5.4
oMSyntax: 20
+#
+# Based on domainDNS, but without the DNS bits.
+#
+
+dn: CN=Samba4-Local-Domain,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+subClassOf: top
+governsID: 1.3.6.1.4.1.7165.4.2.2
+possibleInferiors: group
+possibleInferiors: lostAndFound
+possibleInferiors: builtinDomain
+possibleInferiors: computer
+possibleInferiors: user
+possibleInferiors: container
+possibleInferiors: groupPolicyContainer
+possibleInferiors: organization
+possibleInferiors: domainDNS
+possibleInferiors: locality
+possibleInferiors: msDS-AzAdminManager
+possibleInferiors: country
+possibleInferiors: organizationalUnit
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Samba4-Local-Domain
+adminDescription: Samba4-Local-Domain
+systemMayContain: msDS-Behavior-Version
+systemMayContain: managedBy
+objectClassCategory: 1
+lDAPDisplayName: samba4LocalDomain
+schemaIDGUID: 07be1647-8310-4fba-91ae-34e55d5a8293
+systemOnly: FALSE
+systemAuxiliaryClass: samDomainBase
+defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)
+systemFlags: 16
+defaultHidingValue: TRUE
+defaultObjectCategory: CN=Builtin-Domain,${SCHEMADN}
+
diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf
index 83f4da3359..cdf9ff79a9 100644
--- a/source4/setup/slapd.conf
+++ b/source4/setup/slapd.conf
@@ -21,7 +21,7 @@ include ${LDAPDIR}/modules.conf
defaultsearchbase ${DOMAINDN}
-include ${LDAPDIR}/memberof.conf
+${MEMBEROF_CONFIG}
database hdb
suffix ${SCHEMADN}
@@ -62,8 +62,6 @@ syncprov-sessionlog 100
database hdb
suffix ${DOMAINDN}
-rootdn ${LDAPMANAGERDN}
-rootpw ${LDAPMANAGERPASS}
directory ${LDAPDIR}/db/user
index objectClass eq
index samAccountName eq
@@ -82,8 +80,12 @@ index dnsRoot eq
index nETBIOSName eq
index cn eq
+rootdn ${LDAPMANAGERDN}
+rootpw ${LDAPMANAGERPASS}
+
#syncprov is stable in OpenLDAP 2.3, and available in 2.2.
#We only need this for the contextCSN attribute anyway....
overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100
+
diff --git a/source4/setup/tests/blackbox_provision.sh b/source4/setup/tests/blackbox_provision.sh
index 83c045e40d..75d4fcfcb4 100755
--- a/source4/setup/tests/blackbox_provision.sh
+++ b/source4/setup/tests/blackbox_provision.sh
@@ -28,7 +28,7 @@ testit() {
}
testit "simple-default" $PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-default
-testit "simple-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-dc
+testit "simple-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --domain-sid=S-1-5-21-4177067393-1453636373-93818738 --targetdir=$PREFIX/simple-dc
testit "simple-member" $PYTHON ./setup/provision $CONFIGURATION --server-role="member" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-member
testit "simple-standalone" $PYTHON ./setup/provision $CONFIGURATION --server-role="standalone" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-standalone
diff --git a/source4/smb_server/smb/nttrans.c b/source4/smb_server/smb/nttrans.c
index a20c41ba4d..1b49e23511 100644
--- a/source4/smb_server/smb/nttrans.c
+++ b/source4/smb_server/smb/nttrans.c
@@ -287,7 +287,30 @@ static NTSTATUS nttrans_set_sec_desc(struct smbsrv_request *req,
static NTSTATUS nttrans_rename(struct smbsrv_request *req,
struct nttrans_op *op)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct smb_nttrans *trans = op->trans;
+ union smb_rename *io;
+
+ if (trans->in.params.length < 5) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* parse the request */
+ io = talloc(req, union smb_rename);
+ NT_STATUS_HAVE_NO_MEMORY(io);
+
+ io->nttrans.level = RAW_RENAME_NTTRANS;
+ io->nttrans.in.file.ntvfs = smbsrv_pull_fnum(req, trans->in.params.data, 0);
+ io->nttrans.in.flags = SVAL(trans->in.params.data, 2);
+
+ smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 4,
+ &io->nttrans.in.new_name,
+ STR_TERMINATE);
+ if (!io->nttrans.in.new_name) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(io->nttrans.in.file.ntvfs);
+ return ntvfs_rename(req->ntvfs, io);
}
/*
diff --git a/source4/static_deps.mk b/source4/static_deps.mk
index 1f86372aa3..ade41614c2 100644
--- a/source4/static_deps.mk
+++ b/source4/static_deps.mk
@@ -36,7 +36,8 @@ heimdal_basics: \
heimdal/lib/krb5/krb_err.h \
heimdal/lib/krb5/krb5_err.h \
heimdal/lib/gssapi/gkrb5_err.h \
- heimdal/lib/hx509/hx509_err.h
+ heimdal/lib/hx509/hx509_err.h \
+ heimdal/lib/wind/wind_err.h
proto: basics
basics: include/includes.h \
diff --git a/source4/torture/raw/openbench.c b/source4/torture/raw/openbench.c
index 87b27d0728..e8b2f56813 100644
--- a/source4/torture/raw/openbench.c
+++ b/source4/torture/raw/openbench.c
@@ -37,7 +37,7 @@
static int nprocs;
static int open_failed;
-static int open_retries;
+static int close_failed;
static char **fnames;
static int num_connected;
static struct timed_event *report_te;
@@ -49,12 +49,16 @@ struct benchopen_state {
struct smbcli_state *cli;
struct smbcli_tree *tree;
int client_num;
- int old_fnum;
- int fnum;
- int file_num;
+ int close_fnum;
+ int open_fnum;
+ int close_file_num;
+ int open_file_num;
+ int pending_file_num;
+ int next_file_num;
int count;
int lastcount;
union smb_open open_parms;
+ int open_retries;
union smb_close close_parms;
struct smbcli_request *req_open;
struct smbcli_request *req_close;
@@ -95,11 +99,11 @@ static void reopen_connection_complete(struct composite_context *ctx)
num_connected++;
- DEBUG(0,("reconnect to %s finished (%u connected)\n", state->dest_host,
- num_connected));
+ DEBUG(0,("[%u] reconnect to %s finished (%u connected)\n",
+ state->client_num, state->dest_host, num_connected));
- state->fnum = -1;
- state->old_fnum = -1;
+ state->open_fnum = -1;
+ state->close_fnum = -1;
next_open(state);
}
@@ -136,7 +140,8 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te,
/* kill off the remnants of the old connection */
talloc_free(state->tree);
state->tree = NULL;
- state->fnum = -1;
+ state->open_fnum = -1;
+ state->close_fnum = -1;
ctx = smb_composite_connect_send(io, state->mem_ctx,
lp_resolve_context(state->tctx->lp_ctx),
@@ -158,9 +163,10 @@ static void next_open(struct benchopen_state *state)
{
state->count++;
- state->file_num = (state->file_num+1) % (3*nprocs);
+ state->pending_file_num = state->next_file_num;
+ state->next_file_num = (state->next_file_num+1) % (3*nprocs);
- DEBUG(2,("[%d] opening %u\n", state->client_num, state->file_num));
+ DEBUG(2,("[%d] opening %u\n", state->client_num, state->pending_file_num));
state->open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
state->open_parms.ntcreatex.in.flags = 0;
state->open_parms.ntcreatex.in.root_fid = 0;
@@ -172,7 +178,7 @@ static void next_open(struct benchopen_state *state)
state->open_parms.ntcreatex.in.create_options = 0;
state->open_parms.ntcreatex.in.impersonation = 0;
state->open_parms.ntcreatex.in.security_flags = 0;
- state->open_parms.ntcreatex.in.fname = fnames[state->file_num];
+ state->open_parms.ntcreatex.in.fname = fnames[state->pending_file_num];
state->req_open = smb_raw_open_send(state->tree, &state->open_parms);
state->req_open->async.fn = open_completed;
@@ -182,18 +188,18 @@ static void next_open(struct benchopen_state *state)
static void next_close(struct benchopen_state *state)
{
- DEBUG(2,("[%d] closing %d\n", state->client_num, state->old_fnum));
- if (state->old_fnum == -1) {
+ if (state->close_fnum == -1) {
return;
}
+ DEBUG(2,("[%d] closing %d (fnum[%d])\n",
+ state->client_num, state->close_file_num, state->close_fnum));
state->close_parms.close.level = RAW_CLOSE_CLOSE;
- state->close_parms.close.in.file.fnum = state->old_fnum;
+ state->close_parms.close.in.file.fnum = state->close_fnum;
state->close_parms.close.in.write_time = 0;
state->req_close = smb_raw_close_send(state->tree, &state->close_parms);
state->req_close->async.fn = close_completed;
state->req_close->async.private = state;
- state->old_fnum = -1;
}
/*
@@ -218,7 +224,8 @@ static void open_completed(struct smbcli_request *req)
state->tree = NULL;
state->cli = NULL;
num_connected--;
- DEBUG(0,("reopening connection to %s\n", state->dest_host));
+ DEBUG(0,("[%u] reopening connection to %s\n",
+ state->client_num, state->dest_host));
talloc_free(state->te);
state->te = event_add_timed(state->ev, state->mem_ctx,
timeval_current_ofs(1,0),
@@ -227,8 +234,9 @@ static void open_completed(struct smbcli_request *req)
}
if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
- DEBUG(2,("[%d] retrying open\n", state->client_num));
- open_retries++;
+ DEBUG(2,("[%d] retrying open %d\n",
+ state->client_num, state->pending_file_num));
+ state->open_retries++;
state->req_open = smb_raw_open_send(state->tree, &state->open_parms);
state->req_open->async.fn = open_completed;
state->req_open->async.private = state;
@@ -237,17 +245,21 @@ static void open_completed(struct smbcli_request *req)
if (!NT_STATUS_IS_OK(status)) {
open_failed++;
- DEBUG(0,("open failed - %s\n", nt_errstr(status)));
+ DEBUG(0,("[%u] open failed %d - %s\n",
+ state->client_num, state->pending_file_num,
+ nt_errstr(status)));
return;
}
- state->old_fnum = state->fnum;
- state->fnum = state->open_parms.ntcreatex.out.file.fnum;
+ state->close_file_num = state->open_file_num;
+ state->close_fnum = state->open_fnum;
+ state->open_file_num = state->pending_file_num;
+ state->open_fnum = state->open_parms.ntcreatex.out.file.fnum;
- DEBUG(2,("[%d] open completed: fnum=%d old_fnum=%d\n",
- state->client_num, state->fnum, state->old_fnum));
+ DEBUG(2,("[%d] open completed %d (fnum[%d])\n",
+ state->client_num, state->open_file_num, state->open_fnum));
- if (state->old_fnum != -1) {
+ if (state->close_fnum != -1) {
next_close(state);
}
@@ -271,7 +283,8 @@ static void close_completed(struct smbcli_request *req)
state->tree = NULL;
state->cli = NULL;
num_connected--;
- DEBUG(0,("reopening connection to %s\n", state->dest_host));
+ DEBUG(0,("[%u] reopening connection to %s\n",
+ state->client_num, state->dest_host));
talloc_free(state->te);
state->te = event_add_timed(state->ev, state->mem_ctx,
timeval_current_ofs(1,0),
@@ -280,13 +293,17 @@ static void close_completed(struct smbcli_request *req)
}
if (!NT_STATUS_IS_OK(status)) {
- open_failed++;
- DEBUG(0,("close failed - %s\n", nt_errstr(status)));
+ close_failed++;
+ DEBUG(0,("[%u] close failed %d (fnum[%d]) - %s\n",
+ state->client_num, state->close_file_num,
+ state->close_fnum,
+ nt_errstr(status)));
return;
}
- DEBUG(2,("[%d] close completed: fnum=%d old_fnum=%d\n",
- state->client_num, state->fnum, state->old_fnum));
+ DEBUG(2,("[%d] close completed %d (fnum[%d])\n",
+ state->client_num, state->close_file_num,
+ state->close_fnum));
}
static void echo_completion(struct smbcli_request *req)
@@ -298,7 +315,8 @@ static void echo_completion(struct smbcli_request *req)
talloc_free(state->tree);
state->tree = NULL;
num_connected--;
- DEBUG(0,("reopening connection to %s\n", state->dest_host));
+ DEBUG(0,("[%u] reopening connection to %s\n",
+ state->client_num, state->dest_host));
talloc_free(state->te);
state->te = event_add_timed(state->ev, state->mem_ctx,
timeval_current_ofs(1,0),
@@ -352,7 +370,9 @@ bool torture_bench_open(struct torture_context *torture)
struct timeval tv;
struct event_context *ev = event_context_find(mem_ctx);
struct benchopen_state *state;
- int total = 0, minops=0;
+ int total = 0;
+ int total_retries = 0;
+ int minops = 0;
bool progress=false;
progress = torture_setting_bool(torture, "progress", true);
@@ -397,11 +417,10 @@ bool torture_bench_open(struct torture_context *torture)
}
for (i=0;i<nprocs;i++) {
- state[i].file_num = i;
- state[i].fnum = smbcli_open(state[i].tree,
- fnames[state->file_num],
- O_RDWR|O_CREAT, DENY_ALL);
- state[i].old_fnum = -1;
+ /* all connections start with the same file */
+ state[i].next_file_num = 0;
+ state[i].open_fnum = -1;
+ state[i].close_fnum = -1;
next_open(&state[i]);
}
@@ -420,17 +439,30 @@ bool torture_bench_open(struct torture_context *torture)
DEBUG(0,("open failed\n"));
goto failed;
}
+ if (close_failed) {
+ DEBUG(0,("open failed\n"));
+ goto failed;
+ }
}
talloc_free(report_te);
+ if (progress) {
+ for (i=0;i<nprocs;i++) {
+ printf(" ");
+ }
+ printf("\r");
+ }
- printf("%.2f ops/second (%d retries)\n",
- total/timeval_elapsed(&tv), open_retries);
minops = state[0].count;
for (i=0;i<nprocs;i++) {
- printf("[%d] %u ops\n", i, state[i].count);
+ total += state[i].count;
+ total_retries += state[i].open_retries;
+ printf("[%d] %u ops (%u retries)\n",
+ i, state[i].count, state[i].open_retries);
if (state[i].count < minops) minops = state[i].count;
}
+ printf("%.2f ops/second (%d retries)\n",
+ total/timeval_elapsed(&tv), total_retries);
if (minops < 0.5*total/nprocs) {
printf("Failed: unbalanced open\n");
goto failed;
diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index 1926b12128..8b2e4fb177 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -229,7 +229,7 @@ static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbc
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
+ torture_comment(tctx, "EXCLUSIVE1: open a file with an exclusive oplock (share mode: none)\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
@@ -294,7 +294,7 @@ static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbc
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open a file with an exclusive oplock (share mode: all)\n");
+ torture_comment(tctx, "EXCLUSIVE2: open a file with an exclusive oplock (share mode: all)\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
@@ -363,7 +363,6 @@ static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbc
union smb_open io;
union smb_setfileinfo sfi;
uint16_t fnum=0;
- bool s3 = torture_setting_bool(tctx, "samba3", false);
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
@@ -389,15 +388,10 @@ static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbc
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
- s3?"all":"none");
+ torture_comment(tctx, "EXCLUSIVE3: open a file with an exclusive oplock (share mode: none)\n");
+
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
- if (s3) {
- io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
- NTCREATEX_SHARE_ACCESS_WRITE|
- NTCREATEX_SHARE_ACCESS_DELETE;
- }
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
@@ -458,7 +452,7 @@ static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbc
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with exclusive oplock\n");
+ torture_comment(tctx, "EXCLUSIVE4: open with exclusive oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -523,7 +517,7 @@ static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbc
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with exclusive oplock\n");
+ torture_comment(tctx, "EXCLUSIVE5: open with exclusive oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -570,7 +564,6 @@ static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbc
union smb_open io;
union smb_rename rn;
uint16_t fnum=0;
- bool s3 = torture_setting_bool(tctx, "samba3", false);
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
@@ -597,16 +590,9 @@ static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbc
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname1;
- /* we should use no share mode, when samba3 passes this */
- torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
- s3?"all":"none");
+ torture_comment(tctx, "EXCLUSIVE6: open a file with an exclusive oplock (share mode: none)\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
- if (s3) {
- io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
- NTCREATEX_SHARE_ACCESS_WRITE|
- NTCREATEX_SHARE_ACCESS_DELETE;
- }
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
@@ -673,7 +659,7 @@ static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_s
/*
with a batch oplock we get a break
*/
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH1: open with batch oplock\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -754,7 +740,7 @@ static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH2: open with batch oplock\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -832,7 +818,7 @@ static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "if we close on break then the unlink can succeed\n");
+ torture_comment(tctx, "BATCH3: if we close on break then the unlink can succeed\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
@@ -896,7 +882,7 @@ static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "a self read should not cause a break\n");
+ torture_comment(tctx, "BATCH4: a self read should not cause a break\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -959,7 +945,7 @@ static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "a 2nd open should give a break\n");
+ torture_comment(tctx, "BATCH5: a 2nd open should give a break\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1024,7 +1010,7 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
+ torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
@@ -1104,7 +1090,7 @@ static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "a 2nd open should get an oplock when we close instead of ack\n");
+ torture_comment(tctx, "BATCH7: a 2nd open should get an oplock when we close instead of ack\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
@@ -1174,7 +1160,7 @@ static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH8: open with batch oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1243,7 +1229,7 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with attributes only can create file\n");
+ torture_comment(tctx, "BATCH9: open with attributes only can create file\n");
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -1348,7 +1334,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "Open with oplock after a non-oplock open should grant level2\n");
+ torture_comment(tctx, "BATCH10: Open with oplock after a non-oplock open should grant level2\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
@@ -1458,7 +1444,7 @@ static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.fname = fname;
/* Test if a set-eof on pathname breaks an exclusive oplock. */
- torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
+ torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1533,7 +1519,7 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.fname = fname;
/* Test if a set-allocation size on pathname breaks an exclusive oplock. */
- torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
+ torture_comment(tctx, "BATCH12: Test if setpathinfo allocation size breaks oplocks.\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1607,7 +1593,7 @@ static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH13: open with batch oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1684,7 +1670,7 @@ static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH14: open with batch oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1761,7 +1747,7 @@ static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.fname = fname;
/* Test if a qpathinfo all info on pathname breaks a batch oplock. */
- torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
+ torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1833,7 +1819,7 @@ static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH16: open with batch oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
@@ -1887,7 +1873,6 @@ static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_
union smb_open io;
union smb_rename rn;
uint16_t fnum=0;
- bool s3 = torture_setting_bool(tctx, "samba3", false);
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
@@ -1914,18 +1899,12 @@ static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname1;
- /* we should use no share mode, when samba3 passes this */
- torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
- s3?"all":"none");
+ torture_comment(tctx, "BATCH17: open a file with an batch oplock (share mode: none)\n");
+
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
- if (s3) {
- io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
- NTCREATEX_SHARE_ACCESS_WRITE|
- NTCREATEX_SHARE_ACCESS_DELETE;
- }
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
@@ -1965,7 +1944,6 @@ static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_
union smb_open io;
union smb_rename rn;
uint16_t fnum=0;
- bool s3 = torture_setting_bool(tctx, "samba3", false);
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
@@ -1992,18 +1970,12 @@ static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname1;
- /* we should use no share mode, when samba3 passes this */
- torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
- s3?"all":"none");
+ torture_comment(tctx, "BATCH18: open a file with an batch oplock (share mode: none)\n");
+
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
- if (s3) {
- io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
- NTCREATEX_SHARE_ACCESS_WRITE|
- NTCREATEX_SHARE_ACCESS_DELETE;
- }
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
@@ -2046,10 +2018,6 @@ static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_
union smb_setfileinfo sfi;
uint16_t fnum=0;
- if (torture_setting_bool(tctx, "samba3", false)) {
- torture_skip(tctx, "BACHT19 disabled against samba3\n");
- }
-
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
}
@@ -2076,7 +2044,7 @@ static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname1;
- torture_comment(tctx, "open a file with an batch oplock (share mode: none)\n");
+ torture_comment(tctx, "BATCH19: open a file with an batch oplock (share mode: none)\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -2136,6 +2104,232 @@ done:
return ret;
}
+/****************************************************
+ Called from raw-rename - we need oplock handling for
+ this test so this is why it's in oplock.c, not rename.c
+****************************************************/
+
+bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+ const char *fname1 = BASEDIR "\\test_trans2rename_1.dat";
+ const char *fname2 = BASEDIR "\\test_trans2rename_2.dat";
+ const char *fname3 = BASEDIR "\\test_trans2rename_3.dat";
+ NTSTATUS status;
+ bool ret = true;
+ union smb_open io;
+ union smb_fileinfo qfi;
+ union smb_setfileinfo sfi;
+ uint16_t fnum=0;
+
+ if (!torture_setup_dir(cli1, BASEDIR)) {
+ return false;
+ }
+
+ /* cleanup */
+ smbcli_unlink(cli1->tree, fname1);
+ smbcli_unlink(cli1->tree, fname2);
+ smbcli_unlink(cli1->tree, fname3);
+
+ smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
+
+ /*
+ base ntcreatex parms
+ */
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname1;
+
+ torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
+ ZERO_STRUCT(break_info);
+ io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
+ NTCREATEX_FLAGS_REQUEST_OPLOCK;
+ status = smb_raw_open(cli1->tree, tctx, &io);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+ CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
+
+ torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
+ ZERO_STRUCT(sfi);
+ sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sfi.generic.in.file.path = fname1;
+ sfi.rename_information.in.overwrite = 0;
+ sfi.rename_information.in.root_fid = 0;
+ sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
+
+ status = smb_raw_setpathinfo(cli2->tree, &sfi);
+
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_VAL(break_info.count, 0);
+
+ ZERO_STRUCT(qfi);
+ qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qfi.generic.in.file.fnum = fnum;
+
+ status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
+
+ torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
+ ZERO_STRUCT(sfi);
+ sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sfi.generic.in.file.fnum = fnum;
+ sfi.rename_information.in.overwrite = 0;
+ sfi.rename_information.in.root_fid = 0;
+ sfi.rename_information.in.new_name = fname3+strlen(BASEDIR)+1;
+
+ status = smb_raw_setfileinfo(cli1->tree, &sfi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_VAL(break_info.count, 0);
+
+ ZERO_STRUCT(qfi);
+ qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qfi.generic.in.file.fnum = fnum;
+
+ status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
+
+ smbcli_close(cli1->tree, fnum);
+
+done:
+ smb_raw_exit(cli1->session);
+ smb_raw_exit(cli2->session);
+ smbcli_deltree(cli1->tree, BASEDIR);
+ return ret;
+}
+
+/****************************************************
+ Called from raw-rename - we need oplock handling for
+ this test so this is why it's in oplock.c, not rename.c
+****************************************************/
+
+bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
+{
+ const char *fname1 = BASEDIR "\\test_nttransrename_1.dat";
+ const char *fname2 = BASEDIR "\\test_nttransrename_2.dat";
+ NTSTATUS status;
+ bool ret = true;
+ union smb_open io;
+ union smb_fileinfo qfi, qpi;
+ union smb_rename rn;
+ uint16_t fnum=0;
+
+ if (!torture_setup_dir(cli1, BASEDIR)) {
+ return false;
+ }
+
+ /* cleanup */
+ smbcli_unlink(cli1->tree, fname1);
+ smbcli_unlink(cli1->tree, fname2);
+
+ smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
+
+ /*
+ base ntcreatex parms
+ */
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.access_mask = 0;/* ask for no access at all */;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname1;
+
+ torture_comment(tctx, "nttrans_rename: open a file with an exclusive oplock (share mode: none)\n");
+ ZERO_STRUCT(break_info);
+ io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
+ NTCREATEX_FLAGS_REQUEST_OPLOCK;
+ status = smb_raw_open(cli1->tree, tctx, &io);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+ CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
+
+ torture_comment(tctx, "nttrans_rename: should not trigger a break nor a share mode violation\n");
+ ZERO_STRUCT(rn);
+ rn.generic.level = RAW_RENAME_NTTRANS;
+ rn.nttrans.in.file.fnum = fnum;
+ rn.nttrans.in.flags = 0;
+ rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
+
+ status = smb_raw_rename(cli1->tree, &rn);
+
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_VAL(break_info.count, 0);
+
+ /* w2k3 does nothing, it doesn't rename the file */
+ torture_comment(tctx, "nttrans_rename: the server should have done nothing\n");
+ ZERO_STRUCT(qfi);
+ qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qfi.generic.in.file.fnum = fnum;
+
+ status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_STRMATCH(qfi.all_info.out.fname.s, fname1);
+
+ ZERO_STRUCT(qpi);
+ qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qpi.generic.in.file.path = fname1;
+
+ status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
+
+ ZERO_STRUCT(qpi);
+ qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qpi.generic.in.file.path = fname2;
+
+ status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+ torture_comment(tctx, "nttrans_rename: after closing the file the file is still not renamed\n");
+ status = smbcli_close(cli1->tree, fnum);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ ZERO_STRUCT(qpi);
+ qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qpi.generic.in.file.path = fname1;
+
+ status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ CHECK_STRMATCH(qpi.all_info.out.fname.s, fname1);
+
+ ZERO_STRUCT(qpi);
+ qpi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ qpi.generic.in.file.path = fname2;
+
+ status = smb_raw_pathinfo(cli1->tree, tctx, &qpi);
+ CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+ torture_comment(tctx, "nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE\n");
+ ZERO_STRUCT(rn);
+ rn.generic.level = RAW_RENAME_NTTRANS;
+ rn.nttrans.in.file.fnum = fnum+1;
+ rn.nttrans.in.flags = 0;
+ rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
+
+ status = smb_raw_rename(cli1->tree, &rn);
+
+ CHECK_STATUS(tctx, status, NT_STATUS_INVALID_HANDLE);
+
+done:
+ smb_raw_exit(cli1->session);
+ smbcli_deltree(cli1->tree, BASEDIR);
+ return ret;
+}
+
+
static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
{
const char *fname1 = BASEDIR "\\test_batch20_1.dat";
@@ -2148,10 +2342,6 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
union smb_setfileinfo sfi;
uint16_t fnum=0,fnum2=0;
- if (torture_setting_bool(tctx, "samba3", false)) {
- torture_skip(tctx, "BACHT20 disabled against samba3\n");
- }
-
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
}
@@ -2178,7 +2368,7 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname1;
- torture_comment(tctx, "open a file with an batch oplock (share mode: all)\n");
+ torture_comment(tctx, "BATCH20: open a file with an batch oplock (share mode: all)\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -2212,7 +2402,6 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
CHECK_STATUS(tctx, status, NT_STATUS_OK);
CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
- /* we should use no share mode, when samba3 passes this */
torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
@@ -2307,7 +2496,7 @@ static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_
/*
with a batch oplock we get a break
*/
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH21: open with batch oplock\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -2350,7 +2539,7 @@ static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_
int te;
if (torture_setting_bool(tctx, "samba3", false)) {
- torture_skip(tctx, "BACHT22 disabled against samba3\n");
+ torture_skip(tctx, "BATCH22 disabled against samba3\n");
}
if (!torture_setup_dir(cli1, BASEDIR)) {
@@ -2380,7 +2569,7 @@ static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_
/*
with a batch oplock we get a break
*/
- torture_comment(tctx, "open with batch oplock\n");
+ torture_comment(tctx, "BATCH22: open with batch oplock\n");
ZERO_STRUCT(break_info);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -2440,7 +2629,7 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
struct smbcli_state *cli3 = NULL;
if (torture_setting_bool(tctx, "samba3", false)) {
- torture_skip(tctx, "BACHT23 disabled against samba3\n");
+ torture_skip(tctx, "BATCH23 disabled against samba3\n");
}
if (!torture_setup_dir(cli1, BASEDIR)) {
@@ -2470,7 +2659,7 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "a open and ask for a batch oplock\n");
+ torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
@@ -2557,7 +2746,7 @@ static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = fname;
- torture_comment(tctx, "a open without level support and ask for a batch oplock\n");
+ torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
ZERO_STRUCT(break_info);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c
index 4b0d986659..9765c04101 100644
--- a/source4/torture/raw/rename.c
+++ b/source4/torture/raw/rename.c
@@ -434,6 +434,8 @@ done:
return ret;
}
+extern bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2);
+extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1);
/*
basic testing of rename calls
@@ -443,6 +445,10 @@ struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
struct torture_suite *suite = torture_suite_create(mem_ctx, "RENAME");
torture_suite_add_1smb_test(suite, "mv", test_mv);
+ /* test_trans2rename and test_nttransrename are actually in torture/raw/oplock.c to
+ use the handlers and macros there. */
+ torture_suite_add_2smb_test(suite, "trans2rename", test_trans2rename);
+ torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename);
torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);
return suite;
diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c
index 0242b9c545..725ed261aa 100644
--- a/source4/torture/raw/search.c
+++ b/source4/torture/raw/search.c
@@ -708,6 +708,16 @@ static bool test_many_files(struct torture_context *tctx,
for (t=0;t<ARRAY_SIZE(search_types);t++) {
ZERO_STRUCT(result);
+
+ if ((search_types[t].cont_type == CONT_RESUME_KEY) &&
+ (search_types[t].data_level != RAW_SEARCH_DATA_SEARCH) &&
+ torture_setting_bool(tctx, "samba3", false)) {
+ torture_comment(tctx,
+ "SKIP: Continue %s via %s\n",
+ search_types[t].name, search_types[t].cont_name);
+ continue;
+ }
+
result.tctx = talloc_new(tctx);
torture_comment(tctx,
diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c
index ca6b488af5..1dab36c28b 100644
--- a/source4/torture/raw/streams.c
+++ b/source4/torture/raw/streams.c
@@ -356,22 +356,24 @@ static bool test_stream_sharemodes(struct torture_context *tctx,
* A different stream does not give a sharing violation
*/
+ io.ntcreatex.in.fname = sname2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- fnum1 = io.ntcreatex.out.file.fnum;
+ fnum2 = io.ntcreatex.out.file.fnum;
/*
* ... whereas the same stream does with unchanged access/share_access
* flags
*/
+ io.ntcreatex.in.fname = sname1;
io.ntcreatex.in.open_disposition = 0;
status = smb_raw_open(cli->tree, mem_ctx, &io);
CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
io.ntcreatex.in.fname = sname2;
status = smb_raw_open(cli->tree, mem_ctx, &io);
- CHECK_STATUS(status, NT_STATUS_OK);
- fnum2 = io.ntcreatex.out.file.fnum;
+ CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
done:
if (fnum1 != -1) smbcli_close(cli->tree, fnum1);
@@ -558,7 +560,9 @@ bool torture_raw_streams(struct torture_context *torture,
}
ret &= test_stream_io(torture, cli, torture);
+ smb_raw_exit(cli->session);
ret &= test_stream_sharemodes(torture, cli, torture);
+ smb_raw_exit(cli->session);
if (!torture_setting_bool(torture, "samba4", false)) {
ret &= test_stream_delete(torture, cli, torture);
}
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index 60d022fbea..04d13a97c1 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -295,8 +295,8 @@ static bool test_LookupNames_wellknown(struct dcerpc_pipe *p,
ret &= test_LookupNames(p, mem_ctx, handle, &tnames);
name.name.string = "BUILTIN\\Administrators";
- ret &= test_LookupNames(p, mem_ctx, handle, &tnames);
name.sid_type = SID_NAME_ALIAS;
+ ret &= test_LookupNames(p, mem_ctx, handle, &tnames);
name.name.string = "SYSTEM";
name.sid_type = SID_NAME_WKN_GRP;
diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index 95252e7397..204a9f2865 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -47,6 +47,7 @@
#include "libcli/smb_composite/smb_composite.h"
#include "libcli/auth/libcli_auth.h"
#include "lib/crypto/crypto.h"
+#include "auth/ntlmssp/ntlmssp.h"
#include "libcli/security/proto.h"
#include "param/param.h"
#include "lib/registry/registry.h"
@@ -682,6 +683,7 @@ static bool join3(struct smbcli_state *cli,
struct dcerpc_pipe *samr_pipe;
struct policy_handle *wks_handle;
bool ret = false;
+ NTTIME last_password_change;
if ((mem_ctx = talloc_init("join3")) == NULL) {
d_printf("talloc_init failed\n");
@@ -701,6 +703,22 @@ static bool join3(struct smbcli_state *cli,
goto done;
}
+ {
+ struct samr_QueryUserInfo q;
+
+ q.in.user_handle = wks_handle;
+ q.in.level = 21;
+
+ status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) QueryUserInfo failed: %s\n",
+ __location__, nt_errstr(status));
+ goto done;
+ }
+
+ last_password_change = q.out.info->info21.last_password_change;
+ }
+
cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
if (use_level25) {
@@ -794,6 +812,39 @@ static bool join3(struct smbcli_state *cli,
}
}
+ {
+ struct samr_QueryUserInfo q;
+
+ q.in.user_handle = wks_handle;
+ q.in.level = 21;
+
+ status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) QueryUserInfo failed: %s\n",
+ __location__, nt_errstr(status));
+ goto done;
+ }
+
+ if (use_level25) {
+ if (last_password_change
+ == q.out.info->info21.last_password_change) {
+ d_printf("(%s) last_password_change unchanged "
+ "during join, level25 must change "
+ "it\n", __location__);
+ goto done;
+ }
+ }
+ else {
+ if (last_password_change
+ != q.out.info->info21.last_password_change) {
+ d_printf("(%s) last_password_change changed "
+ "during join, level24 doesn't "
+ "change it\n", __location__);
+ goto done;
+ }
+ }
+ }
+
ret = true;
done:
@@ -1321,6 +1372,8 @@ bool torture_samba3_sessionkey(struct torture_context *torture)
goto done;
}
+ cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);
+
ret = true;
if (!torture_setting_bool(torture, "samba3", false)) {
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 1d6ec43399..55c75ba270 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -2332,9 +2332,15 @@ static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx
status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
- if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- printf("Server refused create of '%s'\n", r.in.alias_name->string);
- return true;
+ if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
+ return true;
+ } else {
+ printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
+ nt_errstr(status));
+ return false;
+ }
}
if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
@@ -2515,7 +2521,8 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *domain_handle,
- struct policy_handle *user_handle_out,
+ struct policy_handle *user_handle_out,
+ struct dom_sid *domain_sid,
enum torture_samr_choice which_ops)
{
@@ -2546,10 +2553,15 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
status = dcerpc_samr_CreateUser(p, user_ctx, &r);
- if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
- talloc_free(user_ctx);
- return true;
+ if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
+ return true;
+ } else {
+ printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
+ nt_errstr(status));
+ return false;
+ }
}
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
@@ -2610,7 +2622,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
- struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
+ struct policy_handle *domain_handle,
+ struct dom_sid *domain_sid,
+ enum torture_samr_choice which_ops)
{
NTSTATUS status;
struct samr_CreateUser2 r;
@@ -2663,12 +2677,19 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
- if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- talloc_free(user_ctx);
- printf("Server refused create of '%s'\n", r.in.account_name->string);
- continue;
+ if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
+ continue;
+ } else {
+ printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
+ nt_errstr(status));
+ ret = false;
+ continue;
+ }
+ }
- } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
talloc_free(user_ctx);
ret = false;
@@ -3893,6 +3914,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
if (!q1.out.sam) {
+ printf("EnumDomainGroups failed to return q1.out.sam\n");
return false;
}
@@ -4138,7 +4160,9 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *domain_handle, struct policy_handle *group_handle)
+ struct policy_handle *domain_handle,
+ struct policy_handle *group_handle,
+ struct dom_sid *domain_sid)
{
NTSTATUS status;
struct samr_CreateDomainGroup r;
@@ -4158,15 +4182,19 @@ static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
- if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- printf("Server refused create of '%s'\n", r.in.name->string);
- ZERO_STRUCTP(group_handle);
- return true;
+ if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("Server correctly refused create of '%s'\n", r.in.name->string);
+ return true;
+ } else {
+ printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
+ nt_errstr(status));
+ return false;
+ }
}
if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
-
printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
nt_errstr(status));
return false;
@@ -4244,7 +4272,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
ZERO_STRUCT(group_handle);
ZERO_STRUCT(domain_handle);
- printf("Testing OpenDomain\n");
+ printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
r.in.connect_handle = handle;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -4264,17 +4292,23 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
switch (which_ops) {
case TORTURE_SAMR_USER_ATTRIBUTES:
case TORTURE_SAMR_PASSWORDS:
- ret &= test_CreateUser2(p, tctx, &domain_handle, which_ops);
- ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
+ ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
+ ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
/* This test needs 'complex' users to validate */
ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
+ if (!ret) {
+ printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
+ }
break;
case TORTURE_SAMR_OTHER:
- ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
+ ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
+ if (!ret) {
+ printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
+ }
ret &= test_QuerySecurity(p, tctx, &domain_handle);
ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
- ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle);
+ ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
@@ -4295,6 +4329,9 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
ret &= test_RidToSid(p, tctx, sid, &domain_handle);
ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
+ if (!ret) {
+ printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
+ }
break;
}
diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c
index 3144fe91b1..0c9a41fd70 100644
--- a/source4/utils/ntlm_auth.c
+++ b/source4/utils/ntlm_auth.c
@@ -285,7 +285,7 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod
DATA_BLOB in;
if (strlen(buf) < 2) {
DEBUG(1, ("query [%s] invalid", buf));
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH Query invalid\n");
return;
}
@@ -302,7 +302,7 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod
if (*password == NULL) {
DEBUG(1, ("Out of memory\n"));
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH Out of memory\n");
data_blob_free(&in);
return;
}
@@ -312,7 +312,7 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod
return;
}
DEBUG(1, ("Asked for (and expected) a password\n"));
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH Expected a password\n");
data_blob_free(&in);
}
@@ -420,7 +420,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
if (strlen(buf) < 2) {
DEBUG(1, ("query [%s] invalid", buf));
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH Query invalid\n");
return;
}
@@ -444,7 +444,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
}
} else if ( (strncmp(buf, "OK", 2) == 0)) {
/* Just return BH, like ntlm_auth from Samba 3 does. */
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH Command expected\n");
data_blob_free(&in);
return;
} else if ( (strncmp(buf, "TT ", 3) != 0) &&
@@ -456,7 +456,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
(strncmp(buf, "GK", 2) != 0) &&
(strncmp(buf, "GF", 2) != 0)) {
DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH SPNEGO request invalid\n");
data_blob_free(&in);
return;
}
@@ -545,7 +545,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("GENSEC mech failed to start: %s\n", nt_errstr(nt_status)));
- mux_printf(mux_id, "BH\n");
+ mux_printf(mux_id, "BH GENSEC mech failed to start\n");
return;
}
@@ -655,11 +655,11 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
- reply_code = "BH";
+ reply_code = "BH NT_STATUS_ACCESS_DENIED";
reply_arg = nt_errstr(nt_status);
DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) {
- reply_code = "BH";
+ reply_code = "BH NT_STATUS_UNSUCCESSFUL";
reply_arg = nt_errstr(nt_status);
DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));
} else if (!NT_STATUS_IS_OK(nt_status)) {
@@ -671,7 +671,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
nt_status = gensec_session_info(state->gensec_state, &session_info);
if (!NT_STATUS_IS_OK(nt_status)) {
- reply_code = "BH";
+ reply_code = "BH Failed to retrive session info";
reply_arg = nt_errstr(nt_status);
DEBUG(1, ("GENSEC failed to retreive the session info: %s\n", nt_errstr(nt_status)));
} else {
diff --git a/source4/winbind/config.mk b/source4/winbind/config.mk
index d303d20901..3c5b740e68 100644
--- a/source4/winbind/config.mk
+++ b/source4/winbind/config.mk
@@ -28,6 +28,8 @@ WINBIND_OBJ_FILES = $(addprefix winbind/, \
wb_dom_info_trusted.o \
wb_sid2domain.o \
wb_name2domain.o \
+ wb_sids2xids.o \
+ wb_xids2sids.o \
wb_gid2sid.o \
wb_sid2uid.o \
wb_sid2gid.o \
diff --git a/source4/winbind/idmap.c b/source4/winbind/idmap.c
index 3372ad51ee..de8a43ec02 100644
--- a/source4/winbind/idmap.c
+++ b/source4/winbind/idmap.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
- Map SIDs to uids/gids and back
+ Map SIDs to unixids and back
Copyright (C) Kai Blin 2008
@@ -177,39 +177,46 @@ struct idmap_context *idmap_init(TALLOC_CTX *mem_ctx,
return NULL;
}
+ idmap_ctx->unix_groups_sid = dom_sid_parse_talloc(mem_ctx, "S-1-22-2");
+ if (idmap_ctx->unix_groups_sid == NULL) {
+ return NULL;
+ }
+
+ idmap_ctx->unix_users_sid = dom_sid_parse_talloc(mem_ctx, "S-1-22-1");
+ if (idmap_ctx->unix_users_sid == NULL) {
+ return NULL;
+ }
+
return idmap_ctx;
}
/**
- * Convert a uid to the corresponding SID
+ * Convert an unixid to the corresponding SID
*
* \param idmap_ctx idmap context to use
* \param mem_ctx talloc context the memory for the struct dom_sid is allocated
* from.
- * \param uid Unix uid to map to a SID
- * \param sid Pointer that will take the struct dom_sid pointer if the mapping
+ * \param unixid pointer to a unixid struct to convert
+ * \param sid pointer that will take the struct dom_sid pointer if the mapping
* succeeds.
* \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping not
* possible or some other NTSTATUS that is more descriptive on failure.
*/
-NTSTATUS idmap_uid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
- const uid_t uid, struct dom_sid **sid)
+NTSTATUS idmap_xid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
+ const struct unixid *unixid, struct dom_sid **sid)
{
int ret;
NTSTATUS status = NT_STATUS_NONE_MAPPED;
struct ldb_context *ldb = idmap_ctx->ldb_ctx;
- struct ldb_message *msg;
struct ldb_result *res = NULL;
- int trans = -1;
- uid_t low, high;
- char *sid_string, *uid_string;
- struct dom_sid *unix_users_sid, *new_sid;
+ uint32_t low, high;
+ struct dom_sid *unix_sid, *new_sid;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(uidNumber=%u))",
- uid);
+ NULL, "(&(objectClass=sidMap)(xidNumber=%u))",
+ unixid->id);
if (ret != LDB_SUCCESS) {
DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
status = NT_STATUS_NONE_MAPPED;
@@ -228,19 +235,13 @@ NTSTATUS idmap_uid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- DEBUG(6, ("uid not found in idmap db, trying to allocate SID.\n"));
-
- trans = ldb_transaction_start(ldb);
- if (trans != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
+ DEBUG(6, ("xid not found in idmap db, trying to allocate SID.\n"));
/* Now redo the search to make sure noone added a mapping for that SID
* while we weren't looking.*/
ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(uidNumber=%u))",
- uid);
+ NULL, "(&(objectClass=sidMap)(xidNumber=%u))",
+ unixid->id);
if (ret != LDB_SUCCESS) {
DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
status = NT_STATUS_NONE_MAPPED;
@@ -260,285 +261,58 @@ NTSTATUS idmap_uid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
- if (uid >= low && uid <= high) {
- /* An existing user would have been mapped before */
- status = NT_STATUS_NO_SUCH_USER;
+ if (unixid->id >= low && unixid->id <= high) {
+ /* An existing xid would have been mapped before */
+ status = NT_STATUS_NONE_MAPPED;
goto failed;
}
/* For local users, we just create a rid = uid +1, so root doesn't end
* up with a 0 rid */
- unix_users_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-1");
- if (unix_users_sid == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- new_sid = dom_sid_add_rid(mem_ctx, unix_users_sid, uid + 1);
- if (new_sid == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- sid_string = dom_sid_string(tmp_ctx, new_sid);
- if (sid_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- uid_string = talloc_asprintf(tmp_ctx, "%u", uid);
- if (uid_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- msg = ldb_msg_new(tmp_ctx);
- if (msg == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s", sid_string);
- if (msg->dn == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- ret = ldb_msg_add_string(msg, "uidNumber", uid_string);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = idmap_msg_add_dom_sid(idmap_ctx, tmp_ctx, msg, "objectSid",
- new_sid);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_msg_add_string(msg, "objectClass", "sidMap");
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_msg_add_string(msg, "cn", sid_string);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_add(ldb, msg);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- trans = ldb_transaction_commit(ldb);
- if (trans != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- *sid = new_sid;
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
-
-failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
- talloc_free(tmp_ctx);
- return status;
-}
-
-/**
- * Map a Unix gid to the corresponding SID
- *
- * \param idmap_ctx idmap context to use
- * \param mem_ctx talloc context the memory for the struct dom_sid is allocated
- * from.
- * \param gid Unix gid to map to a SID
- * \param sid Pointer that will take the struct dom_sid pointer if mapping
- * succeeds.
- * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping not
- * possible or some other NTSTATUS that is more descriptive on failure.
- */
-NTSTATUS idmap_gid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
- const gid_t gid, struct dom_sid **sid)
-{
- int ret;
- NTSTATUS status = NT_STATUS_NONE_MAPPED;
- struct ldb_context *ldb = idmap_ctx->ldb_ctx;
- struct ldb_message *msg;
- struct ldb_result *res = NULL;
- int trans = -1;
- gid_t low, high;
- char *sid_string, *gid_string;
- struct dom_sid *unix_groups_sid, *new_sid;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-
- ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(gidNumber=%u))", gid);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (res->count == 1) {
- *sid = idmap_msg_get_dom_sid(mem_ctx, res->msgs[0],
- "objectSid");
- if (*sid == NULL) {
- DEBUG(1, ("Failed to get sid from db: %u\n", ret));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
- /* No change, so cancel the transaction */
- ldb_transaction_cancel(ldb);
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
- }
-
- DEBUG(6, ("gid not found in idmap db, trying to allocate SID.\n"));
-
- trans = ldb_transaction_start(ldb);
- if (trans != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- /* Now redo the search to make sure noone added a mapping for that SID
- * while we weren't looking.*/
- ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(gidNumber=%u))",
- gid);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (res->count > 0) {
- DEBUG(1, ("sidMap modified while trying to add a mapping.\n"));
- status = NT_STATUS_RETRY;
- goto failed;
- }
-
- ret = idmap_get_bounds(idmap_ctx, &low, &high);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to get id bounds from db: %u\n", ret));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (gid >= low && gid <= high) {
- /* An existing group would have been mapped before */
- status = NT_STATUS_NO_SUCH_USER;
- goto failed;
+ if (unixid->type == ID_TYPE_UID) {
+ unix_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-1");
+ } else {
+ unix_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-2");
}
-
- /* For local groups, we just create a rid = gid +1, so root doesn't end
- * up with a 0 rid */
- unix_groups_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-2");
- if (unix_groups_sid == NULL) {
+ if (unix_sid == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
- new_sid = dom_sid_add_rid(mem_ctx, unix_groups_sid, gid + 1);
+ new_sid = dom_sid_add_rid(mem_ctx, unix_sid, unixid->id + 1);
if (new_sid == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
- sid_string = dom_sid_string(tmp_ctx, new_sid);
- if (sid_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- gid_string = talloc_asprintf(tmp_ctx, "%u", gid);
- if (gid_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- msg = ldb_msg_new(tmp_ctx);
- if (msg == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s", sid_string);
- if (msg->dn == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- ret = ldb_msg_add_string(msg, "gidNumber", gid_string);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = idmap_msg_add_dom_sid(idmap_ctx, tmp_ctx, msg, "objectSid",
- new_sid);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_msg_add_string(msg, "objectClass", "sidMap");
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_msg_add_string(msg, "cn", sid_string);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_add(ldb, msg);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- trans = ldb_transaction_commit(ldb);
- if (trans != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
*sid = new_sid;
talloc_free(tmp_ctx);
return NT_STATUS_OK;
failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
talloc_free(tmp_ctx);
return status;
}
+
/**
- * Map a SID to a Unix uid.
+ * Map a SID to an unixid struct.
*
* If no mapping exists, a new mapping will be created.
*
* \todo Check if SIDs can be resolved if lp_idmap_trusted_only() == true
+ * \todo Fix backwards compatibility for Samba3
*
* \param idmap_ctx idmap context to use
* \param mem_ctx talloc context to use
- * \param sid SID to map to a Unix uid
- * \param uid pointer to receive the mapped uid
+ * \param sid SID to map to an unixid struct
+ * \param unixid pointer to a unixid struct pointer
* \return NT_STATUS_OK on success, NT_STATUS_INVALID_SID if the sid is not from
* a trusted domain and idmap trusted only = true, NT_STATUS_NONE_MAPPED if the
* mapping failed.
*/
-NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
- const struct dom_sid *sid, uid_t *uid)
+NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
+ const struct dom_sid *sid, struct unixid **unixid)
{
int ret;
NTSTATUS status = NT_STATUS_NONE_MAPPED;
@@ -547,8 +321,8 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
struct ldb_message *hwm_msg, *map_msg;
struct ldb_result *res = NULL;
int trans;
- uid_t low, high, hwm, new_uid;
- char *sid_string, *uid_string, *hwm_string;
+ uint32_t low, high, hwm, new_xid;
+ char *sid_string, *unixid_string, *hwm_string;
bool hwm_entry_exists;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
@@ -562,20 +336,65 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
}
if (res->count == 1) {
- new_uid = ldb_msg_find_attr_as_uint(res->msgs[0], "uidNumber",
+ new_xid = ldb_msg_find_attr_as_uint(res->msgs[0], "xidNumber",
-1);
- if (new_uid == (uid_t) -1) {
- DEBUG(1, ("Invalid uid mapping.\n"));
+ if (new_xid == (uint32_t) -1) {
+ DEBUG(1, ("Invalid xid mapping.\n"));
status = NT_STATUS_NONE_MAPPED;
goto failed;
}
- *uid = new_uid;
+
+ *unixid = talloc(mem_ctx, struct unixid);
+ if (*unixid == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+
+ (*unixid)->id = new_xid;
+ (*unixid)->type = ID_TYPE_BOTH;
+
talloc_free(tmp_ctx);
return NT_STATUS_OK;
}
DEBUG(6, ("No existing mapping found, attempting to create one.\n"));
+ if (dom_sid_in_domain(idmap_ctx->unix_users_sid, sid)) {
+ uint32_t rid;
+ DEBUG(6, ("This is a local unix uid, just calculate that.\n"));
+ status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ *unixid = talloc(mem_ctx, struct unixid);
+ if (*unixid == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+ (*unixid)->id = rid - 1;
+ (*unixid)->type = ID_TYPE_UID;
+
+ talloc_free(tmp_ctx);
+ return NT_STATUS_OK;
+ }
+
+ if (dom_sid_in_domain(idmap_ctx->unix_groups_sid, sid)) {
+ uint32_t rid;
+ DEBUG(6, ("This is a local unix gid, just calculate that.\n"));
+ status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ *unixid = talloc(mem_ctx, struct unixid);
+ if (*unixid == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+ (*unixid)->id = rid - 1;
+ (*unixid)->type = ID_TYPE_GID;
+
+ talloc_free(tmp_ctx);
+ return NT_STATUS_OK;
+ }
+
trans = ldb_transaction_start(ldb);
if (trans != LDB_SUCCESS) {
status = NT_STATUS_NONE_MAPPED;
@@ -629,8 +448,8 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
- hwm = ldb_msg_find_attr_as_uint(res->msgs[0], "uidNumber", -1);
- if (hwm == (uid_t)-1) {
+ hwm = ldb_msg_find_attr_as_uint(res->msgs[0], "xidNumber", -1);
+ if (hwm == (uint32_t)-1) {
hwm = low;
hwm_entry_exists = false;
} else {
@@ -638,7 +457,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
}
if (hwm > high) {
- DEBUG(1, ("Out of uids to allocate.\n"));
+ DEBUG(1, ("Out of xids to allocate.\n"));
status = NT_STATUS_NONE_MAPPED;
goto failed;
}
@@ -652,7 +471,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
hwm_msg->dn = dn;
- new_uid = hwm;
+ new_xid = hwm;
hwm++;
hwm_string = talloc_asprintf(tmp_ctx, "%u", hwm);
@@ -667,8 +486,8 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
- uid_string = talloc_asprintf(tmp_ctx, "%u", new_uid);
- if (uid_string == NULL) {
+ unixid_string = talloc_asprintf(tmp_ctx, "%u", new_xid);
+ if (unixid_string == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
@@ -696,7 +515,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
els[0].num_values = 1;
els[0].values = &vals[0];
els[0].flags = LDB_FLAG_MOD_DELETE;
- els[0].name = talloc_strdup(tmp_ctx, "uidNumber");
+ els[0].name = talloc_strdup(tmp_ctx, "xidNumber");
if (els[0].name == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
@@ -707,19 +526,19 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
els[1].flags = LDB_FLAG_MOD_ADD;
els[1].name = els[0].name;
- vals[0].data = (uint8_t *)uid_string;
- vals[0].length = strlen(uid_string);
+ vals[0].data = (uint8_t *)unixid_string;
+ vals[0].length = strlen(unixid_string);
vals[1].data = (uint8_t *)hwm_string;
vals[1].length = strlen(hwm_string);
} else {
- ret = ldb_msg_add_empty(hwm_msg, "uidNumber", LDB_FLAG_MOD_ADD,
+ ret = ldb_msg_add_empty(hwm_msg, "xidNumber", LDB_FLAG_MOD_ADD,
NULL);
if (ret != LDB_SUCCESS) {
status = NT_STATUS_NONE_MAPPED;
goto failed;
}
- ret = ldb_msg_add_string(hwm_msg, "uidNumber", hwm_string);
+ ret = ldb_msg_add_string(hwm_msg, "xidNumber", hwm_string);
if (ret != LDB_SUCCESS)
{
status = NT_STATUS_NONE_MAPPED;
@@ -729,7 +548,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
ret = ldb_modify(ldb, hwm_msg);
if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Updating the uid high water mark failed: %s\n",
+ DEBUG(1, ("Updating the xid high water mark failed: %s\n",
ldb_errstring(ldb)));
status = NT_STATUS_NONE_MAPPED;
goto failed;
@@ -747,7 +566,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
- ret = ldb_msg_add_string(map_msg, "uidNumber", uid_string);
+ ret = ldb_msg_add_string(map_msg, "xidNumber", unixid_string);
if (ret != LDB_SUCCESS) {
status = NT_STATUS_NONE_MAPPED;
goto failed;
@@ -786,7 +605,14 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
goto failed;
}
- *uid = new_uid;
+ *unixid = talloc(mem_ctx, struct unixid);
+ if (*unixid == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+
+ (*unixid)->id = new_xid;
+ (*unixid)->type = ID_TYPE_BOTH;
talloc_free(tmp_ctx);
return NT_STATUS_OK;
@@ -797,276 +623,92 @@ failed:
}
/**
- * Map a SID to a Unix gid.
- *
- * If no mapping exist, a new mapping will be created.
- *
- * \todo Check if SID resolve when lp_idmap_trusted_only() == true
+ * Convert an array of unixids to the corresponding array of SIDs
*
* \param idmap_ctx idmap context to use
- * \param mem_ctx talloc context to use
- * \param sid SID to map to a Unix gid
- * \param gid pointer to receive the mapped gid
- * \return NT_STATUS_OK on success, NT_STATUS_INVALID_SID if the sid is not from
- * a trusted domain and idmap trusted only = true, NT_STATUS_NONE_MAPPED if the
- * mapping failed.
+ * \param mem_ctx talloc context the memory for the dom_sids is allocated
+ * from.
+ * \param count length of id_mapping array.
+ * \param id array of id_mappings.
+ * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping is not
+ * possible at all, NT_STATUS_SOME_UNMAPPED if some mappings worked and some
+ * did not.
*/
-NTSTATUS idmap_sid_to_gid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
- const struct dom_sid *sid, gid_t *gid)
-{
- int ret;
- NTSTATUS status = NT_STATUS_NONE_MAPPED;
- struct ldb_context *ldb = idmap_ctx->ldb_ctx;
- struct ldb_dn *dn;
- struct ldb_message *hwm_msg, *map_msg;
- struct ldb_result *res = NULL;
- int trans = -1;
- gid_t low, high, hwm, new_gid;
- char *sid_string, *gid_string, *hwm_string;
- bool hwm_entry_exists;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(objectSid=%s))",
- ldap_encode_ndr_dom_sid(tmp_ctx, sid));
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (res->count == 1) {
- new_gid = ldb_msg_find_attr_as_uint(res->msgs[0], "gidNumber",
- -1);
- if (new_gid == (gid_t) -1) {
- DEBUG(1, ("Invalid gid mapping.\n"));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
+NTSTATUS idmap_xids_to_sids(struct idmap_context *idmap_ctx,
+ TALLOC_CTX *mem_ctx, int count,
+ struct id_mapping *id)
+{
+ int i;
+ int error_count = 0;
+
+ for (i = 0; i < count; ++i) {
+ id[i].status = idmap_xid_to_sid(idmap_ctx, mem_ctx,
+ id[i].unixid, &id[i].sid);
+ if (NT_STATUS_EQUAL(id[i].status, NT_STATUS_RETRY)) {
+ id[i].status = idmap_xid_to_sid(idmap_ctx, mem_ctx,
+ id[i].unixid,
+ &id[i].sid);
+ }
+ if (!NT_STATUS_IS_OK(id[i].status)) {
+ DEBUG(1, ("idmapping failed for id[%d]\n", i));
+ error_count++;
}
- *gid = new_gid;
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
- }
-
- DEBUG(6, ("No existing mapping found, attempting to create one.\n"));
-
- trans = ldb_transaction_start(ldb);
- if (trans != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- /* Redo the search to make sure noone changed the mapping while we
- * weren't looking */
- ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
- NULL, "(&(objectClass=sidMap)(objectSid=%s))",
- ldap_encode_ndr_dom_sid(tmp_ctx, sid));
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- if (res->count > 0) {
- DEBUG(1, ("Database changed while trying to add a sidmap.\n"));
- status = NT_STATUS_RETRY;
- goto failed;
- }
-
- /*FIXME: if lp_idmap_trusted_only() == true, check if SID can be
- * resolved here. */
-
- ret = idmap_get_bounds(idmap_ctx, &low, &high);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- dn = ldb_dn_new(tmp_ctx, ldb, "CN=CONFIG");
- if (dn == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- talloc_steal(tmp_ctx, res);
-
- if (res->count != 1) {
- DEBUG(1, ("No CN=CONFIG record, idmap database is broken.\n"));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
}
- hwm = ldb_msg_find_attr_as_uint(res->msgs[0], "gidNumber", -1);
- if (hwm == (gid_t)-1) {
- hwm = low;
- hwm_entry_exists = false;
+ if (error_count == count) {
+ /* Mapping did not work at all. */
+ return NT_STATUS_NONE_MAPPED;
+ } else if (error_count > 0) {
+ /* Some mappings worked, some did not. */
+ return STATUS_SOME_UNMAPPED;
} else {
- hwm_entry_exists = true;
- }
-
- if (hwm > high) {
- DEBUG(1, ("Out of gids to allocate.\n"));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- hwm_msg = ldb_msg_new(tmp_ctx);
- if (hwm_msg == NULL) {
- DEBUG(1, ("Out of memory when creating ldb_message\n"));
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- hwm_msg->dn = dn;
-
- new_gid = hwm;
- hwm++;
-
- hwm_string = talloc_asprintf(tmp_ctx, "%u", hwm);
- if (hwm_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- sid_string = dom_sid_string(tmp_ctx, sid);
- if (sid_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- gid_string = talloc_asprintf(tmp_ctx, "%u", new_gid);
- if (gid_string == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
+ return NT_STATUS_OK;
}
+}
- if (hwm_entry_exists) {
- struct ldb_message_element *els;
- struct ldb_val *vals;
-
- /* We're modifying the entry, not just adding a new one. */
- els = talloc_array(tmp_ctx, struct ldb_message_element, 2);
- if (els == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- vals = talloc_array(tmp_ctx, struct ldb_val, 2);
- if (els == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- hwm_msg->num_elements = 2;
- hwm_msg->elements = els;
-
- els[0].num_values = 1;
- els[0].values = &vals[0];
- els[0].flags = LDB_FLAG_MOD_DELETE;
- els[0].name = talloc_strdup(tmp_ctx, "gidNumber");
- if (els[0].name == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- els[1].num_values = 1;
- els[1].values = &vals[1];
- els[1].flags = LDB_FLAG_MOD_ADD;
- els[1].name = els[0].name;
+/**
+ * Convert an array of SIDs to the corresponding array of unixids
+ *
+ * \param idmap_ctx idmap context to use
+ * \param mem_ctx talloc context the memory for the unixids is allocated
+ * from.
+ * \param count length of id_mapping array.
+ * \param id array of id_mappings.
+ * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping is not
+ * possible at all, NT_STATUS_SOME_UNMAPPED if some mappings worked and some
+ * did not.
+ */
- vals[0].data = (uint8_t *)gid_string;
- vals[0].length = strlen(gid_string);
- vals[1].data = (uint8_t *)hwm_string;
- vals[1].length = strlen(hwm_string);
- } else {
- ret = ldb_msg_add_empty(hwm_msg, "gidNumber", LDB_FLAG_MOD_ADD,
- NULL);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
+NTSTATUS idmap_sids_to_xids(struct idmap_context *idmap_ctx,
+ TALLOC_CTX *mem_ctx, int count,
+ struct id_mapping *id)
+{
+ int i;
+ int error_count = 0;
+
+ for (i = 0; i < count; ++i) {
+ id[i].status = idmap_sid_to_xid(idmap_ctx, mem_ctx,
+ id[i].sid, &id[i].unixid);
+ if (NT_STATUS_EQUAL(id[i].status, NT_STATUS_RETRY)) {
+ id[i].status = idmap_sid_to_xid(idmap_ctx, mem_ctx,
+ id[i].sid,
+ &id[i].unixid);
}
-
- ret = ldb_msg_add_string(hwm_msg, "gidNumber", hwm_string);
- if (ret != LDB_SUCCESS)
- {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
+ if (!NT_STATUS_IS_OK(id[i].status)) {
+ DEBUG(1, ("idmapping failed for id[%d]\n", i));
+ error_count++;
}
}
- ret = ldb_modify(ldb, hwm_msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Updating the gid high water mark failed: %s\n",
- ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- map_msg = ldb_msg_new(tmp_ctx);
- if (map_msg == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- map_msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s", sid_string);
- if (map_msg->dn == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- ret = ldb_msg_add_string(map_msg, "gidNumber", gid_string);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = idmap_msg_add_dom_sid(idmap_ctx, tmp_ctx, map_msg, "objectSid",
- sid);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_msg_add_string(map_msg, "objectClass", "sidMap");
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_msg_add_string(map_msg, "cn", sid_string);
- if (ret != LDB_SUCCESS) {
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- ret = ldb_add(ldb, map_msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Adding a sidmap failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
- }
-
- trans = ldb_transaction_commit(ldb);
- if (trans != LDB_SUCCESS) {
- DEBUG(1, ("Transaction failed: %s\n", ldb_errstring(ldb)));
- status = NT_STATUS_NONE_MAPPED;
- goto failed;
+ if (error_count == count) {
+ /* Mapping did not work at all. */
+ return NT_STATUS_NONE_MAPPED;
+ } else if (error_count > 0) {
+ /* Some mappings worked, some did not. */
+ return STATUS_SOME_UNMAPPED;
+ } else {
+ return NT_STATUS_OK;
}
-
- *gid = new_gid;
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
-
-failed:
- if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
- talloc_free(tmp_ctx);
- return status;
}
diff --git a/source4/winbind/idmap.h b/source4/winbind/idmap.h
index 8781819be0..045d50c568 100644
--- a/source4/winbind/idmap.h
+++ b/source4/winbind/idmap.h
@@ -25,6 +25,26 @@
struct idmap_context {
struct loadparm_context *lp_ctx;
struct ldb_context *ldb_ctx;
+ struct dom_sid *unix_groups_sid;
+ struct dom_sid *unix_users_sid;
+};
+
+enum id_type {
+ ID_TYPE_NOT_SPECIFIED = 0,
+ ID_TYPE_UID,
+ ID_TYPE_GID,
+ ID_TYPE_BOTH
+};
+
+struct unixid {
+ uint32_t id;
+ enum id_type type;
+};
+
+struct id_mapping {
+ struct unixid *unixid;
+ struct dom_sid *sid;
+ NTSTATUS status;
};
#include "winbind/idmap_proto.h"
diff --git a/source4/winbind/wb_gid2sid.c b/source4/winbind/wb_gid2sid.c
index f2577029aa..834d869845 100644
--- a/source4/winbind/wb_gid2sid.c
+++ b/source4/winbind/wb_gid2sid.c
@@ -3,7 +3,7 @@
Command backend for wbinfo -G
- Copyright (C) Kai Blin 2007
+ Copyright (C) 2007-2008 Kai Blin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,35 +33,60 @@ struct gid2sid_state {
struct dom_sid *sid;
};
+static void gid2sid_recv_sid(struct composite_context *ctx);
+
struct composite_context *wb_gid2sid_send(TALLOC_CTX *mem_ctx,
struct wbsrv_service *service, gid_t gid)
{
- struct composite_context *result;
+ struct composite_context *result, *ctx;
struct gid2sid_state *state;
+ struct unixid *unixid;
+ struct id_mapping *ids;
DEBUG(5, ("wb_gid2sid_send called\n"));
result = composite_create(mem_ctx, service->task->event_ctx);
if (!result) return NULL;
- state = talloc(mem_ctx, struct gid2sid_state);
+ state = talloc(result, struct gid2sid_state);
if (composite_nomem(state, result)) return result;
state->ctx = result;
result->private_data = state;
state->service = service;
- state->ctx->status = idmap_gid_to_sid(service->idmap_ctx, mem_ctx, gid,
- &state->sid);
- if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
- state->ctx->status = idmap_gid_to_sid(service->idmap_ctx,
- mem_ctx, gid,
- &state->sid);
+ unixid = talloc(result, struct unixid);
+ if (composite_nomem(unixid, result)) return result;
+ unixid->id = gid;
+ unixid->type = ID_TYPE_GID;
+
+ ids = talloc(result, struct id_mapping);
+ if (composite_nomem(ids, result)) return result;
+ ids->unixid = unixid;
+ ids->sid = NULL;
+
+ ctx = wb_xids2sids_send(result, service, 1, ids);
+ if (composite_nomem(ctx, result)) return result;
+
+ composite_continue(result, ctx, gid2sid_recv_sid, state);
+ return result;
+}
+
+static void gid2sid_recv_sid(struct composite_context *ctx)
+{
+ struct gid2sid_state *state = talloc_get_type(ctx->async.private_data,
+ struct gid2sid_state);
+ struct id_mapping *ids = NULL;
+ state->ctx->status = wb_xids2sids_recv(ctx, &ids);
+ if (!composite_is_ok(state->ctx)) return;
+
+ if (!NT_STATUS_IS_OK(ids->status)) {
+ composite_error(state->ctx, ids->status);
+ return;
}
- if (!composite_is_ok(state->ctx)) return result;
+ state->sid = ids->sid;
composite_done(state->ctx);
- return result;
}
NTSTATUS wb_gid2sid_recv(struct composite_context *ctx, TALLOC_CTX *mem_ctx,
diff --git a/source4/winbind/wb_sid2gid.c b/source4/winbind/wb_sid2gid.c
index 12129226be..d68956ce85 100644
--- a/source4/winbind/wb_sid2gid.c
+++ b/source4/winbind/wb_sid2gid.c
@@ -3,7 +3,7 @@
Map a SID to a gid
- Copyright (C) Kai Blin 2007
+ Copyright (C) 2007-2008 Kai Blin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,11 +33,14 @@ struct sid2gid_state {
gid_t gid;
};
+static void sid2gid_recv_gid(struct composite_context *ctx);
+
struct composite_context *wb_sid2gid_send(TALLOC_CTX *mem_ctx,
struct wbsrv_service *service, const struct dom_sid *sid)
{
- struct composite_context *result;
+ struct composite_context *result, *ctx;
struct sid2gid_state *state;
+ struct id_mapping *ids;
DEBUG(5, ("wb_sid2gid_send called\n"));
@@ -51,18 +54,43 @@ struct composite_context *wb_sid2gid_send(TALLOC_CTX *mem_ctx,
result->private_data = state;
state->service = service;
- state->ctx->status = idmap_sid_to_gid(service->idmap_ctx, state, sid,
- &state->gid);
- if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
- state->ctx->status = idmap_sid_to_gid(service->idmap_ctx, state,
- sid, &state->gid);
- }
- if (!composite_is_ok(state->ctx)) return result;
+ ids = talloc(result, struct id_mapping);
+ if (composite_nomem(ids, result)) return result;
+
+ ids->sid = dom_sid_dup(result, sid);
+ if (composite_nomem(ids->sid, result)) return result;
+
+ ctx = wb_sids2xids_send(result, service, 1, ids);
+ if (composite_nomem(ctx, result)) return result;
- composite_done(state->ctx);
+ composite_continue(result, ctx, sid2gid_recv_gid, state);
return result;
}
+static void sid2gid_recv_gid(struct composite_context *ctx)
+{
+ struct sid2gid_state *state = talloc_get_type(ctx->async.private_data,
+ struct sid2gid_state);
+
+ struct id_mapping *ids = NULL;
+
+ state->ctx->status = wb_sids2xids_recv(ctx, &ids);
+ if (!composite_is_ok(state->ctx)) return;
+
+ if (!NT_STATUS_IS_OK(ids->status)) {
+ composite_error(state->ctx, ids->status);
+ return;
+ }
+
+ if (ids->unixid->type == ID_TYPE_BOTH ||
+ ids->unixid->type == ID_TYPE_GID) {
+ state->gid = ids->unixid->id;
+ composite_done(state->ctx);
+ } else {
+ composite_error(state->ctx, NT_STATUS_INVALID_SID);
+ }
+}
+
NTSTATUS wb_sid2gid_recv(struct composite_context *ctx, gid_t *gid)
{
NTSTATUS status = composite_wait(ctx);
diff --git a/source4/winbind/wb_sid2uid.c b/source4/winbind/wb_sid2uid.c
index 0de45fdea9..b65e41978c 100644
--- a/source4/winbind/wb_sid2uid.c
+++ b/source4/winbind/wb_sid2uid.c
@@ -3,7 +3,7 @@
Map a SID to a uid
- Copyright (C) Kai Blin 2007-2008
+ Copyright (C) 2007-2008 Kai Blin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,11 +33,14 @@ struct sid2uid_state {
uid_t uid;
};
+static void sid2uid_recv_uid(struct composite_context *ctx);
+
struct composite_context *wb_sid2uid_send(TALLOC_CTX *mem_ctx,
struct wbsrv_service *service, const struct dom_sid *sid)
{
- struct composite_context *result;
+ struct composite_context *result, *ctx;
struct sid2uid_state *state;
+ struct id_mapping *ids;
DEBUG(5, ("wb_sid2uid_send called\n"));
@@ -45,24 +48,49 @@ struct composite_context *wb_sid2uid_send(TALLOC_CTX *mem_ctx,
if (!result) return NULL;
state = talloc(result, struct sid2uid_state);
- if(composite_nomem(state, result)) return result;
+ if (composite_nomem(state, result)) return result;
state->ctx = result;
result->private_data = state;
state->service = service;
- state->ctx->status = idmap_sid_to_uid(service->idmap_ctx, state, sid,
- &state->uid);
- if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
- state->ctx->status = idmap_sid_to_uid(service->idmap_ctx, state,
- sid, &state->uid);
- }
- if (!composite_is_ok(state->ctx)) return result;
+ ids = talloc(result, struct id_mapping);
+ if (composite_nomem(ids, result)) return result;
+
+ ids->sid = dom_sid_dup(result, sid);
+ if (composite_nomem(ids->sid, result)) return result;
+
+ ctx = wb_sids2xids_send(result, service, 1, ids);
+ if (composite_nomem(ctx, result)) return result;
- composite_done(state->ctx);
+ composite_continue(result, ctx, sid2uid_recv_uid, state);
return result;
}
+static void sid2uid_recv_uid(struct composite_context *ctx)
+{
+ struct sid2uid_state *state = talloc_get_type(ctx->async.private_data,
+ struct sid2uid_state);
+
+ struct id_mapping *ids = NULL;
+
+ state->ctx->status = wb_sids2xids_recv(ctx, &ids);
+ if (!composite_is_ok(state->ctx)) return;
+
+ if (!NT_STATUS_IS_OK(ids->status)) {
+ composite_error(state->ctx, ids->status);
+ return;
+ }
+
+ if (ids->unixid->type == ID_TYPE_BOTH ||
+ ids->unixid->type == ID_TYPE_UID) {
+ state->uid = ids->unixid->id;
+ composite_done(state->ctx);
+ } else {
+ composite_error(state->ctx, NT_STATUS_INVALID_SID);
+ }
+}
+
NTSTATUS wb_sid2uid_recv(struct composite_context *ctx, uid_t *uid)
{
NTSTATUS status = composite_wait(ctx);
diff --git a/source4/winbind/wb_sids2xids.c b/source4/winbind/wb_sids2xids.c
new file mode 100644
index 0000000000..302b915ff5
--- /dev/null
+++ b/source4/winbind/wb_sids2xids.c
@@ -0,0 +1,82 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Map SIDs to unixids.
+
+ Copyright (C) 2008 Kai Blin
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/composite/composite.h"
+#include "winbind/wb_server.h"
+#include "smbd/service_task.h"
+#include "winbind/wb_helper.h"
+#include "libcli/security/proto.h"
+#include "winbind/idmap.h"
+
+struct sids2xids_state {
+ struct composite_context *ctx;
+ struct wbsrv_service *service;
+ struct id_mapping *ids;
+ int count;
+};
+
+struct composite_context *wb_sids2xids_send(TALLOC_CTX *mem_ctx,
+ struct wbsrv_service *service,
+ int count, struct id_mapping *ids)
+{
+ struct composite_context *result;
+ struct sids2xids_state *state;
+
+ DEBUG(5, ("wb_sids2xids_send called\n"));
+
+ result = composite_create(mem_ctx, service->task->event_ctx);
+ if (!result) return NULL;
+
+ state = talloc(result, struct sids2xids_state);
+ if (composite_nomem(state, result)) return result;
+
+ state->ctx = result;
+ result->private_data = state;
+ state->service = service;
+ state->count = count;
+ state->ids = ids;
+
+ state->ctx->status = idmap_sids_to_xids(service->idmap_ctx, mem_ctx,
+ count, state->ids);
+ if (!composite_is_ok(state->ctx)) return result;
+
+ composite_done(state->ctx);
+ return result;
+}
+
+NTSTATUS wb_sids2xids_recv(struct composite_context *ctx,
+ struct id_mapping **ids)
+{
+ NTSTATUS status = composite_wait(ctx);
+
+ DEBUG(5, ("wb_sids2xids_recv called\n"));
+
+ if (NT_STATUS_IS_OK(status)) {
+ struct sids2xids_state *state =
+ talloc_get_type(ctx->private_data,
+ struct sids2xids_state);
+ *ids = state->ids;
+ }
+ talloc_free(ctx);
+ return status;
+}
+
diff --git a/source4/winbind/wb_uid2sid.c b/source4/winbind/wb_uid2sid.c
index e81d2e4671..fd43dd64b9 100644
--- a/source4/winbind/wb_uid2sid.c
+++ b/source4/winbind/wb_uid2sid.c
@@ -3,7 +3,7 @@
Command backend for wbinfo -U
- Copyright (C) Kai Blin 2007-2008
+ Copyright (C) 2007-2008 Kai Blin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,35 +33,62 @@ struct uid2sid_state {
struct dom_sid *sid;
};
+static void uid2sid_recv_sid(struct composite_context *ctx);
+
struct composite_context *wb_uid2sid_send(TALLOC_CTX *mem_ctx,
struct wbsrv_service *service, uid_t uid)
{
- struct composite_context *result;
+ struct composite_context *result, *ctx;
struct uid2sid_state *state;
+ struct unixid *unixid;
+ struct id_mapping *ids;
DEBUG(5, ("wb_uid2sid_send called\n"));
result = composite_create(mem_ctx, service->task->event_ctx);
if (!result) return NULL;
- state = talloc(mem_ctx, struct uid2sid_state);
+ state = talloc(result, struct uid2sid_state);
if (composite_nomem(state, result)) return result;
state->ctx = result;
result->private_data = state;
state->service = service;
- state->ctx->status = idmap_uid_to_sid(service->idmap_ctx, mem_ctx, uid,
- &state->sid);
- if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
- state->ctx->status = idmap_uid_to_sid(service->idmap_ctx,
- mem_ctx, uid,
- &state->sid);
+ unixid = talloc(result, struct unixid);
+ if (composite_nomem(unixid, result)) return result;
+ unixid->id = uid;
+ unixid->type = ID_TYPE_UID;
+
+ ids = talloc(result, struct id_mapping);
+ if (composite_nomem(ids, result)) return result;
+ ids->unixid = unixid;
+ ids->sid = NULL;
+
+ ctx = wb_xids2sids_send(result, service, 1, ids);
+ if (composite_nomem(ctx, result)) return result;
+
+ composite_continue(result, ctx, uid2sid_recv_sid, state);
+ return result;
+}
+
+static void uid2sid_recv_sid(struct composite_context *ctx)
+{
+ struct uid2sid_state *state = talloc_get_type(ctx->async.private_data,
+ struct uid2sid_state);
+ struct id_mapping *ids = NULL;
+
+ state->ctx->status = wb_xids2sids_recv(ctx, &ids);
+ if (!composite_is_ok(state->ctx)) return;
+
+ if (!NT_STATUS_IS_OK(ids->status)) {
+ composite_error(state->ctx, ids->status);
+ return;
}
- if (!composite_is_ok(state->ctx)) return result;
+
+ state->sid = ids->sid;
composite_done(state->ctx);
- return result;
}
NTSTATUS wb_uid2sid_recv(struct composite_context *ctx, TALLOC_CTX *mem_ctx,
diff --git a/source4/winbind/wb_xids2sids.c b/source4/winbind/wb_xids2sids.c
new file mode 100644
index 0000000000..843d292c07
--- /dev/null
+++ b/source4/winbind/wb_xids2sids.c
@@ -0,0 +1,82 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Convet an unixid struct to a SID
+
+ Copyright (C) 2008 Kai Blin
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/composite/composite.h"
+#include "winbind/wb_server.h"
+#include "smbd/service_task.h"
+#include "winbind/wb_helper.h"
+#include "libcli/security/proto.h"
+#include "winbind/idmap.h"
+
+struct xids2sids_state {
+ struct composite_context *ctx;
+ struct wbsrv_service *service;
+ struct id_mapping *ids;
+ int count;
+};
+
+struct composite_context *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
+ struct wbsrv_service *service,
+ int count, struct id_mapping *ids)
+{
+ struct composite_context *result;
+ struct xids2sids_state *state;
+
+ DEBUG(0, ("wb_xids2sids_send called\n"));
+
+ result = composite_create(mem_ctx, service->task->event_ctx);
+ if (!result) return NULL;
+
+ state = talloc(mem_ctx, struct xids2sids_state);
+ if (composite_nomem(state, result)) return result;
+
+ state->ctx = result;
+ result->private_data = state;
+ state->service = service;
+ state->count = count;
+ state->ids = ids;
+
+ state->ctx->status = idmap_xids_to_sids(service->idmap_ctx, mem_ctx,
+ count, state->ids);
+ if (!composite_is_ok(state->ctx)) return result;
+
+ composite_done(state->ctx);
+ return result;
+}
+
+NTSTATUS wb_xids2sids_recv(struct composite_context *ctx,
+ struct id_mapping **ids)
+{
+ NTSTATUS status = composite_wait(ctx);
+
+ DEBUG(0, ("wb_xids2sids_recv called.\n"));
+
+ if (NT_STATUS_IS_OK(status)) {
+ struct xids2sids_state *state =
+ talloc_get_type(ctx->private_data,
+ struct xids2sids_state);
+ *ids = state->ids;
+ }
+ talloc_free(ctx);
+ return status;
+}
+
diff --git a/testprogs/ejs/ldap.js b/testprogs/ejs/ldap.js
index c30f29e249..44e4c83e67 100755
--- a/testprogs/ejs/ldap.js
+++ b/testprogs/ejs/ldap.js
@@ -866,12 +866,30 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer," + base_dn + "
}
assert(res.msgs[0].dn == ("CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn));
- assert(strupper(res.msgs[0].memberOf[0]) == strupper(("CN=ldaptestgroup2,CN=Users," + base_dn)));
+ assert(strupper(res.msgs[0].memberOf[0]) == (strupper("CN=ldaptestgroup2,CN=Users," + base_dn)));
- println("Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn + ")(objectclass=group)) to check subtree renames and linked attributes");
- var res = ldb.search("(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn + ")(objectclass=group))", base_dn, ldb.SCOPE_SUBTREE);
+ println("Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) in cn=users");
+ var res_group = ldb.search("(&(cn=ldaptestgroup2)(objectClass=group))", "cn=users," + base_dn, ldb.SCOPE_SUBTREE);
+ if (res_group.error != 0 || res_group.msgs.length != 1) {
+ println("Could not find (&(cn=ldaptestgroup2)(objectClass=group)) under cn=users," + base_dn);
+ assert(res_group.error == 0);
+ assert(res_group.msgs.length == 1);
+ }
+
+ println("Testing ldb.search for (member=CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn + ") to check subtree renames and linked attributes");
+ var res = ldb.search("(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn + ")", base_dn, ldb.SCOPE_SUBTREE);
if (res.error != 0 || res.msgs.length != 1) {
- println("Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn + ")(objectclass=group)), perhaps linked attributes are not conistant with subtree renames?");
+ for (i=0; i < res_group.msgs[0].member.length; i++) {
+ println("res_group.member[" + i + "]: " + res_group.msgs[0].member[i]);
+ }
+
+ println("Could not find (member=CN=ldaptestuser4,CN=ldaptestcontainer2," + base_dn + "), perhaps linked attributes are not conistant with subtree renames?");
+ println("Testing ldb.search for (member=CN=ldaptestuser4,CN=ldaptestcontainer," + base_dn + ") to check if it just hasn't been updated");
+ var res2 = ldb.search("(member=CN=ldaptestuser4,CN=ldaptestcontainer," + base_dn + ")", base_dn, ldb.SCOPE_SUBTREE);
+ if (res2.error != 0 || res2.msgs.length != 1) {
+ println("Could not find (member=CN=ldaptestuser4,CN=ldaptestcontainer," + base_dn + "), very odd, it wasn't here at all..");
+ }
+
assert(res.error == 0);
assert(res.msgs.length == 1);
}
@@ -992,7 +1010,7 @@ objectClass: user
assert(res.msgs[0].objectCategory == ("CN=Person,CN=Schema,CN=Configuration," + base_dn));
assert(res.msgs[0].sAMAccountType == 805306368);
assert(res.msgs[0].userAccountControl == 546);
- assert(res.msgs[0].memberOf[0] == ("CN=ldaptestgroup2,CN=Users," + base_dn));
+ assert(strupper(res.msgs[0].memberOf[0]) == strupper("CN=ldaptestgroup2,CN=Users," + base_dn));
assert(res.msgs[0].memberOf.length == 1);
println("Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + base_dn + "))");