Ejemplo n.º 1
0
void fs_private_bin_list(void) {
	char *private_list = cfg.bin_private_keep;
	assert(private_list);
	
	// create /tmp/firejail/mnt/bin directory
	fs_build_mnt_dir();
	int rv = mkdir(RUN_BIN_DIR, 0755);
	if (rv == -1)
		errExit("mkdir");
	if (chown(RUN_BIN_DIR, 0, 0) < 0)
		errExit("chown");
	if (chmod(RUN_BIN_DIR, 0755) < 0)
		errExit("chmod");
	
	
	// copy the list of files in the new etc directory
	// using a new child process without root privileges
	fs_logger_print();	// save the current log
	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		if (arg_debug)
			printf("Copying files in the new home:\n");

		// elevate privileges - files in the new /bin directory belong to root
		if (setreuid(0, 0) < 0)
			errExit("setreuid");
		if (setregid(0, 0) < 0)
			errExit("setregid");
		
		// copy the list of files in the new home directory
		char *dlist = strdup(private_list);
		if (!dlist)
			errExit("strdup");
	
	
		char *ptr = strtok(dlist, ",");
		duplicate(ptr);
	
		while ((ptr = strtok(NULL, ",")) != NULL)
			duplicate(ptr);
		free(dlist);	
		fs_logger_print();
		exit(0);
	}
	// wait for the child to finish
	waitpid(child, NULL, 0);

	// mount-bind
	int i = 0;
	while (paths[i]) {
		struct stat s;
		if (stat(paths[i], &s) == 0) {
			if (arg_debug)
				printf("Mount-bind %s on top of %s\n", RUN_BIN_DIR, paths[i]);
			if (mount(RUN_BIN_DIR, paths[i], NULL, MS_BIND|MS_REC, NULL) < 0)
				errExit("mount bind");
			fs_logger2("tmpfs", paths[i]);
			fs_logger2("mount", paths[i]);
		}
		i++;
	}
	
	// log cloned files
	char *dlist = strdup(private_list);
	if (!dlist)
		errExit("strdup");
	
	
	char *ptr = strtok(dlist, ",");
	while (ptr) {
		i = 0;
		while (paths[i]) {
			struct stat s;
			if (stat(paths[i], &s) == 0) {
				char *fname;
				if (asprintf(&fname, "%s/%s", paths[i], ptr) == -1)
					errExit("asprintf");
				fs_logger2("clone", fname);
				free(fname);
			}
			i++;
		}
		ptr = strtok(NULL, ",");
	}
	free(dlist);
}
Ejemplo n.º 2
0
void call_setreuid (gid_t ruid, gid_t euid, gid_t suid) {
  setreuid(ruid, euid);
}
/* A binary wrapper is needed around python scripts if we want
 * to run them in sgid/suid mode.
 *
 * This is such a wrapper.
 */
int main(int argc, char **argv)
{
    /*
     * We disallow passing of arguments which point to writable dirs
     * and other files possibly not accessible to calling user.
     * This way, the script will always use default values for these arguments.
     */
    char **pp = argv;
    char *arg;
    while ((arg = *++pp) != NULL)
    {
        /* Allow taking ids from stdin */
        if (strcmp(arg, "--ids=-") == 0)
            continue;

        if (strncmp(arg, "--cache", 7) == 0)
            error_msg_and_die("bad option", arg);
        if (strncmp(arg, "--tmpdir", 8) == 0)
            error_msg_and_die("bad option", arg);
        if (strncmp(arg, "--ids", 5) == 0)
            error_msg_and_die("bad option", arg);
    }

    /* Switch real user/group to effective ones.
     * Otherwise yum library gets confused - gets EPERM (why??).
     */
    gid_t g = getegid();
    /* do setregid only if we have to, to not upset selinux needlessly */
    if (g != getgid())
        setregid(g, g);
    uid_t u = geteuid();
    if (u != getuid())
    {
        setreuid(u, u);
        /* We are suid'ed! */
        /* Prevent malicious user from messing up with suid'ed process: */
        /* Set safe PATH */
// TODO: honor configure --prefix here by adding it to PATH
// (otherwise abrt-action-install-debuginfo would fail to spawn abrt-action-trim-files):
        if (u == 0)
            putenv((char*) "PATH=/usr/sbin:/sbin:/usr/bin:/bin");
        else
            putenv((char*) "PATH=/usr/bin:/bin");
        /* Clear dangerous stuff from env */
        static const char forbid[] =
            "LD_LIBRARY_PATH" "\0"
            "LD_PRELOAD" "\0"
            "LD_TRACE_LOADED_OBJECTS" "\0"
            "LD_BIND_NOW" "\0"
            "LD_AOUT_LIBRARY_PATH" "\0"
            "LD_AOUT_PRELOAD" "\0"
            "LD_NOWARN" "\0"
            "LD_KEEPDIR" "\0"
        ;
        const char *p = forbid;
        do {
            unsetenv(p);
            p += strlen(p) + 1;
        } while (*p);
    }

    execvp(EXECUTABLE, argv);
    error_msg_and_die("Can't execute", EXECUTABLE);
}
Ejemplo n.º 4
0
/* Specify what privileges an suid root binary needs.  */
int __init_suid_priv (int flags, ...)
{
  int res = 0;
  priv_set_t *permit = NULL, *inherit = NULL, *scratch = NULL;

  /* Check flags.  */
  if (flags != PU_LIMITPRIVS && flags != PU_CLEARLIMITSET)
    return -1;

  /* We can only initialize once.  */
  if (__suidset)
    return -1;

  /* Do nothing if we are running as root but not setuid root.  */
  uid_t uid = getuid ();
  uid_t euid = geteuid ();
  if (uid == 0 && euid == 0)
    return 0;

  /* Allocate a scratch set.  */
  scratch = priv_allocset ();
  if (!scratch)
    goto error;

  /* Get the basic set.  */
  const priv_data_t *pd = __priv_parse_data_cached ();
  if (!pd)
    goto error;
  priv_set_t *basic = pd->pd_basicprivs;

  /* Get the inherited set.  */
  inherit = priv_allocset ();
  if (!inherit)
    goto error;
  if (getppriv (PRIV_INHERITABLE, inherit) != 0)
    goto error;

  /* Get the permitted set.  */
  permit = priv_allocset ();
  if (!permit)
    goto error;
  if (getppriv (PRIV_PERMITTED, permit) != 0)
    goto error;

  /* Get passed privileges.  */
  __suidset = priv_allocset ();
  if (!__suidset)
    goto error;
  priv_emptyset (__suidset);
  va_list ap;
  va_start (ap, flags);
  const char *priv;
  while ((priv = va_arg (ap, const char *)))
    if (priv_addset (__suidset, priv) != 0)
      goto error;

  /* Make sure that the passed privileges are a subset of the current
     permitted privileges.  */
  if (priv_issubset (__suidset, permit) != _B_TRUE)
    goto error;

  /* Set the effective privileges to the inherited ones.  */
  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, inherit) != 0)
    goto error;

  /* Set the permitted privileges to those currently permitted privileges in
     set of the ones passed in, the inherited ones, and the basic set.  */
  priv_copyset (__suidset, scratch);
  priv_union (inherit, scratch);
  if (basic)
    priv_union (basic, scratch);
  priv_intersect (permit, scratch);
  if (setppriv (PRIV_SET, PRIV_PERMITTED, scratch) != 0)
    goto error;

  /* Check if we need to set the limit set.  */
  if (flags & PU_CLEARLIMITSET)
    {
      priv_emptyset (scratch);
      if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0)
        goto error;
    }
  else if (flags & PU_LIMITPRIVS)
    {
      if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0)
        goto error;
    }

  /* Change the uid to the caller's uid if we're setuid root.  */
  if (euid == 0 && setreuid (uid, uid) != 0)
    goto error;

  goto out;

error:
  res = -1;
  if (__suidset)
    {
      priv_freeset (__suidset);
      __suidset = NULL;
    }
  if (euid == 0)
    setreuid (uid, uid);

