Added CONFIGURE_GROUP as a build-time facility, cf CONFIGURE_OWNER.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 18 Oct 2004 09:16:57 +0000 (09:16 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 18 Oct 2004 09:16:57 +0000 (09:16 +0000)
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
src/src/EDITME
src/src/buildconfig.c
src/src/config.h.defaults
src/src/exim.c
src/src/globals.c
src/src/globals.h
src/src/readconf.c

index 17264e6..c27cbbe 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.6 2004/10/15 13:21:21 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.7 2004/10/18 09:16:57 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -25,6 +25,8 @@ Exim version 4.44
     now done for all such subprocesses. The other cases are: ${run, transport
     filters, and the commands run by the lmtp and pipe transports.
 
+ 5. Added CONFIGURE_GROUP build-time option.
+
 
 Exim version 4.43
 -----------------
index dfcc5e7..6d73f19 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.2 2004/10/18 09:16:57 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -9,6 +9,14 @@ updated when there is a relatively large batch of changes). The doc/ChangeLog
 file contains a listing of all changes, including bug fixes.
 
 
+Version 4.44
+------------
+
+ 1. There is a new build-time option called CONFIGURE_GROUP which works like
+    CONFIGURE_OWNER. It specifies one additional group that is permitted for
+    the runtime configuration file when the group write permission is set.
+
+
 Version 4.43
 ------------
 
index 2437abf..753aa91 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.2 2004/10/18 09:16:57 ph10 Exp $
 
 LISTS OF EXIM OPTIONS
 ---------------------
@@ -740,6 +740,7 @@ COMPRESS_SUFFIX              system       suffix added to compressed files
 CONFIGURE_FILE               mandatory    Exim runtime configuration file
 CONFIGURE_FILE_USE_EUID      optional*
 CONFIGURE_FILE_USE_NODE      optional*
+CONFIGURE_GROUP              optional*    alternate group for configuration file
 CONFIGURE_OWNER              optional*    alternate owner for configuration file
 CYRUS_PWCHECK_SOCKET         optional     socket for pwcheck daemon
 DBMLIB                       optional**   location of DBM library
index 2f900f2..418b51b 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/src/src/EDITME,v 1.2 2004/10/11 13:24:19 ph10 Exp $
+# $Cambridge: exim/src/src/EDITME,v 1.3 2004/10/18 09:16:57 ph10 Exp $
 
 ##################################################
 #          The Exim mail transport agent         #
@@ -347,18 +347,26 @@ FIXED_NEVER_USERS=root
 
 # CONFIGURE_OWNER=
 
-# If you specify CONFIGURE_OWNER as a name, this is looked up at build time,
-# and the uid number is built into the binary. However, you can specify that
-# this lookup is deferred until runtime. In this case, it is the name that is
-# built into the binary. You can do this by a setting of the form:
+# If the configuration file is group-writeable, Exim insists by default that it
+# is owned by root or the Exim user. You can specify one additional permitted 
+# group owner here.
+
+# CONFIGURE_GROUP=
+
+# If you specify CONFIGURE_OWNER or CONFIGURE_GROUP as a name, this is looked
+# up at build time, and the uid or gid number is built into the binary.
+# However, you can specify that the lookup is deferred until runtime. In this
+# case, it is the name that is built into the binary. You can do this by a
+# setting of the form:
 
 # CONFIGURE_OWNER=ref:mail
+# CONFIGURE_GROUP=ref:sysadmin
 
-# In other words, put "ref:" in front of the user name. Although this costs a
-# bit of resource at runtime, it is convenient to use this feature when
-# building binaries that are to be run on multiple systems where the name may
-# refer to different uids. It also allows you to build Exim on a system where
-# the relevant user is not defined.
+# In other words, put "ref:" in front of the user or group name. Although this
+# costs a bit of resource at runtime, it is convenient to use this feature when
+# building binaries that are to be run on multiple systems where the names may
+# refer to different uids or gids. It also allows you to build Exim on a system
+# where the relevant user or group is not defined.
 
 
 #------------------------------------------------------------------------------
index 6dd0d51..f596ff8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/buildconfig.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/buildconfig.c,v 1.2 2004/10/18 09:16:57 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -472,17 +472,20 @@ while (fgets(buffer, sizeof(buffer), base) != NULL)
     continue;
     }
 
