summaryrefslogtreecommitdiff
path: root/src/server/mod_wsgi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/mod_wsgi.c')
-rw-r--r--src/server/mod_wsgi.c331
1 files changed, 93 insertions, 238 deletions
diff --git a/src/server/mod_wsgi.c b/src/server/mod_wsgi.c
index 34bfd88..0e891dd 100644
--- a/src/server/mod_wsgi.c
+++ b/src/server/mod_wsgi.c
@@ -2509,7 +2509,7 @@ static int Adapter_run(AdapterObject *self, PyObject *object)
if (wsgi_newrelic_config_file) {
PyObject *module = NULL;
- module = PyImport_ImportModule("newrelic.api.web_transaction");
+ module = PyImport_ImportModule("newrelic.agent");
if (module) {
PyObject *dict;
@@ -2524,6 +2524,12 @@ static int Adapter_run(AdapterObject *self, PyObject *object)
wrapper = PyObject_CallFunctionObjArgs(
factory, object, Py_None, NULL);
+ if (!wrapper) {
+ wsgi_log_python_error(self->r, self->log,
+ self->r->filename);
+ PyErr_Clear();
+ }
+
Py_DECREF(factory);
}
@@ -2863,8 +2869,6 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r,
PyObject *co = NULL;
struct _node *n = NULL;
- PyObject *transaction = NULL;
-
#if defined(WIN32) && defined(APR_HAS_UNICODE_FS)
apr_wchar_t wfilename[APR_PATH_MAX];
#endif
@@ -2970,85 +2974,6 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r,
return NULL;
}
- if (wsgi_newrelic_config_file) {
- PyObject *module = NULL;
-
- PyObject *application = NULL;
-
-
- module = PyImport_ImportModule("newrelic.api.application");
-
- if (module) {
- PyObject *dict = NULL;
- PyObject *object = NULL;
-
- dict = PyModule_GetDict(module);
- object = PyDict_GetItemString(dict, "application");
-
- Py_INCREF(object);
- application = PyObject_CallFunctionObjArgs(object, NULL);
- Py_DECREF(object);
-
- Py_DECREF(module);
- module = NULL;
-
- if (!application)
- PyErr_Clear();
- }
- else
- PyErr_Clear();
-
- if (application)
- module = PyImport_ImportModule("newrelic.api.background_task");
-
- if (module) {
- PyObject *dict = NULL;
- PyObject *object = NULL;
-
- dict = PyModule_GetDict(module);
- object = PyDict_GetItemString(dict, "BackgroundTask");
-
- if (object) {
- PyObject *args = NULL;
-
- Py_INCREF(object);
-
- args = Py_BuildValue("(Oss)", application, filename,
- "Script/Import");
- transaction = PyObject_Call(object, args, NULL);
-
- if (!transaction)
- PyErr_WriteUnraisable(object);
-
- Py_DECREF(args);
- Py_DECREF(object);
-
- if (transaction) {
- PyObject *result = NULL;
-
- object = PyObject_GetAttrString(
- transaction, "__enter__");
- args = PyTuple_Pack(0);
- result = PyObject_Call(object, args, NULL);
-
- if (!result)
- PyErr_WriteUnraisable(object);
-
- Py_XDECREF(result);
- Py_DECREF(object);
- }
- }
-
- Py_DECREF(module);
- }
- else
- PyErr_Print();
-
- Py_XDECREF(application);
- }
- else
- PyErr_Clear();
-
co = (PyObject *)PyNode_Compile(n, filename);
PyNode_Free(n);
@@ -3057,67 +2982,6 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r,
Py_XDECREF(co);
- if (wsgi_newrelic_config_file) {
- if (transaction) {
- PyObject *object;
-
- object = PyObject_GetAttrString(transaction, "__exit__");
-
- if (m) {
- PyObject *args = NULL;
- PyObject *result = NULL;
-
- args = PyTuple_Pack(3, Py_None, Py_None, Py_None);
- result = PyObject_Call(object, args, NULL);
-
- if (!result)
- PyErr_WriteUnraisable(object);
- else
- Py_DECREF(result);
-
- Py_DECREF(args);
- }
- else {
- PyObject *args = NULL;
- PyObject *result = NULL;
-
- PyObject *type = NULL;
- PyObject *value = NULL;
- PyObject *traceback = NULL;
-
- PyErr_Fetch(&type, &value, &traceback);
-
- if (!value) {
- value = Py_None;
- Py_INCREF(value);
- }
-
- if (!traceback) {
- traceback = Py_None;
- Py_INCREF(traceback);
- }
-
- PyErr_NormalizeException(&type, &value, &traceback);
-
- args = PyTuple_Pack(3, type, value, traceback);
- result = PyObject_Call(object, args, NULL);
-
- if (!result)
- PyErr_WriteUnraisable(object);
- else
- Py_DECREF(result);
-
- Py_DECREF(args);
-
- PyErr_Restore(type, value, traceback);
- }
-
- Py_DECREF(object);
-
- Py_DECREF(transaction);
- }
- }
-
if (m) {
PyObject *object = NULL;
@@ -7196,11 +7060,6 @@ static void wsgi_setup_daemon_name(WSGIDaemonProcess *daemon, apr_pool_t *p)
static int wsgi_setup_access(WSGIDaemonProcess *daemon)
{
- /* Setup the umask for the effective user. */
-
- if (daemon->group->umask != -1)
- umask(daemon->group->umask);
-
/* Change to chroot environment. */
if (daemon->group->root) {
@@ -7213,35 +7072,86 @@ static int wsgi_setup_access(WSGIDaemonProcess *daemon)
}
}
- /* Setup the working directory.*/
+ /* We don't need to switch user/group if not root. */
- if (daemon->group->home) {
- if (chdir(daemon->group->home) == -1) {
+ if (geteuid() == 0) {
+ /* Setup the daemon process real and effective group. */
+
+ if (setgid(daemon->group->gid) == -1) {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
- "mod_wsgi (pid=%d): Unable to change working "
- "directory to '%s'.", getpid(), daemon->group->home);
+ "mod_wsgi (pid=%d): Unable to set group id "
+ "to gid=%u.", getpid(),
+ (unsigned)daemon->group->gid);
return -1;
}
- }
- else if (geteuid()) {
- struct passwd *pwent;
+ else {
+ if (daemon->group->groups) {
+ if (setgroups(daemon->group->groups_count,
+ daemon->group->groups) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno,
+ wsgi_server, "mod_wsgi (pid=%d): Unable "
+ "to set supplementary groups for uname=%s "
+ "of '%s'.", getpid(), daemon->group->user,
+ daemon->group->groups_list);
+
+ return -1;
+ }
+ }
+ else if (initgroups(daemon->group->user,
+ daemon->group->gid) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno,
+ wsgi_server, "mod_wsgi (pid=%d): Unable "
+ "to set groups for uname=%s and gid=%u.",
+ getpid(), daemon->group->user,
+ (unsigned)daemon->group->gid);
- pwent = getpwuid(geteuid());
+ return -1;
+ }
+ }
- if (pwent) {
- if (chdir(pwent->pw_dir) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
- "mod_wsgi (pid=%d): Unable to change working "
- "directory to '%s'.", getpid(), pwent->pw_dir);
+ /* Setup the daemon process real and effective user. */
+
+ if (setuid(daemon->group->uid) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
+ "mod_wsgi (pid=%d): Unable to change to uid=%ld.",
+ getpid(), (long)daemon->group->uid);
+
+ /*
+ * On true UNIX systems this should always succeed at
+ * this point. With certain Linux kernel versions though
+ * we can get back EAGAIN where the target user had
+ * reached their process limit. In that case will be left
+ * running as wrong user. Just exit on all failures to be
+ * safe. Don't die immediately to avoid a fork bomb.
+ *
+ * We could just return -1 here and let the caller do the
+ * sleep() and exit() but this failure is critical enough
+ * that we still do it here so it is obvious that the issue
+ * is being addressed.
+ */
+
+ ap_log_error(APLOG_MARK, APLOG_ALERT, 0, wsgi_server,
+ "mod_wsgi (pid=%d): Failure to configure the "
+ "daemon process correctly and process left in "
+ "unspecified state. Restarting daemon process "
+ "after delay.", getpid());
+
+ sleep(20);
+
+ wsgi_exit_daemon_process(-1);
return -1;
- }
}
- else {
+ }
+
+ /* Setup the working directory for the process. */
+
+ if (daemon->group->home) {
+ if (chdir(daemon->group->home) == -1) {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
- "mod_wsgi (pid=%d): Unable to determine home "
- "directory for uid=%ld.", getpid(), (long)geteuid());
+ "mod_wsgi (pid=%d): Unable to change working "
+ "directory to '%s'.", getpid(), daemon->group->home);
return -1;
}
@@ -7249,7 +7159,7 @@ static int wsgi_setup_access(WSGIDaemonProcess *daemon)
else {
struct passwd *pwent;
- pwent = getpwuid(daemon->group->uid);
+ pwent = getpwuid(geteuid());
if (pwent) {
if (chdir(pwent->pw_dir) == -1) {
@@ -7257,87 +7167,22 @@ static int wsgi_setup_access(WSGIDaemonProcess *daemon)
"mod_wsgi (pid=%d): Unable to change working "
"directory to '%s'.", getpid(), pwent->pw_dir);
- return -1;
+ return -1;
}
}
else {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
"mod_wsgi (pid=%d): Unable to determine home "
- "directory for uid=%ld.", getpid(),
- (long)daemon->group->uid);
-
- return -1;
- }
- }
-
- /* Don't bother switch user/group if not root. */
-
- if (geteuid())
- return 0;
-
- /* Setup the daemon process real and effective group. */
-
- if (setgid(daemon->group->gid) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
- "mod_wsgi (pid=%d): Unable to set group id to gid=%u.",
- getpid(), (unsigned)daemon->group->gid);
-
- return -1;
- }
- else {
- if (daemon->group->groups) {
- if (setgroups(daemon->group->groups_count,
- daemon->group->groups) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno,
- wsgi_server, "mod_wsgi (pid=%d): Unable "
- "to set supplementary groups for uname=%s "
- "of '%s'.", getpid(), daemon->group->user,
- daemon->group->groups_list);
-
- return -1;
- }
- }
- else if (initgroups(daemon->group->user, daemon->group->gid) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno,
- wsgi_server, "mod_wsgi (pid=%d): Unable "
- "to set groups for uname=%s and gid=%u.", getpid(),
- daemon->group->user, (unsigned)daemon->group->gid);
+ "directory for uid=%ld.", getpid(), (long)geteuid());
return -1;
}
}
- /* Setup the daemon process real and effective user. */
-
- if (setuid(daemon->group->uid) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
- "mod_wsgi (pid=%d): Unable to change to uid=%ld.",
- getpid(), (long)daemon->group->uid);
-
- /*
- * On true UNIX systems this should always succeed at
- * this point. With certain Linux kernel versions though
- * we can get back EAGAIN where the target user had
- * reached their process limit. In that case will be left
- * running as wrong user. Just exit on all failures to be
- * safe. Don't die immediately to avoid a fork bomb.
- *
- * We could just return -1 here and let the caller do the
- * sleep() and exit() but this failure is critical enough
- * that we still do it here so it is obvious that the issue
- * is being addressed.
- */
-
- ap_log_error(APLOG_MARK, APLOG_ALERT, 0, wsgi_server,
- "mod_wsgi (pid=%d): Failure to configure the "
- "daemon process correctly and process left in "
- "unspecified state. Restarting daemon process "
- "after delay.", getpid());
-
- sleep(20);
+ /* Setup the umask for the effective user. */
- wsgi_exit_daemon_process(-1);
- }
+ if (daemon->group->umask != -1)
+ umask(daemon->group->umask);
/*
* Linux prevents generation of core dumps after setuid()
@@ -7347,6 +7192,7 @@ static int wsgi_setup_access(WSGIDaemonProcess *daemon)
#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
/* This applies to Linux 2.4 and later. */
+
if (ap_coredumpdir_configured) {
if (prctl(PR_SET_DUMPABLE, 1)) {
ap_log_error(APLOG_MARK, APLOG_ALERT, errno, wsgi_server,
@@ -9496,7 +9342,16 @@ static int wsgi_connect_daemon(request_rec *r, WSGIDaemonSocket *daemon)
rv = wsgi_socket_connect_un(daemon->socket, &addr);
if (rv != APR_SUCCESS) {
- if (APR_STATUS_IS_ECONNREFUSED(rv)) {
+ /*
+ * We need to check for both connection refused and
+ * connection unavailable as Linux systems when
+ * connecting to a UNIX listener socket in non
+ * blocking mode, where the listener backlog is full
+ * will return the error EAGAIN rather than returning
+ * ECONNREFUSED as is supposedly dictated by POSIX.
+ */
+
+ if (APR_STATUS_IS_ECONNREFUSED(rv) || APR_STATUS_IS_EAGAIN(rv)) {
if ((apr_time_now()-start_time) < daemon->connect_timeout) {
if (wsgi_server_config->verbose_debugging) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,