156 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* su - become super-user		Author: Patrick van Kleef */
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <pwd.h>
 | 
						|
#include <grp.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <limits.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <time.h>
 | 
						|
#if __minix_vmd
 | 
						|
#include <sys/syslog.h>
 | 
						|
#endif
 | 
						|
#include <minix/minlib.h>
 | 
						|
 | 
						|
_PROTOTYPE(int main, (int argc, char **argv));
 | 
						|
 | 
						|
int main(argc, argv)
 | 
						|
int argc;
 | 
						|
char *argv[];
 | 
						|
{
 | 
						|
  register char *name, *password;
 | 
						|
  char *shell, sh0[100];
 | 
						|
  char from_user[8+1], from_shell[100];
 | 
						|
  register struct passwd *pwd;
 | 
						|
  char USER[20], LOGNAME[25], HOME[100], SHELL[100];
 | 
						|
  char *envv[20], **envp;
 | 
						|
  int smallenv;
 | 
						|
  char *p;
 | 
						|
  int super;
 | 
						|
  int loginshell;
 | 
						|
#if __minix_vmd
 | 
						|
  gid_t groups[NGROUPS_MAX];
 | 
						|
  int ngroups;
 | 
						|
  int g;
 | 
						|
#endif
 | 
						|
 | 
						|
  smallenv = 0;
 | 
						|
  loginshell = 0;
 | 
						|
  if (argc > 1 && (strcmp(argv[1], "-") == 0 || strcmp(argv[1], "-e") == 0)) {
 | 
						|
	if (argv[1][1] == 0)
 | 
						|
		loginshell= 1;		/* 'su -' reads .profile */
 | 
						|
	argv[1] = argv[0];
 | 
						|
	argv++;
 | 
						|
	argc--;
 | 
						|
	smallenv = 1;	/* Use small environment. */
 | 
						|
  }
 | 
						|
  if (argc > 1) {
 | 
						|
	if (argv[1][0] == '-') {
 | 
						|
		fprintf(stderr,
 | 
						|
			"Usage: su [-[e]] [user [shell-arguments ...]]\n");
 | 
						|
		exit(1);
 | 
						|
	}
 | 
						|
	name = argv[1];
 | 
						|
	argv[1] = argv[0];
 | 
						|
	argv++;
 | 
						|
  } else {
 | 
						|
	name = "root";
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pwd = getpwuid(getuid())) == 0) {
 | 
						|
	fprintf(stderr, "You do not exist\n");
 | 
						|
	exit(1);
 | 
						|
  }
 | 
						|
  strncpy(from_user, pwd->pw_name, 8);
 | 
						|
  from_user[8]= 0;
 | 
						|
  strncpy(from_shell, pwd->pw_shell[0] == '\0' ? "/bin/sh" : pwd->pw_shell,
 | 
						|
						sizeof(from_shell)-1);
 | 
						|
  from_shell[sizeof(from_shell)-1]= 0;
 | 
						|
 | 
						|
  if ((pwd = getpwnam(name)) == 0) {
 | 
						|
	fprintf(stderr, "Unknown id: %s\n", name);
 | 
						|
	exit(1);
 | 
						|
  }
 | 
						|
  super = 0;
 | 
						|
  if (getgid() == 0) super = 1;
 | 
						|
#if __minix_vmd
 | 
						|
  ngroups = getgroups(NGROUPS_MAX, groups);
 | 
						|
  for (g = 0; g < ngroups; g++) if (groups[g] == 0) super = 1;
 | 
						|
#endif
 | 
						|
 | 
						|
  if (!super && strcmp(pwd->pw_passwd, crypt("", pwd->pw_passwd)) != 0) {
 | 
						|
#if __minix_vmd
 | 
						|
	openlog("su", 0, LOG_AUTH);
 | 
						|
#endif
 | 
						|
	password = getpass("Password:");
 | 
						|
	if (password == 0
 | 
						|
	  || strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
 | 
						|
		if (password != 0 && *password != 0) {
 | 
						|
#if __minix_vmd
 | 
						|
			syslog(LOG_WARNING, "su %s failed for %s",
 | 
						|
							name, from_user);
 | 
						|
#endif
 | 
						|
		}
 | 
						|
		fprintf(stderr, "Sorry\n");
 | 
						|
		exit(2);
 | 
						|
	}
 | 
						|
#if __minix_vmd
 | 
						|
	syslog(LOG_NOTICE, "su %s succeeded for %s", name, from_user);
 | 
						|
	closelog();
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
#if __minix_vmd
 | 
						|
  initgroups(pwd->pw_name, pwd->pw_gid);
 | 
						|
#endif
 | 
						|
  setgid(pwd->pw_gid);
 | 
						|
  setuid(pwd->pw_uid);
 | 
						|
  if (loginshell) {
 | 
						|
	shell = pwd->pw_shell[0] == '\0' ? "/bin/sh" : pwd->pw_shell;
 | 
						|
  } else {
 | 
						|
	if ((shell = getenv("SHELL")) == NULL) shell = from_shell;
 | 
						|
  }
 | 
						|
  if ((p= strrchr(shell, '/')) == 0) p= shell; else p++;
 | 
						|
  sh0[0]= '-';
 | 
						|
  strcpy(loginshell ? sh0+1 : sh0, p);
 | 
						|
  argv[0]= sh0;
 | 
						|
 | 
						|
  if (smallenv) {
 | 
						|
	envp = envv;
 | 
						|
	*envp++ = "PATH=:/bin:/usr/bin",
 | 
						|
	strcpy(USER, "USER=");
 | 
						|
	strcpy(USER + 5, name);
 | 
						|
	*envp++ = USER;
 | 
						|
	strcpy(LOGNAME, "LOGNAME=");
 | 
						|
	strcpy(LOGNAME + 8, name);
 | 
						|
	*envp++ = LOGNAME;
 | 
						|
	strcpy(SHELL, "SHELL=");
 | 
						|
	strcpy(SHELL + 6, shell);
 | 
						|
	*envp++ = SHELL;
 | 
						|
	strcpy(HOME, "HOME=");
 | 
						|
	strcpy(HOME + 5, pwd->pw_dir);
 | 
						|
	*envp++ = HOME;
 | 
						|
	if ((p = getenv("TERM")) != NULL) {
 | 
						|
		*envp++ = p - 5;
 | 
						|
	}
 | 
						|
	if ((p = getenv("TERMCAP")) != NULL) {
 | 
						|
		*envp++ = p - 8;
 | 
						|
	}
 | 
						|
	if ((p = getenv("TZ")) != NULL) {
 | 
						|
		*envp++ = p - 3;
 | 
						|
	}
 | 
						|
	*envp = NULL;
 | 
						|
	(void) chdir(pwd->pw_dir);
 | 
						|
	execve(shell, argv, envv);
 | 
						|
	perror(shell);
 | 
						|
  } else {
 | 
						|
	execv(shell, argv);
 | 
						|
	perror(shell);
 | 
						|
  }
 | 
						|
  fprintf(stderr, "No shell\n");
 | 
						|
  return(3);
 | 
						|
}
 |