-  /* CONFIGURE_OWNER is a special case. We look in the environment for
-  CONFIGURE_OWNER. If the value is not numeric, we look up the user. A lot of
-  this code is similar to that for EXIM_USER, but we aren't interested in a gid
-  here, and it's all optional, so just keep it separate. */
+  /* CONFIGURE_OWNER and CONFIGURE_GROUP are special cases. We look in the
+  environment for first. If the value is not numeric, we look up the user or
+  group. A lot of this code is similar to that for EXIM_USER, but it's easier
+  to keep it separate. */
 
-  if (strcmp(name, "CONFIGURE_OWNER") == 0)
+  if (strcmp(name, "CONFIGURE_OWNER") == 0 ||
+      strcmp(name, "CONFIGURE_GROUP") == 0)
     {
+    int isgroup = name[10] == 'G'; 
     uid_t uid = 0;
+    gid_t gid = 0; 
     char *s;
     char *username = NULL;
-    char *user = getenv("CONFIGURE_OWNER");
+    char *user = getenv(name);
 
     if (user == NULL) user = "";
     while (isspace((unsigned char)(*user))) user++;
@@ -496,9 +499,9 @@ while (fgets(buffer, sizeof(buffer), base) != NULL)
       {
       if (iscntrl((unsigned char)(*s)))
         {
-        printf("\n*** CONFIGURE_OWNER contains the control character 0x%02X in "
+        printf("\n*** %s contains the control character 0x%02X in "
           "one of the files\n    in the \"Local\" directory. Please review "
-          "your build-time\n    configuration.\n\n", *s);
+          "your build-time\n    configuration.\n\n", name, *s);
         return 1;
         }
       }
@@ -507,10 +510,13 @@ while (fgets(buffer, sizeof(buffer), base) != NULL)
 
     if (user[strspn(user, "0123456789")] == 0)
       {
-      uid = (uid_t)atoi(user);
+      if (isgroup)
+        gid = (gid_t)atoi(user);
+      else    
+        uid = (uid_t)atoi(user);
       }
 
-    /* User name given. Normally, we look up the uid right away. However,
+    /* Name given. Normally, we look up the uid or gid right away. However,
     people building binary distributions sometimes want to retain the name till
     runtime. This is supported if the name begins "ref:". */
 
@@ -521,6 +527,19 @@ while (fgets(buffer, sizeof(buffer), base) != NULL)
       username = user;
       }
 
+    else if (isgroup)
+      {
+      struct group *gr = getgrnam(user);
+      if (gr == NULL)
+        {
+        printf("\n*** Group \"%s\" (specified in one of the Makefiles) does not "
+          "exist.\n    Please review your build-time configuration.\n\n",
+          user);
+        return 1;
+        }
+      gid = gr->gr_gid;
+      }
+
     else
       {
       struct passwd *pw = getpwnam(user);
@@ -531,7 +550,6 @@ while (fgets(buffer, sizeof(buffer), base) != NULL)
           user);
         return 1;
         }
-
       uid = pw->pw_uid;
       }
 
@@ -539,8 +557,17 @@ while (fgets(buffer, sizeof(buffer), base) != NULL)
     are set to zero but will be replaced at runtime. */
 
     if (username != NULL)
-      fprintf(new, "#define CONFIGURE_OWNERNAME         \"%s\"\n", username);
-    fprintf(new, "#define CONFIGURE_OWNER              %d\n", (int)uid);
+      {
+      if (isgroup)
+        fprintf(new, "#define CONFIGURE_GROUPNAME         \"%s\"\n", username);
+      else 
+        fprintf(new, "#define CONFIGURE_OWNERNAME         \"%s\"\n", username);
+      }
+    
+    if (isgroup)
+      fprintf(new, "#define CONFIGURE_GROUP              %d\n", (int)gid);
+    else   
+      fprintf(new, "#define CONFIGURE_OWNER              %d\n", (int)uid);
     continue;
     }
 
