inn.conf: Support for `newsuser', `newsgrp' options (patch is, hopefully, included)

Ivan Shmakov oneingray at gmail.com
Sun Dec 16 18:16:42 UTC 2007


SOT

	Great, I'm experimenting with it for some time now, and it even
	manages to run under my own user account!

	The first patch provides the `newsstar.c' module:

* include/innconf.h (struct innconf): New `newsuser' and `newsgrp'
  options.
* lib/innconf.c (config_table): Likewise.
* lib/Makefile (SOURCES): Added `newsuser.c'.
* include/newsuser.h: New file.
* lib/newsuser.c: New file.

	The second one tries to rip off every occurence of `NEWSUSER'
	and `NEWSGRP' outside of `newsuser.c':

* expire/expire.c
  (pwd.h): Don't include it anymore.
  (newsuser.h): Include this one instead.
  (setuid_news): Removed.
  (main): Call `ensure_news_user_grp' instead of now removed
  `setuid_news'.
* expire/expireover.c: Likewise.
* expire/makedbz.c: Likewise.
* expire/makehistory.c: Likewise.
* storage/tradindexed/tdx-util.c: Likewise.
* frontends/inews.c
  (grp.h): Don't include it anymore.
  (newsuser.h): Include this one instead.
  (AnAdministrator): Call `get_news_uid_gid' to obtain the IDs instead
  of calling `getpwnam' and `getgrnam' directly; check for process to
  posess the group ID, and not the group(5) entry.
* frontends/ovdb_init.c (main): The string `newsuser' replaces the value
  of the `NEWSUSER' CPP macro in the error message.
* frontends/ovdb_monitor.c (main): Likewise.
* frontends/ovdb_stat.c (main): Likewise.
* frontends/rnews.c
  (pwd.h): Don't include it anymore.
  (newsuser.h): Include this one instead.
  (main): Call `get_news_uid_gid' to obtain the UID instead of calling
  `getpwnam' directly.
* innd/inndstart.c
  (grp.h): Don't include it anymore.
  (pwd.h): Likewise.
  (newsuser.h): Include this one instead.
  (main): Call `get_news_uid_gid' to obtain the IDs instead of calling
  `getpwnam' and `gettgrnam' directly; changed the error message
  accordingly.
* innd/startinnfeed.c: Likewise.
* innd/inndstart.c: Don't use `setuid' if EUID is already that of
  newsuser.
* nnrpd/nnrpd.c
  (pwd.h): Don't include it anymore.
  (newsuser.h): Include this one instead.
  (main): Call `get_news_uid_gid' to obtain the IDs instead of calling
  `getpwnam' and `gettgrnam' directly; changed the error message
  accordingly.
* nnrpd/tls.c (set_cert_stuff): The UID of the process replaces the
  value of the `NEWSUSER' CPP macro in the error message.
* storage/ovdb/ovdb.c
  (pwd.h): Don't include it anymore.
  (newsuser.h): Include this one instead.
  (ovdb_check_user): Call `get_news_uid_gid' to obtain the UID instead
  of calling `getpwnam' directly; changed the error messages
  accordingly.

	Patch #3 finishes the transition by altering
	`scripts/innshellvars*.in' and `scripts/inncheck.in' as well:

* scripts/inncheck.in ($newsuser): Removed variable.
  ($newsgroup): Likewise.
* scripts/innshellvars.in (NEWSUSER): Removed variable.
  (NEWSGRP): Likewise.
* scripts/innshellvars.pl.in ($newsuser): Removed variable.
  ($newsgroup): Likewise.
* scripts/innshellvars.tcl.in (inn_newsuser): Removed variable.
  (inn_newsgroup): Likewise.

	Patch #4 updates `samples/inn.conf.in':

