meillo@0: /* MasqMail meillo@0: Copyright (C) 2000 Oliver Kurth meillo@174: Copyright (C) 2010 markus schnalke meillo@0: meillo@0: This program is free software; you can redistribute it and/or modify meillo@0: it under the terms of the GNU General Public License as published by meillo@0: the Free Software Foundation; either version 2 of the License, or meillo@0: (at your option) any later version. meillo@0: meillo@0: This program is distributed in the hope that it will be useful, meillo@0: but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@0: GNU General Public License for more details. meillo@0: meillo@0: You should have received a copy of the GNU General Public License meillo@0: along with this program; if not, write to the Free Software meillo@0: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: meillo@0: #include meillo@0: #include meillo@0: meillo@15: #include "masqmail.h" meillo@15: meillo@0: /* is there really no function in libc for this? */ meillo@10: gboolean meillo@10: is_ingroup(uid_t uid, gid_t gid) meillo@0: { meillo@10: struct group *grent = getgrgid(gid); meillo@84: struct passwd *pwent = getpwuid(uid); meillo@84: char *entry; meillo@84: int i = 0; meillo@0: meillo@84: if (!grent) { meillo@84: return FALSE; meillo@84: } meillo@84: if (!pwent) { meillo@84: return FALSE; meillo@84: } meillo@84: /* check primary group */ meillo@84: if (pwent->pw_gid == gid) { meillo@84: return TRUE; meillo@84: } meillo@84: /* check secondary groups */ meillo@84: while ((entry = grent->gr_mem[i++])) { meillo@84: if (strcmp(pwent->pw_name, entry) == 0) meillo@84: return TRUE; meillo@10: } meillo@10: return FALSE; meillo@0: } meillo@0: meillo@10: gboolean meillo@10: is_privileged_user(uid_t uid) meillo@0: { meillo@87: /* uncomment these lines if you need the `uucp' group to be trusted too meillo@87: struct group* grent = getgrnam("uucp"); meillo@87: meillo@87: if (is_ingroup(uid, grent->gr_gid)) { meillo@87: return TRUE; meillo@87: } meillo@87: */ meillo@87: meillo@10: return (uid == 0) || (uid == conf.mail_uid) || (is_ingroup(uid, conf.mail_gid)); meillo@0: } meillo@0: meillo@10: void meillo@10: set_euidgid(gint uid, gint gid, uid_t * old_uid, gid_t * old_gid) meillo@0: { meillo@10: if (old_uid) meillo@10: *old_uid = geteuid(); meillo@10: if (old_gid) meillo@10: *old_gid = getegid(); meillo@0: meillo@10: seteuid(0); meillo@0: meillo@10: if (setegid(gid) != 0) { meillo@10: logwrite(LOG_ALERT, "could not change gid to %d: %s\n", gid, strerror(errno)); meillo@10: exit(EXIT_FAILURE); meillo@10: } meillo@10: if (seteuid(uid) != 0) { meillo@10: logwrite(LOG_ALERT, "could not change uid to %d: %s\n", uid, strerror(errno)); meillo@10: exit(EXIT_FAILURE); meillo@10: } meillo@0: } meillo@0: meillo@10: void meillo@10: set_identity(uid_t old_uid, gchar * task_name) meillo@0: { meillo@10: if (!conf.run_as_user) { meillo@10: if (!is_privileged_user(old_uid)) { meillo@10: fprintf(stderr, "must be root, %s or in group %s for %s.\n", DEF_MAIL_USER, DEF_MAIL_GROUP, task_name); meillo@10: exit(EXIT_FAILURE); meillo@10: } meillo@0: meillo@10: set_euidgid(conf.mail_uid, conf.mail_gid, NULL, NULL); meillo@10: } meillo@0: }