From 3ba8a78955449e8d258f758ad5fcc0db910118b4 Mon Sep 17 00:00:00 2001 From: dds Date: Fri, 11 Mar 2005 08:39:58 +0000 Subject: [PATCH] Move common credential save and restore code into a separate file. Improve credential handling in pt_file.c --- usr.sbin/mount_portalfs/Makefile | 2 +- usr.sbin/mount_portalfs/cred.c | 75 +++++++++++++++++++++++++++++++ usr.sbin/mount_portalfs/portald.h | 3 ++ usr.sbin/mount_portalfs/pt_file.c | 13 ++---- usr.sbin/mount_portalfs/pt_pipe.c | 22 ++------- 5 files changed, 86 insertions(+), 29 deletions(-) create mode 100644 usr.sbin/mount_portalfs/cred.c diff --git a/usr.sbin/mount_portalfs/Makefile b/usr.sbin/mount_portalfs/Makefile index 5ee42daef602..610ac233b5b0 100644 --- a/usr.sbin/mount_portalfs/Makefile +++ b/usr.sbin/mount_portalfs/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PROG= mount_portalfs -SRCS= mount_portalfs.c activate.c conf.c getmntopts.c pt_conf.c \ +SRCS= mount_portalfs.c activate.c conf.c cred.c getmntopts.c pt_conf.c \ pt_exec.c pt_file.c pt_pipe.c pt_tcp.c pt_tcplisten.c MAN= mount_portalfs.8 diff --git a/usr.sbin/mount_portalfs/cred.c b/usr.sbin/mount_portalfs/cred.c new file mode 100644 index 000000000000..9e5d9f3f222b --- /dev/null +++ b/usr.sbin/mount_portalfs/cred.c @@ -0,0 +1,75 @@ +/*- + * Copyright (C) 2005 Diomidis Spinellis. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include + +#include "portald.h" + +/* + * Set the process's credentials to those specified in user, + * saveing the existing ones in save. + * Return 0 on success, -1 (with errno set) on error. + */ +int +set_user_credentials(struct portal_cred *user, struct portal_cred *save) +{ + save->pcr_uid = geteuid(); + if ((save->pcr_ngroups = getgroups(NGROUPS_MAX, save->pcr_groups)) < 0) + return (-1); + if (setgroups(user->pcr_ngroups, user->pcr_groups) < 0) + return (-1); + if (seteuid(user->pcr_uid) < 0) + return (-1); + return (0); +} + +/* + * Restore the process's credentials to the ones specified in save. + * Log failures using LOG_ERR. + * Return 0 on success, -1 (with errno set) on error. + */ +int +restore_credentials(struct portal_cred *save) +{ + if (seteuid(save->pcr_uid) < 0) { + syslog(LOG_ERR, "seteuid: %m"); + return (-1); + } + if (setgroups(save->pcr_ngroups, save->pcr_groups) < 0) { + syslog(LOG_ERR, "setgroups: %m"); + return (-1); + } + return (0); +} diff --git a/usr.sbin/mount_portalfs/portald.h b/usr.sbin/mount_portalfs/portald.h index bf8b50bec7de..ff4c3fd4451d 100644 --- a/usr.sbin/mount_portalfs/portald.h +++ b/usr.sbin/mount_portalfs/portald.h @@ -80,3 +80,6 @@ extern int portal_tcplisten(struct portal_cred *, extern void activate(qelem *q, int so); extern char **conf_match(qelem *q, char *key); extern void conf_read(qelem *q, char *conf); +extern int set_user_credentials(struct portal_cred *user, + struct portal_cred *save_area); +extern int restore_credentials(struct portal_cred *save_area); diff --git a/usr.sbin/mount_portalfs/pt_file.c b/usr.sbin/mount_portalfs/pt_file.c index 153c7337ffff..e2c396ac6380 100644 --- a/usr.sbin/mount_portalfs/pt_file.c +++ b/usr.sbin/mount_portalfs/pt_file.c @@ -56,7 +56,7 @@ int *fdp; int fd; char pbuf[MAXPATHLEN]; int error; - gid_t gidset[NGROUPS]; + struct portal_cred save_area; int i; pbuf[0] = '/'; @@ -67,13 +67,7 @@ int *fdp; printf ("fflag = %x, oflag = %x\n", pcr->pcr_flag, (pcr->pcr_flag)-1); #endif - for (i = 0; i < pcr->pcr_ngroups; i++) - gidset[i] = pcr->pcr_groups[i]; - - if (setgroups(pcr->pcr_ngroups, gidset) < 0) - return (errno); - - if (seteuid(pcr->pcr_uid) < 0) + if (set_user_credentials(pcr, &save_area) < 0) return (errno); /* dmb convert kernel flags to oflags, see */ @@ -83,9 +77,8 @@ int *fdp; else error = 0; - if (seteuid((uid_t) 0) < 0) { /* XXX - should reset gidset too */ + if (restore_credentials(&save_area) < 0) { error = errno; - syslog(LOG_ERR, "setcred: %s", strerror(error)); if (fd >= 0) { (void) close(fd); fd = -1; diff --git a/usr.sbin/mount_portalfs/pt_pipe.c b/usr.sbin/mount_portalfs/pt_pipe.c index 6a2a24e860e6..285f193b4f17 100644 --- a/usr.sbin/mount_portalfs/pt_pipe.c +++ b/usr.sbin/mount_portalfs/pt_pipe.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 1005 Diomidis Spinellis. All rights reserved. + * Copyright (C) 2005 Diomidis Spinellis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -64,10 +64,7 @@ int *fdp; int i; char **argv; int argc; - /* Variables used to save the the caller's credentials. */ - uid_t old_uid; - int ngroups; - gid_t old_groups[NGROUPS_MAX]; + struct portal_cred save_area; /* Validate open mode, and assign roles. */ if ((pcr->pcr_flag & FWRITE) && (pcr->pcr_flag & FREAD)) @@ -100,12 +97,7 @@ int *fdp; return (ENOENT); /* Swap priviledges. */ - old_uid = geteuid(); - if ((ngroups = getgroups(NGROUPS_MAX, old_groups)) < 0) - return (errno); - if (setgroups(pcr->pcr_ngroups, pcr->pcr_groups) < 0) - return (errno); - if (seteuid(pcr->pcr_uid) < 0) + if (set_user_credentials(pcr, &save_area) < 0) return (errno); /* Redirect and spawn the specified process. */ @@ -150,14 +142,8 @@ int *fdp; done: /* Re-establish our priviledges. */ - if (seteuid(old_uid) < 0) { + if (restore_credentials(&save_area) < 0) error = errno; - syslog(LOG_ERR, "seteuid: %m"); - } - if (setgroups(ngroups, old_groups) < 0) { - error = errno; - syslog(LOG_ERR, "setgroups: %m"); - } /* Set return fd value. */ if (error == 0)