* samples/inn.conf.in (newsuser): New option.
  (newsgrp): Likewise.

	The documentation is still to be updated, and `ensure_news_*'
	are probably to be used more widely in the code.

* Patch #1

diff -drHu  inn2-2.4.3+20070806-debian-1/include/inn/innconf.h inn2-2.4.3+20070806-debian-1-newsuser/include/inn/innconf.h
--- inn2-2.4.3+20070806-debian-1/include/inn/innconf.h	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/include/inn/innconf.h	2007-12-16 23:24:54.000000000 +0600
@@ -26,6 +26,8 @@
     char *mta;                  /* MTA for mailing to moderators, innmail */
     char *pathhost;             /* Entry for the Path line */
     char *server;               /* Default server to connect to */
+    char *newsuser;             /* User to run under */
+    char *newsgrp;              /* Group to run under */
 
     /* Feed Configuration */
     long artcutoff;             /* Max accepted article age */
diff -drHu  inn2-2.4.3+20070806-debian-1/lib/innconf.c inn2-2.4.3+20070806-debian-1-newsuser/lib/innconf.c
--- inn2-2.4.3+20070806-debian-1/lib/innconf.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/lib/innconf.c	2007-12-11 22:33:17.000000000 +0600
@@ -121,6 +121,9 @@
     { K(sourceaddress6),        STRING  (NULL) },
     { K(timer),                 NUMBER  (0) },
 
+    { K(newsuser),              STRING  (NEWSUSER) },
+    { K(newsgrp),               STRING  (NEWSGRP) },
+
     { K(patharchive),           STRING  (NULL) },
     { K(patharticles),          STRING  (NULL) },
     { K(pathbin),               STRING  (NULL) },
diff -drHu  inn2-2.4.3+20070806-debian-1/lib/Makefile inn2-2.4.3+20070806-debian-1-newsuser/lib/Makefile
--- inn2-2.4.3+20070806-debian-1/lib/Makefile	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/lib/Makefile	2007-12-11 23:15:46.000000000 +0600
@@ -10,7 +10,8 @@
 		conffile.c confparse.c daemonize.c date.c dbz.c defdist.c \
 		fdflags.c fdlimit.c genid.c getfqdn.c getmodaddr.c gettime.c \
 		hash.c hashtab.c innconf.c inndcomm.c list.c localopen.c \
-		lockfile.c makedir.c md5.c messages.c mmap.c parsedate.c \
+		lockfile.c makedir.c md5.c messages.c mmap.c newsuser.c \
+		parsedate.c \
 		qio.c radix32.c readin.c remopen.c reservedfd.c resource.c \
 		sendarticle.c sendpass.c sequence.c sockaddr.c timer.c tst.c \
 		uwildmat.c vector.c version.c wire.c xfopena.c xmalloc.c \
diff -drHuN  inn2-2.4.3+20070806-debian-1/include/newsuser.h inn2-2.4.3+20070806-debian-1-newsuser/include/newsuser.h
--- inn2-2.4.3+20070806-debian-1/include/newsuser.h	1970-01-01 07:00:00.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/include/newsuser.h	2007-12-16 15:55:17.000000000 +0600
@@ -0,0 +1,21 @@
+/*** newsuser.h --- Ensure running as `news' user / group: header  -*- C -*- */
+
+/*** Ivan Shmakov, 2007 */
+/** This code is in the public domain */
+
+/*** Code: */
+#ifndef NEWSUSER_H
+#define NEWSUSER_H 1
+
+#include "config.h"
+#include "clibrary.h"
+
+int get_news_uid_gid (uid_t *uid, gid_t *gid, int may_die_p);
+
+/** the following functions die () on failure */
+void ensure_news_user (int may_setuid_p);
+void ensure_news_grp  (int may_setgid_p);
+void ensure_news_user_grp (int may_setuid_p, int may_setgid_p);
+
+#endif
+/*** newsuser.h ends here */
diff -drHuN  inn2-2.4.3+20070806-debian-1/lib/newsuser.c inn2-2.4.3+20070806-debian-1-newsuser/lib/newsuser.c
--- inn2-2.4.3+20070806-debian-1/lib/newsuser.c	1970-01-01 07:00:00.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/lib/newsuser.c	2007-12-16 15:54:55.000000000 +0600
@@ -0,0 +1,102 @@
+/*** newsuser.c --- Ensure running as `news' user / group  -*- C -*- */
+
+/*** Ivan Shmakov, 2007 */
+/** This code is in the public domain */
+
+/*** Code: */
+#include "config.h"
+#include "clibrary.h"
+
+#include <pwd.h>
+#include <grp.h>
+
+#include "inn/innconf.h"
+#include "newsuser.h"
+
+/** Resolve newsuser to a UID and newsgrp to a GID */
+int
+get_news_uid_gid (uid_t *uid, gid_t *gid, int may_die_p)
+{
+  /* NB: get_news_uid_gid () may be called before innconf_read () */
+  const char *newsuser = innconf != 0 ? innconf->newsuser : NEWSUSER;
+  const char *newsgrp  = innconf != 0 ? innconf->newsgrp  : NEWSGRP;
+  int fail_p = 0;
+  struct passwd *pwd;
+  struct group *grp;
+
+  /* resolve newsuser to a UID */
+  if (uid == 0) {
+    /* do nothing */
+  } else if ((pwd = getpwnam (newsuser)) != 0) {
+    *uid = pwd->pw_uid;
+  } else if (may_die_p) {
+    die (("can't resolve %s to a UID"
+          " (account doesn't exist?)"), newsuser);
+  } else {
+    fail_p = 1;
+  }
+
+  /* resolve newsgrp to a GID */
+  if (gid == 0) {
+    /* do nothing */
+  } else if ((grp = getgrnam (newsgrp)) != 0) {
+    *gid = grp->gr_gid;
+  } else if (may_die_p) {
+    die (("can't resolve %s to a GID"
+          " (group doesn't exist?)"), newsgrp);
+  } else {
+    fail_p = 1;
+  }
+
+  /* . */
+  return fail_p ? -1 : 0;
+}
+
+/** Ensure running as newsuser */
+void
+ensure_news_user (int may_setuid_p)
+{
+  uid_t uid;
+
+  get_news_uid_gid (&uid, 0, 1);
+  if (geteuid () == 0) {
+    if (! may_setuid_p) {
+      /* NB: mustn't be run as root, unless `may_setuid_p' is true */
+      die ("must be run as %s, not as root", innconf->newsuser);
+    }
+    setuid (uid);
+  }
+  if (geteuid () != uid || getuid () != uid) {
+    die ("must be run as %s", innconf->newsuser);
+  }
+
+  /* . */
+}
+
+/** Ensure running as newsgrp group */
+void
+ensure_news_grp (int may_setgid_p)
+{
+  gid_t gid;
+
+  get_news_uid_gid (0, &gid, 1);
+  if (may_setgid_p && geteuid () == 0) {
+    setgid (gid);
+  }
+  if (getegid () != gid || getgid () != gid) {
+    die ("must be run as %s group", innconf->newsgrp);
+  }
+
+  /* . */
+}
+
+/** Ensure running as newsuser and newsgrp group */
+void
+ensure_news_user_grp (int may_setuid_p, int may_setgid_p)
+{
+  /* NB: changing the group first to lose root privileges last */
+  ensure_news_grp  (may_setgid_p);
+  ensure_news_user (may_setuid_p);
+}
+
+/*** newsuser.c ends here */

