From: Wietse Venema Date: Thu, 22 Sep 2005 05:00:00 +0000 (-0500) Subject: postfix-2.3-20050922 X-Git-Tag: v2.3-RC1~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9526ba7e6062fca0122b164968b0611b82b62ec8;p=thirdparty%2Fpostfix.git postfix-2.3-20050922 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 8c9da4bb8..d88540f36 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -11124,6 +11124,17 @@ Apologies for any names omitted. Files: tls_client.c, tls_server.c, tls_session.c, tls_misc.c, tls_verify.c. +20050922 + + Bugfix: the *SQL clients did not uniformly choose the + database host from the available pool of servers due to an + off-by-one error, so that the "last" available server was + not selected. Leandro Santi. Files: dict_mysql.c, dict_pgsql.c. + + Update: common code factored out into db_common.c, and + adoption of Liviu Daia's connection aware MySQL quoting. + Files: dict_ldap.c, dict_mysql.c, dict_pgsql.c, db_common.c. + Open problems: Look for systems with XPG basename() declared in , diff --git a/postfix/src/bounce/bounce_notify_util.c b/postfix/src/bounce/bounce_notify_util.c index ae42a3e18..1b5d70bf3 100644 --- a/postfix/src/bounce/bounce_notify_util.c +++ b/postfix/src/bounce/bounce_notify_util.c @@ -505,7 +505,7 @@ int bounce_boilerplate(VSTREAM *bounce, BOUNCE_INFO *bounce_info) var_max_queue_time / 86400.0); } else if (bounce_info->report_type == BOUNCE_REPORT_SUCCESS) { post_mail_fputs(bounce, - "Your message was sucessfully delivered to the destination(s) listed"); + "Your message was successfully delivered to the destination(s) listed"); post_mail_fputs(bounce, "below. In the case of delivery to mailbox you will receive no further"); post_mail_fputs(bounce, diff --git a/postfix/src/global/db_common.c b/postfix/src/global/db_common.c index 1522711d9..b5ab21e6b 100644 --- a/postfix/src/global/db_common.c +++ b/postfix/src/global/db_common.c @@ -154,9 +154,11 @@ #define DB_COMMON_KEY_USER (1 << 1) /* Need lookup key localpart */ #define DB_COMMON_VALUE_DOMAIN (1 << 2) /* Need result domain */ #define DB_COMMON_VALUE_USER (1 << 3) /* Need result localpart */ +#define DB_COMMON_KEY_PARTIAL (1 << 4) /* Key uses input substrings */ typedef struct { DICT *dict; + STRING_LIST *domain; int flags; int nparts; } DB_COMMON_CTX; @@ -172,6 +174,7 @@ int db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query) if (ctx == 0) { ctx = (DB_COMMON_CTX *)(*ctxPtr = mymalloc(sizeof *ctx)); ctx->dict = dict; + ctx->domain = 0; ctx->flags = 0; ctx->nparts = 0; } @@ -182,20 +185,22 @@ int db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query) case '%': break; case 'u': - ctx->flags |= - query ? DB_COMMON_KEY_USER : DB_COMMON_VALUE_USER; + ctx->flags |= + query ? DB_COMMON_KEY_USER | DB_COMMON_KEY_PARTIAL + : DB_COMMON_VALUE_USER; dynamic = 1; break; case 'd': - ctx->flags |= - query ? DB_COMMON_KEY_DOMAIN : DB_COMMON_VALUE_DOMAIN; + ctx->flags |= + query ? DB_COMMON_KEY_DOMAIN | DB_COMMON_KEY_PARTIAL + : DB_COMMON_VALUE_DOMAIN; dynamic = 1; break; case 's': case 'S': dynamic = 1; break; case 'U': - ctx->flags |= DB_COMMON_KEY_USER; + ctx->flags |= DB_COMMON_KEY_PARTIAL | DB_COMMON_KEY_USER; dynamic = 1; break; case '1': case '2': case '3': case '4': case '5': @@ -204,7 +209,7 @@ int db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query) ctx->nparts = *cp - '0'; /* FALLTHROUGH */ case 'D': - ctx->flags |= DB_COMMON_KEY_DOMAIN; + ctx->flags |= DB_COMMON_KEY_PARTIAL | DB_COMMON_KEY_DOMAIN; dynamic = 1; break; default: @@ -214,10 +219,49 @@ int db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query) return dynamic; } +/* db_common_parse_domain - parse domain matchlist*/ + +void db_common_parse_domain(CFG_PARSER *parser, void *ctxPtr) +{ + DB_COMMON_CTX *ctx = (DB_COMMON_CTX *)ctxPtr; + char *domainlist; + char *myname = "db_common_parse_domain"; + + domainlist = cfg_get_str(parser, "domain", "", 0, 0); + if (*domainlist) { + ctx->domain = string_list_init(MATCH_FLAG_NONE, domainlist); + if (ctx->domain == 0) + /* + * The "domain" optimization skips input keys that may in fact + * have unwanted matches in the database, so failure to create + * the match list is fatal. + */ + msg_fatal("%s: %s: domain match list creation using '%s' failed", + myname, parser->name, domainlist); + } + myfree(domainlist); +} + +/* db_common_dict_partial - Does query use partial lookup keys? */ + +int db_common_dict_partial(void *ctxPtr) +{ +#if 0 /* Breaks recipient_delimiter */ + DB_COMMON_CTX *ctx = (DB_COMMON_CTX *)ctxPtr; + + return (ctx->domain || ctx->flags & DB_COMMON_KEY_PARTIAL); +#endif + return (0); +} + /* db_common_free_ctx - free parse context */ void db_common_free_ctx(void *ctxPtr) { + DB_COMMON_CTX *ctx = (DB_COMMON_CTX *)ctxPtr; + + if (ctx->domain) + string_list_free(ctx->domain); myfree((char *)ctxPtr); } @@ -401,16 +445,17 @@ int db_common_expand(void *ctxArg, const char *format, const char *value, /* db_common_check_domain - check domain list */ -int db_common_check_domain(STRING_LIST *domain_list, const char *addr) +int db_common_check_domain(void *ctxPtr, const char *addr) { + DB_COMMON_CTX *ctx = (DB_COMMON_CTX *)ctxPtr; char *domain; - if (domain_list) { + if (ctx->domain) { if ((domain = strrchr(addr, '@')) != NULL) ++domain; if (domain == NULL || domain == addr + 1) return (0); - if (match_list_match(domain_list, domain) == 0) + if (match_list_match(ctx->domain, domain) == 0) return (0); } return (1); diff --git a/postfix/src/global/db_common.h b/postfix/src/global/db_common.h index 73c466136..ce7adc1e1 100644 --- a/postfix/src/global/db_common.h +++ b/postfix/src/global/db_common.h @@ -21,10 +21,12 @@ typedef void (*db_quote_callback_t)(DICT *, const char *, VSTRING *); extern int db_common_parse(DICT *, void **, const char *, int); -extern void db_common_free_ctx(void *); +extern void db_common_parse_domain(CFG_PARSER *, void *); +extern int db_common_dict_partial(void *); extern int db_common_expand(void *, const char *, const char *, const char *, VSTRING *, db_quote_callback_t); -extern int db_common_check_domain(STRING_LIST *, const char *); +extern int db_common_check_domain(void *, const char *); +extern void db_common_free_ctx(void *); extern void db_common_sql_build_query(VSTRING *query, CFG_PARSER *parser); /* LICENSE diff --git a/postfix/src/global/dict_ldap.c b/postfix/src/global/dict_ldap.c index 6e8a4f752..24daf2972 100644 --- a/postfix/src/global/dict_ldap.c +++ b/postfix/src/global/dict_ldap.c @@ -216,7 +216,6 @@ typedef struct { CFG_PARSER *parser; /* common parameter parser */ char *query; /* db_common_expand() query */ char *result_format; /* db_common_expand() result_format */ - STRING_LIST *domain; /* restrict queries to these domains */ void *ctx; /* db_common_parse() context */ int dynamic_base; /* Search base has substitutions? */ int expansion_limit; @@ -908,7 +907,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name) * addresses in domains on the list. This can significantly reduce the * load on the LDAP server. */ - if (db_common_check_domain(dict_ldap->domain, name) == 0) { + if (db_common_check_domain(dict_ldap->ctx, name) == 0) { if (msg_verbose) msg_info("%s: Skipping lookup of '%s'", myname, name); return (0); @@ -1126,8 +1125,6 @@ static void dict_ldap_close(DICT *dict) cfg_parser_free(dict_ldap->parser); myfree(dict_ldap->server_host); myfree(dict_ldap->search_base); - if (dict_ldap->domain) - string_list_free(dict_ldap->domain); myfree(dict_ldap->query); if (dict_ldap->result_format) myfree(dict_ldap->result_format); @@ -1157,7 +1154,6 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) char *s; char *h; char *server_host; - char *domainlist; char *scope; char *attr; int tmp; @@ -1169,7 +1165,7 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) sizeof(*dict_ldap)); dict_ldap->dict.lookup = dict_ldap_lookup; dict_ldap->dict.close = dict_ldap_close; - dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED; + dict_ldap->dict.flags = dict_flags; dict_ldap->ld = NULL; dict_ldap->parser = cfg_parser_alloc(ldapsource); @@ -1285,22 +1281,6 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) dict_ldap->search_base = cfg_get_str(dict_ldap->parser, "search_base", "", 0, 0); - domainlist = cfg_get_str(dict_ldap->parser, "domain", "", 0, 0); - if (*domainlist) { - dict_ldap->domain = string_list_init(MATCH_FLAG_NONE, domainlist); - if (dict_ldap->domain == NULL) - /* - * The "domain" optimization skips input keys that may in fact - * have unwanted matches in the database, so failure to create - * the match list is fatal. - */ - msg_fatal("%s: %s: domain match list creation using '%s' failed", - myname, ldapsource, domainlist); - } else { - dict_ldap->domain = NULL; - } - myfree(domainlist); - /* * get configured value of "timeout"; default to 10 seconds * @@ -1337,6 +1317,16 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags) myname, ldapsource, dict_ldap->query); } (void) db_common_parse(0, &dict_ldap->ctx, dict_ldap->result_format, 0); + db_common_parse_domain(dict_ldap->parser, dict_ldap->ctx); + + /* + * Maps that use substring keys should only be used with the full + * input key. + */ + if (db_common_dict_partial(dict_ldap->ctx)) + dict_ldap->dict.flags |= DICT_FLAG_PATTERN; + else + dict_ldap->dict.flags |= DICT_FLAG_FIXED; attr = cfg_get_str(dict_ldap->parser, "result_attribute", "maildrop", 0, 0); diff --git a/postfix/src/global/dict_mysql.c b/postfix/src/global/dict_mysql.c index e16d22933..62dbf38b3 100644 --- a/postfix/src/global/dict_mysql.c +++ b/postfix/src/global/dict_mysql.c @@ -216,7 +216,6 @@ typedef struct { CFG_PARSER *parser; char *query; char *result_format; - STRING_LIST *domain; void *ctx; int expansion_limit; char *username; @@ -224,6 +223,9 @@ typedef struct { char *dbname; ARGV *hosts; PLMYSQL *pldb; +#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000 + HOST *active_host; +#endif } DICT_MYSQL; #define STATACTIVE (1<<0) @@ -239,7 +241,8 @@ typedef struct { /* internal function declarations */ static PLMYSQL *plmysql_init(ARGV *); -static MYSQL_RES *plmysql_query(PLMYSQL *, const char *, char *, char *, char *); +static MYSQL_RES *plmysql_query(DICT_MYSQL *, const char *, VSTRING *, char *, + char *, char *); static void plmysql_dealloc(PLMYSQL *); static void plmysql_close_host(HOST *); static void plmysql_down_host(HOST *); @@ -266,16 +269,14 @@ static void dict_mysql_quote(DICT *dict, const char *name, VSTRING *result) msg_panic("dict_mysql_quote: integer overflow in 2*%d+1", len); VSTRING_SPACE(result, buflen); - /* - * XXX Too expensive to find out which connection is still open at - * this point. Grrr! - */ -#if 0 && defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000 - mysql_real_escape_string(dict_mysql->pldb->db_hosts[i].db, - vstring_end(result), name, len); -#else - mysql_escape_string(vstring_end(result), name, len); +#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000 + if (dict_mysql->active_host) + mysql_real_escape_string(dict_mysql->active_host->db, + vstring_end(result), name, len); + else #endif + mysql_escape_string(vstring_end(result), name, len); + VSTRING_SKIP(result); } @@ -295,15 +296,16 @@ static const char *dict_mysql_lookup(DICT *dict, const char *name) int numrows; int expansion; const char *r; + db_quote_callback_t quote_func = dict_mysql_quote; dict_errno = 0; /* * If there is a domain list for this map, then only search for * addresses in domains on the list. This can significantly reduce - * the load on the server. Do not try "@domain" keys. + * the load on the server. */ - if (db_common_check_domain(dict_mysql->domain, name) == 0) { + if (db_common_check_domain(dict_mysql->ctx, name) == 0) { if (msg_verbose) msg_info("%s: Skipping lookup of '%s'", myname, name); return (0); @@ -320,13 +322,21 @@ static const char *dict_mysql_lookup(DICT *dict, const char *name) /* * Suppress the lookup if the query expansion is empty + * + * This initial expansion is outside the context of any + * specific host connection, we just want to check the + * key pre-requisites, so when quoting happens separately + * for each connection, we don't bother with quoting... */ +#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000 + quote_func = 0; +#endif if (!db_common_expand(dict_mysql->ctx, dict_mysql->query, - name, 0, query, dict_mysql_quote)) + name, 0, query, quote_func)) return (0); /* do the query - set dict_errno & cleanup if there's an error */ - if ((query_res = plmysql_query(pldb, vstring_str(query), + if ((query_res = plmysql_query(dict_mysql, name, query, dict_mysql->dbname, dict_mysql->username, dict_mysql->password)) == 0) { @@ -393,16 +403,12 @@ static HOST *dict_mysql_find_host(PLMYSQL *PLDB, unsigned stat, unsigned type) } if (count) { - /* - * Calling myrand() can deplete the random pool. - * Don't rely on the optimizer to weed out the call - * when count == 1. - */ - idx = (count > 1) ? 1 + (count - 1) * (double) myrand() / RAND_MAX : 1; + idx = (count > 1) ? + 1 + count * (double) myrand() / (1.0 + RAND_MAX) : 1; for (i = 0; i < PLDB->len_hosts; i++) { if (dict_mysql_check_stat(PLDB->db_hosts[i], stat, type, t) && - --idx == 0) + --idx == 0) return PLDB->db_hosts[i]; } } @@ -466,17 +472,33 @@ static void dict_mysql_event(int unused_event, char *context) * close unnecessary active connections */ -static MYSQL_RES *plmysql_query(PLMYSQL *PLDB, - const char *query, +static MYSQL_RES *plmysql_query(DICT_MYSQL *dict_mysql, + const char *name, + VSTRING *query, char *dbname, char *username, char *password) { + PLMYSQL *PLDB = dict_mysql->pldb; HOST *host; MYSQL_RES *res = 0; while ((host = dict_mysql_get_active(PLDB, dbname, username, password)) != NULL) { - if (!(mysql_query(host->db, query))) { + +#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000 + /* + * The active host is used to escape strings in the + * context of the active connection's character encoding. + */ + dict_mysql->active_host = host; + VSTRING_RESET(query); + VSTRING_TERMINATE(query); + db_common_expand(dict_mysql->ctx, dict_mysql->query, + name, 0, query, dict_mysql_quote); + dict_mysql->active_host = 0; +#endif + + if (!(mysql_query(host->db, vstring_str(query)))) { if ((res = mysql_store_result(host->db)) == 0) { msg_warn("mysql query failed: %s", mysql_error(host->db)); plmysql_down_host(host); @@ -553,7 +575,6 @@ static void mysql_parse_config(DICT_MYSQL *dict_mysql, const char *mysqlcf) VSTRING *buf; int i; char *hosts; - char *domain; p = dict_mysql->parser = cfg_parser_alloc(mysqlcf); dict_mysql->username = cfg_get_str(p, "user", "", 0, 0); @@ -584,21 +605,16 @@ static void mysql_parse_config(DICT_MYSQL *dict_mysql, const char *mysqlcf) (void) db_common_parse(&dict_mysql->dict, &dict_mysql->ctx, dict_mysql->query, 1); (void) db_common_parse(0, &dict_mysql->ctx, dict_mysql->result_format, 0); + db_common_parse_domain(p, dict_mysql->ctx); - domain = cfg_get_str(p, "domain", "", 0, 0); - if (*domain) { - if (!(dict_mysql->domain = string_list_init(MATCH_FLAG_NONE, domain))) - /* - * The "domain" optimization skips input keys that may in fact - * have unwanted matches in the database, so failure to create - * the match list is fatal. - */ - msg_fatal("%s: %s: domain match list creation using '%s' failed", - myname, mysqlcf, domain); - } + /* + * Maps that use substring keys should only be used with the full + * input key. + */ + if (db_common_dict_partial(dict_mysql->ctx)) + dict_mysql->dict.flags |= DICT_FLAG_PATTERN; else - dict_mysql->domain = 0; - myfree(domain); + dict_mysql->dict.flags |= DICT_FLAG_FIXED; hosts = cfg_get_str(p, "hosts", "", 0, 0); @@ -630,8 +646,11 @@ DICT *dict_mysql_open(const char *name, int open_flags, int dict_flags) sizeof(DICT_MYSQL)); dict_mysql->dict.lookup = dict_mysql_lookup; dict_mysql->dict.close = dict_mysql_close; - dict_mysql->dict.flags = dict_flags | DICT_FLAG_FIXED; + dict_mysql->dict.flags = dict_flags; mysql_parse_config(dict_mysql, name); +#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000 + dict_mysql->active_host = 0; +#endif dict_mysql->pldb = plmysql_init(dict_mysql->hosts); if (dict_mysql->pldb == NULL) msg_fatal("couldn't intialize pldb!\n"); @@ -717,8 +736,6 @@ static void dict_mysql_close(DICT *dict) myfree(dict_mysql->dbname); myfree(dict_mysql->query); myfree(dict_mysql->result_format); - if (dict_mysql->domain) - string_list_free(dict_mysql->domain); if (dict_mysql->hosts) argv_free(dict_mysql->hosts); if (dict_mysql->ctx) diff --git a/postfix/src/global/dict_pgsql.c b/postfix/src/global/dict_pgsql.c index 025cb6b37..976168eba 100644 --- a/postfix/src/global/dict_pgsql.c +++ b/postfix/src/global/dict_pgsql.c @@ -208,7 +208,6 @@ typedef struct { CFG_PARSER *parser; char *query; char *result_format; - STRING_LIST *domain; void *ctx; int expansion_limit; char *username; @@ -306,9 +305,9 @@ static const char *dict_pgsql_lookup(DICT *dict, const char *name) /* * If there is a domain list for this map, then only search for * addresses in domains on the list. This can significantly reduce - * the load on the server. Do not try "@domain" keys. + * the load on the server. */ - if (db_common_check_domain(dict_pgsql->domain, name) == 0) { + if (db_common_check_domain(dict_pgsql->ctx, name) == 0) { if (msg_verbose) msg_info("%s: Skipping lookup of '%s'", myname, name); return (0); @@ -388,16 +387,12 @@ static HOST *dict_pgsql_find_host(PLPGSQL *PLDB, unsigned stat, unsigned type) } if (count) { - /* - * Calling myrand() can deplete the random pool. - * Don't rely on the optimizer to weed out the call - * when count == 1. - */ - idx = (count > 1) ? 1 + (count - 1) * (double) myrand() / RAND_MAX : 1; + idx = (count > 1) ? + 1 + count * (double) myrand() / (1.0 + RAND_MAX) : 1; for (i = 0; i < PLDB->len_hosts; i++) { if (dict_pgsql_check_stat(PLDB->db_hosts[i], stat, type, t) && - --idx == 0) + --idx == 0) return PLDB->db_hosts[i]; } } @@ -545,7 +540,6 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf) char *hosts; VSTRING *query; char *select_function; - char *domain; p = dict_pgsql->parser = cfg_parser_alloc(pgsqlcf); dict_pgsql->username = cfg_get_str(p, "user", "", 0, 0); @@ -581,21 +575,16 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf) (void) db_common_parse(&dict_pgsql->dict, &dict_pgsql->ctx, dict_pgsql->query, 1); (void) db_common_parse(0, &dict_pgsql->ctx, dict_pgsql->result_format, 0); + db_common_parse_domain(p, dict_pgsql->ctx); - domain = cfg_get_str(p, "domain", "", 0, 0); - if (*domain) { - if (!(dict_pgsql->domain = string_list_init(MATCH_FLAG_NONE, domain))) - /* - * The "domain" optimization skips input keys that may in fact - * have unwanted matches in the database, so failure to create - * the match list is fatal. - */ - msg_fatal("%s: %s: domain match list creation using '%s' failed", - myname, pgsqlcf, domain); - } + /* + * Maps that use substring keys should only be used with the full + * input key. + */ + if (db_common_dict_partial(dict_pgsql->ctx)) + dict_pgsql->dict.flags |= DICT_FLAG_PATTERN; else - dict_pgsql->domain = 0; - myfree(domain); + dict_pgsql->dict.flags |= DICT_FLAG_FIXED; hosts = cfg_get_str(p, "hosts", "", 0, 0); @@ -624,9 +613,9 @@ DICT *dict_pgsql_open(const char *name, int open_flags, int dict_flags) sizeof(DICT_PGSQL)); dict_pgsql->dict.lookup = dict_pgsql_lookup; dict_pgsql->dict.close = dict_pgsql_close; + dict_pgsql->dict.flags = dict_flags; pgsql_parse_config(dict_pgsql, name); dict_pgsql->pldb = plpgsql_init(dict_pgsql->hosts); - dict_pgsql->dict.flags = dict_flags | DICT_FLAG_FIXED; if (dict_pgsql->pldb == NULL) msg_fatal("couldn't intialize pldb!\n"); return &dict_pgsql->dict; @@ -698,8 +687,6 @@ static void dict_pgsql_close(DICT *dict) myfree(dict_pgsql->dbname); myfree(dict_pgsql->query); myfree(dict_pgsql->result_format); - if (dict_pgsql->domain) - string_list_free(dict_pgsql->domain); if (dict_pgsql->hosts) argv_free(dict_pgsql->hosts); if (dict_pgsql->ctx) diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 72a3f5a01..55236fe84 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20050920" +#define MAIL_RELEASE_DATE "20050922" #define MAIL_VERSION_NUMBER "2.3" #ifdef SNAPSHOT diff --git a/postfix/src/tls/tls_verify.c b/postfix/src/tls/tls_verify.c index 2580ff21c..4471da58e 100644 --- a/postfix/src/tls/tls_verify.c +++ b/postfix/src/tls/tls_verify.c @@ -242,7 +242,7 @@ char *tls_peer_CN(X509 *peercert) return (cn); } -/* tls_text_name - extract issuer common name from certificate */ +/* tls_issuer_CN - extract issuer common name from certificate */ char *tls_issuer_CN(X509 *peer) {