Exemple #1
0
main()
{
        if (getuid() != 0) {
#if (defined(AIX) && defined(USE_SETREUID))
		/* setreuid is badly broken on AIX 4.1, we avoid it completely */
                fprintf(stderr,"avoiding possibly broken setreuid\n");
		exit(1);
#endif

		/* if not running as root then at least check to see if we get ENOSYS - this 
		   handles Linux 2.0.x with glibc 2.1 */
                fprintf(stderr,"not running as root: checking for ENOSYS\n");
		exit(have_syscall());
	}

	gain_root_privilege();
	gain_root_group_privilege();
	set_effective_gid(1);
	set_effective_uid(1);
	save_re_uid();
	restore_re_uid();
	gain_root_privilege();
	gain_root_group_privilege();
	become_user_permanently(1, 1);
	setuid(0);
	if (getuid() == 0) {
		fprintf(stderr,"uid not set permanently\n");
		exit(1);
	}

	printf("OK\n");

	exit(0);
}
Exemple #2
0
/*
This is a wrapper around the system() call to allow commands to run correctly 
as non root from a program which is switching between root and non-root 

It takes 3 arguments as uid,gid,command and runs command after
becoming a non-root user */
 int main(int argc,char *argv[])
{
  uid_t uid;
  gid_t gid;

  close_fds();

  if (argc != 4) exit(2);

  uid = (uid_t)atoi(argv[1]);
  gid = (gid_t)atoi(argv[2]);

  become_user_permanently( uid, gid);

  /* paranoia :-) */
  if (getuid() != uid)
    return(3);

  if (geteuid() != getuid())
    return(4);

  /* this is to make sure that the system() call doesn't run forever */
  alarm(30);

  return(system(argv[3]));
}
static int dochild(int master,char *slavedev, char *name, char *passwordprogram, BOOL as_root)
{
  int slave;
  struct termios stermios;
  struct passwd *pass = Get_Pwnam(name,True);
  gid_t gid;
  uid_t uid;

  if (pass == NULL) {
    DEBUG(0,("dochild: user name %s doesn't exist in the UNIX password database.\n",
              name));
    return False;
  }

  gid = pass->pw_gid;
  uid = pass->pw_uid;

  gain_root_privilege();

  /* Start new session - gets rid of controlling terminal. */
  if (setsid() < 0) {
    DEBUG(3,("Weirdness, couldn't let go of controlling terminal\n"));
    return(False);
  }

  /* Open slave pty and acquire as new controlling terminal. */
  if ((slave = sys_open(slavedev, O_RDWR, 0)) < 0) {
    DEBUG(3,("More weirdness, could not open %s\n", 
	     slavedev));
    return(False);
  }
#ifdef I_PUSH
  ioctl(slave, I_PUSH, "ptem");
  ioctl(slave, I_PUSH, "ldterm");
#elif defined(TIOCSCTTY)
  if (ioctl(slave,TIOCSCTTY,0) <0) {
     DEBUG(3,("Error in ioctl call for slave pty\n"));
     /* return(False); */
  }
#endif 

  /* Close master. */
  close(master);

  /* Make slave stdin/out/err of child. */

  if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) {
    DEBUG(3,("Could not re-direct stdin\n"));
    return(False);
  }
  if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) {
    DEBUG(3,("Could not re-direct stdout\n"));
    return(False);
  }
  if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) {
    DEBUG(3,("Could not re-direct stderr\n"));
    return(False);
  }
  if (slave > 2) close(slave);

  /* Set proper terminal attributes - no echo, canonical input processing,
     no map NL to CR/NL on output. */

  if (tcgetattr(0, &stermios) < 0) {
    DEBUG(3,("could not read default terminal attributes on pty\n"));
    return(False);
  }
  stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
  stermios.c_lflag |= ICANON;
  stermios.c_oflag &= ~(ONLCR);
  if (tcsetattr(0, TCSANOW, &stermios) < 0) {
    DEBUG(3,("could not set attributes of pty\n"));
    return(False);
  }

  /* make us completely into the right uid */
  if (!as_root) {
	  become_user_permanently(uid, gid);
  }

  DEBUG(10, ("Invoking '%s' as password change program.\n", passwordprogram));

  /* execl() password-change application */
  if (execl("/bin/sh","sh","-c",passwordprogram,NULL) < 0) {
    DEBUG(3,("Bad status returned from %s\n",passwordprogram));
    return(False);
  }
  return(True);
}
Exemple #4
0
/****************************************************************************
run a command being careful about uid/gid handling and putting the output in
outfile (or discard it if outfile is NULL).

if shared is True then ensure the file will be writeable by all users
but created such that its owned by root. This overcomes a security hole.

if shared is not set then open the file with O_EXCL set
****************************************************************************/
int smbrun(char *cmd,char *outfile,BOOL shared)
{
	int fd;
	pid_t pid;
	uid_t uid = current_user.uid;
	gid_t gid = current_user.gid;

    /*
     * Lose any kernel oplock capabilities we may have.
     */
    set_process_capability(KERNEL_OPLOCK_CAPABILITY, False);
    set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY, False);

