From 35edf2ff67ad9fa5fc0e83bde865d807c297864f Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Mon, 18 Oct 2004 09:16:57 +0000 Subject: Added CONFIGURE_GROUP as a build-time facility, cf CONFIGURE_OWNER. --- src/src/EDITME | 28 +++++++++++++++--------- src/src/buildconfig.c | 55 +++++++++++++++++++++++++++++++++++------------ src/src/config.h.defaults | 3 ++- src/src/exim.c | 13 +++++++++-- src/src/globals.c | 5 ++++- src/src/globals.h | 5 ++++- src/src/readconf.c | 9 +++++--- 7 files changed, 86 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/src/EDITME b/src/src/EDITME index 2f900f271..418b51bab 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -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. #------------------------------------------------------------------------------ diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c index 6dd0d5112..f596ff827 100644 --- a/src/src/buildconfig.c +++ b/src/src/buildconfig.c @@ -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; } diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 39a17ae17..e31cffb10 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -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 diff --git a/src/src/exim.c b/src/src/exim.c index 37f206d26..bfdcbc6e0 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -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. */ diff --git a/src/src/globals.c b/src/src/globals.c index b9cf2458f..a206d4232 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -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; diff --git a/src/src/globals.h b/src/src/globals.h index 17183c6f8..9cd0bf72e 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -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 */ diff --git a/src/src/readconf.c b/src/src/readconf.c index 95470763d..caa78ee90 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -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 */ -- cgit v1.2.3