out:
  priv_freeset (permit);
  priv_freeset (inherit);
  priv_freeset (scratch);

  return res;
}
Ejemplo n.º 5
0
int main(int argc, char **argv)
{
	const char	*socket_path = UUIDD_SOCKET_PATH;
	const char	*pidfile_path = UUIDD_PIDFILE_PATH;
	const char	*err_context;
	char		buf[1024], *cp;
	char   		str[37], *tmp;
	uuid_t		uu;
	uid_t		uid;
	gid_t 		gid;
	int		i, c, ret;
	int		debug = 0, do_type = 0, do_kill = 0, num = 0;
	int		timeout = 0, quiet = 0, drop_privs = 0;

#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
#endif

	while ((c = getopt (argc, argv, "dkn:qp:s:tT:r")) != EOF) {
		switch (c) {
		case 'd':
			debug++;
			drop_privs = 1;
			break;
		case 'k':
			do_kill++;
			drop_privs = 1;
			break;
		case 'n':
			num = strtol(optarg, &tmp, 0);
			if ((num < 0) || *tmp) {
				fprintf(stderr, _("Bad number: %s\n"), optarg);
				exit(1);
			}
			break;
		case 'p':
			pidfile_path = optarg;
			drop_privs = 1;
			break;
		case 'q':
			quiet++;
			break;
		case 's':
			socket_path = optarg;
			drop_privs = 1;
			break;
		case 't':
			do_type = UUIDD_OP_TIME_UUID;
			drop_privs = 1;
			break;
		case 'T':
			timeout = strtol(optarg, &tmp, 0);
			if ((timeout < 0) || *tmp) {
				fprintf(stderr, _("Bad number: %s\n"), optarg);
				exit(1);
			}
			break;
		case 'r':
			do_type = UUIDD_OP_RANDOM_UUID;
			drop_privs = 1;
			break;
		default:
			usage(argv[0]);
		}
	}
	uid = getuid();
	if (uid && drop_privs) {
		gid = getgid();
#ifdef HAVE_SETRESGID
		if (setresgid(gid, gid, gid) < 0)
			die("setresgid");
#else
		if (setregid(gid, gid) < 0)
			die("setregid");
#endif

#ifdef HAVE_SETRESUID
		if (setresuid(uid, uid, uid) < 0)
			die("setresuid");
#else
		if (setreuid(uid, uid) < 0)
			die("setreuid");
#endif
	}
	if (num && do_type) {
		ret = call_daemon(socket_path, do_type+2, buf,
				  sizeof(buf), &num, &err_context);
		if (ret < 0) {
			printf(_("Error calling uuidd daemon (%s): %s\n"),
			       err_context, strerror(errno));
			exit(1);
		}
		if (do_type == UUIDD_OP_TIME_UUID) {
			if (ret != sizeof(uu) + sizeof(num))
				goto unexpected_size;

			uuid_unparse((unsigned char *) buf, str);

			printf(P_("%s and subsequent UUID\n",
				  "%s and subsequent %d UUIDs\n", num),
			       str, num);
		} else {
			printf("%s", _("List of UUID's:\n"));
			cp = buf + 4;
			if (ret != (int) (sizeof(num) + num*sizeof(uu)))
				goto unexpected_size;
			for (i=0; i < num; i++, cp+=16) {
				uuid_unparse((unsigned char *) cp, str);
				printf("\t%s\n", str);
			}
		}
		exit(0);
	}
	if (do_type) {
		ret = call_daemon(socket_path, do_type, (char *) &uu,
				  sizeof(uu), 0, &err_context);
		if (ret < 0) {
			printf(_("Error calling uuidd daemon (%s): %s\n"),
			       err_context, strerror(errno));
			exit(1);
		}
		if (ret != sizeof(uu)) {
		unexpected_size:
			printf(_("Unexpected reply length from server %d\n"),
			       ret);
			exit(1);
		}
		uuid_unparse(uu, str);

		printf("%s\n", str);
		exit(0);
	}

	if (do_kill) {
		ret = call_daemon(socket_path, 0, buf, sizeof(buf), 0, 0);
		if ((ret > 0) && ((do_kill = atoi((char *) buf)) > 0)) {
			ret = kill(do_kill, SIGTERM);
			if (ret < 0) {
				if (!quiet)
					fprintf(stderr,
						_("Couldn't kill uuidd running "
						  "at pid %d: %s\n"), do_kill,
						strerror(errno));
				exit(1);
			}
			if (!quiet)
				printf(_("Killed uuidd running at pid %d\n"),
				       do_kill);
		}
		exit(0);
	}

	server_loop(socket_path, pidfile_path, debug, timeout, quiet);
	return 0;
}
Ejemplo n.º 6
0
bool
init(InitOptions options, int & retval)
{
  init_options = new InitOptions(options);

  if (init_options->show_help())  return true;

  if ( options.daemonize() ) {
    fawkes::daemon::init(options.daemon_pid_file(), options.basename());
    if (options.daemonize_kill()) {
      fawkes::daemon::kill();
      retval = 0;
      return false;
    } else if (options.daemonize_status()) {
      retval = fawkes::daemon::running() ? 0 : 1;
      return false;
    } else {
      if (fawkes::daemon::start()) {
	retval = 0;
	return false;
      }
    }
  }

  // *** set user group if requested
  const char *user  = NULL;
  const char *group = NULL;
  if (options.has_username()) {
    user = options.username();
  }
  if (options.has_groupname()) {
    group = options.groupname();
  }

  if (user != NULL) {
    struct passwd *pw;
    if (! (pw = getpwnam(user))) {
      printf("Failed to find user %s, check -u argument.\n", user);
      retval = 203;
      return false;
    }
    int r = 0;
    r = setreuid(pw->pw_uid, pw->pw_uid);
    if (r < 0) {
      perror("Failed to drop privileges (user)");
    }
  }

  if (group != NULL) {
    struct group *gr;
    if (! (gr = getgrnam(group))) {
      printf("Failed to find group %s, check -g argument.\n", user);
      retval = 204;
      return false;
    }
    int r = 0;
    r = setregid(gr->gr_gid, gr->gr_gid);
    if (r < 0) {
      perror("Failed to drop privileges (group)");
    }
  }

  // *** setup base thread and shm registry
  Thread::init_main();

  shm_registry = NULL;
  struct passwd *uid_pw = getpwuid(getuid());
  if (uid_pw == NULL) {
    shm_registry = new SharedMemoryRegistry();
  } else {
    char *registry_name;
    if (asprintf(&registry_name, USER_SHM_NAME, uid_pw->pw_name) == -1) {
      shm_registry = new SharedMemoryRegistry();
    } else {
      shm_registry = new SharedMemoryRegistry(registry_name);
      free(registry_name);
    }
  }

  if (! shm_registry) {
    throw Exception("Failed to create shared memory registry");
  }

  // *** setup logging
  if (options.has_loggers()) {
    try {
      logger = LoggerFactory::multilogger_instance(options.loggers());
    } catch (Exception &e) {
      e.append("Initializing multi logger failed");
      throw;
    }
  } else {
    logger = new MultiLogger(new ConsoleLogger());
  }

  logger->set_loglevel(options.log_level());
  LibLogger::init(logger);

  // *** Prepare home dir directory, just in case
  const char *homedir = getenv("HOME");
  if (homedir) {
    char *userdir;
    if (asprintf(&userdir, "%s/%s", homedir, USERDIR) != -1) {
      if (access(userdir, W_OK) != 0) {
	if (mkdir(userdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
	  logger->log_warn("FawkesMainThread", "Failed to create .fawkes "
			   "directory %s, trying without", userdir);
	}
      }
      free(userdir);
    }
  }

  // *** setup config
  
  SQLiteConfiguration *sqconfig = NULL;

  if (options.config_file() &&
      fnmatch("*.sql", options.config_file(), FNM_PATHNAME) == 0)
  {
    sqconfig = new SQLiteConfiguration(CONFDIR);
    config = sqconfig;
  } else {
    config = new YamlConfiguration(CONFDIR);
  }

  config->load(options.config_file());

  if (sqconfig) {
    try {
      SQLiteConfiguration::SQLiteValueIterator *i = sqconfig->modified_iterator();
      while (i->next()) {
	std::string modtype = i->get_modtype();
	if (modtype == "changed") {
	  logger->log_warn("FawkesMainThread", "Default config value CHANGED: %s"
			   "(was: %s now: %s)", i->path(),
			   i->get_oldvalue().c_str(), i->get_as_string().c_str());
	} else if (modtype == "erased") {
	  logger->log_warn("FawkesMainThread", "Default config value ERASED:  %s",
			   i->path());
	} else {
	  logger->log_debug("FawkesMainThread", "Default config value ADDED:   %s "
			    "(value: %s)", i->path(), i->get_as_string().c_str());
	}
      }
      delete i;
    } catch (Exception &e) {
      logger->log_warn("FawkesMainThread", "Failed to read modified default "
		       "config values, no dump?");
    }
  }

  if (! options.has_loggers()) {
    // Allow configuration override from config
    if (config->exists("/fawkes/mainapp/loggers")) {
      try {
        std::string loggers = config->get_string("/fawkes/mainapp/loggers");
        MultiLogger *new_logger =
	  LoggerFactory::multilogger_instance(loggers.c_str(), options.log_level());
        logger = new_logger;
        LibLogger::finalize();
        LibLogger::init(new_logger);
      } catch (Exception &e) {
        logger->log_warn("FawkesMainThread", "Loggers set in config file, "
			 "but failed to read, exception follows.");
        logger->log_warn("FawkesMainThread", e);
      }
    }
  }

  if (config->exists("/fawkes/mainapp/log_stderr_as_warn")) {
    try {
      bool log_stderr_as_warn = config->get_bool("/fawkes/mainapp/log_stderr_as_warn");
      if (log_stderr_as_warn) {
#ifdef HAVE_LOGGING_FD_REDIRECT
	log_fd_redirect_stderr_ =
	  new LogFileDescriptorToLog(STDERR_FILENO, logger, "stderr", Logger::LL_WARN);
#else
	logger->log_warn("FawkesMainThread", "stderr log redirection enabled but not available at compile time");
#endif
      }
    } catch (Exception &e) {} // ignored
  }

  // *** Determine network parameters
  bool enable_ipv4 = true;
  bool enable_ipv6 = true;
  std::string listen_ipv4;
  std::string listen_ipv6;
  unsigned int net_tcp_port     = 1910;
  std::string  net_service_name = "Fawkes on %h";
  if (options.has_net_tcp_port()) {
    net_tcp_port = options.net_tcp_port();
  } else {
    try {
      net_tcp_port = config->get_uint("/network/fawkes/tcp_port");
    } catch (Exception &e) {}  // ignore, we stick with the default
  }

  if (options.has_net_service_name()) {
    net_service_name = options.net_service_name();
  } else {
    try {
      net_service_name = config->get_string("/network/fawkes/service_name");
    } catch (Exception &e) {}  // ignore, we stick with the default
  }

  if (net_tcp_port > 65535) {
    logger->log_warn("FawkesMainThread", "Invalid port '%u', using 1910",
		     net_tcp_port);
    net_tcp_port = 1910;
  }

  try {
	  enable_ipv4 = config->get_bool("/network/ipv4/enable");
  } catch (Exception &e) {}  // ignore, we stick with the default
  try {
	  enable_ipv6 = config->get_bool("/network/ipv6/enable");
  } catch (Exception &e) {}  // ignore, we stick with the default

  try {
	  listen_ipv4 = config->get_string("/network/ipv4/listen");
  } catch (Exception &e) {}  // ignore, we stick with the default
  try {
	  listen_ipv6 = config->get_string("/network/ipv6/listen");
  } catch (Exception &e) {}  // ignore, we stick with the default

  if (! enable_ipv4) {
	  logger->log_warn("FawkesMainThread", "Disabling IPv4 support");
  }
  if (! enable_ipv6) {
	  logger->log_warn("FawkesMainThread", "Disabling IPv6 support");
  }
  if (! listen_ipv4.empty()) {
	  logger->log_info("FawkesMainThread", "Listening on IPv4 address %s", listen_ipv4.c_str());
  }
  if (! listen_ipv6.empty()) {
	  logger->log_info("FawkesMainThread", "Listening on IPv6 address %s", listen_ipv4.c_str());
  }
  
  // *** Setup blackboard
  std::string bb_magic_token = "";
  unsigned int bb_size = 2097152;
  try {
    bb_magic_token = config->get_string("/fawkes/mainapp/blackboard_magic_token");
    logger->log_info("FawkesMainApp", "BlackBoard magic token defined. "
		     "Using shared memory BlackBoard.");
  } catch (Exception &e) {
    // ignore
  }
  try {
    bb_size = config->get_uint("/fawkes/mainapp/blackboard_size");
  } catch (Exception &e) {
    logger->log_warn("FawkesMainApp", "BlackBoard size not defined. "
		     "Will use %u, saving to default DB", bb_size);
    config->set_default_uint("/fawkes/mainapp/blackboard_size", bb_size);
  }

  // Cleanup stale BlackBoard shared memory segments if requested
  if ( options.bb_cleanup()) {
    LocalBlackBoard::cleanup(bb_magic_token.c_str(),
			     /* output with lister? */ true);
    SharedMemoryRegistry::cleanup();
  }

  LocalBlackBoard *lbb = NULL;
  if ( bb_magic_token == "") {
    lbb = new LocalBlackBoard(bb_size);
  } else {
    lbb = new LocalBlackBoard(bb_size, bb_magic_token.c_str());
  }
  blackboard = lbb;

#ifdef HAVE_TF
  tf_transformer     = new tf::Transformer();
  tf_listener        = new tf::TransformListener(blackboard, tf_transformer);
#endif

  aspect_manager     = new AspectManager();
  thread_manager     = new ThreadManager(aspect_manager, aspect_manager);

  plugin_manager     = new PluginManager(thread_manager, config,
					 "/fawkes/meta_plugins/",
					 options.plugin_module_flags(),
					 options.init_plugin_cache());
  network_manager    = new FawkesNetworkManager(thread_manager,
                                                enable_ipv4, enable_ipv6,
                                                listen_ipv4, listen_ipv6,
                                                net_tcp_port,
                                                net_service_name.c_str());
  nethandler_config  = new ConfigNetworkHandler(config,
						network_manager->hub());

  nethandler_plugin  = new PluginNetworkHandler(plugin_manager,
						network_manager->hub());
  nethandler_plugin->start();

  network_logger = new NetworkLogger(network_manager->hub(),
				     logger->loglevel());
  logger->add_logger(network_logger);

  clock = Clock::instance();
  start_time = new Time(clock);

  lbb->start_nethandler(network_manager->hub());


  // *** Create main thread, but do not start, yet
  main_thread = new fawkes::FawkesMainThread(config, logger,
					     thread_manager,
					     plugin_manager,
					     options.load_plugin_list(),
                                             options.default_plugin());

  aspect_manager->register_default_inifins(blackboard,
					   thread_manager->aspect_collector(),
					   config, logger, clock,
					   network_manager->hub(),
					   main_thread, logger,
					   thread_manager,
					   network_manager->nnresolver(),
					   network_manager->service_publisher(),
					   network_manager->service_browser(),
					   plugin_manager, tf_transformer);

  retval = 0;
  return true;
}
Ejemplo n.º 7
0
qboolean
VID_LoadRefresh ( char *name )
{
	refimport_t ri;
	R_GetRefAPI_t R_GetRefAPI;
	char fn [ MAX_OSPATH ];
	char    *path;
	struct stat st;
	extern uid_t saved_euid;

	if ( reflib_active )
	{
		if ( IN_Close_fp )
		{
			IN_Close_fp();
		}

		if ( IN_BackendShutdown_fp )
		{
			IN_BackendShutdown_fp();
		}

		IN_Close_fp = NULL;
		IN_BackendShutdown_fp = NULL;
		re.Shutdown();
		VID_FreeReflib();
	}

	Com_Printf( "----- refresher initialization -----\n");

	/* regain root */
	seteuid( saved_euid );

	path = Cvar_Get( "basedir", ".", CVAR_NOSET )->string;

	snprintf( fn, MAX_OSPATH, "%s/%s", path, name );

	if ( stat( fn, &st ) == -1 )
	{
		Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, strerror( errno ) );
		return ( false );
	}

	if ( ( reflib_library = dlopen( fn, RTLD_LAZY ) ) == 0 )
	{
		Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, dlerror() );
		return ( false );
	}

	Com_Printf( "LoadLibrary(\"%s\")\n", fn );

	ri.Cmd_AddCommand = Cmd_AddCommand;
	ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
	ri.Cmd_Argc = Cmd_Argc;
	ri.Cmd_Argv = Cmd_Argv;
	ri.Cmd_ExecuteText = Cbuf_ExecuteText;
	ri.Con_Printf = VID_Printf;
	ri.Sys_Error = VID_Error;
	ri.Sys_Mkdir = Sys_Mkdir;
	ri.FS_LoadFile = FS_LoadFile;
	ri.FS_FreeFile = FS_FreeFile;
	ri.FS_Gamedir = FS_Gamedir;
	ri.Cvar_Get = Cvar_Get;
	ri.Cvar_Set = Cvar_Set;
	ri.Cvar_SetValue = Cvar_SetValue;
	ri.Vid_GetModeInfo = VID_GetModeInfo;
	ri.Vid_MenuInit = VID_MenuInit;
	ri.Vid_NewWindow = VID_NewWindow;

	if ( ( R_GetRefAPI = (void *) dlsym( reflib_library, "R_GetRefAPI" ) ) == 0 )
	{
		Com_Error( ERR_FATAL, "dlsym failed on %s", name );
	}

	re = R_GetRefAPI( ri );

	if ( re.api_version != API_VERSION )
	{
		VID_FreeReflib();
		Com_Error( ERR_FATAL, "%s has incompatible api_version", name );
	}

	/* Init IN (Mouse) */
	in_state.IN_CenterView_fp = IN_CenterView;
	in_state.Key_Event_fp = Do_Key_Event;
	in_state.viewangles = cl.viewangles;
	in_state.in_strafe_state = &in_strafe.state;
	in_state.in_speed_state = &in_speed.state;

	if ( ( ( IN_BackendInit_fp = dlsym( reflib_library, "IN_BackendInit" ) ) == NULL ) ||
		 ( ( IN_BackendShutdown_fp = dlsym( reflib_library, "IN_BackendShutdown" ) ) == NULL ) ||
		 ( ( IN_BackendMouseButtons_fp = dlsym( reflib_library, "IN_BackendMouseButtons" ) ) == NULL ) ||
		 ( ( IN_BackendMove_fp = dlsym( reflib_library, "IN_BackendMove" ) ) == NULL ) )
	{
		Sys_Error( "No input backend init functions in REF.\n" );
	}

	if ( IN_BackendInit_fp )
	{
		IN_BackendInit_fp( &in_state );
	}

	if ( re.Init( 0, 0 ) == -1 )
	{
		re.Shutdown();
		VID_FreeReflib();
		return ( false );
	}

	/* Init IN */
	if ( ( ( IN_KeyboardInit_fp = dlsym( reflib_library, "IN_KeyboardInit" ) ) == NULL ) ||
		 ( ( IN_Update_fp = dlsym( reflib_library, "IN_Update" ) ) == NULL ) ||
		 ( ( IN_Close_fp = dlsym( reflib_library, "IN_Close" ) ) == NULL ) )
	{
		Sys_Error( "No keyboard input functions in REF.\n" );
	}

	IN_KeyboardInit_fp( Do_Key_Event );
	Key_ClearStates();

	/* give up root now */
	setreuid( getuid(), getuid() );
	setegid( getgid() );

	Com_Printf( "------------------------------------\n\n" );
	reflib_active = true;
	return ( true );
}
Ejemplo n.º 8
0
int main(int ac, char **av)
{
	int lc;			/* loop counter */
	char *msg;		/* message returned from parse_opts */

	pid_t pid, pid1;
	int status;

	/* parse standard options */
	if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *)NULL) {
		tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
	}

	setup();

	/* set up the expected errnos */
	TEST_EXP_ENOS(exp_enos);

	/* check for looping state if -i option is given */
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		/* reset Tst_count in case we are looping */
		Tst_count = 0;

		if ((pid = FORK_OR_VFORK()) < 0) {
			tst_brkm(TBROK, cleanup, "first fork failed");
		}

		if (pid == 0) {	/* first child */
			/* set the child's ID to ltpuser1 */
			if (setreuid(ltpuser1->pw_uid, ltpuser1->pw_uid) != 0) {
				tst_resm(TINFO, "setreuid failed in child #1");
				exit(1);
			}
			if (mkdir(good_dir, 00700) != 0) {
				tst_resm(TINFO, "mkdir failed in child #1");
				exit(1);
			}
			exit(0);
		}
		wait(&status);

		if ((pid1 = FORK_OR_VFORK()) < 0) {
			tst_brkm(TBROK, cleanup, "second fork failed");
		}

		if (pid1 == 0) {	/* second child */
			/*
			 * set the child's ID to ltpuser2 using seteuid()
			 * so that the ID can be changed back after the
			 * TEST call is made.
			 */
			if (seteuid(ltpuser2->pw_uid) != 0) {
				tst_resm(TINFO, "setreuid failed in child #2");
				exit(1);
			}

			TEST(chdir(good_dir));

			if (TEST_RETURN != -1) {
				tst_resm(TFAIL, "call succeeded unexpectedly");
			} else if (TEST_ERRNO != EACCES) {
				tst_resm(TFAIL|TTERRNO, "expected EACCES");
			} else {
				TEST_ERROR_LOG(TEST_ERRNO);
				tst_resm(TPASS|TTERRNO, "expected failure");
			}

			/* reset the process ID to the saved ID (root) */
			if (setuid(0) == -1) {
				tst_resm(TINFO|TERRNO, "setuid(0) failed");
			}

		} else {	/* parent */
			wait(&status);

			/* let the child carry on */
			exit(0);
		}

		/* clean up things in case we are looping */
		if (rmdir(good_dir) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup, "rmdir(%s) failed", good_dir);
		}
	}
	cleanup();

	return 0;
 /*NOTREACHED*/}