#ifndef HAVE_EXECL
	int ret;
	pstring syscmd;  
	char *path = lp_smbrun();
	
	/* in the old method we use system() to execute smbrun which then
	   executes the command (using system() again!). This involves lots
	   of shell launches and is very slow. It also suffers from a
	   potential security hole */
	if (!file_exist(path,NULL)) {
		DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path));
		return(1);
	}

	slprintf(syscmd,sizeof(syscmd)-1,"%s %d %d \"(%s 2>&1) > %s\"",
		 path,(int)uid,(int)gid,cmd,
		 outfile?outfile:"/dev/null");
	
	DEBUG(5,("smbrun - running %s ",syscmd));
	ret = system(syscmd);
	DEBUG(5,("gave %d\n",ret));
	return(ret);
#else
	/* in this newer method we will exec /bin/sh with the correct
	   arguments, after first setting stdout to point at the file */

	/*
	 * We need to temporarily stop CatchChild from eating
	 * SIGCLD signals as it also eats the exit status code. JRA.
	 */

	CatchChildLeaveStatus();
                                   	
	if ((pid=fork()) < 0) {
		DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
		CatchChild(); 
		return errno;
    }

	if (pid) {
		/*
		 * Parent.
		 */
		int status=0;
		pid_t wpid;

		
		/* the parent just waits for the child to exit */
		while((wpid = sys_waitpid(pid,&status,0)) < 0) {
			if(errno == EINTR) {
				errno = 0;
				continue;
			}
			break;
		}

		CatchChild(); 

		if (wpid != pid) {
			DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
			return -1;
		}
#if defined(WIFEXITED) && defined(WEXITSTATUS)
		if (WIFEXITED(status)) {
			return WEXITSTATUS(status);
		}
#endif
		return status;
	}
	
	CatchChild(); 
	
	/* we are in the child. we exec /bin/sh to do the work for us. we
	   don't directly exec the command we want because it may be a
	   pipeline or anything else the config file specifies */
	
	/* point our stdout at the file we want output to go into */
	if (outfile && !setup_stdout_file(outfile,shared)) {
		exit(80);
	}
	
	/* now completely lose our privileges. This is a fairly paranoid
	   way of doing it, but it does work on all systems that I know of */

	become_user_permanently(uid, gid);

	if (getuid() != uid || geteuid() != uid ||
	    getgid() != gid || getegid() != gid) {
		/* we failed to lose our privileges - do not execute
                   the command */
		exit(81); /* we can't print stuff at this stage,
			     instead use exit codes for debugging */
	}
	
	/* close all other file descriptors, leaving only 0, 1 and 2. 0 and
	   2 point to /dev/null from the startup code */
	for (fd=3;fd<256;fd++) close(fd);
	
	execl("/bin/sh","sh","-c",cmd,NULL);  
	
	/* not reached */
	exit(82);
