view 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 source

/*  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);
  }
}