Ejemplo n.º 9
0
int main(int ac, char **av)
{
  int     ch, i=0;
  pid_t   pid;
  FILE    *fp;
  uid_t   uid;
#ifdef USE_THREAD
  pthread_t tid;
  pthread_attr_t attr;
  struct rlimit rl;
  rlim_t max_fd = (rlim_t)MAX_FD;
  rlim_t save_fd = 0;
#endif

#ifdef USE_THREAD
  threading = 1;
  max_thread = MAX_THREAD;
#endif

  max_child = MAX_CHILD;
  cur_child = 0;

  /* create service socket table (malloc) */
  if (serv_init(NULL) < 0) {
    msg_out(crit, "cannot malloc: %m\n");
    exit(-1);
  }

  proxy_tbl = NULL;
  proxy_tbl_ind = 0;

  method_num = 0;

  uid = getuid();

  openlog(ident, LOG_PID | LOG_NDELAY, SYSLOGFAC);

  while((ch = getopt(ac, av, "a:c:i:J:m:o:p:u:frstbwgIqvh?")) != -1)
    switch (ch) {
    case 'a':
      if (optarg != NULL) {
	for (i=0; i<sizeof method_tab; optarg++) {
	  if (*optarg == '\0')
	    break;
	  switch (*optarg) {
	  case 'p':
	    if ( uid != 0 ) {
	      /* process does not started by root */
	      msg_out(warn, "uid == %d (!=0),"
		      "user/pass auth will not work, ignored.\n",
		      uid);
	      break;
	    }
	    method_tab[i++] = S5AUSRPAS;
	    method_num++;
	    break;
	  case 'n':
	    method_tab[i++] = S5ANOAUTH;
	    method_num++;
	    break;
	  default:
	    break;
	  }
	}
      }
      break;

    case 'b':
      bind_restrict = 0;
      break;

    case 'c':
      if (optarg != NULL) {
        config = strdup(optarg);
      }
      break;

    case 'u':
      if (optarg != NULL) {
        pwdfile = strdup(optarg);
      }
      break;

    case 'i':
      if (optarg != NULL) {
	if (serv_init(optarg) < 0) {
	  msg_out(warn, "cannot init server socket(-i %s): %m\n", optarg);
	  break;
	}
      }
      break;

#ifdef SO_BINDTODEVICE
    case 'J':
      if (optarg != NULL) {
	bindtodevice = strdup(optarg);
      }
      break;
#endif

    case 'o':
      if (optarg != NULL) {
	idle_timeout = atol(optarg);
      }
      break;

    case 'p':
      if (optarg != NULL) {
	pidfile = strdup(optarg);
      }
      break;

    case 'm':
      if (optarg != NULL) {
#ifdef USE_THREAD
	max_thread = atoi(optarg);
#endif
	max_child = atoi(optarg);
      }
      break;

    case 't':
#ifdef USE_THREAD
      threading = 0;    /* threading disabled. */
#endif
      break;

    case 'g':
      same_interface = 1;
      break;

    case 'f':
      fg = 1;
      break;

    case 'r':
      resolv_client = 1;
      break;

    case 's':
      forcesyslog = 1;
      break;

    case 'w':
#ifdef HAVE_LIBWRAP
      use_tcpwrap = 1;
#endif /* HAVE_LIBWRAP */
      break;

    case 'I':
      inetd_mode = 1;
      break;

    case 'q':
      be_quiet = 1;
      break;

    case 'v':
      show_version();
      exit(1);

    case 'h':
    case '?':
    default:
      usage();
    }

  ac -= optind;
  av += optind;

  if ((fp = fopen(config, "r")) != NULL) {
    if (readconf(fp) != 0) {
      /* readconf error */
      exit(1);
    }
    fclose(fp);
  }

  if (inetd_mode) {
    /* close all server socket if opened */
    close_all_serv();
    /* assuming that STDIN_FILENO handles bi-directional
     */
    exit(inetd_service(STDIN_FILENO));
    /* not reached */
  }

  if (serv_sock_ind == 0) {   /* no valid ifs yet */
    if (serv_init(":") < 0) { /* use default */
      /* fatal */
      msg_out(crit, "cannot open server socket\n");
      exit(1);
    }
  }

#ifdef USE_THREAD
  if ( ! threading ) {
#endif
    if (queue_init() != 0) {
      msg_out(crit, "cannot init signal queue\n");
      exit(1);
    }
#ifdef USE_THREAD
  }
#endif

  /* try changing working directory */
  if ( chdir(WORKDIR0) != 0 )
    if ( chdir(WORKDIR1) != 0 )
      msg_out(norm, "giving up chdir to workdir");

  if (!fg) {
    /* force stdin/out/err allocate to /dev/null */
    fclose(stdin);
    fp = fopen("/dev/null", "w+");
    if (fileno(fp) != STDIN_FILENO) {
      msg_out(crit, "fopen: %m");
      exit(1);
    }
    if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1) {
      msg_out(crit, "dup2-1: %m");
      exit(1);
    }
    if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
      msg_out(crit, "dup2-2: %m");
      exit(1);
    }

    switch(fork()) {
    case -1:
      msg_out(crit, "fork: %m");
      exit(1);
    case 0:
      /* child */
      pid = setsid();
      if (pid == -1) {
	msg_out(crit, "setsid: %m");
	exit(1);
      }
      break;
    default:
      /* parent */
      exit(0);
    }
  }

  master_pid = getpid();
  umask(S_IWGRP|S_IWOTH);
  if ((fp = fopen(pidfile, "w")) != NULL) {
    fprintf(fp, "%u\n", (unsigned)master_pid);
    fchown(fileno(fp), PROCUID, PROCGID);
    fclose(fp);
  } else {
    msg_out(warn, "cannot open pidfile %s", pidfile);
  }

  setsignal(SIGHUP, reload);
  setsignal(SIGINT, SIG_IGN);
  setsignal(SIGQUIT, SIG_IGN);
  setsignal(SIGILL, SIG_IGN);
  setsignal(SIGTRAP, SIG_IGN);
  setsignal(SIGABRT, SIG_IGN);
#ifdef SIGEMT
  setsignal(SIGEMT, SIG_IGN);
#endif
  setsignal(SIGFPE, SIG_IGN);
  setsignal(SIGBUS, SIG_IGN);
  setsignal(SIGSEGV, SIG_IGN);
  setsignal(SIGSYS, SIG_IGN);
  setsignal(SIGPIPE, SIG_IGN);
  setsignal(SIGALRM, SIG_IGN);
  setsignal(SIGTERM, cleanup);
  setsignal(SIGUSR1, SIG_IGN);
  setsignal(SIGUSR2, SIG_IGN);
#ifdef SIGPOLL
  setsignal(SIGPOLL, SIG_IGN);
#endif
  setsignal(SIGVTALRM, SIG_IGN);
  setsignal(SIGPROF, SIG_IGN);
  setsignal(SIGXCPU, SIG_IGN);
  setsignal(SIGXFSZ, SIG_IGN);

#ifdef USE_THREAD
  if ( threading ) {
    if (max_thread <= 0 || max_thread > THREAD_LIMIT) {
      max_thread = THREAD_LIMIT;
    }
    /* resource limit is problem in threadig (e.g. Solaris:=64)*/
    memset((caddr_t)&rl, 0, sizeof rl);
    if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
      msg_out(warn, "getrlimit: %m");
    else
      save_fd = rl.rlim_cur;
    if (rl.rlim_cur < (rlim_t)max_fd)
      rl.rlim_cur = max_fd;        /* willing to fix to max_fd */
    if ( rl.rlim_cur != save_fd )  /* if rlim_cur is changed   */
      if (setrlimit(RLIMIT_NOFILE, &rl) != 0)
        msg_out(warn, "cannot set rlimit(max_fd)");

    setregid(0, PROCGID);
    setreuid(0, PROCUID);

    pthread_mutex_init(&mutex_select, NULL);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    msg_out(norm, "Starting: MAX_TH(%d)", max_thread);
    for (i=0; i<max_thread; i++) {
      if (pthread_create(&tid, &attr,
			 (void *)&serv_loop, (void *)NULL) != 0)
        exit(1);
    }
    main_thread = pthread_self();   /* store main thread ID */
    for (;;) {
      pause();
    }
  } else {
#endif
    setsignal(SIGCHLD, reapchild);
    setregid(0, PROCGID);
    setreuid(0, PROCUID);
    msg_out(norm, "Starting: MAX_CH(%d)", max_child);
    serv_loop();
#ifdef USE_THREAD
  }
#endif
  return(0);
}
Ejemplo n.º 10
0
int sh_access(register const char *name, register int mode)
{
	Shell_t	*shp = sh_getinterp();
	struct stat statb;
	if(*name==0)
		return(-1);
	if(sh_isdevfd(name))
		return(sh_ioaccess((int)strtol(name+8, (char**)0, 10),mode));
	/* can't use access function for execute permission with root */
	if(mode==X_OK && shp->gd->euserid==0)
		goto skip;
	if(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid)
		return(access(name,mode));
#ifdef _lib_setreuid
	/* swap the real uid to effective, check access then restore */
	/* first swap real and effective gid, if different */
	if(shp->gd->groupid==shp->gd->euserid || setregid(shp->gd->egroupid,shp->gd->groupid)==0) 
	{
		/* next swap real and effective uid, if needed */
		if(shp->gd->userid==shp->gd->euserid || setreuid(shp->gd->euserid,shp->gd->userid)==0)
		{
			mode = access(name,mode);
			/* restore ids */
			if(shp->gd->userid!=shp->gd->euserid)
				setreuid(shp->gd->userid,shp->gd->euserid);
			if(shp->gd->groupid!=shp->gd->egroupid)
				setregid(shp->gd->groupid,shp->gd->egroupid);
			return(mode);
		}
		else if(shp->gd->groupid!=shp->gd->egroupid)
			setregid(shp->gd->groupid,shp->gd->egroupid);
	}
#endif /* _lib_setreuid */
skip:
	if(test_stat(name, &statb) == 0)
	{
		if(mode == F_OK)
			return(mode);
		else if(shp->gd->euserid == 0)
		{
			if(!S_ISREG(statb.st_mode) || mode!=X_OK)
				return(0);
		    	/* root needs execute permission for someone */
			mode = (S_IXUSR|S_IXGRP|S_IXOTH);
		}
		else if(shp->gd->euserid == statb.st_uid)
			mode <<= 6;
		else if(shp->gd->egroupid == statb.st_gid)
			mode <<= 3;
#ifdef _lib_getgroups
		/* on some systems you can be in several groups */
		else
		{
			static int maxgroups;
			gid_t *groups; 
			register int n;
			if(maxgroups==0)
			{
				/* first time */
				if((maxgroups=getgroups(0,(gid_t*)0)) <= 0)
				{
					/* pre-POSIX system */
					maxgroups=NGROUPS_MAX;
				}
			}
			groups = (gid_t*)stakalloc((maxgroups+1)*sizeof(gid_t));
			n = getgroups(maxgroups,groups);
			while(--n >= 0)
			{
				if(groups[n] == statb.st_gid)
				{
					mode <<= 3;
					break;
				}
			}
		}
#   endif /* _lib_getgroups */
		if(statb.st_mode & mode)
			return(0);
	}
	return(-1);
}
Ejemplo n.º 11
0
/*@-bounds -boundswrite @*/
static int execCommand(poptContext con)
	/*@globals internalState @*/
	/*@modifies internalState @*/
{
    poptItem item = con->doExec;
    const char ** argv;
    int argc = 0;
    int rc;

    if (item == NULL) /*XXX can't happen*/
	return POPT_ERROR_NOARG;

    if (item->argv == NULL || item->argc < 1 ||
	(!con->execAbsolute && strchr(item->argv[0], '/')))
	    return POPT_ERROR_NOARG;

    argv = malloc(sizeof(*argv) *
			(6 + item->argc + con->numLeftovers + con->finalArgvCount));
    if (argv == NULL) return POPT_ERROR_MALLOC;

    if (!strchr(item->argv[0], '/') && con->execPath != NULL) {
	char *s = alloca(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
	sprintf(s, "%s/%s", con->execPath, item->argv[0]);
	argv[argc] = s;
    } else
	argv[argc] = findProgramPath(item->argv[0]);
    if (argv[argc++] == NULL) return POPT_ERROR_NOARG;

    if (item->argc > 1) {
	memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1));
	argc += (item->argc - 1);
    }

    if (con->finalArgv != NULL && con->finalArgvCount > 0) {
	memcpy(argv + argc, con->finalArgv,
		sizeof(*argv) * con->finalArgvCount);
	argc += con->finalArgvCount;
    }

    if (con->leftovers != NULL && con->numLeftovers > 0) {
	memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers);
	argc += con->numLeftovers;
    }

    argv[argc] = NULL;

#if defined(hpux) || defined(__hpux)
    rc = setresgid(getgid(), getgid(),-1);
    if (rc) return POPT_ERROR_ERRNO;
    rc = setresuid(getuid(), getuid(),-1);
    if (rc) return POPT_ERROR_ERRNO;
#else
/*
 * XXX " ... on BSD systems setuid() should be preferred over setreuid()"
 * XXX 	sez' Timur Bakeyev <[email protected]>
 * XXX	from Norbert Warmuth <[email protected]>
 */
#if defined(HAVE_SETUID)
    rc = setgid(getgid());
    if (rc) return POPT_ERROR_ERRNO;
    rc = setuid(getuid());
    if (rc) return POPT_ERROR_ERRNO;
#elif defined (HAVE_SETREUID)
    rc = setregid(getgid(), getgid());
    if (rc) return POPT_ERROR_ERRNO;
    rc = setreuid(getuid(), getuid());
    if (rc) return POPT_ERROR_ERRNO;
#else
    ; /* Can't drop privileges */
#endif
#endif

    if (argv[0] == NULL)
	return POPT_ERROR_NOARG;

#ifdef	MYDEBUG
if (_popt_debug)
    {	const char ** avp;
	fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc);
	for (avp = argv; *avp; avp++)
	    fprintf(stderr, " '%s'", *avp);
	fprintf(stderr, "\n");
    }