#endif
	return 1;
}
Exemple #5
0
/***************************************************************************
handle a http authentication line
  ***************************************************************************/
static bool cgi_handle_authorization(char *line)
{
	char *p;
	fstring user, user_pass;
	struct passwd *pass = NULL;

	if (!strnequal(line,"Basic ", 6)) {
		goto err;
	}
	line += 6;
	while (line[0] == ' ') line++;
	base64_decode_inplace(line);
	if (!(p=strchr_m(line,':'))) {
		/*
		 * Always give the same error so a cracker
		 * cannot tell why we fail.
		 */
		goto err;
	}
	*p = 0;

	convert_string(CH_UTF8, CH_UNIX, 
		       line, -1, 
		       user, sizeof(user), True);

	convert_string(CH_UTF8, CH_UNIX, 
		       p+1, -1, 
		       user_pass, sizeof(user_pass), True);

	/*
	 * Try and get the user from the UNIX password file.
	 */
	
	pass = getpwnam_alloc(talloc_autofree_context(), user);
	
	/*
	 * Validate the password they have given.
	 */
	
	if NT_STATUS_IS_OK(pass_check(pass, user, user_pass, 
		      strlen(user_pass), NULL, False)) {
		
		if (pass) {
			/*
			 * Password was ok.
			 */
			
			if ( initgroups(pass->pw_name, pass->pw_gid) != 0 )
				goto err;

			become_user_permanently(pass->pw_uid, pass->pw_gid);
			
			/* Save the users name */
			C_user = SMB_STRDUP(user);
			TALLOC_FREE(pass);
			return True;
		}
	}
	
err:
	cgi_setup_error("401 Bad Authorization", 
			"WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
			"username or password incorrect");

	TALLOC_FREE(pass);
	return False;
}
static int dochild(int master, const char *slavedev, const struct passwd *pass,
		   const char *passwordprogram, bool as_root)
{
	int slave;
	struct termios stermios;
	gid_t gid;
	uid_t uid;
	char * const eptrs[1] = { NULL };

	if (pass == NULL)
	{
		DEBUG(0,
		      ("dochild: user doesn't exist in the UNIX password database.\n"));
		return False;
	}

	gid = pass->pw_gid;
	uid = pass->pw_uid;

	gain_root_privilege();

	/* Start new session - gets rid of controlling terminal. */
	if (setsid() < 0)
	{
		DEBUG(3,
		      ("Weirdness, couldn't let go of controlling terminal\n"));
		return (False);
	}

	/* Open slave pty and acquire as new controlling terminal. */
	if ((slave = open(slavedev, O_RDWR, 0)) < 0)
	{
		DEBUG(3, ("More weirdness, could not open %s\n", slavedev));
		return (False);
	}
#if defined(TIOCSCTTY) && !defined(SUNOS5)
	/*
	 * On patched Solaris 10 TIOCSCTTY is defined but seems not to work,
	 * see the discussion under
	 * https://bugzilla.samba.org/show_bug.cgi?id=5366.
	 */
	if (ioctl(slave, TIOCSCTTY, 0) < 0)
	{
		DEBUG(3, ("Error in ioctl call for slave pty\n"));
		/* return(False); */
	}
#elif defined(I_PUSH) && defined(I_FIND)
	if (ioctl(slave, I_FIND, "ptem") == 0) {
		ioctl(slave, I_PUSH, "ptem");
	}
	if (ioctl(slave, I_FIND, "ldterm") == 0) {
		ioctl(slave, I_PUSH, "ldterm");
	}
#endif

	/* Close master. */
	close(master);

	/* Make slave stdin/out/err of child. */

	if (dup2(slave, STDIN_FILENO) != STDIN_FILENO)
	{
		DEBUG(3, ("Could not re-direct stdin\n"));
		return (False);
	}
	if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
	{
		DEBUG(3, ("Could not re-direct stdout\n"));
		return (False);
	}
	if (dup2(slave, STDERR_FILENO) != STDERR_FILENO)
	{
		DEBUG(3, ("Could not re-direct stderr\n"));
		return (False);
	}
	if (slave > 2)
		close(slave);

	/* Set proper terminal attributes - no echo, canonical input processing,
	   no map NL to CR/NL on output. */

	if (tcgetattr(0, &stermios) < 0)
	{
		DEBUG(3,
		      ("could not read default terminal attributes on pty\n"));
		return (False);
	}
	stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
	stermios.c_lflag |= ICANON;
#ifdef ONLCR
	stermios.c_oflag &= ~(ONLCR);
#endif
	if (tcsetattr(0, TCSANOW, &stermios) < 0)
	{
		DEBUG(3, ("could not set attributes of pty\n"));
		return (False);
	}

	/* make us completely into the right uid */
	if (!as_root)
	{
		become_user_permanently(uid, gid);
	}

	DEBUG(10,
	      ("Invoking '%s' as password change program.\n",
	       passwordprogram));

	/* execl() password-change application */
	if (execle("/bin/sh", "sh", "-c", passwordprogram, NULL, eptrs) < 0)
	{
		DEBUG(3, ("Bad status returned from %s\n", passwordprogram));
		return (False);
	}
	return (True);
}
Exemple #7
0
int smbrun(char *cmd, int *outfd)
{
	pid_t pid;
	uid_t uid = current_user.uid;
	gid_t gid = current_user.gid;
	
	/*
	 * Lose any kernel oplock capabilities we may have.
	 */
	oplock_set_capability(False, False);

	/* point our stdout at the file we want output to go into */

	if (outfd && ((*outfd = setup_out_fd()) == -1)) {
		return -1;
	}

	/* in this method we will exec /bin/sh with the correct
	   arguments, after first setting stdout to point at the file */

	/*
	 * We need to temporarily stop CatchChild from eating
	 * SIGCLD signals as it also eats the exit status code. JRA.
	 */

	CatchChildLeaveStatus();
                                   	
	if ((pid=sys_fork()) < 0) {
		DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
		CatchChild(); 
		if (outfd) {
			close(*outfd);
			*outfd = -1;
		}
		return errno;
    }

	if (pid) {
		/*
		 * Parent.
		 */
		int status=0;
		pid_t wpid;

		
		/* the parent just waits for the child to exit */
		while((wpid = sys_waitpid(pid,&status,0)) < 0) {
			if(errno == EINTR) {
				errno = 0;
				continue;
			}
			break;
		}

		CatchChild(); 

		if (wpid != pid) {
			DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
			if (outfd) {
				close(*outfd);
				*outfd = -1;
			}
			return -1;
		}

		/* Reset the seek pointer. */
		if (outfd) {
			sys_lseek(*outfd, 0, SEEK_SET);
		}

#if defined(WIFEXITED) && defined(WEXITSTATUS)
		if (WIFEXITED(status)) {
			return WEXITSTATUS(status);
		}
#endif

		return status;
	}
	
	CatchChild(); 
	
	/* we are in the child. we exec /bin/sh to do the work for us. we
	   don't directly exec the command we want because it may be a
	   pipeline or anything else the config file specifies */
	
	/* point our stdout at the file we want output to go into */
	if (outfd) {
		close(1);
		if (dup2(*outfd,1) != 1) {
			DEBUG(2,("Failed to create stdout file descriptor\n"));
			close(*outfd);
			exit(80);
		}
	}

	/* now completely lose our privileges. This is a fairly paranoid
	   way of doing it, but it does work on all systems that I know of */

	become_user_permanently(uid, gid);

	if (getuid() != uid || geteuid() != uid ||
	    getgid() != gid || getegid() != gid) {
		/* we failed to lose our privileges - do not execute
                   the command */
		exit(81); /* we can't print stuff at this stage,
			     instead use exit codes for debugging */
	}
	
#ifndef __INSURE__
	/* close all other file descriptors, leaving only 0, 1 and 2. 0 and
	   2 point to /dev/null from the startup code */
	{
	int fd;
	for (fd=3;fd<256;fd++) close(fd);
	}
#endif

	execl("/bin/sh","sh","-c",cmd,NULL);  
	
	/* not reached */
	exit(82);
	return 1;
}
Exemple #8
0
int smbrunsecret(const char *cmd, const char *secret)
{
	OutputDebugString("smbrunsecret is not supported\n");
#ifndef _XBOX

	pid_t pid;
	uid_t uid = current_user.ut.uid;
	gid_t gid = current_user.ut.gid;
	int ifd[2];
	
	/*
	 * Lose any elevated privileges.
	 */
	drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
	drop_effective_capability(DMAPI_ACCESS_CAPABILITY);

	/* build up an input pipe */
	if(pipe(ifd)) {
		return -1;
	}

	/* in this method we will exec /bin/sh with the correct
	   arguments, after first setting stdout to point at the file */

	/*
	 * We need to temporarily stop CatchChild from eating
	 * SIGCLD signals as it also eats the exit status code. JRA.
	 */

	CatchChildLeaveStatus();
                                   	
	if ((pid=sys_fork()) < 0) {
		DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno)));
		CatchChild(); 
		return errno;
    	}

	if (pid) {
		/*
		 * Parent.
		 */
		int status = 0;
		pid_t wpid;
		size_t towrite;
		ssize_t wrote;
		
		close(ifd[0]);
		/* send the secret */
		towrite = strlen(secret);
		wrote = write(ifd[1], secret, towrite);
		if ( wrote != towrite ) {
		    DEBUG(0,("smbrunsecret: wrote %ld of %lu bytes\n",(long)wrote,(unsigned long)towrite));
		}
		fsync(ifd[1]);
		close(ifd[1]);

		/* the parent just waits for the child to exit */
		while((wpid = sys_waitpid(pid, &status, 0)) < 0) {
			if(errno == EINTR) {
				errno = 0;
				continue;
			}
			break;
		}

		CatchChild(); 

		if (wpid != pid) {
			DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno)));
			return -1;
		}

