* src/ttt-args.h:
* src/ttt-args.c: (ttt_args_help), (ttt_args_parse): Add a -u,
--user option for controlling the uid under which the server
process runs.
* src/ttt.h:
* src/ttt-server.c: (ttt_server_register_client), (main): Recert
the dup of stdout which wasn't working. Instead just print client
join information on stderr so that it goes into the log. Implement
support for the user option by calling setuid to drop root
privileges the process might start out with.
+2005-12-09 Carl Worth <cworth@cworth.org>
+
+ * src/ttt-args.h:
+ * src/ttt-args.c: (ttt_args_help), (ttt_args_parse): Add a -u,
+ --user option for controlling the uid under which the server
+ process runs.
+
+ * src/ttt.h:
+ * src/ttt-server.c: (ttt_server_register_client), (main): Recert
+ the dup of stdout which wasn't working. Instead just print client
+ join information on stderr so that it goes into the log. Implement
+ support for the user option by calling setuid to drop root
+ privileges the process might start out with.
+
2005-12-09 Bryan Worth <bryan@theworths.org>
* src/ttt-curses-client.c: added error checking to ttt_create_client
call. Added ability to escape server commands by prepending with "/".
2005-12-09 Bryan Worth <bryan@theworths.org>
* src/ttt-curses-client.c: added error checking to ttt_create_client
call. Added ability to escape server commands by prepending with "/".
-static char ttt_args_optstring[] = "dh:p:";
+static char ttt_args_optstring[] = "dh:p:u:";
static struct option ttt_args_options[] = {
/* name, has_arg, flag, val */
{"host", 1, 0, 'h'},
{"port", 1, 0, 'p'},
static struct option ttt_args_options[] = {
/* name, has_arg, flag, val */
{"host", 1, 0, 'h'},
{"port", 1, 0, 'p'},
{"detach", 0, 0, 'd'},
{"log-file", 1, 0, TTT_ARGS_VAL_LOG_FILE},
{"pid-file", 1, 0, TTT_ARGS_VAL_PID_FILE},
{"detach", 0, 0, 'd'},
{"log-file", 1, 0, TTT_ARGS_VAL_LOG_FILE},
{"pid-file", 1, 0, TTT_ARGS_VAL_PID_FILE},
TTT_ARGS_HOST_DEFAULT);
printf (" -p PORT, --port=PORT\tPort to connect/bind to [%s]\n",
TTT_ARGS_PORT_DEFAULT);
TTT_ARGS_HOST_DEFAULT);
printf (" -p PORT, --port=PORT\tPort to connect/bind to [%s]\n",
TTT_ARGS_PORT_DEFAULT);
+ printf (" -u USER, --user=USER\tUser the server should run as.\n");
printf (" --help\tGive this help list\n");
printf (" --version\tPrint program version\n");
puts ("");
printf (" --help\tGive this help list\n");
printf (" --version\tPrint program version\n");
puts ("");
args->host = TTT_ARGS_HOST_DEFAULT;
args->port = TTT_ARGS_PORT_DEFAULT;
args->host = TTT_ARGS_HOST_DEFAULT;
args->port = TTT_ARGS_PORT_DEFAULT;
args->log_file = TTT_ARGS_LOG_FILE_DEFAULT;
args->detach = FALSE;
args->pid_file = TTT_ARGS_PID_FILE_DEFAULT;
args->log_file = TTT_ARGS_LOG_FILE_DEFAULT;
args->detach = FALSE;
args->pid_file = TTT_ARGS_PID_FILE_DEFAULT;
case 'p':
args->port = optarg;
break;
case 'p':
args->port = optarg;
break;
+ case 'u':
+ args->user = optarg;
+ break;
case TTT_ARGS_VAL_LOG_FILE:
args->log_file = optarg;
break;
case TTT_ARGS_VAL_LOG_FILE:
args->log_file = optarg;
break;
{
char *host;
char *port;
{
char *host;
char *port;
char *log_file;
ttt_bool_t detach;
char *pid_file;
char *log_file;
ttt_bool_t detach;
char *pid_file;
- printf ("Client %s has joined.\r\n", username);
+ fprintf (stderr, "Client %s has joined.\r\n", username);
if (args.detach)
_detach_and_write_child_pid_to (args.pid_file);
if (args.detach)
_detach_and_write_child_pid_to (args.pid_file);
+ /* Now that we've setup logging and the pid file, drop any special
+ * permissions we might have if we were asked to do that. */
+ if (args.user) {
+ int ret;
+ struct passwd *pwd;
+ errno = 0;
+ pwd = getpwnam (args.user);
+ if (pwd == NULL) {
+ fprintf (stderr, "Error: Failed to lookup uid for %s: %s. Aborting.\n",
+ args.user,
+ errno == 0 ? "User not found" : strerror (errno));
+ exit (1);
+ }
+ ret = setuid (pwd->pw_uid);
+ if (ret == -1) {
+ fprintf (stderr, "Error: Failed to setuid to %d (%s): %s. Aborting.\n",
+ pwd->pw_uid, args.user, strerror (errno));
+ exit (1);
+ }
+ }
+
socket = ttt_socket_create_server (args.host, args.port);
socket = ttt_socket_create_server (args.host, args.port);
- if (args.detach) {
- xdup2 (2, 1);
printf ("Server started listening on %s:%s\n", args.host, args.port);
printf ("Server started listening on %s:%s\n", args.host, args.port);
printf (WELCOME_MESSAGE, args.host, args.port, args.host, args.port);
printf (WELCOME_MESSAGE, args.host, args.port, args.host, args.port);
fclose (stdout);
fclose (stdin);
fclose (stdout);
fclose (stdin);
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#define ASSERT_NOT_REACHED \
do { \
#define ASSERT_NOT_REACHED \
do { \