#endif

    rc = execvp(argv[0], (char *const *)argv);

    return POPT_ERROR_ERRNO;
}
Ejemplo n.º 12
0
int
main(int argc, char **argv) {
    char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
    char buf[32], passwd[256], passdisp[256];
    int num, screen, width, height, update, sleepmode, term, pid;

#ifndef HAVE_BSD_AUTH
    const char *pws;
#endif
    unsigned int len;
    Bool running = True;
    Cursor invisible;
    Display *dpy;
    KeySym ksym;
    Pixmap pmap;
    Window root, w;
    XColor black, red, dummy;
    XEvent ev;
    XSetWindowAttributes wa;
    XFontStruct* font;
    GC gc;
    XGCValues values;

    // defaults
    char* passchar = "*";
    char* fontname = "-*-dejavu sans-bold-r-*-*-*-420-100-100-*-*-iso8859-1";
    char* username = "";
    int showline = 1;
    int xshift = 0;

    for (int i = 0; i < argc; i++) {
        if (!strcmp(argv[i], "-c")) {
            if (i + 1 < argc)
                passchar = argv[i + 1];
            else
                die("error: no password character given.\n");
        } else if (!strcmp(argv[i], "-f")) {
            if (i + 1 < argc)
                fontname = argv[i + 1];
            else
                die("error: font not specified.\n");
        }
        else if (!strcmp(argv[i], "-v"))
            die("sflock-"VERSION", © 2015 Ben Ruijl\n");
        else if (!strcmp(argv[i], "-h"))
            showline = 0;
        else if (!strcmp(argv[i], "-xshift"))
            xshift = atoi(argv[i + 1]);
        else if (!strcmp(argv[i], "?"))
            die("usage: sflock [-v] [-c passchars] [-f fontname] [-xshift horizontal shift]\n");
    }

    // fill with password characters
    for (int i = 0; i < sizeof passdisp; i+= strlen(passchar))
        for (int j = 0; j < strlen(passchar) && i + j < sizeof passdisp; j++)
            passdisp[i + j] = passchar[j];


    /* disable tty switching */
    if ((term = open("/dev/console", O_RDWR)) == -1) {
        perror("error opening console");
    }

    if ((ioctl(term, VT_LOCKSWITCH)) == -1) {
        perror("error locking console");
    }

    /* deamonize */
    pid = fork();
    if (pid < 0)
        die("Could not fork sflock.");
    if (pid > 0)
        exit(0); // exit parent

#ifndef HAVE_BSD_AUTH
    pws = get_password();
    username = getpwuid(geteuid())->pw_name;
#else
    username = getlogin();
#endif

    if(!(dpy = XOpenDisplay(0)))
        die("sflock: cannot open dpy\n");

    screen = DefaultScreen(dpy);
    root = RootWindow(dpy, screen);
    width = DisplayWidth(dpy, screen);
    height = DisplayHeight(dpy, screen);

    wa.override_redirect = 1;
    wa.background_pixel = XBlackPixel(dpy, screen);
    w = XCreateWindow(dpy, root, 0, 0, width, height,
                      0, DefaultDepth(dpy, screen), CopyFromParent,
                      DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa);

    XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "orange red", &red, &dummy);
    XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy);
    pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8);
    invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0);
    XDefineCursor(dpy, w, invisible);
    XMapRaised(dpy, w);

    font = XLoadQueryFont(dpy, fontname);

    if (font == 0) {
        die("error: could not find font. Try using a full description.\n");
    }

    gc = XCreateGC(dpy, w, (unsigned long)0, &values);
    XSetFont(dpy, gc, font->fid);
    XSetForeground(dpy, gc, XWhitePixel(dpy, screen));

    for(len = 1000; len; len--) {
        if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
                        GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess)
            break;
        usleep(1000);
    }
    if((running = running && (len > 0))) {
        for(len = 1000; len; len--) {
            if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
                    == GrabSuccess)
                break;
            usleep(1000);
        }
        running = (len > 0);
    }

    len = 0;
    XSync(dpy, False);
    update = True;
    sleepmode = False;

    /* main event loop */
    while(running && !XNextEvent(dpy, &ev)) {
        if (sleepmode) {
            DPMSEnable(dpy);
            DPMSForceLevel(dpy, DPMSModeOff);
            XFlush(dpy);
        }

        if (update) {
            int x, y, dir, ascent, descent;
            XCharStruct overall;

            XClearWindow(dpy, w);
            XTextExtents (font, passdisp, len, &dir, &ascent, &descent, &overall);
            x = (width - overall.width) / 2;
            y = (height + ascent - descent) / 2;

            XDrawString(dpy,w,gc, (width - XTextWidth(font, username, strlen(username))) / 2 + xshift, y - ascent - 20, username, strlen(username));

            if (showline)
                XDrawLine(dpy, w, gc, width * 3 / 8 + xshift, y - ascent - 10, width * 5 / 8 + xshift, y - ascent - 10);

            XDrawString(dpy,w,gc, x + xshift, y, passdisp, len);
            update = False;
        }

        if (ev.type == MotionNotify) {
            sleepmode = False;
        }

        if(ev.type == KeyPress) {
            sleepmode = False;

            buf[0] = 0;
            num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0);
            if(IsKeypadKey(ksym)) {
                if(ksym == XK_KP_Enter)
                    ksym = XK_Return;
                else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
                    ksym = (ksym - XK_KP_0) + XK_0;
            }
            if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
                    || IsMiscFunctionKey(ksym) || IsPFKey(ksym)
                    || IsPrivateKeypadKey(ksym))
                continue;

            switch(ksym) {
            case XK_Return:
                passwd[len] = 0;
#ifdef HAVE_BSD_AUTH
                running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd);
#else
                running = strcmp(crypt(passwd, pws), pws);
#endif
                if (running != 0)
                    // change background on wrong password
                    XSetWindowBackground(dpy, w, red.pixel);
                len = 0;
                break;
            case XK_Escape:
                len = 0;

                if (DPMSCapable(dpy)) {
                    sleepmode = True;
                }

                break;
            case XK_BackSpace:
                if(len)
                    --len;
                break;
            default:
                if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) {
                    memcpy(passwd + len, buf, num);
                    len += num;
                }

                break;
            }

            update = True; // show changes
        }
    }

    /* free and unlock */
    setreuid(geteuid(), 0);
    if ((ioctl(term, VT_UNLOCKSWITCH)) == -1) {
        perror("error unlocking console");
    }

    close(term);
    setuid(getuid()); // drop rights permanently


    XUngrabPointer(dpy, CurrentTime);
    XFreePixmap(dpy, pmap);
    XFreeFont(dpy, font);
    XFreeGC(dpy, gc);
    XDestroyWindow(dpy, w);
    XCloseDisplay(dpy);
    return 0;
}
Ejemplo n.º 13
0
int main(int argc, char * argv[])
{
	server_configuration config;
	bzero(&config, sizeof(config));

	if(!network_subsystem_init())
	{
		fprintf(stderr, "Network subsystem init failed.\n");
		return error_network_subsystem;
	}

	if(!read_configuration(argc, argv, &config))
	{
		fprintf(stderr, PROG_NAME ": configuration error! Exit.\n");
		return error_config;
	}

	if(config.discover)
		interfaces_discover(0);

	if(config.print_header_offsets)
	{
		print_dhcp_header_offsets();
		return 0;
	}

	if(!log_init(config.log_file_name,
			(config.debug_mode ? LOG_DEBUG_FLAG : 0) |
			(config.log_stdout ? LOG_STDOUT_FLAG : 0),
			config.uid)
		)
	{
		fprintf(stderr, "Can't open log file.\n");
		return error_log;
	}

	log_wr(ILOG, "Program " PROG_NAME " " PROG_VERS " " PROG_DESC " started.");

	struct sigaction sig_handler_s;
	sig_handler_s.sa_handler = sig_handler;
	sigemptyset(&sig_handler_s.sa_mask);
	sig_handler_s.sa_flags = 0;

	if(config.daemon)
		daemonize();

	/* Init DHCP cache */
	if(config.cache_ttl && !dhcp_cache_init(config.cache_ttl))
	{
		log_wr(CLOG, "Can't init DHCP cache. Exit.");
		return error_abnormal;
	}

	/* STARTING DATABASE CLIENTS */

	/* Create array of childen threads */
	request_handler_thread_t **handler_threads =
		(request_handler_thread_t **) malloc(sizeof(request_handler_thread_t *) * config.db_clients_count);

	CHECK_VALUE(handler_threads, "Can't allocate memory for array of children threads for connecting to DB.",
		error_memory);

	/* Create DHCP messages queue */
	config.dhcp_queue = dhcp_queue_create("DHCP requests", YES, DEFAULT_QUEUE_MAX_SIZE);
	CHECK_VALUE(config.dhcp_queue, "Can't create DHCP queue.", error_queue_init);

	/* Running DB clients */
	CHECK_VALUE(run_requests_handlers(handler_threads, &config), "", error_run_db_clients);

	/* STARTING DHCP PROCESSES  */
	dhcp_proc_thread_t **dhcp_threads =
		(dhcp_proc_thread_t**) malloc(sizeof(dhcp_proc_thread_t *) * config.if_count);

	CHECK_VALUE(dhcp_threads, "Can't allocate memory for array of children threads for "
			"processing DHCP clients.", error_run_dhcp_procs);

	CHECK_VALUE(run_dhcp_threads(dhcp_threads, &config, handler_threads), "", error_run_dhcp_procs);

	/* Set signal handlers */
    if( sigaction(SIGINT, &sig_handler_s, NULL) ||
        sigaction(SIGTERM, &sig_handler_s, NULL) ||
        sigaction(SIGUSR1, &sig_handler_s, NULL))
    {
		log_wr(CLOG, "Can't set signal handlers: '%s'", strerror(errno));
        return error_abnormal;
    }

#ifndef _WIN32
	if(config.uid)
	{
		log_wr(DLOG, "Set effective and real user ID to %u.", config.uid);
		if(setreuid(config.uid, config.uid))
		{
			log_wr(CLOG, "Can't execute setreuid(%u): '%s'", config.uid, strerror(errno));
			return 0;
		}
	}
	else
		log_wr(WLOG, "Running with uid 0 - it is not safe!!! Use configuration directive 'User' for set uid.");
#endif

	int i;
	for(i = 0; i < config.if_count; ++i)
		pthread_join(dhcp_threads[i]->thread_id, 0);

	log_wr(ILOG, "All DHCP threads finished");

	for(i = 0; i < config.db_clients_count; ++i)
		pthread_join(handler_threads[i]->thread_id, 0);

	log_wr(ILOG, "All DB threads finished.");

	/* Cleaning up */
	/* TODO 30 Need gracefull cleanup database connections and free all allocated memory */
	log_wr(ILOG, "Program exited.");
	log_close();

	return EXIT_SUCCESS;
}
Ejemplo n.º 14
0
int
main(int argc, char **argv)
{
    extern int optind;
    extern char *optarg, **environ;
    struct group *gr;
    register int ch;
    register char *p;
    int ask, fflag, hflag, pflag, cnt, errsv;
    int quietlog, passwd_req;
    char *domain, *ttyn;
    char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
    char *termenv;
    char *childArgv[10];
    char *buff;
    int childArgc = 0;
#ifdef HAVE_SECURITY_PAM_MISC_H
    int retcode;
    pam_handle_t *pamh = NULL;
    struct pam_conv conv = { misc_conv, NULL };
    pid_t childPid;
#else
    char *salt, *pp;
#endif
#ifdef LOGIN_CHOWN_VCS
    char vcsn[20], vcsan[20];
#endif

    pid = getpid();

    signal(SIGALRM, timedout);
    alarm((unsigned int)timeout);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGINT, SIG_IGN);

    setlocale(LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
    
    setpriority(PRIO_PROCESS, 0, 0);
    initproctitle(argc, argv);
    
    /*
     * -p is used by getty to tell login not to destroy the environment
     * -f is used to skip a second login authentication 
     * -h is used by other servers to pass the name of the remote
     *    host to login so that it may be placed in utmp and wtmp
     */
    gethostname(tbuf, sizeof(tbuf));
    xstrncpy(thishost, tbuf, sizeof(thishost));
    domain = index(tbuf, '.');
    
    username = tty_name = hostname = NULL;
    fflag = hflag = pflag = 0;
    passwd_req = 1;

    while ((ch = getopt(argc, argv, "fh:p")) != -1)
      switch (ch) {
	case 'f':
	  fflag = 1;
	  break;
	  
	case 'h':
	  if (getuid()) {
	      fprintf(stderr,
		      _("login: -h for super-user only.\n"));
	      exit(1);
	  }
	  hflag = 1;
	  if (domain && (p = index(optarg, '.')) &&
	      strcasecmp(p, domain) == 0)
	    *p = 0;

	  hostname = strdup(optarg); 	/* strdup: Ambrose C. Li */
	  {
		  struct hostent *he = gethostbyname(hostname);

		  /* he points to static storage; copy the part we use */
		  hostaddress[0] = 0;
		  if (he && he->h_addr_list && he->h_addr_list[0])
			  memcpy(hostaddress, he->h_addr_list[0],
				 sizeof(hostaddress));
	  }
	  break;
	  
	case 'p':
	  pflag = 1;
	  break;

	case '?':
	default:
	  fprintf(stderr,
		  _("usage: login [-fp] [username]\n"));
	  exit(1);
      }
    argc -= optind;
    argv += optind;
    if (*argv) {
	char *p = *argv;
	username = strdup(p);
	ask = 0;
	/* wipe name - some people mistype their password here */
	/* (of course we are too late, but perhaps this helps a little ..) */
	while(*p)
	    *p++ = ' ';
    } else
        ask = 1;

    for (cnt = getdtablesize(); cnt > 2; cnt--)
      close(cnt);
    
    ttyn = ttyname(0);

    if (ttyn == NULL || *ttyn == '\0') {
	/* no snprintf required - see definition of tname */
	sprintf(tname, "%s??", _PATH_TTY);
	ttyn = tname;
    }

    check_ttyname(ttyn);

    if (strncmp(ttyn, "/dev/", 5) == 0)
	tty_name = ttyn+5;
    else
	tty_name = ttyn;

    if (strncmp(ttyn, "/dev/tty", 8) == 0)
	tty_number = ttyn+8;
    else {
	char *p = ttyn;
	while (*p && !isdigit(*p)) p++;
	tty_number = p;
    }

#ifdef LOGIN_CHOWN_VCS
    /* find names of Virtual Console devices, for later mode change */
    snprintf(vcsn, sizeof(vcsn), "/dev/vcs%s", tty_number);
    snprintf(vcsan, sizeof(vcsan), "/dev/vcsa%s", tty_number);
#endif

    /* set pgid to pid */
    setpgrp();
    /* this means that setsid() will fail */
    
    {
	struct termios tt, ttt;
	
	tcgetattr(0, &tt);
	ttt = tt;
	ttt.c_cflag &= ~HUPCL;

	/* These can fail, e.g. with ttyn on a read-only filesystem */
	chown(ttyn, 0, 0);
	chmod(ttyn, TTY_MODE);

	/* Kill processes left on this tty */
	tcsetattr(0,TCSAFLUSH,&ttt);
	signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */
	vhangup();
	signal(SIGHUP, SIG_DFL);

	/* open stdin,stdout,stderr to the tty */
	opentty(ttyn);
	
	/* restore tty modes */
	tcsetattr(0,TCSAFLUSH,&tt);
    }

    openlog("login", LOG_ODELAY, LOG_AUTHPRIV);

#if 0
    /* other than iso-8859-1 */
    printf("\033(K");
    fprintf(stderr,"\033(K");
#endif

#ifdef HAVE_SECURITY_PAM_MISC_H
    /*
     * username is initialized to NULL
     * and if specified on the command line it is set.
     * Therefore, we are safe not setting it to anything
     */

    retcode = pam_start("login",username, &conv, &pamh);
    if(retcode != PAM_SUCCESS) {
	fprintf(stderr, _("login: PAM Failure, aborting: %s\n"),
		pam_strerror(pamh, retcode));
	syslog(LOG_ERR, _("Couldn't initialize PAM: %s"),
	       pam_strerror(pamh, retcode));
	exit(99);
    }
    /* hostname & tty are either set to NULL or their correct values,
       depending on how much we know */
    retcode = pam_set_item(pamh, PAM_RHOST, hostname);
    PAM_FAIL_CHECK;
    retcode = pam_set_item(pamh, PAM_TTY, tty_name);
    PAM_FAIL_CHECK;

    /*
     * [email protected]: Provide a user prompt to PAM
     * so that the "login: " prompt gets localized. Unfortunately,
     * PAM doesn't have an interface to specify the "Password: " string
     * (yet).
     */
    retcode = pam_set_item(pamh, PAM_USER_PROMPT, _("login: "));
    PAM_FAIL_CHECK;

#if 0
    /*
     * other than iso-8859-1
     * one more time due to reset tty by PAM
     */
    printf("\033(K");
    fprintf(stderr,"\033(K");
#endif
	    
    /* if fflag == 1, then the user has already been authenticated */
    if (fflag && (getuid() == 0))
	passwd_req = 0;
    else
	passwd_req = 1;

    if(passwd_req == 1) {
	int failcount=0;

	/* if we didn't get a user on the command line, set it to NULL */
	pam_get_item(pamh,  PAM_USER, (const void **) &username);
	if (!username)
		pam_set_item(pamh, PAM_USER, NULL);

	/* there may be better ways to deal with some of these
	   conditions, but at least this way I don't think we'll
	   be giving away information... */
	/* Perhaps someday we can trust that all PAM modules will
	   pay attention to failure count and get rid of MAX_LOGIN_TRIES? */

	retcode = pam_authenticate(pamh, 0);
	while((failcount++ < PAM_MAX_LOGIN_TRIES) &&
	      ((retcode == PAM_AUTH_ERR) ||
	       (retcode == PAM_USER_UNKNOWN) ||
	       (retcode == PAM_CRED_INSUFFICIENT) ||
	       (retcode == PAM_AUTHINFO_UNAVAIL))) {
	    pam_get_item(pamh, PAM_USER, (const void **) &username);

	    syslog(LOG_NOTICE,_("FAILED LOGIN %d FROM %s FOR %s, %s"),
		   failcount, hostname, username, pam_strerror(pamh, retcode));
	    logbtmp(tty_name, username, hostname);

	    fprintf(stderr,_("Login incorrect\n\n"));
	    pam_set_item(pamh,PAM_USER,NULL);
	    retcode = pam_authenticate(pamh, 0);
	}

	if (retcode != PAM_SUCCESS) {
	    pam_get_item(pamh, PAM_USER, (const void **) &username);

	    if (retcode == PAM_MAXTRIES)
		syslog(LOG_NOTICE,_("TOO MANY LOGIN TRIES (%d) FROM %s FOR "
			"%s, %s"), failcount, hostname, username,
			 pam_strerror(pamh, retcode));
	    else
		syslog(LOG_NOTICE,_("FAILED LOGIN SESSION FROM %s FOR %s, %s"),
			hostname, username, pam_strerror(pamh, retcode));
	    logbtmp(tty_name, username, hostname);

	    fprintf(stderr,_("\nLogin incorrect\n"));
	    pam_end(pamh, retcode);
	    exit(0);
	}

	retcode = pam_acct_mgmt(pamh, 0);

	if(retcode == PAM_NEW_AUTHTOK_REQD) {
	    retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
	}

	PAM_FAIL_CHECK;
    }

    /*
     * Grab the user information out of the password file for future usage
     * First get the username that we are actually using, though.
     */
    retcode = pam_get_item(pamh, PAM_USER, (const void **) &username);
    PAM_FAIL_CHECK;

    if (!username || !*username) {
	    fprintf(stderr, _("\nSession setup problem, abort.\n"));
	    syslog(LOG_ERR, _("NULL user name in %s:%d. Abort."),
		   __FUNCTION__, __LINE__);
	    pam_end(pamh, PAM_SYSTEM_ERR);
	    exit(1);
    }
    if (!(pwd = getpwnam(username))) {
	    fprintf(stderr, _("\nSession setup problem, abort.\n"));
	    syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."),
		   username, __FUNCTION__, __LINE__);
	    pam_end(pamh, PAM_SYSTEM_ERR);
	    exit(1);
    }

    /*
     * Create a copy of the pwd struct - otherwise it may get
     * clobbered by PAM
     */
    memcpy(&pwdcopy, pwd, sizeof(*pwd));
    pwd = &pwdcopy;
    pwd->pw_name   = strdup(pwd->pw_name);
    pwd->pw_passwd = strdup(pwd->pw_passwd);
    pwd->pw_gecos  = strdup(pwd->pw_gecos);
    pwd->pw_dir    = strdup(pwd->pw_dir);
    pwd->pw_shell  = strdup(pwd->pw_shell);
    if (!pwd->pw_name || !pwd->pw_passwd || !pwd->pw_gecos ||
	!pwd->pw_dir || !pwd->pw_shell) {
	    fprintf(stderr, _("login: Out of memory\n"));
	    syslog(LOG_ERR, "Out of memory");
	    pam_end(pamh, PAM_SYSTEM_ERR);
	    exit(1);
    }
    username = pwd->pw_name;

    /*
     * Initialize the supplementary group list.
     * This should be done before pam_setcred because
     * the PAM modules might add groups during pam_setcred.
     */
    if (initgroups(username, pwd->pw_gid) < 0) {
	    syslog(LOG_ERR, "initgroups: %m");
	    fprintf(stderr, _("\nSession setup problem, abort.\n"));
	    pam_end(pamh, PAM_SYSTEM_ERR);
	    exit(1);
    }

    retcode = pam_open_session(pamh, 0);
    PAM_FAIL_CHECK;

    retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
    PAM_FAIL_CHECK;