#if defined(WIFEXITED) && defined(WEXITSTATUS)
		if (WIFEXITED(status)) {
			return WEXITSTATUS(status);
		}
#endif

		return status;
	}
	
	CatchChild(); 
	
	/* we are in the child. we exec /bin/sh to do the work for us. we
	   don't directly exec the command we want because it may be a
	   pipeline or anything else the config file specifies */
	
	close(ifd[1]);
	close(0);
	if (sys_dup2(ifd[0], 0) != 0) {
		DEBUG(2,("Failed to create stdin file descriptor\n"));
		close(ifd[0]);
		exit(80);
	}

	/* now completely lose our privileges. This is a fairly paranoid
	   way of doing it, but it does work on all systems that I know of */

	become_user_permanently(uid, gid);

	if (getuid() != uid || geteuid() != uid ||
	    getgid() != gid || getegid() != gid) {
		/* we failed to lose our privileges - do not execute
                   the command */
		exit(81); /* we can't print stuff at this stage,
			     instead use exit codes for debugging */
	}
	
#ifndef __INSURE__
	/* close all other file descriptors, leaving only 0, 1 and 2. 0 and
	   2 point to /dev/null from the startup code */
	{
		int fd;
		for (fd = 3; fd < 256; fd++) close(fd);
	}
#endif

	execl("/bin/sh", "sh", "-c", cmd, NULL);  
	
	/* not reached */
	exit(82);
#endif
	return 1;
}