+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 "/".
TTT_ARGS_VAL_VERSION,
};
-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'},
+ {"user", 1, 0, 'u'},
{"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);
+ 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 ("");
args->host = TTT_ARGS_HOST_DEFAULT;
args->port = TTT_ARGS_PORT_DEFAULT;
+ args->user = NULL;
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 'u':
+ args->user = optarg;
+ break;
case TTT_ARGS_VAL_LOG_FILE:
args->log_file = optarg;
break;
{
char *host;
char *port;
+ char *user;
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);
server->num_clients++;
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);
- if (args.detach) {
- xdup2 (2, 1);
+ if (args.detach)
printf ("Server started listening on %s:%s\n", args.host, args.port);
- } else {
+ else
printf (WELCOME_MESSAGE, args.host, args.port, args.host, args.port);
- }
fclose (stdout);
fclose (stdin);
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
+#include <pwd.h>
#define ASSERT_NOT_REACHED \
do { \