#else /* ! HAVE_SECURITY_PAM_MISC_H */

    for (cnt = 0;; ask = 1) {

	if (ask) {
	    fflag = 0;
	    getloginname();
	}

	/* Dirty patch to fix a gigantic security hole when using 
	   yellow pages. This problem should be solved by the
	   libraries, and not by programs, but this must be fixed
	   urgently! If the first char of the username is '+', we 
	   avoid login success.
	   Feb 95 <[email protected]> */
	
	if (username[0] == '+') {
	    puts(_("Illegal username"));
	    badlogin(username);
	    sleepexit(1);
	}
	
	/* (void)strcpy(tbuf, username); why was this here? */
	if ((pwd = getpwnam(username))) {
#  ifdef SHADOW_PWD
	    struct spwd *sp;
	    
	    if ((sp = getspnam(username)))
	      pwd->pw_passwd = sp->sp_pwdp;
#  endif
	    salt = pwd->pw_passwd;
	} else
	  salt = "xx";
	
	if (pwd) {
	    initgroups(username, pwd->pw_gid);
	    checktty(username, tty_name, pwd); /* in checktty.c */
	}
	
	/* if user not super-user, check for disabled logins */
	if (pwd == NULL || pwd->pw_uid)
	  checknologin();
	
	/*
	 * Disallow automatic login to root; if not invoked by
	 * root, disallow if the uid's differ.
	 */
	if (fflag && pwd) {
	    int uid = getuid();
	    
	    passwd_req = pwd->pw_uid == 0 ||
	      (uid && uid != pwd->pw_uid);
	}
	
	/*
	 * If trying to log in as root, but with insecure terminal,
	 * refuse the login attempt.
	 */
	if (pwd && pwd->pw_uid == 0 && !rootterm(tty_name)) {
	    fprintf(stderr,
		    _("%s login refused on this terminal.\n"),
		    pwd->pw_name);
	    
	    if (hostname)
	      syslog(LOG_NOTICE,
		     _("LOGIN %s REFUSED FROM %s ON TTY %s"),
		     pwd->pw_name, hostname, tty_name);
	    else
	      syslog(LOG_NOTICE,
		     _("LOGIN %s REFUSED ON TTY %s"),
		     pwd->pw_name, tty_name);
	    continue;
	}

	/*
	 * If no pre-authentication and a password exists
	 * for this user, prompt for one and verify it.
	 */
	if (!passwd_req || (pwd && !*pwd->pw_passwd))
	  break;
	
	setpriority(PRIO_PROCESS, 0, -4);
	pp = getpass(_("Password: "));
	
#  ifdef CRYPTOCARD
	if (strncmp(pp, "CRYPTO", 6) == 0) {
	    if (pwd && cryptocard()) break;
	}
#  endif /* CRYPTOCARD */
	
	p = crypt(pp, salt);
	setpriority(PRIO_PROCESS, 0, 0);

#  ifdef KERBEROS
	/*
	 * If not present in pw file, act as we normally would.
	 * If we aren't Kerberos-authenticated, try the normal
	 * pw file for a password.  If that's ok, log the user
	 * in without issueing any tickets.
	 */
	
	if (pwd && !krb_get_lrealm(realm,1)) {
	    /*
	     * get TGT for local realm; be careful about uid's
	     * here for ticket file ownership
	     */
	    setreuid(geteuid(),pwd->pw_uid);
	    kerror = krb_get_pw_in_tkt(pwd->pw_name, "", realm,
				       "krbtgt", realm, DEFAULT_TKT_LIFE, pp);
	    setuid(0);
	    if (kerror == INTK_OK) {
		memset(pp, 0, strlen(pp));
		notickets = 0;	/* user got ticket */
		break;
	    }
	}
#  endif /* KERBEROS */
	memset(pp, 0, strlen(pp));

	if (pwd && !strcmp(p, pwd->pw_passwd))
	  break;
	
	printf(_("Login incorrect\n"));
	badlogin(username); /* log ALL bad logins */
	failures++;
	
	/* we allow 10 tries, but after 3 we start backing off */
	if (++cnt > 3) {
	    if (cnt >= 10) {
		sleepexit(1);
	    }
	    sleep((unsigned int)((cnt - 3) * 5));
	}
    }
#endif /* !HAVE_SECURITY_PAM_MISC_H */
    
    /* committed to login -- turn off timeout */
    alarm((unsigned int)0);
    
    endpwent();
    
    /* This requires some explanation: As root we may not be able to
       read the directory of the user if it is on an NFS mounted
       filesystem. We temporarily set our effective uid to the user-uid
       making sure that we keep root privs. in the real uid. 
       
       A portable solution would require a fork(), but we rely on Linux
       having the BSD setreuid() */
    
    {
	char tmpstr[MAXPATHLEN];
	uid_t ruid = getuid();
	gid_t egid = getegid();

	/* avoid snprintf - old systems do not have it, or worse,
	   have a libc in which snprintf is the same as sprintf */
	if (strlen(pwd->pw_dir) + sizeof(_PATH_HUSHLOGIN) + 2 > MAXPATHLEN)
		quietlog = 0;
	else {
		sprintf(tmpstr, "%s/%s", pwd->pw_dir, _PATH_HUSHLOGIN);
		setregid(-1, pwd->pw_gid);
		setreuid(0, pwd->pw_uid);
		quietlog = (access(tmpstr, R_OK) == 0);
		setuid(0); /* setreuid doesn't do it alone! */
		setreuid(ruid, 0);
		setregid(-1, egid);
	}
    }
    
    /* for linux, write entries in utmp and wtmp */
    {
	struct utmp ut;
	struct utmp *utp;
	
	utmpname(_PATH_UTMP);
	setutent();

	/* Find pid in utmp.
login sometimes overwrites the runlevel entry in /var/run/utmp,
confusing sysvinit. I added a test for the entry type, and the problem
was gone. (In a runlevel entry, st_pid is not really a pid but some number
calculated from the previous and current runlevel).
Michael Riepe <[email protected]>
	*/
	while ((utp = getutent()))
		if (utp->ut_pid == pid
		    && utp->ut_type >= INIT_PROCESS
		    && utp->ut_type <= DEAD_PROCESS)
			break;

	/* If we can't find a pre-existing entry by pid, try by line.
	   BSD network daemons may rely on this. (anonymous) */
	if (utp == NULL) {
	     setutent();
	     ut.ut_type = LOGIN_PROCESS;
	     strncpy(ut.ut_line, tty_name, sizeof(ut.ut_line));
	     utp = getutline(&ut);
	}
	
	if (utp) {
	    memcpy(&ut, utp, sizeof(ut));
	} else {
	    /* some gettys/telnetds don't initialize utmp... */
	    memset(&ut, 0, sizeof(ut));
	}
	
	if (ut.ut_id[0] == 0)
	  strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id));
	
	strncpy(ut.ut_user, username, sizeof(ut.ut_user));
	xstrncpy(ut.ut_line, tty_name, sizeof(ut.ut_line));
#ifdef _HAVE_UT_TV		/* in <utmpbits.h> included by <utmp.h> */
	gettimeofday(&ut.ut_tv, NULL);
#else
	{
	    time_t t;
	    time(&t);
	    ut.ut_time = t;	/* ut_time is not always a time_t */
				/* glibc2 #defines it as ut_tv.tv_sec */
	}
#endif
	ut.ut_type = USER_PROCESS;
	ut.ut_pid = pid;
	if (hostname) {
		xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
		if (hostaddress[0])
			memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr));
	}
	
	pututline(&ut);
	endutent();

#if HAVE_UPDWTMP
	updwtmp(_PATH_WTMP, &ut);
#else
#if 0
	/* The O_APPEND open() flag should be enough to guarantee
	   atomic writes at end of file. */
	{
	    int wtmp;

	    if((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
		write(wtmp, (char *)&ut, sizeof(ut));
		close(wtmp);
	    }
	}
#else
	/* Probably all this locking below is just nonsense,
	   and the short version is OK as well. */
	{ 
	    int lf, wtmp;
	    if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
		flock(lf, LOCK_EX);
		if ((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
		    write(wtmp, (char *)&ut, sizeof(ut));
		    close(wtmp);
		}
		flock(lf, LOCK_UN);
		close(lf);
	    }
	}
#endif
#endif
    }
    
    dolastlog(quietlog);
    
    chown(ttyn, pwd->pw_uid,
	  (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
    chmod(ttyn, TTY_MODE);

#ifdef LOGIN_CHOWN_VCS
    /* if tty is one of the VC's then change owner and mode of the 
       special /dev/vcs devices as well */
    if (consoletty(0)) {
	chown(vcsn, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));
	chown(vcsan, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));
	chmod(vcsn, TTY_MODE);
	chmod(vcsan, TTY_MODE);
    }
