diff src/permissions.c @ 0:08114f7dcc23 0.2.21

this is masqmail-0.2.21 from oliver kurth
author meillo@marmaro.de
date Fri, 26 Sep 2008 17:05:23 +0200
parents
children 26e34ae9a3e3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/permissions.c	Fri Sep 26 17:05:23 2008 +0200
@@ -0,0 +1,78 @@
+/*  MasqMail
+    Copyright (C) 2000 Oliver Kurth
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "masqmail.h"
+#include <pwd.h>
+#include <grp.h>
+
+/* is there really no function in libc for this? */
+gboolean is_ingroup(uid_t uid, gid_t gid)
+{
+  struct group *grent = getgrgid(gid);
+
+  if(grent){
+    struct passwd *pwent = getpwuid(uid);
+    if(pwent){
+      char *entry;
+      int i = 0;
+      while((entry = grent->gr_mem[i++])){
+	if(strcmp(pwent->pw_name, entry) == 0)
+	  return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+gboolean is_privileged_user(uid_t uid)
+{
+  return (uid == 0) || (uid == conf.mail_uid) || (is_ingroup(uid, conf.mail_gid));
+}
+
+void set_euidgid(gint uid, gint gid, uid_t *old_uid, gid_t *old_gid)
+{
+  if(old_uid) *old_uid = geteuid();
+  if(old_gid) *old_gid = getegid();
+
+  seteuid(0);
+
+  if(setegid(gid) != 0){
+    logwrite(LOG_ALERT, "could not change gid to %d: %s\n",
+	     gid, strerror(errno));
+    exit(EXIT_FAILURE);
+  }
+  if(seteuid(uid) != 0){
+    logwrite(LOG_ALERT, "could not change uid to %d: %s\n",
+	     uid, strerror(errno));
+    exit(EXIT_FAILURE);
+  }
+}
+
+void set_identity(uid_t old_uid, gchar *task_name)
+{
+  if(!conf.run_as_user){
+    if(!is_privileged_user(old_uid)){
+      fprintf(stderr,
+	      "must be root, %s or in group %s for %s.\n",
+	      DEF_MAIL_USER, DEF_MAIL_GROUP, task_name);
+      exit(EXIT_FAILURE);
+    }
+
+    set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL);
+  }
+}