index 39a17ae..e31cffb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/config.h.defaults,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/config.h.defaults,v 1.2 2004/10/18 09:16:57 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -28,6 +28,7 @@ in config.h unless some value is defined in Local/Makefile. */
 #define CONFIGURE_FILE
 #define CONFIGURE_FILE_USE_EUID
 #define CONFIGURE_FILE_USE_NODE
+#define CONFIGURE_GROUP
 #define CONFIGURE_OWNER
 #define CYRUS_PWCHECK_SOCKET
 #define CYRUS_SASLAUTHD_SOCKET
index 37f206d..bfdcbc6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.2 2004/10/14 11:21:02 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.3 2004/10/18 09:16:57 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1234,7 +1234,7 @@ because some OS define it in /usr/include/unistd.h. */
 
 extern char **environ;
 
-/* If the Exim user and/or group and/or the configuration file owner were
+/* If the Exim user and/or group and/or the configuration file owner/group were
 defined by ref:name at build time, we must now find the actual uid/gid values.
 This is a feature to make the lives of binary distributors easier. */
 
@@ -1269,6 +1269,15 @@ if (!route_finduser(US CONFIGURE_OWNERNAME, NULL, &config_uid))
   }
 #endif
 
+#ifdef CONFIGURE_GROUPNAME
+if (!route_findgroup(US CONFIGURE_GROUPNAME, &config_gid))
+  {
+  fprintf(stderr, "exim: failed to find gid for group name \"%s\"\n",
+    CONFIGURE_GROUPNAME);
+  exit(EXIT_FAILURE);
+  }
+#endif
+
 /* In the Cygwin environment, some initialization needs doing. It is fudged
 in by means of this macro. */
 
index b9cf245..a206d42 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.2 2004/10/18 09:16:57 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -341,6 +341,9 @@ BOOL    config_changed         = FALSE;
 FILE   *config_file            = NULL;
 uschar *config_filename        = NULL;
 int     config_lineno          = 0;
+#ifdef CONFIGURE_GROUP
+gid_t   config_gid             = CONFIGURE_GROUP;
+#endif
 uschar *config_main_filelist   = US CONFIGURE_FILE
                          "\0<-----------Space to patch configure_filename->";
 uschar *config_main_filename   = NULL;
index 17183c6..9cd0bf7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.2 2004/10/18 09:16:57 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -175,6 +175,9 @@ extern int     connection_max_messages;/* Max down one SMTP connection */
 extern BOOL    config_changed;         /* True if -C used */
 extern FILE   *config_file;            /* Configuration file */
 extern uschar *config_filename;        /* Configuration file name */
+#ifdef CONFIGURE_GROUP
+extern gid_t   config_gid;             /* Additional group owner */
+#endif
 extern int     config_lineno;          /* Line number */
 extern uschar *config_main_filelist;   /* List of possible config files */
 extern uschar *config_main_filename;   /* File name actually used */
index 9547076..caa78ee 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.2 2004/10/18 09:16:57 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2595,8 +2595,11 @@ if (!config_changed)
        && statbuf.st_uid != config_uid           /* owner not the special one */
        #endif
          ) ||                                    /* or */
-      (statbuf.st_gid != exim_gid &&             /* group not exim & */
-       (statbuf.st_mode & 020) != 0) ||          /* group writeable  */
+      (statbuf.st_gid != exim_gid                /* group not exim & */
+       #ifdef CONFIGURE_GROUP
+       && statbuf.st_gid != config_gid           /* group not the special one */
+       #endif  
+       && (statbuf.st_mode & 020) != 0) ||       /* group writeable  */
                                                  /* or */
       ((statbuf.st_mode & 2) != 0))              /* world writeable  */