#endif

    setgid(pwd->pw_gid);
    
    if (*pwd->pw_shell == '\0')
      pwd->pw_shell = _PATH_BSHELL;
    
    /* preserve TERM even without -p flag */
    {
	char *ep;
	
	if(!((ep = getenv("TERM")) && (termenv = strdup(ep))))
	  termenv = "dumb";
    }
    
    /* destroy environment unless user has requested preservation */
    if (!pflag)
      {
          environ = (char**)malloc(sizeof(char*));
	  memset(environ, 0, sizeof(char*));
      }
    
    setenv("HOME", pwd->pw_dir, 0);      /* legal to override */
    if(pwd->pw_uid)
      setenv("PATH", _PATH_DEFPATH, 1);
    else
      setenv("PATH", _PATH_DEFPATH_ROOT, 1);
    
    setenv("SHELL", pwd->pw_shell, 1);
    setenv("TERM", termenv, 1);
    
    /* mailx will give a funny error msg if you forget this one */
    {
      char tmp[MAXPATHLEN];
      /* avoid snprintf */
      if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < MAXPATHLEN) {
	      sprintf(tmp, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
	      setenv("MAIL",tmp,0);
      }
    }
    
    /* LOGNAME is not documented in login(1) but
       HP-UX 6.5 does it. We'll not allow modifying it.
       */
    setenv("LOGNAME", pwd->pw_name, 1);

#ifdef HAVE_SECURITY_PAM_MISC_H
    {
	int i;
	char ** env = pam_getenvlist(pamh);

	if (env != NULL) {
	    for (i=0; env[i]; i++) {
		putenv(env[i]);
		/* D(("env[%d] = %s", i,env[i])); */
	    }
	}
    }
#endif

    setproctitle("login", username);
    
    if (!strncmp(tty_name, "ttyS", 4))
      syslog(LOG_INFO, _("DIALUP AT %s BY %s"), tty_name, pwd->pw_name);
    
    /* allow tracking of good logins.
       -steve philp ([email protected]) */
    
    if (pwd->pw_uid == 0) {
	if (hostname)
	  syslog(LOG_NOTICE, _("ROOT LOGIN ON %s FROM %s"),
		 tty_name, hostname);
	else
	  syslog(LOG_NOTICE, _("ROOT LOGIN ON %s"), tty_name);
    } else {
	if (hostname) 
	  syslog(LOG_INFO, _("LOGIN ON %s BY %s FROM %s"), tty_name, 
		 pwd->pw_name, hostname);
	else 
	  syslog(LOG_INFO, _("LOGIN ON %s BY %s"), tty_name, 
		 pwd->pw_name);
    }
    
    if (!quietlog) {
	motd();

#ifdef LOGIN_STAT_MAIL
	/*
	 * This turns out to be a bad idea: when the mail spool
	 * is NFS mounted, and the NFS connection hangs, the
	 * login hangs, even root cannot login.
	 * Checking for mail should be done from the shell.
	 */
	{
	    struct stat st;
	    char *mail;
	
	    mail = getenv("MAIL");
	    if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
		if (st.st_mtime > st.st_atime)
			printf(_("You have new mail.\n"));
		else
			printf(_("You have mail.\n"));
	    }
	}
#endif
    }
    
    signal(SIGALRM, SIG_DFL);
    signal(SIGQUIT, SIG_DFL);
    signal(SIGTSTP, SIG_IGN);

#ifdef HAVE_SECURITY_PAM_MISC_H
    /*
     * We must fork before setuid() because we need to call
     * pam_close_session() as root.
     */
    
    childPid = fork();
    if (childPid < 0) {
       int errsv = errno;
       /* error in fork() */
       fprintf(stderr, _("login: failure forking: %s"), strerror(errsv));
       PAM_END;
       exit(0);
    }

    if (childPid) {
       /* parent - wait for child to finish, then cleanup session */
       signal(SIGHUP, SIG_IGN);
       signal(SIGINT, SIG_IGN);
       signal(SIGQUIT, SIG_IGN);
       signal(SIGTSTP, SIG_IGN);
       signal(SIGTTIN, SIG_IGN);
       signal(SIGTTOU, SIG_IGN);

       wait(NULL);
       PAM_END;
       exit(0);
    }

    /* child */
    /*
     * Problem: if the user's shell is a shell like ash that doesnt do
     * setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every
     * process in the pgrp, will kill us.
     */

    /* start new session */
    setsid();

    /* make sure we have a controlling tty */
    opentty(ttyn);
    openlog("login", LOG_ODELAY, LOG_AUTHPRIV);	/* reopen */

    /*
     * TIOCSCTTY: steal tty from other process group.
     */
    if (ioctl(0, TIOCSCTTY, 1))
	    syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));
#endif
    signal(SIGINT, SIG_DFL);
    
    /* discard permissions last so can't get killed and drop core */
    if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {
	syslog(LOG_ALERT, _("setuid() failed"));
	exit(1);
    }
    
    /* wait until here to change directory! */
    if (chdir(pwd->pw_dir) < 0) {
	printf(_("No directory %s!\n"), pwd->pw_dir);
	if (chdir("/"))
	  exit(0);
	pwd->pw_dir = "/";
	printf(_("Logging in with home = \"/\".\n"));
    }
    
    /* if the shell field has a space: treat it like a shell script */
    if (strchr(pwd->pw_shell, ' ')) {
	buff = malloc(strlen(pwd->pw_shell) + 6);

	if (!buff) {
	    fprintf(stderr, _("login: no memory for shell script.\n"));
	    exit(0);
	}

	strcpy(buff, "exec ");
	strcat(buff, pwd->pw_shell);
	childArgv[childArgc++] = "/bin/sh";
	childArgv[childArgc++] = "-sh";
	childArgv[childArgc++] = "-c";
	childArgv[childArgc++] = buff;
    } else {
	tbuf[0] = '-';
	xstrncpy(tbuf + 1, ((p = rindex(pwd->pw_shell, '/')) ?
			   p + 1 : pwd->pw_shell),
		sizeof(tbuf)-1);
	
	childArgv[childArgc++] = pwd->pw_shell;
	childArgv[childArgc++] = tbuf;
    }

    childArgv[childArgc++] = NULL;

    execvp(childArgv[0], childArgv + 1);

    errsv = errno;

    if (!strcmp(childArgv[0], "/bin/sh"))
	fprintf(stderr, _("login: couldn't exec shell script: %s.\n"),
		strerror(errsv));
    else
	fprintf(stderr, _("login: no shell: %s.\n"), strerror(errsv));

    exit(0);
}
Ejemplo n.º 15
0
int seteuid(uid_t euid)
{
	return (setreuid(-1, euid));
}
Ejemplo n.º 16
0
int main(int argc, char *argv[])
{
	int tdcount, tlimit, mlimit;
	char exename[1024], inputfile[1024];
	struct rlimit r;

	if (argc < 6)
	{
		printf("Usage: [id] [probid] [input] [time limit] [memory limit]\n");
		exit(RET_SE);
	}

	tlimit = atoi(argv[4]);
	mlimit = atoi(argv[5]);

	sprintf(exename, "./%s", argv[1]);
	strcpy(inputfile, argv[3]);


	if ((pid = fork()) == 0)
	{
		freopen("input.txt", "r", stdin);
		chdir("sandbox");
		chroot(".");
		freopen("output.txt", "w", stdout);
		setregid(99, 99);
		setreuid(99, 99);
		ptrace(PTRACE_TRACEME, 0, NULL, NULL);
		execl(exename, exename, NULL);
		exit(0);
	}
	
	signal(SIGALRM, timer);
	alarm(1);

	int stat, tmpmem, sig;
	for (;;)
	{
		wait4(pid, &stat, 0, &rinfo);
		if (WIFEXITED(stat))
		{
			puts("exited!\n");
			break;
		}
		else if (WIFSTOPPED(stat))
		{
			sig = WSTOPSIG(stat);
			if (sig == SIGTRAP)
			{
					if (checkSyscall() == RET_RF)
					{
						ptrace(PTRACE_KILL, pid, NULL, NULL);
						final_result(RET_RF);
					}
			}
			else if (sig == SIGUSR1)
			{
			}
			else
				printf("Stopped due to signal: %d\n", sig);
		}
		else if (WIFSIGNALED(stat))
		{
			//Runtime Error
			printf("Runtime Error. Received signal: %d\n", WTERMSIG(stat));
			final_result(RET_RE);
			break;
		}
		tmpmem = getMemory();
		if (tmpmem > maxmem) maxmem = tmpmem;

		if (maxmem > mlimit)
			final_result(RET_MLE);
		if (getRuntime() > tlimit)
		{
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			final_result(RET_TLE);
		}
		ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
	}
	final_result(RET_AC);
	
	return 0;
}
Ejemplo n.º 17
0
void xsetreuid(uid_t ruid, uid_t euid)
{
    if (setreuid(ruid, euid) != 0)
        perror_msg_and_die("Can't set %cid %lu", 'u', (long)ruid);
}
Ejemplo n.º 18
0
Archivo: miscd.c Proyecto: wyat/kbs
int main(int argc, char *argv[])
{
    chdir(BBSHOME);
    setuid(BBSUID);
    setgid(BBSGID);
    setreuid(BBSUID, BBSUID);
    setregid(BBSGID, BBSGID);

#ifndef CYGWIN
#undef time
    bbssettime(time(0));
    sleep(1);
#define time(x) bbstime(x)
#endif

    setpublicshmreadonly(0);

#ifndef CYGWIN
    setpublicshmreadonly(1);
#endif
    init_bbslog();
    if (argc > 1) {
        if (strcasecmp(argv[1], "killuser") == 0) {
            if (resolve_ucache() != 0)
                return -1;
            resolve_utmp();
            return dokilluser();
        }
        if (strcasecmp(argv[1], "giveup") == 0) {
            if (resolve_ucache() != 0)
                return -1;
            return doupdategiveupuser();
        }
        if (strcasecmp(argv[1], "allboards") == 0)
            return dokillalldir();
        if (strcasecmp(argv[1], "daemon") == 0)
            return miscd_dodaemon(argv[1], argv[2]);
        if (strcasecmp(argv[1], "killdir") == 0)
            return dokilldir(argv[2]);
        if (strcasecmp(argv[1], "flush") == 0) {
            if (resolve_ucache() != 0)
                return -1;
            resolve_boards();
            flushdata(0);
            return 0;
        }
        if (strcasecmp(argv[1], "flush-u") == 0) {
            if (resolve_ucache() != 0)
                return -1;
            strcpy(specfname, argv[2]);
            specfname[511] = 0;
            flushdata(1);
            return 0;
        }
        return miscd_dodaemon(NULL, argv[1]);
    }
    printf("Usage : %s daemon: to run as a daemon (this is the most common use)\n", argv[0]);
    printf("        %s killuser: to kill old users\n", argv[0]);
    printf("        %s giveup: to unlock given-up users\n", argv[0]);
    printf("        %s killdir <BOARDNAME>: to delete old file in <BOARDNAME>\n", argv[0]);
    printf("        %s allboards: to delete old files in all boards\n", argv[0]);
    printf("        %s flush: to synchronize .PASSWDS and .BOARDS to disk\n", argv[0]);
    printf("        %s flush-u <FILENAME>: to write ucache in shm to <FILENAME>\n", argv[0]);
    printf("That's all, folks. See doc/README.SYSOP for more details\n");

    return 0;
}
Ejemplo n.º 19
0
int main (
  int	argc,
  char	*argv[]
)
{
  pwr_tStatus	sts;
  int		event;
  plc_sProcess	*pp;
  uid_t         ruid;
  struct passwd *pwd;
/*
  struct rlimit rlim;
  int i;
*/  
  /* Set core dump file size limit to infinite */
/*
  rlim.rlim_cur =  RLIM_INFINITY;
  rlim.rlim_max =  RLIM_INFINITY;
  sts = setrlimit(RLIMIT_CORE, &rlim);
  printf("%d\n", sts);
  i = 1/0;
  printf("%d\n", i);
*/
  pp = init_process();

  qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcInit, qcom_cTmoEternal);

  init_plc(pp);
  create_threads(pp);
  init_threads(pp);

  /* Once threads has set their priority don't run as root */
  
#if 0
  ruid = getuid();
  
  if (ruid == 0) {
    pwd = getpwnam("pwrp");
    if (pwd != NULL) {
      setreuid(pwd->pw_uid, pwd->pw_uid);
    }
  }
  else 
    setreuid(ruid, ruid);
#endif

  qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcInitDone);
  qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcStart, qcom_cTmoEternal);

//  proc_SetPriority(pp->PlcProcess->Prio);
  set_values(pp);
  start_threads(pp);
  run_threads(pp);
  time_Uptime(&sts, &pp->PlcProcess->StartTime, NULL);

  qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcStartDone);

#if 0
  /* Force the backup to take care initialized backup objects. */

  bck_ForceBackup(NULL);
#endif

  errh_SetStatus( PWR__SRUN);

  qcom_WaitOr(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_terminate | ini_mEvent_oldPlcStop, qcom_cTmoEternal, &event);

  switch ( event) {
  case ini_mEvent_terminate:
    errh_SetStatus( PWR__SRVTERM);

    stop_threads(pp);
    clean_all(pp);
    nmps_delete_lock( &sts);
    break;
  case ini_mEvent_oldPlcStop:
    errh_SetStatus( PWR__SRVTERM);

    time_Uptime(&sts, &pp->PlcProcess->StopTime, NULL);
    stop_threads(pp);
    save_values(pp);

    qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_oldPlcStopDone);

#if defined OS_ELN
    sts = proc_SetPriority(31);
#endif

    clean_all(pp);
    break;
  default: ;
  }

  exit(0);
}
Ejemplo n.º 20
0
/*
 * setup(void) - performs all ONE TIME setup for this test.
 * 	Exit the test program on receipt of unexpected signals.
 *	Create a temporary directory used to hold test directories created
 *	and change the directory to it.
 *	Verify that pid of process executing the test is root.
 *	Create a test directory on temporary directory and set the ownership
 *	of test directory to guest user and process, change mode permissions
 *	to set group id bit on it.
 *	Set the effective uid/gid of the process to that of guest user.
 */
