-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
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
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
actually due to Kerberos objecting to a clock skew between client
and server.
+
RUNNING Samba4
==============
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__ */
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;
#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__ */
* 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;
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 */
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);
"
])
-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
"
# Start Library $1
@<:@LIBRARY::$1@:>@
PRIVATE_DEPENDENCIES = $3
-VERSION = $4
-SO_VERSION = $5
CFLAGS = \$($1_CFLAGS)
LDFLAGS = \$($1_LDFLAGS)
ENABLE = YES
*/
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)
{
* 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;
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");
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;
}
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) {
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);
*
*/
-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)
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;
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) {
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 */
/* 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,
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;
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;
}
}
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);
+ }
}
}
}
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");
/* 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) {
/* 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,
#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
}
r.u.ntlmInitReply.flags |=
- NTLM_NEG_TARGET_DOMAIN |
+ NTLM_NEG_TARGET |
+ NTLM_TARGET_DOMAIN |
NTLM_ENC_128;
#define ALL \
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");
#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>
_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__ */
*/
/*
- * $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__
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)
#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))
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;
*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.
*/
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;
}
if(n < pa.len) {
- /* stripped out newer enctypes */
+ /* stripped out dups, newer enctypes, and not valid enctypes */
pa.len = n;
}
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);
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;
}
goto out;
}
- ret = _kdc_windc_client_access(context, client, req);
+ ret = _kdc_windc_client_access(context, client, req, &e_data);
if(ret)
goto out;
* 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
#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
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,
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;
}
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);
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);
}
ret = krb5_decrypt_EncryptedData (context,
crypto,
- KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+ usage,
b->enc_authorization_data,
&ad);
krb5_crypto_destroy(context, crypto);
ret = krb5_unparse_name(context, sp, &spn);
if (ret)
goto out;
+ auth_data = NULL; /* ms don't handle AD in referals */
goto 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);
}
/*
- * 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.
*/
*/
#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,
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);
}
#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
static int
match_rfc_san(krb5_context context,
krb5_kdc_configuration *config,
+ hx509_context hx509ctx,
hx509_cert client_cert,
krb5_const_principal match)
{
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)
static int
match_ms_upn_san(krb5_context context,
krb5_kdc_configuration *config,
+ hx509_context hx509ctx,
hx509_cert client_cert,
krb5_const_principal match)
{
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)
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)
if (config->pkinit_princ_in_cert) {
ret = match_rfc_san(context, config,
+ kdc_identity->hx509ctx,
client_params->cert,
client->entry.principal);
if (ret == 0) {
return 0;
}
ret = match_ms_upn_san(context, config,
+ kdc_identity->hx509ctx,
client_params->cert,
client->entry.principal);
if (ret == 0) {
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,
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;
}
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);
}
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
/*
- * 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.
*
*/
#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"
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);
char *renewstr = NULL;
krb5_enctype *enctype = NULL;
struct ntlm_buf ntlmkey;
+ krb5_ccache tempccache;
memset(&ntlmkey, 0, sizeof(ntlmkey));
passwd[0] = '\0';
}
}
- 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);
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");
-/* $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>
--- $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
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 {
#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[] = {
--- $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 {
init [0] DigestInit,
digestRequest [1] DigestRequest,
ntlmInit [2] NTLMInit,
- ntlmRequest [3] NTLMRequest
+ ntlmRequest [3] NTLMRequest,
+ supportedMechs [4] NULL
}
DigestREQ ::= [APPLICATION 128] SEQUENCE {
initReply [1] DigestInitReply,
response [2] DigestResponse,
ntlmInitReply [3] NTLMInitReply,
- ntlmResponse [4] NTLMResponse
+ ntlmResponse [4] NTLMResponse,
+ supportedMechs [5] DigestTypes,
+ ...
}
DigestREP ::= [APPLICATION 129] SEQUENCE {
#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;
#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)
--- $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
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),
-#include "config.h"
-#line 3 "heimdal/lib/asn1/lex.c"
+#line 3 "lex.c"
#define YY_INT_ALIGNED short int
* 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>
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
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.
*/
#line 68 "lex.l"
-#line 1010 "heimdal/lib/asn1/lex.c"
+#line 1039 "lex.c"
if ( !(yy_init) )
{
#line 274 "lex.l"
ECHO;
YY_BREAK
-#line 1679 "heimdal/lib/asn1/lex.c"
+#line 1708 "lex.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
/* 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);
}
/** 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
/* 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>
/* Enabling traces. */
#ifndef YYDEBUG
-# define YYDEBUG 0
+# define YYDEBUG 1
#endif
/* Enabling verbose error messages. */
#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;
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
/* Line 216 of yacc.c. */
-#line 331 "heimdal/lib/asn1/parse.y"
+#line 331 "parse.c"
#ifdef short
# undef short
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) {
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);
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);
break;
case 24:
-#line 303 "heimdal/lib/asn1/parse.y"
+#line 303 "parse.y"
{
Symbol *s = addsym ((yyvsp[(1) - (3)].name));
s->stype = Stype;
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));
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");
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");
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");
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");
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));
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);
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);
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));
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);
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);
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);
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));
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);
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));
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);
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));
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);
break;
case 64:
-#line 486 "heimdal/lib/asn1/parse.y"
+#line 486 "parse.y"
{
(yyval.type) = new_type(TSequence);
(yyval.type)->members = NULL;
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);
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);
break;
case 67:
-#line 509 "heimdal/lib/asn1/parse.y"
+#line 509 "parse.y"
{
(yyval.type) = new_type(TSet);
(yyval.type)->members = NULL;
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);
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);
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);
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));
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));
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
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);
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");
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");
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);
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);
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));
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));
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));
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));
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));
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));
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));
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));
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));
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);
break;
case 104:
-#line 735 "heimdal/lib/asn1/parse.y"
+#line 735 "parse.y"
{
struct member *m = ecalloc(1, sizeof(*m));
m->name = estrdup("...");
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);
break;
case 106:
-#line 757 "heimdal/lib/asn1/parse.y"
+#line 757 "parse.y"
{
(yyval.member) = (yyvsp[(1) - (1)].member);
(yyval.member)->optional = 0;
break;
case 107:
-#line 763 "heimdal/lib/asn1/parse.y"
+#line 763 "parse.y"
{
(yyval.member) = (yyvsp[(1) - (2)].member);
(yyval.member)->optional = 1;
break;
case 108:
-#line 769 "heimdal/lib/asn1/parse.y"
+#line 769 "parse.y"
{
(yyval.member) = (yyvsp[(1) - (3)].member);
(yyval.member)->optional = 0;
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));
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);
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);
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);
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 ||
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)
break;
case 130:
-#line 877 "heimdal/lib/asn1/parse.y"
+#line 877 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = stringvalue;
break;
case 131:
-#line 885 "heimdal/lib/asn1/parse.y"
+#line 885 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = booleanvalue;
break;
case 132:
-#line 891 "heimdal/lib/asn1/parse.y"
+#line 891 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = booleanvalue;
break;
case 133:
-#line 899 "heimdal/lib/asn1/parse.y"
+#line 899 "parse.y"
{
(yyval.value) = emalloc(sizeof(*(yyval.value)));
(yyval.value)->type = integervalue;
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;
/* 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);
}
-#line 922 "heimdal/lib/asn1/parse.y"
+#line 922 "parse.y"
void
#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;
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
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;
DHNonce ::= OCTET STRING
+KDFAlgorithmId ::= SEQUENCE {
+ kdf-id [0] OBJECT IDENTIFIER,
+ ...
+}
+
TrustedCA ::= SEQUENCE {
caName [0] IMPLICIT OCTET STRING,
certificateSerialNumber [1] INTEGER OPTIONAL,
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
clientDHNonce [3] DHNonce OPTIONAL,
+ ...,
+ supportedKDFs [4] SEQUENCE OF KDFAlgorithmId OPTIONAL,
...
}
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 {
...
}
+PkinitSuppPubInfo ::= SEQUENCE {
+ enctype [0] INTEGER (-2147483648..2147483647),
+ as-REQ [1] OCTET STRING,
+ pk-as-rep [2] OCTET STRING,
+ ticket [3] Ticket,
+ ...
+}
+
END
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 }
-#include "config.h"
-#line 3 "heimdal/lib/com_err/lex.c"
+#line 3 "lex.c"
#define YY_INT_ALIGNED short int
#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);
#undef ECHO
-#line 536 "heimdal/lib/com_err/lex.c"
+#line 536 "lex.c"
#define INITIAL 0
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.
*/
#line 59 "lex.l"
-#line 691 "heimdal/lib/com_err/lex.c"
+#line 720 "lex.c"
if ( !(yy_init) )
{
#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();
/* 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);
}
/** 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
/* 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
#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
/* Line 216 of yacc.c. */
-#line 186 "heimdal/lib/com_err/parse.y"
+#line 186 "parse.c"
#ifdef short
# undef short
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));
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));
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));
break;
case 13:
-#line 110 "heimdal/lib/com_err/parse.y"
+#line 110 "parse.y"
{
prefix = realloc(prefix, 1);
if (prefix == NULL)
break;
case 14:
-#line 117 "heimdal/lib/com_err/parse.y"
+#line 117 "parse.y"
{
struct error_code *ec = malloc(sizeof(*ec));
break;
case 15:
-#line 137 "heimdal/lib/com_err/parse.y"
+#line 137 "parse.y"
{
YYACCEPT;
}
/* 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);
}
-#line 142 "heimdal/lib/com_err/parse.y"
+#line 142 "parse.y"
static long
#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
* 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_
/* 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
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 */
#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,
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,
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;
}
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 {
ccache,
handle->principal,
&handle->lifetime);
- if (ret != GSS_S_COMPLETE)
+ if (ret != GSS_S_COMPLETE) {
+ krb5_cc_close(context, ccache);
goto end;
+ }
kret = 0;
}
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);
}
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)
#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
* Context for krb5 calls.
*/
-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*/,
* 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
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;
/*
- * 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.
*
#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
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,
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;
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;
goto failure;
}
} else
- ccache = initiator_cred_handle->ccache;
+ ccache = cred->ccache;
kret = krb5_cc_get_principal (context, ccache, &ctx->source);
if (kret) {
{
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);
}
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,
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;
* 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,
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;
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)
kret = krb5_build_authenticator (context,
ctx->auth_context,
enctype,
- cred,
+ kcred,
&cksum,
NULL,
&authenticator,
kret = krb5_build_ap_req (context,
enctype,
- cred,
+ kcred,
ap_options,
authenticator,
&outbuf);
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) {
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;
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,
)
{
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;
#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,
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
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;
}
#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;
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;
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);
+}
*/
#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)
/*
* 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);
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.
*/
*/
#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>
memset(key, 0, sizeof(*key));
}
-
OM_uint32
gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
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;
+}
+
#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"
*/
#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,
{
*minor_status = 0;
- if (*set) {
+ if (set && *set) {
if ((*set)->elements)
free((*set)->elements);
free(*set);
#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,
gss_cred_id_t *delegated_cred_handle
)
{
- OM_uint32 ret, junk, minor;
+ OM_uint32 ret, junk;
NegotiationToken nt;
size_t nt_len;
NegTokenInit *ni;
/*
* 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,
*/
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,
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
goto out;
first_ok = 1;
+ } else {
+ gss_mg_collect_error(preferred_mech_type, ret, *minor_status);
}
}
* 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) {
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;
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;
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;
}
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;
#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
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) {
#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)
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,
)
{
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 (
#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:
_gss_spnego_verify_mic,
_gss_spnego_wrap,
_gss_spnego_unwrap,
- _gss_spnego_display_status,
+ NULL,
NULL,
_gss_spnego_compare_name,
_gss_spnego_display_name,
#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´.
&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);
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;
}
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;
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;
}
gss_buffer_t /*output_name_buffer*/,
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*/,
#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>
}
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 };
*/
/*
- * $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
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);
--- /dev/null
+/* 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]);
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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 */
#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)
*
*/
-const DH_METHOD hc_dh_imath_method = {
+const DH_METHOD _hc_dh_imath_method = {
"hcrypto imath DH",
dh_generate_key,
dh_compute_key,
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;
}
/*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
#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>
#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 *
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)
{
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)
{
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)
{
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)
{
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
*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;
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)
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)
{
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)
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)
{
+/*
+ * 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>
#include <krb5-types.h>
#include <aes.h>
+#include "camellia.h"
#include <des.h>
#include <sha.h>
#include <rc2.h>
#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 *);
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
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)
{
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)
{
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)
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)
{
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)
{
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)
{
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)
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 *
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)
{
return &md5;
}
+/**
+ * The message digest MD4
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_md4(void)
{
return &md4;
}
+/**
+ * The message digest MD2
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_MD *
EVP_md2(void)
{
{
}
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)
{
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
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)
{
}
#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)
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)
{
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)
{
return 1;
}
+/**
+ * The RC2 cipher type
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
const EVP_CIPHER *
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)
{
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)
{
return &rc2_64_cbc;
}
-/*
+/**
+ * The RC4 cipher type
*
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
*/
const EVP_CIPHER *
return NULL;
}
+/**
+ * The RC4-40 cipher type
+ *
+ * @return the RC4-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
const EVP_CIPHER *
EVP_rc4_40(void)
{
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)
{
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)
{
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)
{
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)
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;
+}
+
/*
*
*/
{ "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)
#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,
return EVP_CIPHER_key_length(type);
}
-/*
+/**
+ * Add all algorithms to the crypto core.
*
+ * @ingroup hcrypto_core
*/
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)
{
* 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
#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
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);
/*
*
-#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>
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.
return MP_RANGE;
/* Skip leading whitespace */
- while(isspace((int)*str))
+ while(isspace((unsigned char)*str))
++str;
/* Handle leading sign tag (+/-, positive default) */
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;
#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>
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;
/*
- * 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.
*
#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>
#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)
{
return rsa;
}
+/**
+ * Free an allocation RSA object.
+ *
+ * @param rsa the RSA object to free.
+ * @ingroup hcrypto_rsa
+ */
void
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)
{
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)
{
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)
{
}
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)
*/
/*
- * $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
/* 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
const RSA_METHOD *RSA_null_method(void);
const RSA_METHOD *RSA_imath_method(void);
+const RSA_METHOD *RSA_gmp_method(void);
/*
*
--- /dev/null
+/*
+ * 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;
+}
HDB **/*db*/,
const char */*filename*/);
+const char *
+hdb_db_dir (krb5_context /*context*/);
+
const char *
hdb_dbinfo_get_acl_file (
krb5_context /*context*/,
krb5_context /*context*/,
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*/,
krb5_context /*context*/,
struct hdb_dbinfo */*dbp*/);
+const char *
+hdb_default_db (krb5_context /*context*/);
+
krb5_error_code
hdb_enctype2key (
krb5_context /*context*/,
* 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__
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;
* 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__
#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*/,
#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)
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' */
} 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
}
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 */
/*
* 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
#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;
*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;
#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;
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)
{
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)
{
*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,
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,
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,
{ 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,
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;
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,
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,
}
+/**
+ * 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)
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,
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,
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,
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,
if (issuername) {
#if 1
+ /**
+ * issuername not supported
+ */
hx509_set_error_string(context, 0, EINVAL,
"CRLDistributionPoints.name.issuername not yet supported");
return EINVAL;
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,
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,
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,
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,
}
+/**
+ * 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,
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,
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,
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,
}
+/**
+ * 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,
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,
*/
#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;
#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
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)
{
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)
{
*context = NULL;
}
-
/*
*
*/
return cert->data;
}
-/*
- *
- */
-
-#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
-
/*
*
*/
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)
{
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)
{
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)
{
return;
if (cert->ref <= 0)
- _hx509_abort("refcount <= 0");
+ _hx509_abort("cert refcount <= 0 on free");
if (--cert->ref > 0)
return;
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++;
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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 &&
{
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;
}
}
free_GeneralNames(&sa);
}
- return ret;
+ return 0;
}
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)
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;
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.
*/
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;
}
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
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);
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,
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)
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)
{
return p->private_key;
}
+int
+hx509_cert_have_private_key(hx509_cert p)
+{
+ return p->private_key ? 1 : 0;
+}
+
+
int
_hx509_cert_private_key_exportable(hx509_cert p)
{
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;
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;
}
free_GeneralNames(&sa);
} while (1);
-
return ret;
}
}
/* 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;
}
}
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;
}
}
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,
{
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;
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
*/
proxy_cert_depth = 0;
+ selfsigned_depth = 0;
if (ctx->flags & HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE)
type = PROXY_CERT;
switch (type) {
case CA_CERT:
+
/* XXX make constants for keyusage */
ret = check_key_usage(context, c, 1 << 5,
REQUIRE_RFC3280(ctx) ? TRUE : FALSE);
"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;
*/
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");
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");
*/
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;
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;
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;
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.
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 */
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,
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,
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)
{
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)
{
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)
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)
{
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)
{
}
}
+/**
+ * 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,
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)
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),
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);
}
_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);
&& 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) {
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 =
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)
{
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)
{
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)
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)
{
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");
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);
+}
*/
#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,
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);
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,
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,
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)
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,
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)
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;
}
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,
}
/*
- * 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) {
*/
#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;
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);
#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 *,
}
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);
const AlgorithmIdentifier *digest_alg;
heim_octet_string indata;
const heim_oid *sig_oid;
- DigestInfo di;
size_t size;
int ret;
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;
}
}
- 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);
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,
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",
rsa_private_key2SPKI,
rsa_private_key_export,
rsa_private_key_import,
- rsa_generate_private_key
+ rsa_generate_private_key,
+ rsa_get_internal
};
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
};
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
};
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
};
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
};
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
};
&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,
{ 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
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; }
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,
*/
#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 {
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)
{
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)
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)
return NULL;
}
+/**
+ * Free an hx509_env enviroment context.
+ *
+ * @param env the enviroment to free.
+ *
+ * @ingroup hx509_env
+ */
void
hx509_env_free(hx509_env *env)
*/
#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;
}
}
+/**
+ * Resets the error strings the hx509 context.
+ *
+ * @param context A hx509 context.
+ *
+ * @ingroup hx509_error
+ */
+
void
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)
}
}
+/**
+ * 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, ...)
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)
{
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, ...)
#define __attribute__(x)
#endif
+int
+_hx509_AlgorithmIdentifier_cmp (
+ const AlgorithmIdentifier */*p*/,
+ const AlgorithmIdentifier */*q*/);
+
int
_hx509_Certificate_cmp (
const Certificate */*p*/,
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 (
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 *),
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*/,
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*/,
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*/,
int
hx509_cert_find_subjectAltName_otherName (
+ hx509_context /*context*/,
hx509_cert /*cert*/,
const heim_oid */*oid*/,
hx509_octet_string_list */*list*/);
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*/,
hx509_cert /*p*/,
hx509_name */*name*/);
+int
+hx509_cert_have_private_key (hx509_cert /*p*/);
+
int
hx509_cert_init (
hx509_context /*context*/,
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
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*/);
const char */*fmt*/,
...);
+void
+hx509_free_error_string (char */*str*/);
+
void
hx509_free_octet_string_list (hx509_octet_string_list */*list*/);
hx509_prompter_fct /*prompt*/,
void */*data*/);
+int
+hx509_name_binary (
+ const hx509_name /*name*/,
+ heim_octet_string */*os*/);
+
int
hx509_name_cmp (
hx509_name /*n1*/,
const hx509_name /*from*/,
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*/,
const void */*data*/,
size_t /*size*/);
-void
-hx509_print_func (
- hx509_vprint_func /*func*/,
- void */*ctx*/,
- const char */*fmt*/,
- ...);
-
void
hx509_print_stdout (
void */*ctx*/,
int (*/*func*/)(void *, hx509_cert),
void */*ctx*/);
+int
+hx509_query_match_eku (
+ hx509_query */*q*/,
+ const heim_oid */*eku*/);
+
int
hx509_query_match_friendly_name (
hx509_query */*q*/,
const AlgorithmIdentifier *
hx509_signature_rsa (void);
+const AlgorithmIdentifier *
+hx509_signature_rsa_pkcs1_x509 (void);
+
const AlgorithmIdentifier *
hx509_signature_rsa_with_md2 (void);
const heim_octet_string */*data*/,
const heim_octet_string */*sig*/);
+void
+hx509_xfree (void */*ptr*/);
+
#ifdef __cplusplus
}
#endif
* 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;
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
/* 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
#
# 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
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"
* 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>
#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;
void *cmp_func_ctx;
heim_octet_string *keyhash_sha1;
time_t timenow;
+ heim_oid *eku;
};
struct hx509_keyset_ops {
*/
#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;
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,
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,
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);
hx509_certs
_hx509_certs_ref(hx509_certs certs)
{
+ if (certs == NULL)
+ return NULL;
if (certs->ref <= 0)
_hx509_abort("certs refcount <= 0");
certs->ref++;
return certs;
}
+/**
+ * Free a certificate store.
+ *
+ * @param certs certificate store to free.
+ *
+ * @ingroup hx509_keyset
+ */
+
void
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,
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);
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,
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,
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;
ret = 0;
break;
}
- ret = (*fn)(context, ctx, c);
+ ret = (*func)(context, ctx, c);
hx509_cert_free(c);
if (ret)
break;
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)
{
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
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,
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)
{
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,
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)
{
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,
*/
#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;
};
+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])) {
"Found no matching PEM format for %s", type);
return ret;
}
+ if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL))
+ return ret;
return 0;
}
{
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;
return 0;
}
- ret = _hx509_collector_alloc(context, lock, &c);
+ ret = _hx509_collector_alloc(context, lock, &pem_ctx.c);
if (ret)
goto out;
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;
}
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;
}
}
}
- 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;
free(f->fn);
free(f);
}
- if (c)
- _hx509_collector_free(c);
+ if (pem_ctx.c)
+ _hx509_collector_free(pem_ctx.c);
+
return ret;
}
*/
#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
SecKeychainAttributeList **attrs)
{
SecKeychainAttributeInfo attrInfo;
- uint32 attrFormat = 0;
+ UInt32 attrFormat = 0;
OSStatus ret;
*attrs = NULL;
{
SecKeychainAttributeList *attrs = NULL;
SecKeychainAttributeInfo attrInfo;
- uint32 attrFormat[1] = { 0 };
+ UInt32 attrFormat[1] = { 0 };
SecKeychainItemRef itemRef;
SecItemAttr item[1];
struct iter *iter = cursor;
*/
#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
* 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.
*
*/
#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;
*/
#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 },
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)
{
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;
}
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,
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)
{
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)
{
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)
{
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,
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];
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)
*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)
{
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)
{
*/
#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)
}
}
+/**
+ * Free a peer info structure.
+ *
+ * @param peer peer info to be freed.
+ *
+ * @ingroup hx509_peer
+ */
+
void
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)
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,
*/
#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;
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);
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)
{
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);
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)
{ 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
{ 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)
{
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,
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,
* 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 {
struct hx509_revoke_ctx_data {
+ unsigned ref;
struct {
struct revoke_crl *val;
size_t len;
} 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)
{
if (*ctx == NULL)
return ENOMEM;
+ (*ctx)->ref = 1;
(*ctx)->crls.len = 0;
(*ctx)->crls.val = NULL;
(*ctx)->ocsps.len = 0;
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)
{
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)
{
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);
/*
* 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) {
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,
static int
verify_crl(hx509_context context,
+ hx509_revoke_ctx ctx,
CRLCertificateList *crl,
time_t time_now,
hx509_certs certs,
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,
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);
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,
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,
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;
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;
}
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;
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);
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;
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;
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;
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;
}
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,
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;
}
}
&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 *
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)
{
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
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)
{
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,
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)
{
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)
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,
/*
- * 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.
*
#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;
;
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,
;
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;
krb5_set_error_string(context, "malloc - out of memory");
fail:
- krb5_free_creds_contents(context, cred);
+ krb5_free_cred_contents(context, cred);
return ret;
}
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);
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;
}
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
return 0;
}
-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)
{
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;
}
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;
}
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;
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) {
name);
}
- free(name);
-
return translate_cc_error(context, error);
}
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);
}
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;
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,
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);
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)
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;
}
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,
acc_get_version,
acc_get_cache_first,
acc_get_cache_next,
- acc_end_cache_get
+ acc_end_cache_get,
+ acc_move,
+ acc_default_name
};
#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
/*
- * 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.
*
#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;
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)
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)
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,
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;
}
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)
{
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)
{
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,
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,
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,
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)
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,
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,
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,
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,
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)
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)
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,
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,
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,
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
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
#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,
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;
}
#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,
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;
/*
- * 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.
*
#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
/*
* 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
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,
{
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);
}
}
-/*
+/**
* 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)
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)
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,
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)
{
{
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;
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)
{
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");
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)
{
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)
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,
}
-/*
+/**
* 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)
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)
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,
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,
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;
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,
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,
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,
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,
}
}
-/*
+/**
* 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,
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,
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,
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,
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,
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)
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)
{
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,
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,
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)
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,
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;
+}
#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'
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)
{
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);
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)
{
}
/*
- * `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
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)
{
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)
{
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)
{
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
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)
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,
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)
{
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)
{
}
}
+/**
+ * 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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
#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)
{
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)
{
*/
#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"
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
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,
#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
#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)
{
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,
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,
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)
{
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)
{
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
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) ==
*/
#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
#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.
*/
size_t len;
unsigned char tmp[24];
DES_cblock keys[3];
+ krb5_error_code ret;
len = password.length + salt.saltvalue.length;
str = malloc(len);
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]));
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];
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;
}
/*
} 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;
}
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);
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,
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);
}
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);
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));
"\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;
/*
- * 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.
*
#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)
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)
{
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)
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)
{
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)
{
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)
{
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,
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)
{
#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
}
}
+/**
+ * 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)
{
#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)
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;
}
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)
{
#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,
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));
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);
/*
- * 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.
*
#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;
_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;
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) {
}
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;
}
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) {
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;
}
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;
}
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;
}
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,
fcc_get_version,
fcc_get_cache_first,
fcc_get_cache_next,
- fcc_end_cache_get
+ fcc_end_cache_get,
+ fcc_move,
+ fcc_default_name
};
#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
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;
#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,
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
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
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);
in_creds,
&out_creds);
krb5_free_addresses (context, &addrs);
- if (ret) {
+ if (ret)
return ret;
- }
memset (&cred, 0, sizeof(cred));
cred.pvno = 5;
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;
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);
#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)
#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;
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;
#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;
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,
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
#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'
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;
#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
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);
#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 --------------------------------------- */
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;
}
#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;
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);
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;
}
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;
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;
}
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;
}
}
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*/,
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*/,
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*/,
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*/,
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*/,
...)
__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*/,
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*/,
krb5_const_principal /*principal*/,
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*/,
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*/,
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*/,
* 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__
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;
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;
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
* 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
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);
* 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__
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
* 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
#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;
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,
NULL,
mcc_get_cache_first,
mcc_get_cache_next,
- mcc_end_cache_get
+ mcc_end_cache_get,
+ mcc_move,
+ mcc_default_name
};
#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 */
}
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)
{
}
}
-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;
memmove(tmp, tmp + size, l);
}
} while(l != 0);
+out:
memset(buf, 0, len);
free(buf);
memset(tmp, 0, maxlen);
free(tmp);
+ return ret;
}
*/
#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;
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;
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;
}
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) {
}
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;
}
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;
krb5_error_code
krb5_pac_get_types(krb5_context context,
- struct krb5_pac *p,
+ krb5_pac p,
size_t *len,
uint32_t **types)
{
*/
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);
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)
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,
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,
#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;
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);
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,
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
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);
} 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;
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) {
*/
#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
}
#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;
list = next;
}
}
-
/*
- * 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.
*
* 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
#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)
#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)
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
#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,
#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,
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.
*/
*
*/
-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;
krb5_set_error_string(context, "out of memory");
return ENOMEM;
}
+ (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0;
return 0;
}
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;
}
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;
#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;
return 0;
}
-struct krb5_sendto_ctx {
+struct krb5_sendto_ctx_data {
int flags;
int type;
krb5_sendto_ctx_func func;
#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)
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.
*/
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.
*/
#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;
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;
#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
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);
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);
}
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);
}
}
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);
*/
#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"
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);
int
heim_ntlm_decode_targetinfo (
- struct ntlm_buf */*data*/,
+ const struct ntlm_buf */*data*/,
int /*ucs2*/,
struct ntlm_targetinfo */*ti*/);
int
heim_ntlm_encode_targetinfo (
- struct ntlm_targetinfo */*ti*/,
+ const struct ntlm_targetinfo */*ti*/,
int /*ucs2*/,
struct ntlm_buf */*data*/);
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*/);
* 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
#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>
#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>
#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;
#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);
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;
}
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)
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;
}
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);
return ret;
}
-/*
+/**
+ * Frees the ntlm_targetinfo message
+ *
+ * @param ti targetinfo to be freed
*
+ * @ingroup ntlm_core
*/
void
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)
{
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
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)
{
return ret;
}
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type2 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
{
if (data->targetname)
free(data->targetname);
- _ntlm_free_buf(&data->targetinfo);
+ heim_ntlm_free_buf(&data->targetinfo);
memset(data, 0, sizeof(*data));
}
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;
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));
}
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);
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;
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
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
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
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;
}
}
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;
}
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
}
-/*
+/**
* 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
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
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;
/*
* 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
#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"
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);
}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/* 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;
+
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/* 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;
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/* 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;
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/* 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,
+};
+
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/* 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,
+};
+
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+#
+# 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
--- /dev/null
+/*
+ * 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_ */
#define SIGRETURN(x) return (RETSIGTYPE)(x)
#endif
+#define HDB_DB_DIR ""
+
#endif
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 \
# 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
#######################
./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
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
#######################
./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
HEIMDAL_ROKEN_GETPROGNAME \
HEIMDAL_ROKEN_CLOSEFROM \
RESOLV \
- EXT_SOCKET
+ LIBREPLACE_NETWORK
# End SUBSYSTEM HEIMDAL_ROKEN
#######################
[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 \
[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
#######################
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
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 {
}
/* 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;
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;
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;
}
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);
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@
#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
#include "replace.h"
#include "system/filesys.h"
-#include "system/network.h"
#include "system/time.h"
#include "talloc.h"
#include "ldb.h"
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,
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;
}
#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;
};
%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");
}
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
};
#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]
#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)
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;
}
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;
}
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");
}
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};
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};
&_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,
&_swigt__p_unsigned_char,
&_swigt__p_unsigned_int,
&_swigt__p_unsigned_long,
- &_swigt__p_unsigned_long_long,
&_swigt__p_unsigned_short,
&_swigt__p_void,
};
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}};
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}};
_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,
_swigc__p_unsigned_char,
_swigc__p_unsigned_int,
_swigc__p_unsigned_long,
- _swigc__p_unsigned_long_long,
_swigc__p_unsigned_short,
_swigc__p_void,
};
.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
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,
};
cat <<EOF | $VALGRIND ldbadd || exit 1
dn: @MODULES
-@LIST: sample_module
+@LIST: sample
EOF
cat <<EOF | $VALGRIND ldbadd || exit 1
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;
}
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) {
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) {
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) {
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) {
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) {
}
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) {
}
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) {
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) {
}
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) {
}
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) {
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) {
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) {
}
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) {
initgroups
memmove
strdup
-inet_ntoa
setlinebuf
vsyslog
timegm
inet_ntoa
inet_ntop
inet_pton
+inet_aton
strtoll
strtoull
socketpair
CFLAGS="$CFLAGS -Wno-format-y2k"
fi
+LIBS="${LIBREPLACE_NETWORK_LIBS}"
+AC_SUBST(LIBS)
+
AC_SUBST(LDFLAGS)
AC_OUTPUT(Makefile)
##################
# 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
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
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
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"
+
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) {
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+AC_CHECK_FUNCS(inet_aton,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_aton.o"])
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+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
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>])
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>])
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])])
#include "system/time.h"
#include "system/passwd.h"
#include "system/syslog.h"
-#include "system/network.h"
#include "system/locale.h"
#include "system/wait.h"
}
#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)
{
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
#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
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
/* 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" */
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'`
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;
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" ||
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" ||
[Whether the system has gethostbyname()])
fi
fi
-
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+AC_CHECK_FUNCS(socketpair,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} socketpair.o"])
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
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);
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.
/* 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
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");
+ }
}
}
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, [
# 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
##############################
[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
################################################
[MODULE::socket_unix]
SUBSYSTEM = samba-socket
OUTPUT_TYPE = MERGED_OBJ
-PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
# End MODULE socket_unix
################################################
##############################
# Start SUBSYSTEM SOCKET_WRAPPER
[SUBSYSTEM::SOCKET_WRAPPER]
-PRIVATE_DEPENDENCIES = EXT_SOCKET
+PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
# End SUBSYSTEM SOCKET_WRAPPER
##############################
#include <unistd.h>
#include <string.h>
#include <stdio.h>
+#include <stdint.h>
#endif
};
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;
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 \
[SUBSYSTEM::ASN1_UTIL]
PRIVATE_PROTO_HEADER = asn1_proto.h
-
ASN1_UTIL_OBJ_FILES = lib/util/asn1.o
PUBLIC_HEADERS += lib/util/asn1.h
/*
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
};
/* 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 {
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 {
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:
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)) {
*/
#include "librpc/gen_ndr/security.h"
+
+enum security_user_level {
+ SECURITY_ANONYMOUS,
+ SECURITY_USER,
+ SECURITY_ADMINISTRATOR,
+ SECURITY_SYSTEM
+};
+
#include "libcli/security/proto.h"
#include "includes.h"
#include "dsdb/samdb/samdb.h"
#include "libcli/security/security.h"
+#include "auth/session.h"
/*
return a blank security token
{
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;
+}
+
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) {
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) {
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) {
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) {
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) {
#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) {
%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) {
} 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));
}
}
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
# 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)
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;
*linux*)
SMB_LIBRARY(nss_winbind,
[nsswitch/winbind_nss_linux.o],
- [LIBWINBIND-CLIENT],
- [2],[2])
+ [LIBWINBIND-CLIENT])
;;
*)
;;
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);
}
# 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
################################################
*/
_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);
}
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,
#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;
};
/*
} 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
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;
}
*/
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;
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,
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)) *
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;
}
}
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;
void odb_tdb_init_ops(void)
{
+ sys_lease_init();
odb_set_ops(&opendb_tdb_ops);
}
/* 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);
}
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;
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);
}
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;
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
/* 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;
}
talloc_steal(r, wait_handle);
- talloc_steal(pvfs, r);
-
return NT_STATUS_OK;
}
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) {
}
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);
return;
}
+retry:
talloc_free(r);
/* try the open again, which could trigger another retry setup
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)) {
} 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);
}
/*
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)) {
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) {
}
}
- 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 */
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);
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;
}
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)) {
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
################################################
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
--- /dev/null
+/*
+ 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);
+}
--- /dev/null
+/*
+ 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);
--- /dev/null
+/*
+ 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);
+}
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) = @_;
$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")) {
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);
/*
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)
/* 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;
}
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) {
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;
}
} 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;
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 */
} 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 {
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;
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;
}
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);
}
}
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;
}
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);
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);
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;
}
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) {
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);
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;
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) {
/* 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),
{
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 };
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++;
}
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) {
{
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;
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);
const char *domain_name;
struct ldb_dn *domain_dn;
enum server_role role;
+ bool builtin;
+ struct loadparm_context *lp_ctx;
};
/*
#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 };
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;
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
}
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;
+ }
}
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;
}
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;
+ }
}
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
CFLAGS="$CFLAGS $2"
AC_TRY_LINK([
+ /* we have our own configure tests */
#include <Python.h>
- #include <stdlib.h>
],[
Py_InitModule(NULL, NULL);
],[
"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) {
class ProvisionPaths:
def __init__(self):
- self.smbconf = None
self.shareconf = None
self.hklm = None
self.hkcu = None
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
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"
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):
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.
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",
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")
})
-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
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.
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)
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:
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")
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!
if domainsid is None:
domainsid = security.random_sid()
+ else:
+ domainsid = security.Sid(domainsid)
+
if policyguid is None:
policyguid = uuid.random()
if adminpass is None:
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
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)
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)
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)
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.
static PyObject *uuid_random(PyObject *self, PyObject *args)
{
struct GUID guid;
+ PyObject *pyobj;
char *str;
if (!PyArg_ParseTuple(args, (char *)""))
return NULL;
}
+ pyobj = PyString_FromString(str);
+
talloc_free(str);
- return PyString_FromString(str);
+ return pyobj;
}
static PyMethodDef methods[] = {
use FindBin qw($RealBin);
use lib "$RealBin/..";
-use Subunit qw(parse_results);
-
use strict;
sub new($$$$$$$) {
my ($self, $output) = @_;
if ($self->{verbose}) {
+ require FileHandle;
print $output;
+ STDOUT->flush();
} else {
$self->{test_output}->{$self->{NAME}} .= $output;
}
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);
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 "
gensec:require_pac = true
log level = $smbd_loglevel
- # this is a global option
- opendb:oplocks = yes
-
[tmp]
path = $tmpdir
read only = no
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
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");
-#!/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)
+++ /dev/null
-#!/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)
import os, sys
import samba
+import param
from auth import system_session
import samba.getopt as options
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
-#!/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")
--- /dev/null
+#!/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;
+++ /dev/null
-#!/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;
################################
dn: ${DOMAINDN}
objectClass: top
-objectClass: domain
-objectClass: domainDNS
+objectClass: ${DOMAIN_OC}
${ACI}
description
cn
top
+#The memberOf plugin provides this attribute
memberOf
#This shouldn't make it to the ldap server
sambaPassword
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}
+
defaultsearchbase ${DOMAINDN}
-include ${LDAPDIR}/memberof.conf
+${MEMBEROF_CONFIG}
database hdb
suffix ${SCHEMADN}
database hdb
suffix ${DOMAINDN}
-rootdn ${LDAPMANAGERDN}
-rootpw ${LDAPMANAGERPASS}
directory ${LDAPDIR}/db/user
index objectClass eq
index samAccountName 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
+
}
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
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);
}
/*
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 \
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;
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;
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);
}
/* 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),
{
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;
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;
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;
}
/*
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),
}
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;
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);
}
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),
}
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)
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),
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);
}
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]);
}
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;
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;
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|
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;
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);
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);
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);
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;
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);
/*
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 |
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 |
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 |
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);
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);
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);
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);
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);
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 |
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;
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);
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);
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);
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);
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);
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);
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;
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);
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;
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);
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;
}
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 |
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";
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;
}
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 |
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 |
/*
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 |
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)) {
/*
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 |
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)) {
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);
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);
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
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;
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,
* 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);
}
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);
}
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;
#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"
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");
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) {
}
}
+ {
+ 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:
goto done;
}
+ cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);
+
ret = true;
if (!torture_setting_bool(torture, "samba3", false)) {
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)) {
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)
{
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)) {
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;
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;
}
if (!q1.out.sam) {
+ printf("EnumDomainGroups failed to return q1.out.sam\n");
return false;
}
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;
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;
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;
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);
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;
}
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;
}
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;
}
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);
}
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;
}
}
} 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) &&
(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;
}
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;
}
} 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)) {
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 {
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 \
/*
Unix SMB/CIFS implementation.
- Map SIDs to uids/gids and back
+ Map SIDs to unixids and back
Copyright (C) Kai Blin 2008
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;
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;
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;
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);
}
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;
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 {
}
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;
}
hwm_msg->dn = dn;
- new_uid = hwm;
+ new_xid = hwm;
hwm++;
hwm_string = talloc_asprintf(tmp_ctx, "%u", hwm);
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;
}
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;
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;
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;
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;
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;
}
/**
- * 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;
}
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"
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
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,
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
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"));
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);
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
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"));
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);
--- /dev/null
+/*
+ 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;
+}
+
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
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,
--- /dev/null
+/*
+ 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;
+}
+
}
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);
}
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 + "))");