Welcome
Welcome to <strong>The Linux And Unix Menagerie</strong>.

You are currently viewing our boards as a guest, which gives you limited access to view most discussions and access our other features. By joining our free community, you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content, and access many other special features. Registration is fast, simple, and absolutely free, so please, <a href="/profile.php?mode=register">join our community today</a>!

SUID programs

Any c or c++ programming questions and answers

SUID programs

Postby hotmule on Fri Nov 16, 2007 2:39 am

Hi,

I've been told that scripting isn't safe to use for suid programs that need to be run as root, but I'm not sure how to code the c program that would act as a wrapper for the root-owned command I want users to be able to run.

Any thoughts?

Thanks,

Mule
hotmule
 
Posts: 12
Joined: Sun Oct 28, 2007 4:49 pm

Postby laum on Sat Nov 17, 2007 12:02 am

My friend; this is a project unto itself. You can make this shorter, but I thought I'd put this code out (under the GPL) so you can see just how much you can protect yourself :)

Enjoy - if you need a shorter version, just let me know. Basically, try to use "n" operaters when checking input to avoid argument overflows and don't switch the real and effective user id or gid until you've verified everything and are just about to run the command - then switch back immediately

, laum


Code: Select all
/*
* Copyright (C), 2000-2007 by the monit project group.
* All Rights Reserved.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/

#include <config.h>

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_PWD_H
#include <pwd.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#include "monitor.h"

#ifndef MAXPATHLEN
#define MAXPATHLEN STRLEN
#endif

/* Private prototypes */
static void set_sandbox(void);
static void set_environment(void);

/**
*  Setup this program for safer exec, and set required runtime
*  "environment" variables.
*
*  @author Jan-Henrik Haukeland, <hauk@tildeslash.com>
*
*  @version \$Id: env.c,v 1.37 2007/07/25 12:54:28 hauk Exp $
*
*  @file
*/


/* ------------------------------------------------------------------ Public */


/**
* Initialize the program environment
*/
void init_env() {
 
  /* Setup for safe(r) exec */
  set_sandbox();

  /* Setup program environment */
  set_environment();

}


/* ----------------------------------------------------------------- Private */


/**
*  DESCRIPTION
*    This code was originally posted by Wietse Venema, years ago, in
*    a discussion on news on how to create safe suid wrappers. For
*    those interested in NNTP archeology, here's the post:
*   
*  Article 5648 of comp.security.unix:
*  From: wietse@wzv.win.tue.nl (Wietse Venema)
*  Newsgroups: comp.security.unix
*  Subject: Re: [8lgm]-Advisory-7.UNIX.passwd.11-May-1994
*  Date: 18 May 1994 07:52:05 +0200
*  Organization: Eindhoven University of Technology, The Netherlands
*  Lines: 68

*  milton@picard.med.miami.edu (H. Milton Johnson) writes:
*  >OK, I admit it, I'm a totally incompetent sysadmin because I am not
*  >sure I could write a bullet-proof setuid wrapper.  However, if one of
*  >the competent sysadmins subscribing to this group could post or point
*  >the way to an example of a bullet- proof setuid wrapper, I'm sure that
*  >I could use it as a template to address this/future/other problems.

*  Ok, here is a first stab. Perhaps we can make this into a combined
*  effort and get rid of the problem once and for all.

*           Wietse
*
*  [code - see the function below, only marginally changed to suit monit]   
*
*  @author Wietse Venema <wietse@wzv.win.tue.nl>
*
*/
static void set_sandbox(void) {

  int    i;
  struct stat st;
  extern char **environ;
  char   *path = "PATH=/bin:/usr/bin:/sbin:/usr/sbin";

  /*
   * Purge the environment. Then make sure PATH is set; some shells default
   * to a path with '.' first. You may have to putenv() other stuff, too,
   * but be careful with importing too much.
   */
  environ[0]= 0;
 
  if(putenv(path)) {
   
    LogError("%s: cannot set the PATH variable -- %s\n", prog, STRERROR);
    exit(1);
   
  }

  /*
   * Require that file descriptors 0,1,2 are open. Mysterious things
   * can happen if that is not the case.
   */
  for(i= 0; i < 3; i++) {
   
    if(fstat(i, &st) == -1 && open("/dev/null", O_RDWR) != i) {
     
      LogError("Cannot open /dev/null -- %s\n", STRERROR);
      exit(1);
     
    }
   
  }

  Util_closeFds();

}


/**
* Get and set required runtime "environment" variables.
*/
static void set_environment(void) {

  struct passwd *pw;
 
  /* Get password struct */
  if ( ! (pw= getpwuid(geteuid())) ) {
    LogError("%s: You don't exist. Go away.\n", prog);
    exit(1);
  }
  Run.Env.home= xstrdup(pw->pw_dir);
  Run.Env.user= xstrdup(pw->pw_name);
 
  /* Get CWD */
  Run.Env.cwd= xcalloc(sizeof(char), MAXPATHLEN+1);
  if ( ! (getcwd(Run.Env.cwd, MAXPATHLEN)) ) {
    LogError("%s: Cannot read current directory -- %s\n", prog, STRERROR);
    exit(1);
  }
 
  /*
   * Save and clear the file creation mask
   */
  Run.umask= umask(0);

}
laum
Site Admin
 
Posts: 46
Joined: Sun Oct 14, 2007 7:04 pm


Return to C/C++

Who is online

Users browsing this forum: No registered users and 0 guests

cron