void setup(void)
{
	tst_require_root(NULL);

	/* Capture unexpected signals */
	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	TEST_PAUSE;

	/* Make a temp dir and cd to it */
	tst_tmpdir();

	/* fix permissions on the tmpdir */
	if (chmod(".", 0711) != 0) {
		tst_brkm(TBROK, cleanup, "chmod() failed");
	}

	/* Save the real user id of the current test process */
	save_myuid = getuid();
	/* Save the process id of the current test process */
	mypid = getpid();

	/* Get the node name to be created in the test */
	sprintf(node_name, TNODE, mypid);

	/* Get the uid/gid of ltpuser user */
	if ((user1 = getpwnam(LTPUSER)) == NULL) {
		tst_brkm(TBROK, cleanup, "%s not in /etc/passwd", LTPUSER);
	}
	user1_uid = user1->pw_uid;
	group1_gid = user1->pw_gid;

	/* Get the effective group id of the test process */
	group2_gid = getegid();

	/*
	 * Create a test directory under temporary directory with the
	 * specified mode permissions, with uid/gid set to that of guest
	 * user and the test process.
	 */
	if (mkdir(DIR_TEMP, MODE_RWX) < 0) {
		tst_brkm(TBROK, cleanup, "mkdir(2) of %s failed", DIR_TEMP);
	}
	if (chown(DIR_TEMP, user1_uid, group2_gid) < 0) {
		tst_brkm(TBROK, cleanup, "chown(2) of %s failed", DIR_TEMP);
	}
	if (chmod(DIR_TEMP, MODE_SGID) < 0) {
		tst_brkm(TBROK, cleanup, "chmod(2) of %s failed", DIR_TEMP);
	}

	/*
	 * Verify that test directory created with expected permission modes
	 * and ownerships.
	 */
	if (stat(DIR_TEMP, &buf) < 0) {
		tst_brkm(TBROK, cleanup, "stat(2) of %s failed", DIR_TEMP);
	}

	/* Verify modes of test directory */
	if (!(buf.st_mode & S_ISGID)) {
		tst_brkm(TBROK, cleanup,
			 "%s: Incorrect modes, setgid bit not set", DIR_TEMP);
	}

	/* Verify group ID of test directory */
	if (buf.st_gid != group2_gid) {
		tst_brkm(TBROK, cleanup, "%s: Incorrect group", DIR_TEMP);
	}

	/*
	 * Set the effective group id and user id of the test process
	 * to that of guest user (nobody)
	 */
	if (setgid(group1_gid) < 0) {
		tst_brkm(TBROK, cleanup,
			 "Unable to set process gid to that of ltp user");
	}
	if (setreuid(-1, user1_uid) < 0) {
		tst_brkm(TBROK, cleanup,
			 "Unable to set process uid to that of ltp user");
	}

	/* Save the real group ID of the current process */
	mygid = getgid();

	/* Change directory to DIR_TEMP */
	if (chdir(DIR_TEMP) < 0) {
		tst_brkm(TBROK, cleanup,
			 "Unable to change to %s directory", DIR_TEMP);
	}
}
Ejemplo n.º 21
0
Archivo: sudo.c Proyecto: stargoo/zshrc
int
main(int argc, char * const argv[])
{
	int ch;
	uid_t uid = 0;
	gid_t gid = 0;
	gid_t gidset[1];
	const char *cwd = NULL;
	const char *errstr;

	while ((ch = getopt(argc, argv, "+u:g:c:h")) != -1) {
		switch (ch) {
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
			break;
		case 'c':
			cwd = optarg;
			break;
		case 'u':
			uid = strtonum(optarg, 0, 65535, &errstr);
			if (errstr != NULL) {
				fprintf(stderr, "Provided UID `%s' is %s\n", optarg, errstr);
				usage();
				exit(EXIT_FAILURE);
			}
			break;
		case 'g':
			gid = strtonum(optarg, 0, 65535, &errstr);
			gidset[0] = gid;
			if (errstr != NULL) {
				fprintf(stderr, "Provided GID `%s' is %s\n", optarg, errstr);
				usage();
				exit(EXIT_FAILURE);
			}
			break;
		default:
			usage();
			exit(EXIT_FAILURE);
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "Missing command to execute\n");
		usage();
		exit(EXIT_FAILURE);
	}

	if (setregid(gid, gid) == -1 ||
	    setgroups(1, gidset) == -1 ||
	    setreuid(uid, uid) == -1) {
		fprintf(stderr, "unable to change UID %d/GID %d: %m\n",
		    uid, gid);
		exit(EXIT_FAILURE);
	}

	if (cwd != NULL && chdir(cwd) == -1) {
		fprintf(stderr, "unable to change to `%s': %m\n", cwd);
		/* But continue */
	}

	if (execvp(argv[optind], &argv[optind]) == -1) {
		fprintf(stderr, "unable to execute `%s': %m\n", argv[optind]);
		exit(EXIT_FAILURE);
	}

	exit(EXIT_SUCCESS);
}
Ejemplo n.º 22
0
/**
 * Drop privileges.
 *
 */
ods_status
privdrop(const char *username, const char *groupname, const char *newroot,
    uid_t* puid, gid_t* pgid)
{
    int status;
    uid_t uid, olduid;
    gid_t gid;
    long ngroups_max;
    gid_t *final_groups;
    int final_group_len = -1;

    /* Save effective uid/gid */
    uid = olduid = geteuid();
    gid = getegid();

    /* Check if we're going to drop uid */
    if (username) {
        uid = privuid(username);
        if (uid == (uid_t)-1) {
            ods_log_error("[%s] user %s does not exist", privdrop_str,
                username);
            return ODS_STATUS_PRIVDROP_ERR;
        }
    }

    /* Check if we're going to drop gid */
    if (groupname) {
        gid = privgid(groupname);
        if (gid == (gid_t)-1) {
            ods_log_error("[%s] group %s does not exist", privdrop_str,
                groupname);
            return ODS_STATUS_PRIVDROP_ERR;
        }
    }

    /* Change root if requested */
    if (newroot) {
#ifdef HAVE_CHROOT
       status = chroot(newroot);
       if (status != 0 || chdir("/") != 0) {
            ods_log_error("[%s] chroot to %s failed: %.100s", privdrop_str,
                newroot, strerror(errno));
            return ODS_STATUS_CHROOT_ERR;
       }
#else
       ods_log_error("[%s] chroot to %s failed: !HAVE_CHROOT", privdrop_str,
           newroot);
       return ODS_STATUS_CHROOT_ERR;
#endif /* HAVE_CHROOT */
    }

    /* Do additional groups first */
    if (username != NULL && !olduid) {
#ifdef HAVE_INITGROUPS
        if (initgroups(username, gid) < 0) {
            ods_log_error("[%s] initgroups failed: %s: %.100s", privdrop_str,
                username, strerror(errno));
            return ODS_STATUS_PRIVDROP_ERR;
        }
#else
        ods_log_error("initgroups failed: %s: !HAVE_INITGROUPS", username);
        return ODS_STATUS_PRIVDROP_ERR;
#endif /* HAVE_INITGROUPS */

        ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
        final_groups = (gid_t *)malloc(ngroups_max *sizeof(gid_t));
        if (!final_groups) {
            return ODS_STATUS_MALLOC_ERR;
        }
#if defined(HAVE_GETGROUPS) && defined(HAVE_SETGROUPS)
        final_group_len = getgroups(ngroups_max, final_groups);
        /* If we are root then drop all groups other than the final one */
        if (!olduid) {
            setgroups(final_group_len, final_groups);
        }
#endif /* defined(HAVE_GETGROUPS) && defined(HAVE_SETGROUPS) */
        free((void*)final_groups);
    }
    else {
        /* If we are root then drop all groups other than the final one */
#if defined(HAVE_SETGROUPS)
        if (!olduid) setgroups(1, &(gid));
#endif /* defined(HAVE_SETGROUPS) */
    }

    /* Drop gid? */
    if (groupname) {

#if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
        status = setresgid(gid, gid, gid);
#elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
        status = setregid(gid, gid);
#else

# ifndef SETEUID_BREAKS_SETUID
        status = setegid(gid);
        if (status != 0) {
           ods_log_error("[%s] setegid() for %s (%lu) failed: %s",
               privdrop_str, groupname, (unsigned long) gid, strerror(errno));
           return ODS_STATUS_PRIVDROP_ERR;
        }
# endif  /* SETEUID_BREAKS_SETUID */

        status = setgid(gid);
#endif

        if (status != 0) {
           ods_log_error("[%s] setgid() for %s (%lu) failed: %s",
               privdrop_str, groupname, (unsigned long) gid, strerror(errno));
           return ODS_STATUS_PRIVDROP_ERR;
        } else {
            ods_log_debug("[%s] group set to %s (%lu)", privdrop_str,
                groupname, (unsigned long) gid);
        }
    }

    /* Drop uid? */
    if (username) {
        /* Set the user to drop to if specified; else just set the uid as the real one */
#if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
        status = setresuid(uid, uid, uid);
#elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
        status = setreuid(uid, uid);
#else

# ifndef SETEUID_BREAKS_SETUID
        status = seteuid(uid);
        if (status != 0) {
           ods_log_error("[%s] seteuid() for %s (%lu) failed: %s",
               privdrop_str, username, (unsigned long) uid, strerror(errno));
           return ODS_STATUS_PRIVDROP_ERR;
        }
# endif  /* SETEUID_BREAKS_SETUID */

        status = setuid(uid);
#endif

        if (status != 0) {
           ods_log_error("[%s] setuid() for %s (%lu) failed: %s",
               privdrop_str, username, (unsigned long) uid, strerror(errno));
           return ODS_STATUS_PRIVDROP_ERR;
        } else {
            ods_log_debug("[%s] user set to %s (%lu)", privdrop_str,
                username, (unsigned long) uid);
        }
    }

    *puid = uid;
    *pgid = gid;
    return ODS_STATUS_OK;
}
Ejemplo n.º 23
0
void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) {
	//************************
	// verify sandbox
	//************************
	char *comm = pid_proc_comm(pid);
	if (!comm) {
		fprintf(stderr, "Error: cannot find sandbox\n");
		exit(1);
	}

	// remove \n and check for firejail sandbox
	char *ptr = strchr(comm, '\n');
	if (ptr)
		*ptr = '\0';
	if (strcmp(comm, "firejail") != 0) {
		fprintf(stderr, "Error: cannot find sandbox\n");
		exit(1);
	}
	free(comm);
	
	// check network namespace
	char *cmd = pid_proc_cmdline(pid);
	if (!cmd || strstr(cmd, "--net") == NULL) {
		fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n");
		exit(1);
	}
	free(cmd);


	//************************
	// join the network namespace
	//************************
	pid_t child;
	if (find_child(pid, &child) == -1) {
		fprintf(stderr, "Error: cannot join the network namespace\n");
		exit(1);
	}
	if (join_namespace(child, "net")) {
		fprintf(stderr, "Error: cannot join the network namespace\n");
		exit(1);
	}

	// set shm file
	if (strcmp(command, "set") == 0)
		bandwidth_shm_set(pid, dev, down, up);
	else if (strcmp(command, "clear") == 0)
		bandwidth_shm_remove(pid, dev);

	//************************
	// build command
	//************************
	char *devname = NULL;
	if (dev) {
		// read shm network map file
		char *fname;
		if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1)
			errExit("asprintf");
		FILE *fp = fopen(fname, "r");
		if (!fp) {
			fprintf(stderr, "Error: cannot read netowk map filel %s\n", fname);
			exit(1);
		}
		
		char buf[1024];
		int len = strlen(dev);
		while (fgets(buf, 1024, fp)) {
			// remove '\n'
			char *ptr = strchr(buf, '\n');
			if (ptr)
				*ptr = '\0';
			if (*buf == '\0')
				break;

			if (strncmp(buf, dev, len) == 0  && buf[len] == ':') {
				devname = strdup(buf + len + 1);
				if (!devname)
					errExit("strdup");
				// check device in namespace
				if (if_nametoindex(devname) == 0) {
					fprintf(stderr, "Error: cannot find network device %s\n", devname);
					exit(1);
				}
				break;
			}
		}
		free(fname);
		fclose(fp);
	}
	
	// build fshaper.sh command
	cmd = NULL;
	if (devname) {
		if (strcmp(command, "set") == 0) {
			if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s %s %d %d",
				PREFIX, command, devname, down, up) == -1)
				errExit("asprintf");
		}
		else {
			if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s %s", 
				PREFIX, command, devname) == -1)
				errExit("asprintf");
		}
	}
	else {
		if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s", PREFIX, command) == -1)
			errExit("asprintf");
	}
	assert(cmd);

	// wipe out environment variables
	environ = NULL;

	//************************
	// build command
	//************************
	// elevate privileges
	if (setreuid(0, 0))
		errExit("setreuid");
	if (setregid(0, 0))
		errExit("setregid");

	char *arg[4];
	arg[0] = "/bin/bash";
	arg[1] = "-c";
	arg[2] = cmd;
	arg[3] = NULL;
	execvp("/bin/bash", arg);
	
	// it will never get here
	exit(0);		
}
Ejemplo n.º 24
0
/*
=================
Sys_GetGameAPI

Loads the game dll
=================
*/
void *Sys_GetGameAPI (void *parms)
{
	void	*(*GetGameAPI) (void *);

	char	name[MAX_OSPATH];
	char	curpath[MAX_OSPATH];
	char	*path;

	// Knightmare- changed game library name for better cohabitation
#ifdef __i386__
	const char *gamename = "kmq2gamei386.so";
#elif defined __alpha__
	const char *gamename = "kmq2gameaxp.so";
#elif defined __x86_64__
	const char *gamename = "kmq2gamex86_64.so";
#elif defined __powerpc__
	const char *gamename = "kmq2gameppc.so";
#elif defined __sparc__
	const char *gamename = "kmq2gamesparc.so";
#elif defined __arm__
        const char *gamename = "kmq2gamearm.so";
#else
#error Unknown arch
#endif

	setreuid(getuid(), getuid());
	setegid(getgid());

	if (game_library)
		Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");

	getcwd(curpath, sizeof(curpath));

	Com_Printf("------- Loading %s -------\n", gamename);

	// now run through the search paths
	path = NULL;
/*	while (1)
	{
		path = FS_NextPath (path);
		if (!path)
			return NULL;		// couldn't find one anywhere
		sprintf (name, "%s/%s/%s", curpath, path, gamename);
		game_library = dlopen (name, RTLD_LAZY );
		if (game_library)
		{
			Com_Printf ("LoadLibrary (%s)\n",name);
			break;
		}
	}
	if (!game_library)*/
	{
                sprintf (name, "%s/%s", curpath, gamename);
                game_library = dlopen (name, RTLD_LAZY );
                if (game_library)
                {
                        Com_Printf ("LoadLibrary (%s)\n",name);
                }
	}

	GetGameAPI = (void *)dlsym (game_library, "GetGameAPI");
	if (!GetGameAPI)
	{
		Sys_UnloadGame ();		
		return NULL;
	}

	return GetGameAPI (parms);
}
Ejemplo n.º 25
0
static void swapUserAndEffectiveUser()
{
    (void) setreuid (geteuid(), getuid());
    (void) setregid (getegid(), getgid());
}
Ejemplo n.º 26
0
/* Switch to the given UID/GID */
int
mu_switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups)
{
  int rc = 0;
  gid_t *emptygidset;
  size_t size = 1, j = 1;
  mu_iterator_t itr;

  if (uid == 0)
    return 0;

  /* Create a list of supplementary groups */
  mu_list_count (retain_groups, &size);
  size++;
  emptygidset = xmalloc (size * sizeof emptygidset[0]);
  emptygidset[0] = gid ? gid : getegid ();

  if (mu_list_get_iterator (retain_groups, &itr) == 0)
    {
      for (mu_iterator_first (itr);
	   !mu_iterator_is_done (itr); mu_iterator_next (itr)) 
	mu_iterator_current (itr,
			     (void **)(emptygidset + j++));
      mu_iterator_destroy (&itr);
    }

  /* Reset group permissions */
  if (geteuid () == 0 && setgroups (j, emptygidset))
    {
      mu_error(_("setgroups(1, %lu) failed: %s"),
	       (unsigned long) emptygidset[0], mu_strerror (errno));
      rc = 1;
    }
  free (emptygidset);
	
  /* Switch to the user's gid. On some OSes the effective gid must
     be reset first */

#if defined(HAVE_SETEGID)
  if ((rc = setegid (gid)) < 0)
    mu_error (_("setegid(%lu) failed: %s"),
	      (unsigned long) gid, mu_strerror (errno));
#elif defined(HAVE_SETREGID)
  if ((rc = setregid (gid, gid)) < 0)
    mu_error (_("setregid(%lu,%lu) failed: %s"),
	      (unsigned long) gid, (unsigned long) gid,
	      mu_strerror (errno));
#elif defined(HAVE_SETRESGID)
  if ((rc = setresgid (gid, gid, gid)) < 0)
    mu_error (_("setresgid(%lu,%lu,%lu) failed: %s"),
	      (unsigned long) gid,
	      (unsigned long) gid,
	      (unsigned long) gid,
	      mu_strerror (errno));
#endif

  if (rc == 0 && gid != 0)
    {
      if ((rc = setgid (gid)) < 0 && getegid () != gid) 
	mu_error (_("setgid(%lu) failed: %s"),
		  (unsigned long) gid, mu_strerror (errno));
      if (rc == 0 && getegid () != gid)
	{
	  mu_error (_("Cannot set effective gid to %lu"),
		    (unsigned long) gid);
	  rc = 1;
	}
    }

  /* Now reset uid */
  if (rc == 0 && uid != 0)
    {
      uid_t euid;

      if (setuid (uid) || geteuid () != uid
	  || (getuid () != uid && (geteuid () == 0 || getuid () == 0)))
	{
#if defined(HAVE_SETREUID)
	  if (geteuid () != uid)
	    {
	      if (setreuid (uid, -1) < 0)
		{
		  mu_error (_("setreuid(%lu,-1) failed: %s"),
			    (unsigned long) uid,
			    mu_strerror (errno));
		  rc = 1;
		}
	      if (setuid (uid) < 0)
		{
		  mu_error (_("second setuid(%lu) failed: %s"),
			    (unsigned long) uid, mu_strerror (errno));
		  rc = 1;
		}
	    } else
#endif
	        {
		  mu_error (_("setuid(%lu) failed: %s"),
			    (unsigned long) uid,
			    mu_strerror (errno));
		  rc = 1;
		}
	}
	
      euid = geteuid ();
      if (uid != 0 && setuid (0) == 0)
	{
	  mu_error (_("seteuid(0) succeeded when it should not"));
	  rc = 1;
	}
      else if (uid != euid && setuid (euid) == 0)
	{
	  mu_error (_("Cannot drop non-root setuid privileges"));
	  rc = 1;
	}
    }
  return rc;
}
Ejemplo n.º 27
0
/*
 * test_rwflag(int i, int cnt)
 * Validate the mount system call for rwflags.
 */
