From: Philip Hazel Date: Tue, 21 Feb 2006 16:24:19 +0000 (+0000) Subject: Add support for setclassresources() in the pipe transport on FreeBSD, X-Git-Tag: exim-4_61~44 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/929ba01ccb7fafbe89e4fa60e93ab2b5f4aab1df Add support for setclassresources() in the pipe transport on FreeBSD, NetBSD, and BSDI (aka BSD/OS). --- diff --git a/doc/doc-misc/WishList b/doc/doc-misc/WishList index 8c058484c..a0cc6a854 100644 --- a/doc/doc-misc/WishList +++ b/doc/doc-misc/WishList @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-misc/WishList,v 1.58 2006/02/13 15:09:30 ph10 Exp $ +$Cambridge: exim/doc/doc-misc/WishList,v 1.59 2006/02/21 16:24:19 ph10 Exp $ EXIM 4 WISH LIST ---------------- @@ -2017,15 +2017,5 @@ It seems that there are clients that send AUTH when it hasn't been advertised, some even after HELO, not even EHLO. Sigh. Possibly this should be an ACL control, to enable it to be restricted to certain hosts. ------------------------------------------------------------------------------ - -(349) 13-Feb-06 S Add login_cap support to the pipe transport - -FreeBSD (and maybe others) have some functions for a per-user resource database -of which login_cap() is one. A copile-time macro (set for FreeBSD) could enable -a new pipe transport option to cause setclassresources() to be called to limit -the resources used. It's a bit tricky, because it has to be done as root, but -in the forked transport process. There will have to be some higher-level code -to deal with this. ------------------------------------------------------------------------------- --- HWM 349 ------------------------------------------------------------------ ---------------------------- End of WishList --------------------------------- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 943b3bd8b..be0fc0dac 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.308 2006/02/20 16:31:48 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.309 2006/02/21 16:24:19 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -207,6 +207,9 @@ JJ/05 exipick: Fixed bug where -bpc always showed a count of all messages PH/40 Changed the default ident timeout from 30s to 5s. +PH/41 Added support for the use of login_cap features, on those BSD systems + that have them, for controlling the resources used by pipe deliveries. + Exim version 4.60 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index bd55514f1..7627fb7f9 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.87 2006/02/20 16:31:48 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.88 2006/02/21 16:24:19 ph10 Exp $ New Features in Exim -------------------- @@ -62,6 +62,12 @@ PH/08 The default for dns_check_names_pattern now allows slashes within names, PH/09 The default for rfc4131_query_timeout has been changed from 30s to 5s. +PH/10 When compiled on FreeBSD, NetBSD, or BSD/OS, the pipe transport has a new + Boolean option called use_classresources, defaulting false. If it is set + true, the setclassresources() function is used to set resource limits + when a pipe transport is run to perform a delivery. The limits for the + uid under which the pipe is to run are obtained from the login class + database. Version 4.60 diff --git a/src/OS/Makefile-BSDI b/src/OS/Makefile-BSDI index 2538c707e..3258940d0 100644 --- a/src/OS/Makefile-BSDI +++ b/src/OS/Makefile-BSDI @@ -1,6 +1,6 @@ -# $Cambridge: exim/src/OS/Makefile-BSDI,v 1.2 2005/05/23 16:58:55 fanf2 Exp $ +# $Cambridge: exim/src/OS/Makefile-BSDI,v 1.3 2006/02/21 16:24:19 ph10 Exp $ -# Exim: OS-specific make file for BSDI. Its antique link editor +# Exim: OS-specific make file for BSDI aka BSD/OS. Its antique link editor # cannot handle the TextPop overriding. CFLAGS=-O diff --git a/src/OS/os.Configuring b/src/OS/os.Configuring index df6c57d8d..62ab83a15 100644 --- a/src/OS/os.Configuring +++ b/src/OS/os.Configuring @@ -1,4 +1,4 @@ -$Cambridge: exim/src/OS/os.Configuring,v 1.1 2004/10/06 15:07:39 ph10 Exp $ +$Cambridge: exim/src/OS/os.Configuring,v 1.2 2006/02/21 16:24:19 ph10 Exp $ Configuring Exim for different Operating Systems ------------------------------------------------ @@ -184,6 +184,13 @@ One OS does not have the sys/resource.h header. If NO_SYS_RESOURCE_H is defined in an os.h- file, then the #include for this header is skipped in exim.h. +Support for login_cap functions +------------------------------- + +Some of the BSD systems support functions for controlling the resources that +user processes can use (e.g. login_getpwclass). If HAVE_LOGIN_CAP is defined, +Exim supports this feature for running pipe deliveries. + The crypt_h header ------------------ diff --git a/src/OS/os.h-BSDI b/src/OS/os.h-BSDI index 09b646197..c49a0ad86 100644 --- a/src/OS/os.h-BSDI +++ b/src/OS/os.h-BSDI @@ -1,8 +1,9 @@ -/* $Cambridge: exim/src/OS/os.h-BSDI,v 1.1 2004/10/06 15:07:39 ph10 Exp $ */ +/* $Cambridge: exim/src/OS/os.h-BSDI,v 1.2 2006/02/21 16:24:19 ph10 Exp $ */ /* Exim: OS-specific C header file for BSDI */ #define HAVE_BSD_GETLOADAVG +#define HAVE_LOGIN_CAP #define HAVE_MMAP #define HAVE_SYS_MOUNT_H #define SIOCGIFCONF_GIVES_ADDR diff --git a/src/OS/os.h-FreeBSD b/src/OS/os.h-FreeBSD index 9a2da7a5a..091089f52 100644 --- a/src/OS/os.h-FreeBSD +++ b/src/OS/os.h-FreeBSD @@ -1,8 +1,9 @@ -/* $Cambridge: exim/src/OS/os.h-FreeBSD,v 1.1 2004/10/06 15:07:39 ph10 Exp $ */ +/* $Cambridge: exim/src/OS/os.h-FreeBSD,v 1.2 2006/02/21 16:24:19 ph10 Exp $ */ /* Exim: OS-specific C header file for FreeBSD */ #define HAVE_BSD_GETLOADAVG +#define HAVE_LOGIN_CAP #define HAVE_MMAP #define HAVE_SYS_MOUNT_H #define SIOCGIFCONF_GIVES_ADDR diff --git a/src/OS/os.h-NetBSD b/src/OS/os.h-NetBSD index e07186bf3..7c3ae4f5e 100644 --- a/src/OS/os.h-NetBSD +++ b/src/OS/os.h-NetBSD @@ -1,8 +1,9 @@ -/* $Cambridge: exim/src/OS/os.h-NetBSD,v 1.1 2004/10/06 15:07:39 ph10 Exp $ */ +/* $Cambridge: exim/src/OS/os.h-NetBSD,v 1.2 2006/02/21 16:24:19 ph10 Exp $ */ /* Exim: OS-specific C header file for NetBSD */ #define HAVE_BSD_GETLOADAVG +#define HAVE_LOGIN_CAP #define HAVE_MMAP #define HAVE_SYS_MOUNT_H #define SIOCGIFCONF_GIVES_ADDR diff --git a/src/src/deliver.c b/src/src/deliver.c index e1e3714cc..dda4897b9 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/deliver.c,v 1.28 2006/02/08 16:10:46 ph10 Exp $ */ +/* $Cambridge: exim/src/src/deliver.c,v 1.29 2006/02/21 16:24:19 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1743,7 +1743,7 @@ if ((pid = fork()) == 0) if (addr->transport->setup != NULL) { - switch((addr->transport->setup)(addr->transport, addr, NULL, + switch((addr->transport->setup)(addr->transport, addr, NULL, uid, gid, &(addr->message))) { case DEFER: @@ -3617,12 +3617,25 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) else return_path = new_return_path; } + /* Find the uid, gid, and use_initgroups setting for this transport. Failure + logs and sets up error messages, so we just post-process and continue with + the next address. */ + + if (!findugid(addr, tp, &uid, &gid, &use_initgroups)) + { + remote_post_process(addr, LOG_MAIN|LOG_PANIC, NULL, fallback); + continue; + } + /* If this transport has a setup function, call it now so that it gets run in this process and not in any subprocess. That way, the results of - any setup that are retained by the transport can be reusable. */ + any setup that are retained by the transport can be reusable. One of the + things the setup does is to set the fallback host lists in the addresses. + That is why it is called at this point, before the continue delivery + processing, because that might use the fallback hosts. */ if (tp->setup != NULL) - (void)((tp->setup)(addr->transport, addr, NULL, NULL)); + (void)((tp->setup)(addr->transport, addr, NULL, uid, gid, NULL)); /* If this is a run to continue delivery down an already-established channel, check that this set of addresses matches the transport and @@ -3698,16 +3711,6 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) transport_filter_argv = NULL; - /* Find the uid, gid, and use_initgroups setting for this transport. Failure - logs and sets up error messages, so we just post-process and continue with - the next address. */ - - if (!findugid(addr, tp, &uid, &gid, &use_initgroups)) - { - remote_post_process(addr, LOG_MAIN|LOG_PANIC, NULL, fallback); - continue; - } - /* Create the pipe for inter-process communication. If pipe creation fails, it is probably because the value of remote_max_parallel is so large that too many file descriptors for pipes have been created. Arrange diff --git a/src/src/exim.c b/src/src/exim.c index ef1865541..8d21a7f9d 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.33 2006/02/16 10:05:33 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.34 2006/02/21 16:24:19 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -842,6 +842,9 @@ fprintf(f, "Support for:"); #if HAVE_IPV6 fprintf(f, " IPv6"); #endif +#ifdef HAVE_LOGIN_CAP + fprintf(f, " use_classresources"); +#endif #ifdef SUPPORT_PAM fprintf(f, " PAM"); #endif diff --git a/src/src/structs.h b/src/src/structs.h index c0c94388f..c0fa960d3 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/structs.h,v 1.9 2006/02/07 11:19:00 ph10 Exp $ */ +/* $Cambridge: exim/src/src/structs.h,v 1.10 2006/02/21 16:24:19 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -138,6 +138,8 @@ typedef struct transport_instance { struct transport_instance *, struct address_item *, struct transport_feedback *, /* For passing back config data */ + uid_t, /* The uid that will be used */ + gid_t, /* The gid that will be used */ uschar **); /* For an error message */ /**************************************/ int batch_max; /* ) */ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index bb5d90bcb..142d55703 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.12 2006/02/10 16:29:20 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.13 2006/02/21 16:24:20 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -247,6 +247,8 @@ Arguments: tblock points to the transport instance addrlist addresses about to be delivered (not used) dummy not used (doesn't pass back data) + uid the uid that will be set (not used) + gid the gid that will be set (not used) errmsg where to put an error message Returns: OK, FAIL, or DEFER @@ -254,7 +256,7 @@ Returns: OK, FAIL, or DEFER static int appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, - transport_feedback *dummy, uschar **errmsg) + transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg) { appendfile_transport_options_block *ob = (appendfile_transport_options_block *)(tblock->options_block); @@ -264,6 +266,8 @@ int i; addrlist = addrlist; /* Keep picky compilers happy */ dummy = dummy; +uid = uid; +gid = gid; /* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size, mailbox_filecount */ diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index cedce6fd9..97d69db0f 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/pipe.c,v 1.9 2006/02/07 11:19:03 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/pipe.c,v 1.10 2006/02/21 16:24:20 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -11,6 +11,10 @@ #include "../exim.h" #include "pipe.h" +#ifdef HAVE_LOGIN_CAP +#include +#endif + /* Options specific to the pipe transport. They must be in alphabetic @@ -71,6 +75,10 @@ optionlist pipe_transport_options[] = { (void *)offsetof(pipe_transport_options_block, umask) }, { "use_bsmtp", opt_bool, (void *)offsetof(pipe_transport_options_block, use_bsmtp) }, + #ifdef HAVE_LOGIN_CAP + { "use_classresources", opt_bool, + (void *)offsetof(pipe_transport_options_block, use_classresources) }, + #endif { "use_crlf", opt_bool, (void *)offsetof(pipe_transport_options_block, use_crlf) }, { "use_shell", opt_bool, @@ -106,11 +114,67 @@ pipe_transport_options_block pipe_transport_option_defaults = { FALSE, /* timeout_defer */ FALSE, /* use_shell */ FALSE, /* use_bsmtp */ + FALSE, /* use_classresources */ FALSE /* use_crlf */ }; +/************************************************* +* Setup entry point * +*************************************************/ + +/* Called for each delivery in the privileged state, just before the uid/gid +are changed and the main entry point is called. In a system that supports the +login_cap facilities, this function is used to set the class resource limits +for the user. + +Arguments: + tblock points to the transport instance + addrlist addresses about to be delivered (not used) + dummy not used (doesn't pass back data) + uid the uid that will be set (not used) + gid the gid that will be set (not used) + errmsg where to put an error message + +Returns: OK, FAIL, or DEFER +*/ + +static int +pipe_transport_setup(transport_instance *tblock, address_item *addrlist, + transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg) +{ +pipe_transport_options_block *ob = + (pipe_transport_options_block *)(tblock->options_block); + +addrlist = addrlist; /* Keep compiler happy */ +dummy = dummy; +uid = uid; +gid = gid; +errmsg = errmsg; +ob = ob; + +#ifdef HAVE_LOGIN_CAP +if (ob->use_classresources) + { + struct passwd *pw = getpwuid(uid); + if (pw != NULL) + { + login_cap_t *lc = login_getpwclass(pw); + if (lc != NULL) + { + setclassresources(lc); + login_close(lc); + } + } + } +#endif + +return OK; +} + + + /************************************************* * Initialization entry point * *************************************************/ @@ -125,6 +189,10 @@ pipe_transport_init(transport_instance *tblock) pipe_transport_options_block *ob = (pipe_transport_options_block *)(tblock->options_block); +/* Set up the setup entry point, to be called in the privileged state */ + +tblock->setup = pipe_transport_setup; + /* If pipe_as_creator is set, then uid/gid should not be set. */ if (tblock->deliver_as_creator && (tblock->uid_set || tblock->gid_set || diff --git a/src/src/transports/pipe.h b/src/src/transports/pipe.h index 2307fc7d5..d417f35b1 100644 --- a/src/src/transports/pipe.h +++ b/src/src/transports/pipe.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/pipe.h,v 1.4 2006/02/07 11:19:03 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/pipe.h,v 1.5 2006/02/21 16:24:20 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -29,6 +29,7 @@ typedef struct { BOOL timeout_defer; BOOL use_shell; BOOL use_bsmtp; + BOOL use_classresources; BOOL use_crlf; } pipe_transport_options_block; diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index bb8c6e018..3c915a4e1 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/smtp.c,v 1.20 2006/02/07 11:19:03 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/smtp.c,v 1.21 2006/02/21 16:24:20 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -207,6 +207,8 @@ Arguments: tblock pointer to the transport instance block addrlist list of addresses about to be transported tf if not NULL, pointer to block in which to return options + uid the uid that will be set (not used) + gid the gid that will be set (not used) errmsg place for error message (not used) Returns: OK always (FAIL, DEFER not used) @@ -214,12 +216,14 @@ Returns: OK always (FAIL, DEFER not used) static int smtp_transport_setup(transport_instance *tblock, address_item *addrlist, - transport_feedback *tf, uschar **errmsg) + transport_feedback *tf, uid_t uid, gid_t gid, uschar **errmsg) { smtp_transport_options_block *ob = (smtp_transport_options_block *)(tblock->options_block); errmsg = errmsg; /* Keep picky compilers happy */ +uid = uid; +gid = gid; /* Pass back options if required. This interface is getting very messy. */ diff --git a/src/src/verify.c b/src/src/verify.c index 5948000c2..b33ebb6df 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/verify.c,v 1.33 2006/02/14 15:56:43 ph10 Exp $ */ +/* $Cambridge: exim/src/src/verify.c,v 1.34 2006/02/21 16:24:19 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1051,7 +1051,7 @@ while (addr_new != NULL) if (addr->transport != NULL && !addr->transport->info->local) { - (void)(addr->transport->setup)(addr->transport, addr, &tf, NULL); + (void)(addr->transport->setup)(addr->transport, addr, &tf, 0, 0, NULL); /* If the transport has hosts and the router does not, or if the transport is configured to override the router's hosts, we must build a