* Patch #2

diff -drHu  inn2-2.4.3+20070806-debian-1/expire/expire.c inn2-2.4.3+20070806-debian-1-newsuser/expire/expire.c
--- inn2-2.4.3+20070806-debian-1/expire/expire.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/expire/expire.c	2007-12-16 23:09:10.000000000 +0600
@@ -7,7 +7,6 @@
 #include "clibrary.h"
 #include <ctype.h>
 #include <errno.h>
-#include <pwd.h>
 #include <sys/stat.h>
 #include <syslog.h>
 #include <time.h>
@@ -17,6 +16,7 @@
 #include "inn/messages.h"
 #include "inndcomm.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "paths.h"
 #include "storage.h"
 
@@ -488,25 +488,6 @@
 }
 
 
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
 int
 main(int ac, char *av[])
 {
@@ -627,8 +608,8 @@
     RealNow = Now;
     Now += TimeWarp;
 
-    /* Change users if necessary. */
-    setuid_news();
+    /* Change to the newsuser and newsgrp group if necessary. */
+    ensure_news_user_grp (1, 1);
 
     /* Parse the control file. */
     if (av[0]) {
diff -drHu  inn2-2.4.3+20070806-debian-1/expire/expireover.c inn2-2.4.3+20070806-debian-1-newsuser/expire/expireover.c
--- inn2-2.4.3+20070806-debian-1/expire/expireover.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/expire/expireover.c	2007-12-16 23:10:24.000000000 +0600
@@ -11,7 +11,6 @@
 #include "config.h"
 #include "clibrary.h"
 #include <errno.h>
-#include <pwd.h>
 #include <signal.h>
 #include <syslog.h>
 #include <time.h>
@@ -20,6 +19,7 @@
 #include "inn/messages.h"
 #include "inn/qio.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "ov.h"
 #include "paths.h"
 #include "storage.h"
@@ -46,25 +46,6 @@
 }
 
 
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
 int
 main(int argc, char *argv[])
 {
@@ -142,8 +123,8 @@
     if (!innconf_read(NULL))
         exit(1);
 
-    /* Change to the news user if necessary. */
-    setuid_news();
+    /* Change to the newsuser and newsgrp group if necessary. */
+    ensure_news_user_grp (1, 1);
 
     /* Initialize the lowmark file, if one was requested. */
     if (lowmark_path != NULL) {
diff -drHu  inn2-2.4.3+20070806-debian-1/expire/makedbz.c inn2-2.4.3+20070806-debian-1-newsuser/expire/makedbz.c
--- inn2-2.4.3+20070806-debian-1/expire/makedbz.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/expire/makedbz.c	2007-12-12 00:03:34.000000000 +0600
@@ -6,7 +6,6 @@
 #include "config.h"
 #include "clibrary.h"
 #include <errno.h>
-#include <pwd.h>
 #include <syslog.h>  
 
 #include "dbz.h"
@@ -14,6 +13,7 @@
 #include "inn/messages.h"
 #include "inn/qio.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "paths.h"
 #include "storage.h"
 
@@ -230,25 +230,6 @@
 }
 
 
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files, so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
 int
 main(int argc, char **argv)
 {
@@ -309,8 +290,8 @@
     if (chdir(HistoryDir) < 0)
         sysdie("cannot chdir to %s", HistoryDir);
 
-    /* Change users if necessary. */
-    setuid_news();
+    /* Change to the newsuser and newsgrp group if necessary. */
+    ensure_news_user_grp (1, 1);
 
     Rebuild(size, IgnoreOld, Overwrite);
     closelog();
diff -drHu  inn2-2.4.3+20070806-debian-1/expire/makehistory.c inn2-2.4.3+20070806-debian-1-newsuser/expire/makehistory.c
--- inn2-2.4.3+20070806-debian-1/expire/makehistory.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/expire/makehistory.c	2007-12-12 00:03:34.000000000 +0600
@@ -8,7 +8,6 @@
 #include "portable/wait.h"
 #include <assert.h>
 #include <errno.h>
-#include <pwd.h>
 #include <syslog.h>  
 
 #include "inn/buffer.h"
@@ -18,6 +17,7 @@
 #include "inn/qio.h"
 #include "inn/wire.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "ov.h"
 #include "paths.h"
 #include "storage.h"
@@ -740,25 +740,6 @@
 }
 
 
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files, so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
 int
 main(int argc, char **argv)
 {
@@ -853,8 +834,8 @@
     if (chdir(HistoryDir) < 0)
         sysdie("cannot chdir to %s", HistoryDir);
 
-    /* Change users if necessary. */
-    setuid_news();
+    /* Change to the newsuser and newsgrp group if necessary. */
+    ensure_news_user_grp (1, 1);
 
     /* Read in the overview schema */
     ARTreadschema(DoOverview);
diff -drHuN  inn2-2.4.3+20070806-debian-1/frontends/inews.c inn2-2.4.3+20070806-debian-1-newsuser/frontends/inews.c
--- inn2-2.4.3+20070806-debian-1/frontends/inews.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/frontends/inews.c	2007-12-16 23:13:36.000000000 +0600
@@ -10,13 +10,13 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <grp.h>
 #include <pwd.h>
 #include <sys/stat.h>
 
 #include "inn/innconf.h"
 #include "inn/messages.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "nntp.h"
 #include "paths.h"
 
@@ -339,8 +339,8 @@
 static bool
 AnAdministrator(char *name, gid_t group)
 {
-    struct passwd	*pwp;
-    struct group	*grp;
+    uid_t               news_uid;
+    gid_t               news_gid;
     char		**mem;
     char		*p;
 
@@ -348,21 +348,35 @@
 	return false;
 
     /* Find out who we are. */
-    if ((pwp = getpwnam(NEWSUSER)) == NULL)
+    if (get_news_uid_gid (&news_uid, &news_gid, 0) != 0) {
 	/* Silent falure; clients might not have the group. */
 	return false;
-    if (getuid() == pwp->pw_uid)
+    }
+    if (getuid() == news_uid)
 	return true;
 
     /* See if the we're in the right group. */
-    if ((grp = getgrnam(NEWSGRP)) == NULL || (mem = grp->gr_mem) == NULL)
-	/* Silent falure; clients might not have the group. */
-	return false;
-    if (group == grp->gr_gid)
-	return true;
-    while ((p = *mem++) != NULL)
-	if (strcmp(name, p) == 0)
-	    return true;
+    /* IS: here, I examine process supplementary groups, rather than the
+     *     group(5) file entry; I'm not sure how the security will be
+     *     affected by this change.
+     */
+    {
+        int ngroups = getgroups (0, 0);
+        gid_t *groups, *gp;
+        int rv;
+        int rest;
+
+        groups = (gid_t *)xmalloc (ngroups * sizeof (*groups));
+        if ((rv = getgroups (ngroups, groups)) < 0) {
+            /* Silent falure; client doesn't have the group. */
+            return false;
+        }
+        for (rest = ngroups, gp = groups; rest > 0; rest--, gp++) {
+            if (*gp == news_gid)
+                return true;
+        }
+    }
+
     return false;
 }
 
diff -drHuN  inn2-2.4.3+20070806-debian-1/frontends/ovdb_init.c inn2-2.4.3+20070806-debian-1-newsuser/frontends/ovdb_init.c
--- inn2-2.4.3+20070806-debian-1/frontends/ovdb_init.c	2007-12-16 14:35:56.000000000 +0600
+++ inn2-2.4.3+20070806-debian-1-newsuser/frontends/ovdb_init.c	2007-12-16 22:50:09.000000000 +0600
@@ -367,7 +367,7 @@
         die("ovmethod not set to ovdb in inn.conf");
 
     if(!ovdb_check_user())
-        die("command must be run as user " NEWSUSER);
+        die ("command must be run as newsuser");
 
     chdir(innconf->pathtmp);
     ovdb_errmode = OVDB_ERR_STDERR;
diff -drHuN  inn2-2.4.3+20070806-debian-1/frontends/ovdb_monitor.c inn2-2.4.3+20070806-debian-1-newsuser/frontends/ovdb_monitor.c
--- inn2-2.4.3+20070806-debian-1/frontends/ovdb_monitor.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/frontends/ovdb_monitor.c	2007-12-16 14:52:03.000000000 +0600
@@ -303,7 +303,7 @@
     if(strcmp(innconf->ovmethod, "ovdb"))
         die("ovmethod not set to ovdb in inn.conf");
     if(!ovdb_check_user())
-        die("command must be run as user " NEWSUSER);
+        die("command must be run as newsuser");
     if(!ovdb_getlock(OVDB_LOCK_ADMIN))
         die("cannot lock database");
 
diff -drHuN  inn2-2.4.3+20070806-debian-1/frontends/ovdb_stat.c inn2-2.4.3+20070806-debian-1-newsuser/frontends/ovdb_stat.c
--- inn2-2.4.3+20070806-debian-1/frontends/ovdb_stat.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/frontends/ovdb_stat.c	2007-12-16 14:55:11.000000000 +0600
@@ -774,7 +774,7 @@
         exit(1);
 
     if(!ovdb_check_user())
-        die("command must be run as user " NEWSUSER);
+        die ("command must be run as newsuser");
     if(!ovdb_getlock(OVDB_LOCK_ADMIN))
         sysdie("cannot lock database");
     if(!ovdb_open(OV_READ|OVDB_SERVER))
diff -drHuN  inn2-2.4.3+20070806-debian-1/frontends/rnews.c inn2-2.4.3+20070806-debian-1-newsuser/frontends/rnews.c
--- inn2-2.4.3+20070806-debian-1/frontends/rnews.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/frontends/rnews.c	2007-12-16 23:15:28.000000000 +0600
@@ -14,7 +14,6 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <pwd.h>
 #include <syslog.h>
 #include <sys/stat.h>
 
@@ -22,6 +21,7 @@
 #include "inn/messages.h"
 #include "inn/wire.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "nntp.h"
 #include "paths.h"
 #include "storage.h"
@@ -858,13 +858,10 @@
        other setups where rnews might be setuid news or be run by other
        processes in the news group. */
     if (getuid() == 0 || geteuid() == 0) {
-        struct passwd *pwd;
+        uid_t uid;
 
-        pwd = getpwnam(NEWSUSER);
-        if (pwd == NULL)
-            die("can't resolve %s to a UID (account doesn't exist?)",
-                NEWSUSER);
-        setuid(pwd->pw_uid);
+        get_news_uid_gid (&uid, 0, 1);
+        setuid (uid);
     }
 
     if (!innconf_read(NULL))
diff -drHu  inn2-2.4.3+20070806-debian-1/innfeed/startinnfeed.c inn2-2.4.3+20070806-debian-1-newsuser/innfeed/startinnfeed.c
--- inn2-2.4.3+20070806-debian-1/innfeed/startinnfeed.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/innfeed/startinnfeed.c	2007-12-16 23:54:52.000000000 +0600
@@ -13,8 +13,6 @@
 #include "clibrary.h"
 #include <syslog.h>
 #include <errno.h>
-#include <grp.h>
-#include <pwd.h>
 
 /* FreeBSD 3.4 RELEASE needs <sys/time.h> before <sys/resource.h>. */
 #if HAVE_SETRLIMIT
@@ -27,6 +25,7 @@
 #include "inn/innconf.h"
 #include "inn/messages.h"
 #include "libinn.h"
+#include "newsuser.h"
 
 /* Options for debugging malloc. */
 #ifdef USE_DMALLOC
@@ -38,8 +37,6 @@
 int
 main(int argc, char *argv[])
 {
-    struct passwd *     pwd;
-    struct group *      grp;
     uid_t               news_uid;
     gid_t               news_gid;
     char **             innfeed_argv;
@@ -54,20 +51,12 @@
     message_handlers_warn(1, message_log_syslog_warning);
     message_handlers_die(1, message_log_syslog_err);
 
-    /* Convert NEWSUSER and NEWSGRP to a UID and GID.  getpwnam() and
-       getgrnam() don't set errno normally, so don't print strerror() on
-       failure; it probably contains garbage.*/
-    pwd = getpwnam(NEWSUSER);
-    if (!pwd) die("can't getpwnam(%s)", NEWSUSER);
-    news_uid = pwd->pw_uid;
-    grp = getgrnam(NEWSGRP);
-    if (!grp) die("can't getgrnam(%s)", NEWSGRP);
-    news_gid = grp->gr_gid;
+    get_news_uid_gid (&news_uid, &news_gid, 1);
 
     /* Exit if run by another user. */
     if (getuid() != news_uid)
-        die("ran by UID %lu, who isn't %s (%lu)", (unsigned long) getuid(),
-            NEWSUSER, (unsigned long) news_uid);
+        die("ran by UID %lu, who isn't newsuser (%lu)",
+            (unsigned long) getuid (), (unsigned long) news_uid);
 
     /* Drop privileges to read inn.conf. */
     if (seteuid(news_uid) < 0)
diff -drHu  inn2-2.4.3+20070806-debian-1/nnrpd/nnrpd.c inn2-2.4.3+20070806-debian-1-newsuser/nnrpd/nnrpd.c
--- inn2-2.4.3+20070806-debian-1/nnrpd/nnrpd.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/nnrpd/nnrpd.c	2007-12-16 23:46:52.000000000 +0600
@@ -12,7 +12,6 @@
 #include "portable/wait.h"
 #include <grp.h>
 #include <netdb.h>
-#include <pwd.h>
 #include <signal.h>
 
 #if HAVE_GETSPNAM
@@ -22,6 +21,7 @@
 #include "inn/innconf.h"
 #include "inn/messages.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "ov.h"
 #define MAINLINE
 #include "nnrpd.h"
@@ -823,7 +823,6 @@
     uid_t               NewsUID;
     int                 one = 1;
     FILE                *pidfile;
-    struct passwd	*pwd;
     int			clienttimeout;
     char		*ConfFile = NULL;
     char                *path;
@@ -985,8 +984,11 @@
 	    exit(1);
 	}
 
-	/* If started as root, switch to news uid */
+        /* If started as root, switch to newsuser / newsgrp */
 	if (getuid() == 0) {
+            uid_t uid;
+            gid_t gid;
+
 	    if (stat(innconf->pathrun, &Sb) < 0 || !S_ISDIR(Sb.st_mode)) {
 		syslog(L_FATAL, "nnrpd cant stat %s %m", innconf->pathrun);
 		exit(1);
@@ -995,15 +997,14 @@
 		syslog(L_FATAL, "nnrpd %s must not be owned by root", innconf->pathrun);
 		exit(1);
 	    }
-	    pwd = getpwnam(NEWSUSER);
-	    if (pwd == (struct passwd *)NULL) {
-		syslog(L_FATAL, "nnrpd getpwnam(%s): %s", NEWSUSER, strerror(errno));
-		exit(1);
-	    } else if (pwd->pw_gid != Sb.st_gid) {
-		syslog(L_FATAL, "nnrpd %s must have group %s", innconf->pathrun, NEWSGRP);
+            get_news_uid_gid (&uid, &gid, 1);
+            if (gid != Sb.st_gid) {
+                syslog(L_FATAL, "nnrpd %s must have group newsgrp",
+                       innconf->pathrun);
 		exit(1);
-	    } else if (pwd->pw_uid != Sb.st_uid) {
-		syslog(L_FATAL, "nnrpd %s must be owned by %s", innconf->pathrun, NEWSUSER);
+            } else if (uid != Sb.st_uid) {
+                syslog(L_FATAL, "nnrpd %s must be owned by newsuser",
+                       innconf->pathrun);
 		exit(1);
 	    }
 
diff -drHu  inn2-2.4.3+20070806-debian-1/nnrpd/tls.c inn2-2.4.3+20070806-debian-1-newsuser/nnrpd/tls.c
--- inn2-2.4.3+20070806-debian-1/nnrpd/tls.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/nnrpd/tls.c	2007-12-16 15:31:25.000000000 +0600
@@ -423,7 +423,7 @@
 	    buf.st_uid != getuid()) {
 	    syslog(L_ERROR, "bad ownership or permissions on private key"
                    " '%s': private key must be mode 600 and owned by "
-                   NEWSUSER, cert_file);
+                   "uid %d", cert_file, getuid ());
 	    return (0);
 	}
 
diff -drHu  inn2-2.4.3+20070806-debian-1/storage/ovdb/ovdb.c inn2-2.4.3+20070806-debian-1-newsuser/storage/ovdb/ovdb.c
--- inn2-2.4.3+20070806-debian-1/storage/ovdb/ovdb.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/storage/ovdb/ovdb.c	2007-12-17 00:03:40.000000000 +0600
@@ -79,7 +79,6 @@
 #ifdef HAVE_LIMITS_H
 # include <limits.h>
 #endif
-#include <pwd.h>
 #include <signal.h>
 #ifdef HAVE_SYS_SELECT_H
 # include <sys/select.h>
@@ -90,6 +89,7 @@
 #include "inn/innconf.h"
 #include "inn/messages.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "paths.h"
 #include "storage.h"
 
@@ -1339,19 +1339,21 @@
     return true;
 }
 
-/* make sure the effective uid is that of NEWSUSER */
+/* make sure the effective uid is that of newsuser */
 bool ovdb_check_user(void)
 {
-    struct passwd *p;
     static int result = -1;
 
     if(result == -1) {
-	p = getpwnam(NEWSUSER);
-	if(!p) {
-	    syslog(L_FATAL, "OVDB: getpwnam(" NEWSUSER ") failed: %m");
-	    return false;
-	}
-	result = (p->pw_uid == geteuid());
+        int rv;
+        uid_t uid;
+
+        rv = get_news_uid_gid (&uid, 0, 0);
+        if (rv != 0) {
+            syslog (L_FATAL, "OVDB: can't resolve newsuser to a UID");
+            return false;
+        }
+        result = (uid == geteuid ());
     }
     return result;
 }
@@ -1578,7 +1580,7 @@
 	clientmode = 0;
     }
     if(!ovdb_check_user()) {
-	syslog(L_FATAL, "OVDB: must be running as " NEWSUSER " to access overview.");
+        syslog (L_FATAL, "OVDB: must be running as newsuser to access overview.");
 	return false;
     }
     if(!ovdb_getlock(OVDB_LOCK_NORMAL)) {
diff -drHu  inn2-2.4.3+20070806-debian-1/storage/tradindexed/tdx-util.c inn2-2.4.3+20070806-debian-1-newsuser/storage/tradindexed/tdx-util.c
--- inn2-2.4.3+20070806-debian-1/storage/tradindexed/tdx-util.c	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/storage/tradindexed/tdx-util.c	2007-12-16 23:59:16.000000000 +0600
@@ -12,7 +12,6 @@
 #include "clibrary.h"
 #include <ctype.h>
 #include <dirent.h>
-#include <pwd.h>
 #include <sys/stat.h>
 
 #include "inn/buffer.h"
@@ -21,6 +20,7 @@
 #include "inn/messages.h"
 #include "inn/vector.h"
 #include "libinn.h"
+#include "newsuser.h"
 #include "ov.h"
 #include "ovinterface.h"
 #include "paths.h"
@@ -347,25 +347,6 @@
 
 
 /*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may change the overview files so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
-/*
 **  Main routine.  Load inn.conf, parse the arguments, and dispatch to the
 **  appropriate function.
 */
@@ -445,11 +426,11 @@
         tdx_index_audit(false);
         break;
     case 'F':
-        setuid_news();
+        ensure_news_user_grp (1, 1);
         tdx_index_audit(true);
         break;
     case 'R':
-        setuid_news();
+        ensure_news_user_grp (1, 1);
         group_rebuild(newsgroup, path);
         break;
     case 'i':

* Patch #3

diff -drHu  inn2-2.4.3+20070806-debian-1/scripts/inncheck.in inn2-2.4.3+20070806-debian-1-newsuser/scripts/inncheck.in
--- inn2-2.4.3+20070806-debian-1/scripts/inncheck.in	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/scripts/inncheck.in	2007-12-16 15:03:24.000000000 +0600
@@ -9,9 +9,6 @@
 $ST_UID  = 4;
 $ST_GID  = 5;
 
-$newsuser = '@NEWSUSER@';
-$newsgroup = '@NEWSGRP@';
-
 ##  We use simple names, mapping them to the real filenames only when
 ##  we actually need a filename.
 %paths = (
diff -drHu  inn2-2.4.3+20070806-debian-1/scripts/innshellvars.in inn2-2.4.3+20070806-debian-1-newsuser/scripts/innshellvars.in
--- inn2-2.4.3+20070806-debian-1/scripts/innshellvars.in	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/scripts/innshellvars.in	2007-12-16 15:00:56.000000000 +0600
@@ -95,8 +95,6 @@
 HAVE_UUSTAT=@HAVE_UUSTAT@
 
 NEWSMASTER=@NEWSMASTER@
-NEWSUSER=@NEWSUSER@
-NEWSGROUP=@NEWSGRP@
 
 TMPDIR=${PATHTMP}; export TMPDIR;
 
diff -drHu  inn2-2.4.3+20070806-debian-1/scripts/innshellvars.pl.in inn2-2.4.3+20070806-debian-1-newsuser/scripts/innshellvars.pl.in
--- inn2-2.4.3+20070806-debian-1/scripts/innshellvars.pl.in	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/scripts/innshellvars.pl.in	2007-12-16 15:01:29.000000000 +0600
@@ -96,8 +96,6 @@
 $have_uustat = ("@HAVE_UUSTAT@" eq "DO" ? 1 : 0) ;
 
 $newsmaster = '@NEWSMASTER@' ;
-$newsuser = '@NEWSUSER@' ;
-$newsgroup = '@NEWSGRP@' ;
 
 $ENV{'TMPDIR'} = $pathtmp;
 $tmpdir = $pathtmp;
diff -drHu  inn2-2.4.3+20070806-debian-1/scripts/innshellvars.tcl.in inn2-2.4.3+20070806-debian-1-newsuser/scripts/innshellvars.tcl.in
--- inn2-2.4.3+20070806-debian-1/scripts/innshellvars.tcl.in	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/scripts/innshellvars.tcl.in	2007-12-16 15:02:06.000000000 +0600
@@ -91,8 +91,6 @@
 set inn_have_uustat [ expr { "@HAVE_UUSTAT@" == "DO" ? 1 : 0 } ]
 
 set inn_newsmaster "@NEWSMASTER@"
-set inn_newsuser "@NEWSUSER@"
-set inn_newsgroup "@NEWSGRP@"
 
 set env(TMPDIR) "$inn_pathtmp"
 set inn_tmpdir "$inn_pathtmp"

* Patch #4

diff -drHu  inn2-2.4.3+20070806-debian-1/samples/inn.conf.in inn2-2.4.3+20070806-debian-1-newsuser/samples/inn.conf.in
--- inn2-2.4.3+20070806-debian-1/samples/inn.conf.in	2007-08-06 16:07:29.000000000 +0700
+++ inn2-2.4.3+20070806-debian-1-newsuser/samples/inn.conf.in	2007-12-16 15:32:52.000000000 +0600
@@ -24,6 +24,9 @@
 pathhost:               @HOSTNAME@
 pathnews:               @prefix@
 
+newsuser:               @NEWSUSER@
+newsgrp:                @NEWSGRP@
+
 # General Settings
 
 #domain:



More information about the inn-workers mailing list