int test_rwflag(int i, int cnt)
{
	int ret, fd, pid, status;
	char nobody_uid[] = "nobody";
	time_t atime;
	struct passwd *ltpuser;
	struct stat file_stat;
	char readbuf[20];

	switch (i) {
	case 0:
		/* Validate MS_RDONLY flag of mount call */

		snprintf(file, PATH_MAX, "%stmp", path_name);
		fd = open(file, O_CREAT | O_RDWR, S_IRWXU);
		if (fd == -1) {
			if (errno == EROFS) {
				return 0;
			} else {
				tst_resm(TWARN | TERRNO,
					 "open didn't fail with EROFS");
				return 1;
			}
		}
		close(fd);
		return 1;
	case 1:
		/* Validate MS_NODEV flag of mount call */

		snprintf(file, PATH_MAX, "%smynod_%d_%d", path_name, getpid(),
			 cnt);
		if (mknod(file, S_IFBLK | 0777, 0) == 0) {
			fd = open(file, O_RDWR, S_IRWXU);
			if (fd == -1) {
				if (errno == EACCES) {
					return 0;
				} else {
					tst_resm(TWARN | TERRNO,
						 "open didn't fail with EACCES");
					return 1;
				}
			}
			close(fd);
		} else {
			tst_resm(TWARN | TERRNO, "mknod(2) failed to create %s",
				 file);
			return 1;
		}
		return 1;
	case 2:
		/* Validate MS_NOEXEC flag of mount call */

		snprintf(file, PATH_MAX, "%stmp1", path_name);
		fd = open(file, O_CREAT | O_RDWR, S_IRWXU);
		if (fd == -1) {
			tst_resm(TWARN | TERRNO, "opening %s failed", file);
		} else {
			close(fd);
			ret = execlp(file, basename(file), NULL);
			if ((ret == -1) && (errno == EACCES))
				return 0;
		}
		return 1;
	case 3:
		/*
		 * Validate MS_SYNCHRONOUS flag of mount call.
		 * Copy some data into data buffer.
		 */

		strcpy(write_buffer, "abcdefghijklmnopqrstuvwxyz");

		/* Creat a temporary file under above directory */
		snprintf(file, PATH_MAX, "%s%s", path_name, TEMP_FILE);
		fildes = open(file, O_RDWR | O_CREAT, FILE_MODE);
		if (fildes == -1) {
			tst_resm(TWARN | TERRNO,
				 "open(%s, O_RDWR|O_CREAT, %#o) failed",
				 file, FILE_MODE);
			return 1;
		}

		/* Write the buffer data into file */
		if (write(fildes, write_buffer, strlen(write_buffer)) !=
		    strlen(write_buffer)) {
			tst_resm(TWARN | TERRNO, "writing to %s failed", file);
			close(fildes);
			return 1;
		}

		/* Set the file ptr to b'nning of file */
		if (lseek(fildes, 0, SEEK_SET) < 0) {
			tst_resm(TWARN, "lseek() failed on %s, error="
				 " %d", file, errno);
			close(fildes);
			return 1;
		}

		/* Read the contents of file */
		if (read(fildes, read_buffer, sizeof(read_buffer)) > 0) {
			if (strcmp(read_buffer, write_buffer)) {
				tst_resm(TWARN, "Data read from %s and written "
					 "mismatch", file);
				close(fildes);
				return 1;
			} else {
				close(fildes);
				return 0;
			}
		} else {
			tst_resm(TWARN | TERRNO, "read() Fails on %s", file);
			close(fildes);
			return 1;
		}

	case 4:
		/* Validate MS_REMOUNT flag of mount call */

		TEST(mount(device, mntpoint, fs_type, MS_REMOUNT, NULL));
		if (TEST_RETURN != 0) {
			tst_resm(TWARN | TTERRNO, "mount(2) failed to remount");
			return 1;
		} else {
			snprintf(file, PATH_MAX, "%stmp2", path_name);
			fd = open(file, O_CREAT | O_RDWR, S_IRWXU);
			if (fd == -1) {
				tst_resm(TWARN, "open(%s) on readonly "
					 "filesystem passed", file);
				return 1;
			} else {
				close(fd);
				return 0;
			}
		}
	case 5:
		/* Validate MS_NOSUID flag of mount call */

		snprintf(file, PATH_MAX, "%ssetuid_test", path_name);
		SAFE_FILE_PRINTF(cleanup, file, "TEST FILE");

		if (stat(file, &file_stat) < 0)
			tst_brkm(TBROK, cleanup, "stat for setuid_test failed");

		if (file_stat.st_mode != SUID_MODE &&
		    chmod(file, SUID_MODE) < 0)
			tst_brkm(TBROK, cleanup,
				 "setuid for setuid_test failed");

		pid = fork();
		switch (pid) {
		case -1:
			tst_resm(TBROK | TERRNO, "fork failed");
			return 1;
		case 0:
			ltpuser = getpwnam(nobody_uid);
			if (setreuid(ltpuser->pw_uid, ltpuser->pw_uid) == -1)
				tst_resm(TWARN | TERRNO,
					 "seteuid() failed to change euid to %d",
					 ltpuser->pw_uid);

			execlp(file, basename(file), NULL);
			exit(1);
		default:
			waitpid(pid, &status, 0);
			if (WIFEXITED(status)) {
				/* reset the setup_uid */
				if (status)
					return 0;
				else
					return 1;
			}
		}
	case 6:
		/* Validate MS_NOATIME flag of mount call */

		snprintf(file, PATH_MAX, "%satime", path_name);
		fd = open(file, O_CREAT | O_RDWR, S_IRWXU);
		if (fd == -1) {
			tst_resm(TWARN | TERRNO, "opening %s failed", file);
			return 1;
		}

		if (write(fd, "TEST_MS_NOATIME", 15) != 15) {
			tst_resm(TWARN | TERRNO, "write %s failed", file);
			return 1;
		}

		if (fstat(fd, &file_stat) == -1) {
			tst_resm(TWARN | TERRNO, "stat %s failed #1", file);
			return 1;
		}

		atime = file_stat.st_atime;

		sleep(1);

		if (read(fd, readbuf, sizeof(readbuf)) == -1) {
			tst_resm(TWARN | TERRNO, "read %s failed", file);
			return 1;
		}

		if (fstat(fd, &file_stat) == -1) {
			tst_resm(TWARN | TERRNO, "stat %s failed #2", file);
			return 1;
		}
		close(fd);

		if (file_stat.st_atime != atime) {
			tst_resm(TWARN, "access time is updated");
			return 1;
		}
		return 0;
	}
	return 0;
}
Ejemplo n.º 28
0
int main(int ac, char **av)
{
	int lc;
	char *msg;		/* message returned from parse_opts */

	/* parse standard options */
	if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *)NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
		tst_exit();
	 /*NOTREACHED*/}

	/* Perform global setup for test */
	setup();

	/* check looping state if -i option is given */
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		int i;

		/* reset Tst_count in case we are looping */
		Tst_count = 0;

		for (i = 0; i < TST_TOTAL; i++) {

			/* Set the real or effective user id */
			TEST(setreuid(*test_data[i].real_uid,
				      *test_data[i].eff_uid));

			if (TEST_RETURN == *test_data[i].exp_ret) {
				if (TEST_RETURN == neg_one) {
					if (TEST_ERRNO != EPERM) {
						tst_resm(TFAIL,
							 "setreuid(%d, %d) "
							 "did not set errno "
							 "value as expected.",
							 *test_data[i].real_uid,
							 *test_data[i].eff_uid);
						continue;
					}
					tst_resm(TPASS, "setreuid(%d, %d) "
						 "failed as expected.",
						 *test_data[i].real_uid,
						 *test_data[i].eff_uid);
				} else {
					tst_resm(TPASS, "setreuid(%d, %d) "
						 "succeeded as expected.",
						 *test_data[i].real_uid,
						 *test_data[i].eff_uid);
				}
			} else {
				tst_resm(TFAIL, "setreuid(%d, %d) "
					 "did not return as expected.",
					 *test_data[i].real_uid,
					 *test_data[i].eff_uid);
			}

			if (TEST_RETURN == -1) {
				TEST_ERROR_LOG(TEST_ERRNO);
			}
			/*
			 * Perform functional verification if test
			 * executed without (-f) option.
			 */
			if (STD_FUNCTIONAL_TEST) {
				uid_verify(test_data[i].exp_real_usr,
					   test_data[i].exp_eff_usr,
					   test_data[i].test_msg);
			}
		}
	}

	cleanup();
	 /*NOTREACHED*/ return 0;

}
Ejemplo n.º 29
0
void ppp_start(struct device_list *entry)
{
	int pgrpid;
	
	/* Run pppd directly here and set up to wait for the iface */
	entry->status = 1;
	entry->link_pid = fork();


	if (entry->link_pid < 0) {
		syslog(LOG_ERR, "failed to fork pppd: %m");
		exit(EXIT_FAILURE);
	}

#define ADD_ARG(arg) { argv[i] = arg; argv_len += strlen(argv[i++]) + 1; }
    
	if (entry->link_pid == 0) {
		char **argv = (char **)malloc(sizeof(char *)*(pppd_argc+12));
		int argv_len = 0;
		char buf[24], tmpbuf[50], *argv_buf, connect[70];
		int i = 0, j;

		ADD_ARG(path_pppd);
		ADD_ARG(entry->device);
		ADD_ARG("-defaultroute");
		ADD_ARG("-detach");
		if (modem){
			ADD_ARG("modem");
			ADD_ARG("connect");
			sprintf(connect, 
// should add ABORT 'BLACKLISTED' here
// pppd dies when it is set
				"/usr/sbin/chat -v ABORT 'BUSY' ABORT "
				"'NO CARRIER' '' ATZ OK  ATDT%s CONNECT",
				iptotel((char *)inet_ntoa(*entry->raddr)));
			ADD_ARG(connect);
		}
		else{
			ADD_ARG("local");
		}
		ADD_ARG("115200");
		sprintf(buf, "%s:", inet_ntoa(*entry->laddr));
		sprintf(tmpbuf, "%s%s", buf, inet_ntoa(*entry->raddr));
		ADD_ARG(tmpbuf);
//		if (crtscts) ADD_ARG("crtscts");
//		ADD_ARG("mtu");
//		sprintf(buf,"%d",mtu);
//		ADD_ARG(strdup(buf));
//		ADD_ARG("mru");
//		sprintf(buf,"%d",mru);
//		ADD_ARG(strdup(buf));
//		if (netmask) {
//			ADD_ARG("netmask");
//			ADD_ARG(netmask);
//		}
		for (j = 0; j < pppd_argc; j++) {
			ADD_ARG(pppd_argv[j]);
		}
		argv[i++] = 0;

		if ((argv_buf = (char *)malloc(argv_len + 1))) {
			argv_len = i - 1;
			*argv_buf = '\0';
			for (i = 0; i < argv_len; i++) {
				strcat(argv_buf, argv[i]);
				strcat(argv_buf, " ");
			}
			syslog(LOG_DEBUG, "Running pppd: %s", argv_buf);
		}

		/* make sure pppd is the session leader and has the controlling
		 * terminal so it gets the SIGHUP's
		 */
		pgrpid = setsid();
		ioctl(modem_fd, TIOCSCTTY, 1);
		tcsetpgrp(modem_fd, pgrpid);

		setreuid(getuid(), getuid());
		setregid(getgid(), getgid());

		if (modem_fd != 0)
			dup2(modem_fd, 0);
		else
			fcntl(modem_fd, F_SETFD, 0);
		dup2(0, 1);

		execv(path_pppd,argv);

		syslog(LOG_ERR, "could not exec %s: %m",path_pppd);
		_exit(99);
		/* NOTREACHED */
	}
	syslog(LOG_INFO,"Running pppd (pid = %d).",entry->link_pid);
}
Ejemplo n.º 30
0
int
setruid(uid_t ruid)
{

	return (setreuid(ruid, -1));
}