to run server on foreground. A patch by debolaz.
Affected files silcd/server.c, silcd/silcd.c.
+ * Fixed MOTD to return the MOTD file server name. Affected
+ file silcd/command.c.
+
+ * Added INFO command reply handling to the Irssi SILC Client.
+ Affected file irssi/src/silc/core/client_ops.c.
+
Wed Nov 14 00:18:08 EET 2001 Pekka Riikonen <priikone@silcnet.org>
* Fixed the silc_idcache_list_* routines to really support
TODO/bugs In SILC Server
========================
- o MOTD and INFO does not work with server name.
-
o After backup resume protocol the TOPIC_SET was not handled correctly
by all (unknown Channel ID).
}
}
break;
+
+ case SILC_COMMAND_INFO:
+ {
+ SilcServerEntry server_entry;
+ char *server_name;
+ char *server_info;
+
+ if (!success)
+ return;
+
+ server_entry = va_arg(vp, SilcServerEntry);
+ server_name = va_arg(vp, char *);
+ server_info = va_arg(vp, char *);
+
+ if (server_name && server_info )
+ {
+ printtext(server, NULL, MSGLEVEL_CRAP, "Server: %s", server_name);
+ printtext(server, NULL, MSGLEVEL_CRAP, "%s", server_info);
+ }
+ }
+ break;
case SILC_COMMAND_TOPIC:
{
SILC_STATUS_OK, ident, 2,
2, idp, idp->len,
3, motd, motd_len);
- goto out;
} else {
/* No motd */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
return FALSE;
}
-/* Fork server to background and set gid+uid to non-root.
- Silcd will not run as root, so trying to set either user or group to
- root will cause silcd to exit. */
+/* Fork server to background and set gid+uid to non-root */
void silc_server_daemonise(SilcServer server)
+{
+ int i;
+
+ i = fork ();
+
+ if (i) {
+ if (i > 0) {
+ if (geteuid())
+ SILC_LOG_DEBUG(("Server started as user"));
+ else
+ SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
+
+ SILC_LOG_DEBUG(("Forking SILC server to background"));
+ exit(0);
+ } else {
+ SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
+ exit(1);
+ }
+ }
+ setsid();
+}
+
+/* Drop root privligies. If this cannot be done, die. */
+
+void silc_server_drop(SilcServer server)
{
/* Are we executing silcd as root or a regular user? */
- if (geteuid()==0) {
-
+ if (!geteuid()) {
+
struct passwd *pw;
struct group *gr;
char *user, *group;
-
+
if (!server->config->identity || !server->config->identity->user ||
!server->config->identity->group) {
fprintf(stderr, "Error:"
"\tthe server as non-root user.\n");
exit(1);
}
-
+
/* Get the values given for user and group in configuration file */
user=server->config->identity->user;
group=server->config->identity->group;
-
+
/* Check whether the user/group information is text */
if (atoi(user)!=0 || atoi(group)!=0) {
SILC_LOG_DEBUG(("Invalid user and/or group information"));
fprintf(stderr, "Please assign them as names, not numbers\n");
exit(1);
}
-
+
/* Catch the nasty incident of string "0" returning 0 from atoi */
if (strcmp("0", user)==0 || strcmp("0", group)==0) {
SILC_LOG_DEBUG(("User and/or group configured to 0. Unacceptable"));
fprintf(stderr, "User and/or group configured to 0. Exiting\n");
exit(1);
}
-
+
pw=getpwnam(user);
gr=getgrnam(group);
fprintf(stderr, "No such group %s found\n", group);
exit(1);
}
-
+
/* Check whether user and/or group is set to root. If yes, exit
immediately. Otherwise, setgid and setuid server to user.group */
if (gr->gr_gid==0 || pw->pw_uid==0) {
"\tthe server as non-root user.\n");
exit(1);
} else {
- /* Fork server to background, making it a daemon */
- if (fork()) {
- SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
- SILC_LOG_DEBUG(("Forking SILC server to background"));
- exit(0);
- }
- setsid();
-
SILC_LOG_DEBUG(("Changing to group %s", group));
if(setgid(gr->gr_gid)==0) {
SILC_LOG_DEBUG(("Setgid to %s", group));
exit(1);
}
}
- } else {
- /* Fork server to background, making it a daemon */
- if (fork()) {
- SILC_LOG_DEBUG(("Server started as user"));
- SILC_LOG_DEBUG(("Forking SILC server to background"));
- exit(0);
- }
- setsid();
}
}
void silc_server_free(SilcServer server);
int silc_server_init(SilcServer server);
void silc_server_daemonise(SilcServer server);
+void silc_server_drop(SilcServer server);
void silc_server_run(SilcServer server);
void silc_server_stop(SilcServer server);
void silc_server_start_key_exchange(SilcServer server,
SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 },
{ "[motd]",
SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
+ { "[pid]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_PID, 1},
{ NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
};
silc_free(config->routers);
silc_free(config->denied);
silc_free(config->motd);
+ silc_free(config->pidfile);
silc_free(config);
}
}
checkmask |= (1L << pc->section->type);
break;
+ case SILC_CONFIG_SERVER_SECTION_TYPE_PID:
+
+ if (!config->pidfile)
+ config->pidfile = silc_calloc(1, sizeof(*config->pidfile));
+
+ ret = silc_config_get_token(line, &config->pidfile->pid_file);
+ if (ret < 0)
+ break;
+
+ check = TRUE;
+ checkmask |= (1L << pc->section->type);
+ break;
+
case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
default:
/* Error */
char *motd_file;
} SilcServerConfigSectionMotd;
+/* holds pid file */
+typedef struct {
+ char *pid_file;
+} SilcServerConfigSectionPid;
+
/*
SILC Server Config object.
SilcServerConfigSectionAdminConnection *admins;
SilcServerConfigSectionDenyConnection *denied;
SilcServerConfigSectionMotd *motd;
+ SilcServerConfigSectionPid *pidfile;
} SilcServerConfigObject;
typedef SilcServerConfigObject *SilcServerConfig;
SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION,
SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION,
SILC_CONFIG_SERVER_SECTION_TYPE_MOTD,
+ SILC_CONFIG_SERVER_SECTION_TYPE_PID,
} SilcServerConfigSectionType;
/* SILC Configuration Section structure. */
{ "config-file", 1, NULL, 'f' },
{ "debug", 1, NULL, 'd' },
{ "help", 0, NULL, 'h' },
+ { "foreground", 0, NULL, 'F' },
{ "version", 0, NULL,'V' },
/* Key management options */
\n\
Generic Options:\n\
-f --config-file=FILE Alternate configuration file\n\
- -d --debug=string Enable debugging (no daemon)\n\
+ -d --debug=string Enable debugging (Implies --foreground)\n\
-h --help Display this message\n\
+ -F --foreground Dont fork\n\
-V --version Display version\n\
\n\
Key Management Options:\n\
{
int ret;
int opt, option_index;
+ int foreground = FALSE;
char *config_file = NULL;
SilcServer silcd;
struct sigaction sa;
/* Parse command line arguments */
if (argc > 1) {
- while ((opt = getopt_long(argc, argv, "cf:d:hVC:",
+ while ((opt = getopt_long(argc, argv, "cf:d:hFVC:",
long_opts, &option_index)) != EOF) {
switch(opt)
{
case 'f':
config_file = strdup(optarg);
break;
+ case 'F':
+ foreground = TRUE;
+ break;
/*
* Key management options
sigemptyset(&sa.sa_mask);
sigaction(SIGPIPE, &sa, NULL);
- if (silc_debug == FALSE)
- /* Before running the server, fork to background and set
- both user and group no non-root */
+ if ((silc_debug == FALSE) && (foreground == FALSE))
+ /* Before running the server, fork to background. */
silc_server_daemonise(silcd);
/* Set /var/run/silcd.pid */
unlink(SILC_SERVER_PID_FILE);
memset(pid, 0, sizeof(pid));
snprintf(pid, sizeof(pid) - 1, "%d\n", getpid());
- silc_file_writefile(SILC_SERVER_PID_FILE, pid, strlen(pid));
+ if (silcd->config->pidfile && silcd->config->pidfile->pid_file) {
+ silc_file_writefile(silcd->config->pidfile->pid_file, pid, strlen(pid));
+ } else {
+ silc_file_writefile(SILC_SERVER_PID_FILE, pid, strlen(pid));
+ }
+ /* Drop root. */
+ silc_server_drop(silcd);
+
/* Run the server. When this returns the server has been stopped
and we will exit. */
silc_server_run(silcd);
/* Add it to the cache */
silc_idcache_add(conn->server_cache, server->server_name,
server->server_id, (void *)server, FALSE);
+
+ if (SILC_ID_SERVER_COMPARE(server_id, conn->remote_id))
+ goto out;
} else {
server = (SilcServerEntry)id_cache->context;
}
#include "silcincludes.h"
#ifdef HAVE_GETSID
-extern __pid_t getsid (__pid_t __pid);
+extern pid_t getsid (pid_t __pid);
#endif
#ifdef HAVE_GETPGID
-extern __pid_t getpgid (__pid_t __pid);
+extern pid_t getpgid (pid_t __pid);
#endif
#undef SILC_RNG_DEBUG