martin 99/01/28 10:27:21
Modified: src CHANGES
src/main http_main.c
src/os/bs2000 bs2login.c
Log:
BS2000 only: Adapt to the new ufork() system call interface which will
make subtasking easier on the OSD/POSIX mainframe environment.
Revision Changes Path
1.1227 +4 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1226
retrieving revision 1.1227
diff -u -r1.1226 -r1.1227
--- CHANGES 1999/01/28 09:24:56 1.1226
+++ CHANGES 1999/01/28 18:27:17 1.1227
@@ -1,5 +1,9 @@
Changes with Apache 1.3.5
+ *) BS2000: Adapt to the new ufork() system call interface which will
+ make subtasking easier on the OSD/POSIX mainframe environment.
+ [Martin Kraemer]
+
*) Add a compatibility define for escape_uri() -> ap_escape_uri() to
ap_compat.h. [David White <[EMAIL PROTECTED]>] PR#3725
1.420 +1 -1 apache-1.3/src/main/http_main.c
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.419
retrieving revision 1.420
diff -u -r1.419 -r1.420
--- http_main.c 1999/01/08 08:48:46 1.419
+++ http_main.c 1999/01/28 18:27:19 1.420
@@ -3935,7 +3935,7 @@
if ((pid = fork()) == -1) {
#else /*_OSD_POSIX*/
/* BS2000 requires a "special" version of fork() before a setuid() call
*/
- if ((pid = os_fork()) == -1) {
+ if ((pid = os_fork(ap_user_name)) == -1) {
#endif /*_OSD_POSIX*/
ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new
process");
1.9 +115 -72 apache-1.3/src/os/bs2000/bs2login.c
Index: bs2login.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/os/bs2000/bs2login.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- bs2login.c 1999/01/01 19:05:27 1.8
+++ bs2login.c 1999/01/28 18:27:21 1.9
@@ -66,6 +66,17 @@
#define USER_LEN 8
static const char *bs2000_account = NULL;
+typedef enum
+{
+ bs2_unknown, /* not initialized yet. */
+ bs2_noFORK, /* no fork() because -X flag was specified */
+ bs2_FORK, /* only fork() because uid != 0 */
+ bs2_FORK_RINI, /* prior to A17, regular fork() and _rini() was used. */
+ bs2_RFORK_RINI, /* for A17, use of _rfork() and _rini() was required */
+ bs2_UFORK /* As of A18, the new ufork() is used. */
+} bs2_ForkType;
+
+static bs2_ForkType forktype = bs2_unknown;
static void ap_pad(char *dest, size_t size, char ch)
@@ -86,6 +97,75 @@
}
}
+/* Determine the method for forking off a child in such a way as to
+ * set both the POSIX and BS2000 user id's to the unprivileged user.
+ */
+static bs2_ForkType os_forktype(void)
+{
+ struct utsname os_version;
+
+ /* have we checked the OS version before? If yes return the previous
+ * result - the OS release isn't going to change suddenly!
+ */
+ if (forktype != bs2_unknown) {
+ return forktype;
+ }
+
+ /* If the user is unprivileged, use the normal fork() only. */
+ if (getuid() != 0) {
+ return forktype = bs2_FORK;
+ }
+
+ if (uname(&os_version) < 0)
+ {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, NULL,
+ "uname() failed - aborting.");
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ /*
+ * Old BS2000/OSD versions (before XPG4 SPEC1170) don't work with Apache.
+ * Anyway, simply return a fork().
+ */
+ if (strcmp(os_version.release, "01.0A") == 0 ||
+ strcmp(os_version.release, "02.0A") == 0 ||
+ strcmp(os_version.release, "02.1A") == 0)
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL,
+ "Error: unsupported OS version. "
+ "You may encounter problems.");
+ forktype = bs2_FORK;
+ }
+
+ /* The following versions are special:
+ * OS versions before A17 needs regular fork() and _rini().
+ * A17 requires _rfork() and _rini(),
+ * and later versions need ufork().
+ */
+ else if (strcmp(os_version.release, "01.1A") == 0 ||
+ strcmp(os_version.release, "03.0A") == 0 ||
+ strcmp(os_version.release, "03.1A") == 0 ||
+ strcmp(os_version.release, "04.0A") == 0)
+ {
+ if (strcmp (os_version.version, "A18") >= 0)
+ forktype = bs2_UFORK;
+
+ else if (strcmp (os_version.version, "A17") < 0)
+ forktype = bs2_FORK_RINI;
+
+ else
+ forktype = bs2_RFORK_RINI;
+ }
+
+ /* All later OS versions will hopefully use ufork() only ;-) */
+ else
+ forktype = bs2_UFORK;
+
+ return forktype;
+}
+
+
+
/* This routine is called by http_core for the BS2000Account directive */
/* It stores the account name for later use */
const char *os_set_account(pool *p, const char *account)
@@ -113,6 +193,7 @@
_rini_struct inittask;
char username[USER_LEN+1];
int save_errno;
+ bs2_ForkType type = os_forktype();
/* We can be sure that no change to uid==0 is possible because of
* the checks in http_core.c:set_user()
@@ -121,6 +202,20 @@
/* The _rini() function works only after a prior _rfork().
* In the case of one_process, it would fail.
*/
+ if (one_process) {
+
+ type = forktype = bs2_noFORK;
+
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server,
+ "The debug mode of Apache should only "
+ "be started by an unprivileged user!");
+ return 0;
+ }
+
+ /* If no _rini() is required, then return quickly. */
+ if (type != bs2_RFORK_RINI && type != bs2_FORK_RINI)
+ return 0;
+
/* An Account is required for _rini() */
if (bs2000_account == NULL)
{
@@ -130,16 +225,6 @@
exit(APEXIT_CHILDFATAL);
}
- /* The one_process test is placed _behind_ the BS2000Account test
- * because we never want the user to forget configuring an account.
- */
- if (one_process) {
- ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server,
- "The debug mode of Apache should only "
- "be started by an unprivileged user!");
- return 0;
- }
-
ap_cpystrn(username, user_name, sizeof username);
/* Make user name all upper case */
@@ -153,34 +238,13 @@
inittask.processor_name = " ";
/* Switch to the new logon user (setuid() and setgid() are done later) */
- /* Only the super use can switch identities. */
+ /* Only the super user can switch identities. */
if (_rini(&inittask) != 0) {
- save_errno = errno;
ap_log_error(APLOG_MARK, APLOG_ALERT, server,
"_rini: BS2000 auth failed for user \"%s\" acct \"%s\"",
inittask.username, inittask.account);
- if (save_errno == EAGAIN) {
- /* This funny error code does NOT mean that the operation should
- * be retried. Instead it means that authentication failed
- * because of possibly incompatible `JOBCLASS'es between
- * the calling (SYSROOT) and the target non-privileged user id.
- * Help the administrator by logging a hint.
- */
- char *curr_user, curr_uid[L_cuserid];
-
- if ((curr_user = cuserid(curr_uid)) == NULL) {
- /* This *SHOULD* not occur. But if it does, deal with it. */
- ap_snprintf(curr_uid, sizeof curr_uid, "#%u", getuid());
- curr_user = curr_uid;
- }
-
- ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, server,
- "_rini: Hint: Possible reason: JOBCLASS of user %s "
- "not compatible with that of user %s ?",
- curr_user, inittask.username);
- }
exit(APEXIT_CHILDFATAL);
}
@@ -188,51 +252,30 @@
}
/* BS2000 requires a "special" version of fork() before a setuid()/_rini()
call */
-/* Additionally, there's an OS release dependency here :-((( */
-/* I'm sorry, but there was no other way to make it work. -Martin */
-pid_t os_fork(void)
+pid_t os_fork(const char *user)
{
- struct utsname os_version;
+ pid_t pid;
- /*
- * When we run as a normal user (and bypass setuid() and _rini()),
- * we use the regular fork().
- */
- if (getuid() != 0) {
- return fork();
- }
+ switch (os_forktype()) {
+ case bs2_FORK:
+ case bs2_FORK_RINI:
+ pid = fork();
+ break;
- if (uname(&os_version) >= 0)
- {
- /*
- * Old versions (before XPG4 SPEC1170) don't work with Apache
- * and they require a fork(), not a _rfork()
- */
- if (strcmp(os_version.release, "01.0A") == 0 ||
- strcmp(os_version.release, "02.0A") == 0 ||
- strcmp(os_version.release, "02.1A") == 0)
- {
- return fork();
- }
-
- /* The following versions are special:
- * OS versions before A17 work with regular fork() only,
- * later versions with _rfork() only.
- */
- if (strcmp(os_version.release, "01.1A") == 0 ||
- strcmp(os_version.release, "03.0A") == 0 ||
- strcmp(os_version.release, "03.1A") == 0 ||
- strcmp(os_version.release, "04.0A") == 0)
- {
- return (strcmp (os_version.version, "A17") < 0)
- ? fork() : _rfork();
- }
+ case bs2_RFORK_RINI:
+ pid = _rfork();
+ break;
+
+ case bs2_UFORK:
+ pid = ufork(user);
+ break;
+
+ default:
+ pid = 0;
+ break;
}
- /* All later OS versions will require _rfork()
- * to prepare for authorization with _rini()
- */
- return _rfork();
+ return pid;
}
#else /* _OSD_POSIX */