*BSD News Article 24608


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!yarrina.connect.com.au!harbinger.cc.monash.edu.au!msuinfo!agate!howland.reston.ans.net!EU.net!ieunet!news.ieunet.ie!jkh
From: jkh@whisker.lotus.ie (Jordan K. Hubbard)
Newsgroups: comp.os.386bsd.questions
Subject: Re: "su" for one command
Date: 03 Dec 1993 09:11:02 GMT
Organization: Dublin, Ireland
Lines: 70
Distribution: world
Message-ID: <JKH.93Dec3011102@whisker.lotus.ie>
References: <2dkb8a$hoq@sylvester.cc.utexas.edu>
NNTP-Posting-Host: whisker.lotus.ie
In-reply-to: vax@sylvester.cc.utexas.edu's message of 2 Dec 1993 03:07:22 -0600

In article <2dkb8a$hoq@sylvester.cc.utexas.edu> vax@sylvester.cc.utexas.edu (Vax) writes:
   Under BSD Unixes, how does one go about executing a single command
   as another user?  I have been unsuccessful in applying the standard:
   "su foo command".  It simply ignores the command.  Is there a proper way
   to do this?  Do you use a "here" document?  Can you nest them?

Try something like this:

#include <stdio.h>
#include <pwd.h>
     
extern int errno;

/* #define MY_UID 700 */

main (argc, argv, envp)
int argc;
char *argv [];
char *envp [];
{
     char *shell, *name, *getenv();
     struct passwd *ent;
     char ps1[128];
     char **av = argv;
     int ac = argc;
     
/*  Enable for security - see MY_UID above
     if (getuid()!=MY_UID) {
	  fprintf(stderr, "piss off!\n");
	  exit(0);
     }
*/

     if ((argc > 1) && (argv[1][0] == '-')) {
	  name = av[1] + 1;
	  sprintf(ps1, "PS1=(%s) ", name);
	  av++;
	  ac--;
     }
     else {
	  name = "root";
	  strcpy(ps1, "PS1=(#) ");
     }
     
     if ((ent = getpwnam(name)) == NULL) {
	  fprintf(stderr, "Can't find password entry for \"%s\"\n", name);
	  exit(0);
     }

     if (!(setgid(ent->pw_gid) || setuid(ent->pw_uid))) {
	  putenv(ps1);
	  if (ac == 1)
		   if(shell = getenv("SHELL"))
			execl(shell, shell, (char *)0L);
		   else
			execl("/bin/sh", "sh", (char *)(0L));
	      else {
			 execvp(av[1], av + 1);
		    }
	       fprintf(stderr, "Error in %s: ", argv[0]);
	       perror("");
	  }
     else { 
	       fprintf(stderr, "%s setuid failed - ", argv[0]);
	       perror("");
	  }
}

--
(Jordan K. Hubbard)  jkh@violet.berkeley.edu, jkh@al.org, jkh@whisker.lotus.ie