summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsm/mpeix.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libsm/mpeix.c')
-rw-r--r--contrib/sendmail/libsm/mpeix.c646
1 files changed, 0 insertions, 646 deletions
diff --git a/contrib/sendmail/libsm/mpeix.c b/contrib/sendmail/libsm/mpeix.c
deleted file mode 100644
index 163dfba..0000000
--- a/contrib/sendmail/libsm/mpeix.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers.
- * All rights reserved.
- *
- * By using this file, you agree to the terms and conditions set
- * forth in the LICENSE file which can be found at the top level of
- * the sendmail distribution.
- *
- */
-
-#include <sm/gen.h>
-SM_RCSID("@(#)$Id: mpeix.c,v 1.7 2007/05/11 18:51:22 gshapiro Exp $")
-
-#ifdef MPE
-/*
-** MPE lacks many common functions required across all sendmail programs
-** so we define implementations for these functions here.
-*/
-
-# include <errno.h>
-# include <fcntl.h>
-# include <limits.h>
-# include <mpe.h>
-# include <netinet/in.h>
-# include <pwd.h>
-# include <sys/socket.h>
-# include <sys/stat.h>
-# include <unistd.h>
-# include <sm/conf.h>
-
-/*
-** CHROOT -- dummy chroot() function
-**
-** The MPE documentation for sendmail says that chroot-based
-** functionality is not implemented because MPE lacks chroot. But
-** rather than mucking around with all the sendmail calls to chroot,
-** we define this dummy function to return an ENOSYS failure just in
-** case a sendmail user attempts to enable chroot-based functionality.
-**
-** Parameters:
-** path -- pathname of new root (ignored).
-**
-** Returns:
-** -1 and errno == ENOSYS (function not implemented)
-*/
-
-int
-chroot(path)
- char *path;
-{
- errno = ENOSYS;
- return -1;
-}
-
-/*
-** ENDPWENT -- dummy endpwent() function
-**
-** Parameters:
-** none
-**
-** Returns:
-** none
-*/
-
-void
-endpwent()
-{
- return;
-}
-
-/*
-** In addition to missing functions, certain existing MPE functions have
-** slightly different semantics (or bugs) compared to normal Unix OSes.
-**
-** Here we define wrappers for these functions to make them behave in the
-** manner expected by sendmail.
-*/
-
-/*
-** SENDMAIL_MPE_BIND -- shadow function for the standard socket bind()
-**
-** MPE requires GETPRIVMODE() for AF_INET sockets less than port 1024.
-**
-** Parameters:
-** sd -- socket descriptor.
-** addr -- socket address.
-** addrlen -- length of socket address.
-**
-** Results:
-** 0 -- success
-** != 0 -- failure
-*/
-
-#undef bind
-int
-sendmail_mpe_bind(sd, addr, addrlen)
- int sd;
- void *addr;
- int addrlen;
-{
- bool priv = false;
- int result;
- extern void GETPRIVMODE __P((void));
- extern void GETUSERMODE __P((void));
-
- if (addrlen == sizeof(struct sockaddr_in) &&
- ((struct sockaddr_in *)addr)->sin_family == AF_INET)
- {
- /* AF_INET */
- if (((struct sockaddr_in *)addr)->sin_port > 0 &&
- ((struct sockaddr_in *)addr)->sin_port < 1024)
- {
- priv = true;
- GETPRIVMODE();
- }
- ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0;
- result = bind(sd, addr, addrlen);
- if (priv)
- GETUSERMODE();
- return result;
- }
-
- /* AF_UNIX */
- return bind(sd, addr, addrlen);
-}
-
-/*
-** SENDMAIL_MPE__EXIT -- wait for children to terminate, then _exit()
-**
-** Child processes cannot survive the death of their parent on MPE, so
-** we must call wait() before _exit() in order to prevent this
-** infanticide.
-**
-** Parameters:
-** status -- _exit status value.
-**
-** Returns:
-** none.
-*/
-
-#undef _exit
-void
-sendmail_mpe__exit(status)
- int status;
-{
- int result;
-
- /* Wait for all children to terminate. */
- do
- {
- result = wait(NULL);
- } while (result > 0 || errno == EINTR);
- _exit(status);
-}
-
-/*
-** SENDMAIL_MPE_EXIT -- wait for children to terminate, then exit()
-**
-** Child processes cannot survive the death of their parent on MPE, so
-** we must call wait() before exit() in order to prevent this
-** infanticide.
-**
-** Parameters:
-** status -- exit status value.
-**
-** Returns:
-** none.
-*/
-
-#undef exit
-void
-sendmail_mpe_exit(status)
- int status;
-{
- int result;
-
- /* Wait for all children to terminate. */
- do
- {
- result = wait(NULL);
- } while (result > 0 || errno == EINTR);
- exit(status);
-}
-
-/*
-** SENDMAIL_MPE_FCNTL -- shadow function for fcntl()
-**
-** MPE requires sfcntl() for sockets, and fcntl() for everything
-** else. This shadow routine determines the descriptor type and
-** makes the appropriate call.
-**
-** Parameters:
-** same as fcntl().
-**
-** Returns:
-** same as fcntl().
-*/
-
-#undef fcntl
-int
-sendmail_mpe_fcntl(int fildes, int cmd, ...)
-{
- int len, result;
- struct sockaddr sa;
-
- void *arg;
- va_list ap;
-
- va_start(ap, cmd);
- arg = va_arg(ap, void *);
- va_end(ap);
-
- len = sizeof sa;
- if (getsockname(fildes, &sa, &len) == -1)
- {
- if (errno == EAFNOSUPPORT)
- {
- /* AF_UNIX socket */
- return sfcntl(fildes, cmd, arg);
- }
- else if (errno == ENOTSOCK)
- {
- /* file or pipe */
- return fcntl(fildes, cmd, arg);
- }
-
- /* unknown getsockname() failure */
- return (-1);
- }
- else
- {
- /* AF_INET socket */
- if ((result = sfcntl(fildes, cmd, arg)) != -1 &&
- cmd == F_GETFL)
- result |= O_RDWR; /* fill in some missing flags */
- return result;
- }
-}
-
-/*
-** SENDMAIL_MPE_GETPWNAM - shadow function for getpwnam()
-**
-** Several issues apply here:
-**
-** - MPE user names MUST have one '.' separator character
-** - MPE user names MUST be in upper case
-** - MPE does not initialize all fields in the passwd struct
-**
-** Parameters:
-** name -- username string.
-**
-** Returns:
-** pointer to struct passwd if found else NULL
-*/
-
-static char *sendmail_mpe_nullstr = "";
-
-#undef getpwnam
-extern struct passwd *getpwnam(const char *);
-
-struct passwd *
-sendmail_mpe_getpwnam(name)
- const char *name;
-{
- int dots = 0;
- int err;
- int i = strlen(name);
- char *upper;
- struct passwd *result = NULL;
-
- if (i <= 0)
- {
- errno = EINVAL;
- return result;
- }
-
- if ((upper = (char *)malloc(i + 1)) != NULL)
- {
- /* upshift the username parameter and count the dots */
- while (i >= 0)
- {
- if (name[i] == '.')
- {
- dots++;
- upper[i] = '.';
- }
- else
- upper[i] = toupper(name[i]);
- i--;
- }
-
- if (dots != 1)
- {
- /* prevent bug when dots == 0 */
- err = EINVAL;
- }
- else if ((result = getpwnam(upper)) != NULL)
- {
- /* init the uninitialized fields */
- result->pw_gecos = sendmail_mpe_nullstr;
- result->pw_passwd = sendmail_mpe_nullstr;
- result->pw_age = sendmail_mpe_nullstr;
- result->pw_comment = sendmail_mpe_nullstr;
- result->pw_audid = 0;
- result->pw_audflg = 0;
- }
- err = errno;
- free(upper);
- }
- errno = err;
- return result;
-}
-
-/*
-** SENDMAIL_MPE_GETPWUID -- shadow function for getpwuid()
-**
-** Initializes the uninitalized fields in the passwd struct.
-**
-** Parameters:
-** uid -- uid to obtain passwd data for
-**
-** Returns:
-** pointer to struct passwd or NULL if not found
-*/
-
-#undef getpwuid
-extern struct passwd *getpwuid __P((uid_t));
-
-struct passwd *
-sendmail_mpe_getpwuid(uid)
- uid_t uid;
-{
- struct passwd *result;
-
- if ((result = getpwuid(uid)) != NULL)
- {
- /* initialize the uninitialized fields */
- result->pw_gecos = sendmail_mpe_nullstr;
- result->pw_passwd = sendmail_mpe_nullstr;
- result->pw_age = sendmail_mpe_nullstr;
- result->pw_comment = sendmail_mpe_nullstr;
- result->pw_audid = 0;
- result->pw_audflg = 0;
- }
- return result;
-}
-
-/*
-** OK boys and girls, time for some serious voodoo!
-**
-** MPE does not have a complete implementation of POSIX users and groups:
-**
-** - there is no uid 0 superuser
-** - setuid/setgid file permission bits exist but have no-op functionality
-** - setgid() exists, but only supports new gid == current gid (boring!)
-** - setuid() forces a gid change to the new uid's primary (and only) gid
-**
-** ...all of which thoroughly annoys sendmail.
-**
-** So what to do? We can't go on an #ifdef MPE rampage throughout
-** sendmail, because there are only about a zillion references to uid 0
-** and so success (and security) would probably be rather dubious by the
-** time we finished.
-**
-** Instead we take the approach of defining wrapper functions for the
-** gid/uid management functions getegid(), geteuid(), setgid(), and
-** setuid() in order to implement the following model:
-**
-** - the sendmail program thinks it is a setuid-root (uid 0) program
-** - uid 0 is recognized as being valid, but does not grant extra powers
-** - MPE priv mode allows sendmail to call setuid(), not uid 0
-** - file access is still controlled by the real non-zero uid
-** - the other programs (vacation, etc) have standard MPE POSIX behavior
-**
-** This emulation model is activated by use of the program file setgid and
-** setuid mode bits which exist but are unused by MPE. If the setgid mode
-** bit is on, then gid emulation will be enabled. If the setuid mode bit is
-** on, then uid emulation will be enabled. So for the mail daemon, we need
-** to do chmod u+s,g+s /SENDMAIL/CURRENT/SENDMAIL.
-**
-** The following flags determine the current emulation state:
-**
-** true == emulation enabled
-** false == emulation disabled, use unmodified MPE semantics
-*/
-
-static bool sendmail_mpe_flaginit = false;
-static bool sendmail_mpe_gidflag = false;
-static bool sendmail_mpe_uidflag = false;
-
-/*
-** SENDMAIL_MPE_GETMODE -- return the mode bits for the current process
-**
-** Parameters:
-** none.
-**
-** Returns:
-** file mode bits for the current process program file.
-*/
-
-mode_t
-sendmail_mpe_getmode()
-{
- int status = 666;
- int myprogram_length;
- int myprogram_syntax = 2;
- char formaldesig[28];
- char myprogram[PATH_MAX + 2];
- char path[PATH_MAX + 1];
- struct stat st;
- extern HPMYPROGRAM __P((int parms, char *formaldesig, int *status,
- int *length, char *myprogram,
- int *myprogram_length, int *myprogram_syntax));
-
- myprogram_length = sizeof(myprogram);
- HPMYPROGRAM(6, formaldesig, &status, NULL, myprogram,
- &myprogram_length, &myprogram_syntax);
-
- /* should not occur, do not attempt emulation */
- if (status != 0)
- return 0;
-
- memcpy(&path, &myprogram[1], myprogram_length - 2);
- path[myprogram_length - 2] = '\0';
-
- /* should not occur, do not attempt emulation */
- if (stat(path, &st) < 0)
- return 0;
-
- return st.st_mode;
-}
-
-/*
-** SENDMAIL_MPE_EMULGID -- should we perform gid emulation?
-**
-** If !sendmail_mpe_flaginit then obtain the mode bits to determine
-** if the setgid bit is on, we want gid emulation and so set
-** sendmail_mpe_gidflag to true. Otherwise we do not want gid emulation
-** and so set sendmail_mpe_gidflag to false.
-**
-** Parameters:
-** none.
-**
-** Returns:
-** true -- perform gid emulation
-** false -- do not perform gid emulation
-*/
-
-bool
-sendmail_mpe_emulgid()
-{
- if (!sendmail_mpe_flaginit)
- {
- mode_t mode;
-
- mode = sendmail_mpe_getmode();
- sendmail_mpe_gidflag = ((mode & S_ISGID) == S_ISGID);
- sendmail_mpe_uidflag = ((mode & S_ISUID) == S_ISUID);
- sendmail_mpe_flaginit = true;
- }
- return sendmail_mpe_gidflag;
-}
-
-/*
-** SENDMAIL_MPE_EMULUID -- should we perform uid emulation?
-**
-** If sendmail_mpe_uidflag == -1 then obtain the mode bits to determine
-** if the setuid bit is on, we want uid emulation and so set
-** sendmail_mpe_uidflag to true. Otherwise we do not want uid emulation
-** and so set sendmail_mpe_uidflag to false.
-**
-** Parameters:
-** none.
-**
-** Returns:
-** true -- perform uid emulation
-** false -- do not perform uid emulation
-*/
-
-bool
-sendmail_mpe_emuluid()
-{
- if (!sendmail_mpe_flaginit)
- {
- mode_t mode;
-
- mode = sendmail_mpe_getmode();
- sendmail_mpe_gidflag = ((mode & S_ISGID) == S_ISGID);
- sendmail_mpe_uidflag = ((mode & S_ISUID) == S_ISUID);
- sendmail_mpe_flaginit = true;
- }
- return sendmail_mpe_uidflag;
-}
-
-/*
-** SENDMAIL_MPE_GETEGID -- shadow function for getegid()
-**
-** If emulation mode is in effect and the saved egid has been
-** initialized, return the saved egid; otherwise return the value of the
-** real getegid() function.
-**
-** Parameters:
-** none.
-**
-** Returns:
-** emulated egid if present, else true egid.
-*/
-
-static gid_t sendmail_mpe_egid = -1;
-
-#undef getegid
-gid_t
-sendmail_mpe_getegid()
-{
- if (sendmail_mpe_emulgid() && sendmail_mpe_egid != -1)
- return sendmail_mpe_egid;
- return getegid();
-}
-
-/*
-** SENDMAIL_MPE_GETEUID -- shadow function for geteuid()
-**
-** If emulation mode is in effect, return the saved euid; otherwise
-** return the value of the real geteuid() function.
-**
-** Note that the initial value of the saved euid is zero, to simulate
-** a setuid-root program.
-**
-** Parameters:
-** none
-**
-** Returns:
-** emulated euid if in emulation mode, else true euid.
-*/
-
-static uid_t sendmail_mpe_euid = 0;
-
-#undef geteuid
-uid_t
-sendmail_mpe_geteuid()
-{
- if (sendmail_mpe_emuluid())
- return sendmail_mpe_euid;
- return geteuid();
-}
-
-/*
-** SENDMAIL_MPE_SETGID -- shadow function for setgid()
-**
-** Simulate a call to setgid() without actually calling the real
-** function. Implement the expected uid 0 semantics.
-**
-** Note that sendmail will also be calling setuid() which will force an
-** implicit real setgid() to the proper primary gid. So it doesn't matter
-** that we don't actually alter the real gid in this shadow function.
-**
-** Parameters:
-** gid -- desired gid.
-**
-** Returns:
-** 0 -- emulated success
-** -1 -- emulated failure
-*/
-
-#undef setgid
-int
-sendmail_mpe_setgid(gid)
- gid_t gid;
-{
- if (sendmail_mpe_emulgid())
- {
- if (gid == getgid() || sendmail_mpe_euid == 0)
- {
- sendmail_mpe_egid = gid;
- return 0;
- }
- errno = EINVAL;
- return -1;
- }
- return setgid(gid);
-}
-
-/*
-** SENDMAIL_MPE_SETUID -- shadow function for setuid()
-**
-** setuid() is broken as of MPE 7.0 in that it changes the current
-** working directory to be the home directory of the new uid. Thus
-** we must obtain the cwd and restore it after the setuid().
-**
-** Note that expected uid 0 semantics have been added, as well as
-** remembering the new uid for later use by the other shadow functions.
-**
-** Parameters:
-** uid -- desired uid.
-**
-** Returns:
-** 0 -- success
-** -1 -- failure
-**
-** Globals:
-** sendmail_mpe_euid
-*/
-
-#undef setuid
-int
-sendmail_mpe_setuid(uid)
- uid_t uid;
-{
- char *cwd;
- char cwd_buf[PATH_MAX + 1];
- int result;
- extern void GETPRIVMODE __P((void));
- extern void GETUSERMODE __P((void));
-
- if (sendmail_mpe_emuluid())
- {
- if (uid == 0)
- {
- if (sendmail_mpe_euid != 0)
- {
- errno = EINVAL;
- return -1;
- }
- sendmail_mpe_euid = 0;
- return 0;
- }
-
- /* Preserve the current working directory */
- if ((cwd = getcwd(cwd_buf, PATH_MAX + 1)) == NULL)
- return -1;
-
- GETPRIVMODE();
- result = setuid(uid);
- GETUSERMODE();
-
- /* Restore the current working directory */
- chdir(cwd_buf);
-
- if (result == 0)
- sendmail_mpe_euid = uid;
-
- return result;
- }
- return setuid(uid);
-}
-#endif /* MPE */
OpenPOWER on IntegriCloud