blob: 675c26cff519d7a77a8ba35febd923c9d537a0c9 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/***************************************************************************
* Description: ISAPI plugin for IIS/PWS *
* Author: Gal Shachor <shachor@il.ibm.com> *
* Author: Larry Isaacs <larryi@apache.org> *
* Author: Ignacio J. Ortega <nacho@apache.org> *
* Version: $Revision$ *
***************************************************************************/
// This define is needed to include wincrypt,h, needed to get client certificates
#define _WIN32_WINNT 0x0400
#include <httpext.h>
#include <httpfilt.h>
#include <wininet.h>
#include "jk_global.h"
#include "jk_requtil.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_logger.h"
#include "jk_env.h"
#include "jk_service.h"
#include "jk_worker.h"
#include "apr_general.h"
#include "jk_iis.h"
#define SERVER_ROOT_TAG ("serverRoot")
#define EXTENSION_URI_TAG ("extensionUri")
#define WORKERS_FILE_TAG ("workersFile")
#define USE_AUTH_COMP_TAG ("authComplete")
#define THREAD_POOL_TAG ("threadPool")
#define SEND_GROUPS_TAG ("sendGroups")
static char file_name[_MAX_PATH];
static char ini_file_name[MAX_PATH];
static int using_ini_file = JK_FALSE;
static int is_inited = JK_FALSE;
static int is_mapread = JK_FALSE;
static int was_inited = JK_FALSE;
static DWORD auth_notification_flags = 0;
static int use_auth_notification_flags = 0;
int send_groups = 0;
static jk_workerEnv_t *workerEnv;
apr_pool_t *jk_globalPool;
static char extension_uri[INTERNET_MAX_URL_LENGTH] =
"/jakarta/isapi_redirector2.dll";
static char worker_file[MAX_PATH * 2] = "";
static char server_root[MAX_PATH * 2] = "";
static int init_jk(char *serverName);
static int initialize_extension();
static int read_registry_init_data(jk_env_t *env);
extern int jk_jni_status_code;
static int get_registry_config_parameter(HKEY hkey,
const char *tag, char *b, DWORD sz);
static jk_env_t *jk2_create_config();
static int get_auth_flags();
/* ThreadPool support
*
*/
int use_thread_pool = 0;
static void write_error_response(PHTTP_FILTER_CONTEXT pfc, char *status,
char *msg)
{
char crlf[3] = { (char)13, (char)10, '\0' };
char *ctype = "Content-Type:text/html\r\n\r\n";
DWORD len = strlen(msg);
/* reject !!! */
pfc->ServerSupportFunction(pfc,
SF_REQ_SEND_RESPONSE_HEADER,
status, (DWORD) crlf, (DWORD) ctype);
pfc->WriteClient(pfc, msg, &len, 0);
}
HANDLE jk2_starter_event;
HANDLE jk2_inited_event;
HANDLE jk2_starter_thread = NULL;
VOID jk2_isapi_starter(LPVOID lpParam)
{
Sleep(1000);
apr_initialize();
apr_pool_create(&jk_globalPool, NULL);
initialize_extension();
if (is_inited) {
if (init_jk(NULL))
is_mapread = JK_TRUE;
}
SetEvent(jk2_inited_event);
WaitForSingleObject(jk2_starter_event, INFINITE);
if (is_inited) {
was_inited = JK_TRUE;
is_inited = JK_FALSE;
if (workerEnv) {
jk_env_t *env = workerEnv->globalEnv;
jk2_iis_close_pool(env);
workerEnv->close(env, workerEnv);
}
is_mapread = JK_FALSE;
}
apr_pool_destroy(jk_globalPool);
apr_terminate();
/* Clean up and die. */
ExitThread(0);
}
BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
DWORD dwThreadId;
ULONG http_filter_revision = HTTP_FILTER_REVISION;
jk2_inited_event = CreateEvent(NULL, FALSE, FALSE, NULL);
jk2_starter_event = CreateEvent(NULL, FALSE, FALSE, NULL);
jk2_starter_thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)
jk2_isapi_starter, NULL, 0,
&dwThreadId);
WaitForSingleObject(jk2_inited_event, INFINITE);
if (!is_inited || !is_mapread) {
return FALSE;
}
pVer->dwFilterVersion = pVer->dwServerFilterVersion;
if (pVer->dwFilterVersion > http_filter_revision) {
pVer->dwFilterVersion = http_filter_revision;
}
auth_notification_flags = get_auth_flags();
if (auth_notification_flags == SF_NOTIFY_AUTH_COMPLETE) {
pVer->dwFlags = SF_NOTIFY_ORDER_HIGH |
SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT |
SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_AUTH_COMPLETE;
}
else {
pVer->dwFlags = SF_NOTIFY_ORDER_HIGH |
SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_PREPROC_HEADERS;
}
strcpy(pVer->lpszFilterDesc, VERSION_STRING);
return TRUE;
}
DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,
DWORD dwNotificationType, LPVOID pvNotification)
{
jk_env_t *env = NULL;
jk_uriEnv_t *uriEnv = NULL;
if (!is_inited) {
initialize_extension();
}
/* Initialise jk */
if (is_inited && !is_mapread) {
char serverName[MAX_SERVERNAME];
DWORD dwLen = sizeof(serverName);
if (pfc->GetServerVariable(pfc, SERVER_NAME, serverName, &dwLen)) {
if (dwLen > 0) {
serverName[dwLen - 1] = '\0';
}
if (init_jk(serverName)) {
is_mapread = JK_TRUE;
}
}
/* If we can't read the map we become dormant */
if (!is_mapread)
is_inited = JK_FALSE;
}
if (is_inited && is_mapread) {
env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
if (auth_notification_flags == dwNotificationType) {
char uri[INTERNET_MAX_URL_LENGTH];
char snuri[INTERNET_MAX_URL_LENGTH] = "/";
char Host[INTERNET_MAX_URL_LENGTH];
char Translate[INTERNET_MAX_URL_LENGTH];
char Port[INTERNET_MAX_URL_LENGTH];
BOOL(WINAPI * GetHeader)
(struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName,
LPVOID lpvBuffer, LPDWORD lpdwSize);
BOOL(WINAPI * SetHeader)
(struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName,
LPSTR lpszValue);
BOOL(WINAPI * AddHeader)
(struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName,
LPSTR lpszValue);
char *query;
DWORD sz = sizeof(uri);
DWORD szHost = sizeof(Host);
DWORD szTranslate = sizeof(Translate);
DWORD szPort = sizeof(Port);
int nPort;
if (auth_notification_flags == SF_NOTIFY_AUTH_COMPLETE) {
GetHeader =
((PHTTP_FILTER_AUTH_COMPLETE_INFO) pvNotification)->
GetHeader;
SetHeader =
((PHTTP_FILTER_AUTH_COMPLETE_INFO) pvNotification)->
SetHeader;
AddHeader =
((PHTTP_FILTER_AUTH_COMPLETE_INFO) pvNotification)->
AddHeader;
}
else {
GetHeader =
((PHTTP_FILTER_PREPROC_HEADERS) pvNotification)->
GetHeader;
SetHeader =
((PHTTP_FILTER_PREPROC_HEADERS) pvNotification)->
SetHeader;
AddHeader =
((PHTTP_FILTER_PREPROC_HEADERS) pvNotification)->
AddHeader;
}
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpFilterProc started\n");
/*
* Just in case somebody set these headers in the request!
*/
SetHeader(pfc, URI_HEADER_NAME, NULL);
SetHeader(pfc, QUERY_HEADER_NAME, NULL);
SetHeader(pfc, WORKER_HEADER_NAME, NULL);
SetHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, NULL);
if (!GetHeader(pfc, "url", (LPVOID) uri, (LPDWORD) & sz)) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpFilterProc error while getting the url\n");
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv, env);
return SF_STATUS_REQ_ERROR;
}
if (strlen(uri)) {
int rc;
char *worker = 0;
query = strchr(uri, '?');
if (query) {
*query++ = '\0';
}
rc = jk_requtil_unescapeUrl(uri);
jk_requtil_getParents(uri);
Host[0] = '\0';
if (pfc->
GetServerVariable(pfc, SERVER_NAME, (LPVOID) Host,
(LPDWORD) & szHost)) {
if (szHost > 0) {
Host[szHost - 1] = '\0';
}
}
Port[0] = '\0';
if (pfc->
GetServerVariable(pfc, "SERVER_PORT", (LPVOID) Port,
(LPDWORD) & szPort)) {
if (szPort > 0) {
Port[szPort - 1] = '\0';
}
}
nPort = atoi(Port);
if (strlen(Host) > 1012 || nPort < 0 || nPort > 65535) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpFilterProc [%s] contains invalid host or port value.\n",
uri);
write_error_response(pfc, "400 Bad Request",
HTML_ERROR_400);
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv,
env);
return SF_STATUS_REQ_FINISHED;
}
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"In HttpFilterProc Virtual Host redirection of %s : %s\n",
Host, Port);
uriEnv =
workerEnv->uriMap->mapUri(env, workerEnv->uriMap, Host,
nPort, uri);
if (uriEnv != NULL) {
char *forwardURI;
/* This is a servlet, should redirect ... */
/* First check if the request was invalidated at decode */
if (rc == BAD_REQUEST) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpFilterProc [%s] contains one or more invalid escape sequences.\n",
uri);
write_error_response(pfc, "400 Bad Request",
HTML_ERROR_400);
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv,
env);
return SF_STATUS_REQ_FINISHED;
}
else if (rc == BAD_PATH) {
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"HttpFilterProc [%s] contains forbidden escape sequences.\n",
uri);
write_error_response(pfc, "403 Forbidden",
HTML_ERROR_403);
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv,
env);
return SF_STATUS_REQ_FINISHED;
}
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpFilterProc [%s] is a servlet url - should redirect to %s\n",
uri, uriEnv->workerName);
/* get URI we should forward */
if (workerEnv->options == JK_OPT_FWDURICOMPATUNPARSED) {
/* get original unparsed URI */
GetHeader(pfc, "url", (LPVOID) uri, (LPDWORD) & sz);
/* restore terminator for uri portion */
if (query)
*(query - 1) = '\0';
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpFilterProc fowarding original URI [%s]\n",
uri);
forwardURI = uri;
}
else if (workerEnv->options == JK_OPT_FWDURIESCAPED) {
if (jk_requtil_escapeUrl
(uri,snuri,INTERNET_MAX_URL_LENGTH) != JK_OK) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpFilterProc [%s] re-encoding request exceeds maximum buffer size.\n",
uri);
write_error_response(pfc, "400 Bad Request",
HTML_ERROR_400);
workerEnv->globalEnv->releaseEnv(workerEnv->
globalEnv, env);
return SF_STATUS_REQ_FINISHED;
}
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpFilterProc fowarding escaped URI [%s]\n",
snuri);
forwardURI = snuri;
}
else {
forwardURI = uri;
}
if (!AddHeader(pfc, URI_HEADER_NAME, forwardURI) ||
((query != NULL && strlen(query) > 0)
? !AddHeader(pfc, QUERY_HEADER_NAME, query) : FALSE)
|| !AddHeader(pfc, WORKER_HEADER_NAME,
uriEnv->workerName)
|| !SetHeader(pfc, "url", extension_uri)) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpFilterProc error while adding request headers\n");
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv,
env);
return SF_STATUS_REQ_ERROR;
}
/* Move Translate: header to a temporary header so
* that the extension proc will be called.
* This allows the servlet to handle 'Translate: f'.
*/
if (GetHeader
(pfc, "Translate:", (LPVOID) Translate,
(LPDWORD) & szTranslate) && Translate != NULL
&& szTranslate > 0) {
if (!AddHeader
(pfc, TOMCAT_TRANSLATE_HEADER_NAME, Translate)) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpFilterProc error while adding Tomcat-Translate headers\n");
workerEnv->globalEnv->releaseEnv(workerEnv->
globalEnv, env);
return SF_STATUS_REQ_ERROR;
}
SetHeader(pfc, "Translate:", NULL);
}
}
else {
char *jsessionid =
strstr(uri, JK_PATH_SESSION_IDENTIFIER);
if (jsessionid) {
env->l->jkLog(env, env->l, JK_LOG_INFO,
"HttpFilterProc removing session identifier [%s] for non servlet url\n",
jsessionid);
*jsessionid = '\0';
SetHeader(pfc, "url", uri);
}
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpFilterProc [%s] is not a servlet url\n",
uri);
}
/*
* Check if somebody is feeding us with his own TOMCAT data headers.
* We reject such postings !
*/
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpFilterProc check if [%s] is pointing to the web-inf directory\n",
uri);
if (jk_requtil_uriIsWebInf(uri)) {
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"HttpFilterProc [%s] points to the web-inf or meta-inf directory.\nSomebody try to hack into the site!!!\n",
uri);
write_error_response(pfc, "403 Forbidden",
HTML_ERROR_403);
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv,
env);
return SF_STATUS_REQ_FINISHED;
}
}
}
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv, env);
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO * pVer)
{
pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
strcpy(pVer->lpszExtensionDesc, VERSION_STRING);
return TRUE;
}
DWORD WINAPI HttpExtensionProcWorker(LPEXTENSION_CONTROL_BLOCK lpEcb,
jk_ws_service_t *service)
{
DWORD rc = HSE_STATUS_ERROR;
jk_env_t *env;
jk_ws_service_t sOnStack;
jk_ws_service_t *s;
char *worker_name;
char huge_buf[16 * 1024]; /* should be enough for all */
DWORD huge_buf_sz;
jk_worker_t *worker;
jk_pool_t *rPool = NULL;
int rc1;
if (service)
s = service;
else
s = &sOnStack;
lpEcb->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR;
env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpExtensionProc started\n");
huge_buf_sz = sizeof(huge_buf);
get_server_value(lpEcb, HTTP_WORKER_HEADER_NAME, huge_buf, huge_buf_sz,
"");
worker_name = huge_buf;
worker = env->getByName(env, worker_name);
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpExtensionProc %s a worker for name %s\n",
worker ? "got" : "could not get", worker_name);
if (worker == NULL) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"HttpExtensionProc worker is NULL\n");
return rc;
}
/* Get a pool for the request XXX move it in workerEnv to
be shared with other server adapters */
rPool = worker->rPoolCache->get(env, worker->rPoolCache);
if (rPool == NULL) {
rPool =
worker->mbean->pool->create(env, worker->mbean->pool,
HUGE_POOL_SIZE);
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpExtensionProc: new rpool\n");
}
jk2_service_iis_init(env, s);
s->pool = rPool;
/* reset the reco_status, will be set to INITED in LB mode */
s->reco_status = RECO_NONE;
s->is_recoverable_error = JK_FALSE;
s->response_started = JK_FALSE;
s->content_read = 0;
s->ws_private = lpEcb;
s->workerEnv = workerEnv;
/* Initialize the ws_service structure */
s->init(env, s, worker, lpEcb);
if (JK_OK == worker->service(env, worker, s)) {
rc = HSE_STATUS_SUCCESS;
lpEcb->dwHttpStatusCode = HTTP_STATUS_OK;
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpExtensionProc service() returned OK\n");
}
else {
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"HttpExtensionProc service() Failed\n");
}
s->afterRequest(env, s);
if (service != NULL) {
lpEcb->ServerSupportFunction(lpEcb->ConnID,
HSE_REQ_DONE_WITH_SESSION,
NULL, NULL, NULL);
}
rPool->reset(env, rPool);
rc1 = worker->rPoolCache->put(env, worker->rPoolCache, rPool);
workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv, env);
return rc;
}
DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpEcb)
{
if (is_inited) {
if (!use_thread_pool) {
return HttpExtensionProcWorker(lpEcb, NULL);
}
else {
/* Pass the request to the thread pool */
jk2_iis_thread_pool(lpEcb);
return HSE_STATUS_PENDING;
}
}
return HSE_STATUS_ERROR;
}
BOOL WINAPI TerminateExtension(DWORD dwFlags)
{
return TerminateFilter(dwFlags);
}
BOOL WINAPI TerminateFilter(DWORD dwFlags)
{
/* detatch the starter thread */
SetEvent(jk2_starter_event);
WaitForSingleObject(jk2_starter_thread, 3000);
CloseHandle(jk2_starter_thread);
jk2_starter_thread = INVALID_HANDLE_VALUE;
return TRUE;
}
BOOL WINAPI DllMain(HINSTANCE hInst, // Instance Handle of the DLL
ULONG ulReason, // Reason why NT called this DLL
LPVOID lpReserved) // Reserved parameter for future use
{
BOOL fReturn = TRUE;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
switch (ulReason) {
case DLL_PROCESS_ATTACH:
if (GetModuleFileName(hInst, file_name, sizeof(file_name))) {
_splitpath(file_name, drive, dir, fname, NULL);
_makepath(ini_file_name, drive, dir, fname, ".properties");
}
else {
fReturn = JK_FALSE;
}
break;
default:
break;
}
return fReturn;
}
static int init_jk(char *serverName)
{
int rc = JK_TRUE;
/* XXX this need review, works well because the initializations are done at the first request
but in case inits should be splited another time using directly globalEnv here could lead
to subtle problems..
*/
jk_env_t *env = workerEnv->globalEnv;
workerEnv->initData->add(env, workerEnv->initData, "serverRoot",
workerEnv->pool->pstrdup(env, workerEnv->pool,
server_root));
/* Logging the initialization type: registry or properties file in virtual dir
*/
if (strlen(worker_file)) {
rc = (JK_OK ==
workerEnv->config->setPropertyString(env, workerEnv->config,
"config.file",
worker_file));
}
workerEnv->init(env, workerEnv);
env->l->jkLog(env, env->l, JK_LOG_INFO, "Set serverRoot %s\n",
server_root);
if (using_ini_file) {
env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Using ini file %s.\n",
ini_file_name);
}
else {
env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Using registry.\n");
}
env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Using extension uri %s.\n",
extension_uri);
env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Using server root %s.\n",
server_root);
env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Using worker file %s.\n",
worker_file);
return rc;
}
static int initialize_extension()
{
jk_env_t *env = jk2_create_config();
if (read_registry_init_data(env)) {
jk2_iis_init_pool(env);
is_inited = JK_TRUE;
}
return is_inited;
}
static int read_registry_init_data(jk_env_t *env)
{
char tmpbuf[INTERNET_MAX_URL_LENGTH];
HKEY hkey;
long rc;
int ok = JK_TRUE;
char *tmp;
jk_map_t *map;
if (JK_OK == jk2_map_default_create(env, &map, workerEnv->pool)) {
if (JK_OK == jk2_config_file_read(env, map, ini_file_name)) {
tmp = map->get(env, map, EXTENSION_URI_TAG);
if (tmp) {
strcpy(extension_uri, tmp);
}
else {
ok = JK_FALSE;
}
tmp = map->get(env, map, SERVER_ROOT_TAG);
if (tmp) {
strcpy(server_root, tmp);
}
else {
ok = JK_FALSE;
}
tmp = map->get(env, map, WORKERS_FILE_TAG);
if (tmp) {
strcpy(worker_file, tmp);
}
tmp = map->get(env, map, THREAD_POOL_TAG);
if (tmp) {
use_thread_pool = atoi(tmp);
if (use_thread_pool < 10)
use_thread_pool = 0;
}
tmp = map->get(env, map, USE_AUTH_COMP_TAG);
if (tmp) {
use_auth_notification_flags = atoi(tmp);
}
tmp = map->get(env, map, SEND_GROUPS_TAG);
if (tmp) {
send_groups = atoi(tmp);
}
using_ini_file = JK_TRUE;
return ok;
}
}
else {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"read_registry_init_data, Failed to create map \n");
}
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGISTRY_LOCATION, (DWORD) 0, KEY_READ, &hkey);
if (ERROR_SUCCESS != rc) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"read_registry_init_data, Failed Registry OpenKey %s\n",
REGISTRY_LOCATION);
return JK_FALSE;
}
if (get_registry_config_parameter(hkey,
EXTENSION_URI_TAG,
tmpbuf, sizeof(extension_uri))) {
strcpy(extension_uri, tmpbuf);
}
else {
ok = JK_FALSE;
}
if (get_registry_config_parameter(hkey,
SERVER_ROOT_TAG,
tmpbuf, sizeof(server_root))) {
strcpy(server_root, tmpbuf);
}
else {
ok = JK_FALSE;
}
if (get_registry_config_parameter(hkey,
WORKERS_FILE_TAG,
tmpbuf, sizeof(server_root))) {
strcpy(worker_file, tmpbuf);
}
else {
ok = JK_FALSE;
}
if (get_registry_config_parameter(hkey, THREAD_POOL_TAG, tmpbuf, 8)) {
use_thread_pool = atoi(tmpbuf);
if (use_thread_pool < 10) {
use_thread_pool = 0;
env->l->jkLog(env, env->l, JK_LOG_INFO,
"read_registry_init_data, ThreadPool must be set to the value 10 or higher\n");
}
}
if (get_registry_config_parameter(hkey, USE_AUTH_COMP_TAG, tmpbuf, 8)) {
use_auth_notification_flags = atoi(tmpbuf);
}
if (get_registry_config_parameter(hkey, SEND_GROUPS_TAG, tmpbuf, 8)) {
send_groups = atoi(tmpbuf);
}
RegCloseKey(hkey);
return ok;
}
static int get_registry_config_parameter(HKEY hkey,
const char *tag, char *b, DWORD sz)
{
DWORD type = 0;
LONG lrc;
lrc = RegQueryValueEx(hkey, tag, (LPDWORD) 0, &type, (LPBYTE) b, &sz);
if ((ERROR_SUCCESS != lrc) || (type != REG_SZ)) {
return JK_FALSE;
}
b[sz] = '\0';
return JK_TRUE;
}
/** Basic initialization for jk2.
*/
static jk_env_t *jk2_create_workerEnv(void)
{
jk_logger_t *l;
jk_pool_t *globalPool;
jk_bean_t *jkb;
jk_env_t *env;
jk2_pool_apr_create(NULL, &globalPool, NULL, jk_globalPool);
/** Create the global environment. This will register the default
factories
*/
env = jk2_env_getEnv(NULL, globalPool);
/* Optional. Register more factories ( or replace existing ones ) */
/* Init the environment. */
/* Create the logger */
jkb = env->createBean2(env, env->globalPool, "logger.win32", "");
env->alias(env, "logger.win32:", "logger");
l = jkb->object;
env->l = l;
env->soName = env->globalPool->pstrdup(env, env->globalPool, file_name);
if (env->soName == NULL) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"Error creating env->soName\n");
return env;
}
env->l->init(env, env->l);
/* We should make it relative to JK_HOME or absolute path.
ap_server_root_relative(cmd->pool,opt); */
/* Create the workerEnv */
jkb = env->createBean2(env, env->globalPool, "workerEnv", "");
workerEnv = jkb->object;
env->alias(env, "workerEnv:", "workerEnv");
if (workerEnv == NULL) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"Error creating workerEnv\n");
return env;
}
workerEnv->childId = 0;
/* XXX
Detect install dir, be means of service configs, */
return env;
}
static jk_env_t *jk2_create_config()
{
jk_env_t *env;
if (workerEnv == NULL) {
env = jk2_create_workerEnv();
env->l->jkLog(env, env->l, JK_LOG_INFO, "JK2 Config Created");
}
else {
env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
env->l->jkLog(env, env->l, JK_LOG_INFO, "JK2 Config Reused");
}
return env;
}
static int get_auth_flags()
{
HKEY hkey;
long rc;
int maj, sz;
int rv = SF_NOTIFY_PREPROC_HEADERS;
int use_auth = JK_FALSE;
/* Retreive the IIS version Major */
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
W3SVC_REGISTRY_KEY, (DWORD) 0, KEY_READ, &hkey);
if (ERROR_SUCCESS != rc) {
return rv;
}
sz = sizeof(int);
rc = RegQueryValueEx(hkey,
"MajorVersion", NULL, NULL, (LPBYTE) & maj, &sz);
if (ERROR_SUCCESS != rc) {
CloseHandle(hkey);
return rv;
}
CloseHandle(hkey);
if (use_auth_notification_flags && maj > 4)
rv = SF_NOTIFY_AUTH_COMPLETE;
return rv;
}