summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-01-09 20:48:55 +0000
committerLennart Poettering <lennart@poettering.net>2004-01-09 20:48:55 +0000
commit2104b80446dfd4bbc26d0d75691de4b4603a30f5 (patch)
tree0a61fba135c5264fac0bfcd7b0610f34b808b674
parentd6448c882c4b3ebe11d2223ad52d98fb0c5a8396 (diff)
implemented user id switching
some locking fixups git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@24 dbf6933d-3bce-0310-9bcc-ed052ba35b35
-rw-r--r--conf/msntab2
-rw-r--r--doc/TODO17
-rw-r--r--src/ivamd.ggo1
-rw-r--r--src/lock.c22
-rw-r--r--src/main.c78
-rw-r--r--src/main.h5
6 files changed, 112 insertions, 13 deletions
diff --git a/conf/msntab b/conf/msntab
index 251e906..16d8e5e 100644
--- a/conf/msntab
+++ b/conf/msntab
@@ -1,6 +1,6 @@
# local MSN remote MSN options action
-41264179 * rings=0,pipehack ivam-autobox
+#41264179 * rings=0,pipehack ivam-autobox
#41264179 41264177 rings=0 ivam-dialup --pin=4711 ppp0
#* 41264179 rings=0 @hangup
diff --git a/doc/TODO b/doc/TODO
index 97e6c8f..c9aad71 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,13 +1,20 @@
+post 1.0:
+
* implement shbuf support
-* uid switching support
-* autoconf
-* documentation
+* uid switching for each client
* regexp support
* @same support
-* uid switching for each client
+
+pre 1.0:
+
+* autoconf
+* documentation
* init script
-* mail on successful mailbox creation in ivam-autobox
+done:
+
+* uid switching support (DONE)
+* mail on successful mailbox creation in ivam-autobox (DONE)
* --no-record --record-only (for voicebox) (DONE)
* make it a daemon (DONE)
* newmessage script (DONE)
diff --git a/src/ivamd.ggo b/src/ivamd.ggo
index 67e6f7e..ca280a4 100644
--- a/src/ivamd.ggo
+++ b/src/ivamd.ggo
@@ -27,3 +27,4 @@ option "check" c "Check if the daemon is currently running" flag off
option "channels" C "Specify how many channels to allocate, defaults to 2" int default="2" no
option "msntab" T "Specify non standard msntab file" string no
option "listen" L "Specify a glob pattern matchin the MSNs to listen on" string no
+option "no-drop-root" - "Do not drop root priviliges" flag off
diff --git a/src/lock.c b/src/lock.c
index 42ad213..efce0bb 100644
--- a/src/lock.c
+++ b/src/lock.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
+#include <pwd.h>
#include <libdaemon/dlog.h>
@@ -35,6 +36,7 @@ int device_lock(const char *dev) {
int fd;
const char *path, *temp;
char buf[100];
+ char uidbuf[32];
if (stat(LOCK_PATH, &st) != 0 || !S_ISDIR(st.st_mode)) {
daemon_log(LOG_ERR, "Failed to lock device, directory "LOCK_PATH" not existent.");
@@ -45,6 +47,9 @@ int device_lock(const char *dev) {
temp = tempfile(path);
for (;;) {
+ mode_t u;
+ struct passwd* pw;
+ char *username;
if ((fd = open(path, O_RDONLY)) < 0) {
if (errno != ENOENT) {
@@ -87,18 +92,33 @@ int device_lock(const char *dev) {
}
}
}
+
+ u = umask(0033);
+ fd = open(temp, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ umask(u);
- if ((fd = open(temp, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0) {
+ if (fd < 0) {
daemon_log(LOG_ERR, "Failed to create temporary lock file: %s", strerror(errno));
return -1;
}
+ if ((pw = getpwuid(target_uid)))
+ username = pw->pw_name;
+ else
+ snprintf(username = uidbuf, sizeof(uidbuf), "%lu", (unsigned long) target_uid);
+
snprintf(buf, sizeof(buf), "%10lu %s %.20s\n", (unsigned long) getpid(), appname, username);
if (loop_write(fd, buf, strlen(buf)) < 0) {
daemon_log(LOG_ERR, "Failed to write to temporary lock file: %s", strerror(errno));
close(fd);
return -1;
}
+
+ if (fchown(fd, target_uid, target_gid) < 0) {
+ daemon_log(LOG_ERR, "Failed to change owners of temporary lock file: %s", strerror(errno));
+ close(fd);
+ return -1;
+ }
close(fd);
diff --git a/src/main.c b/src/main.c
index 204fc69..53f8e80 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,6 +2,9 @@
#include <assert.h>
#include <string.h>
#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/types.h>
#include <libdaemon/dlog.h>
#include <libdaemon/dfork.h>
@@ -15,9 +18,14 @@
oop_source* event_source = NULL;
struct gengetopt_args_info args;
-const char *appname = NULL, *username = NULL;
+const char *appname = NULL;
+
+uid_t target_uid = 0;
+gid_t target_gid = 0;
#define DEFAULT_MSNTABLE "../conf/msntab"
+#define IVAM_USER "ivam"
+#define IVAM_GROUP "ivam"
static void *oop_exit_cb(oop_source *source, int sig, void *user) {
daemon_log(LOG_ERR, "Recieved signal %s", sig == SIGINT ? "SIGINT" : (sig == SIGTERM ? "SIGTERM" : "UNKNWON"));
@@ -42,11 +50,66 @@ static void *oop_dump_cb(oop_source *source, int sig, void *user) {
}
+static int change_uid_gid(void) {
+ if (args.no_drop_root_flag)
+ return 0;
+
+ if (initgroups(IVAM_USER, target_gid) != 0) {
+ daemon_log(LOG_ERR, "Failed to change group list: %s", strerror(errno));
+ return -1;
+ }
+
+ if (setgid(target_gid) != 0) {
+ daemon_log(LOG_ERR, "Failed to change GID: %s", strerror(errno));
+ return -1;
+ }
+
+ if (setuid(target_uid) != 0) {
+ daemon_log(LOG_ERR, "Failed to change UID: %s", strerror(errno));
+ return -1;
+ }
+
+ daemon_log(LOG_INFO, "Successfully dropped root privileges.");
+
+ return 0;
+}
+
+static int get_target_uid_gid(void) {
+ struct passwd *pw;
+ struct group * gr;
+
+ if (args.no_drop_root_flag) {
+ target_uid = getuid();
+ target_gid = getgid();
+ return 0;
+ }
+
+ if (!(pw = getpwnam(IVAM_USER))) {
+ daemon_log(LOG_ERR, "Failed to find user '%s'.", IVAM_USER);
+ return -1;
+ }
+
+ if (!(gr = getgrnam(IVAM_GROUP))) {
+ daemon_log(LOG_ERR, "Failed to find group '%s'.", IVAM_GROUP);
+ return -1;
+ }
+
+ target_uid = pw->pw_uid;
+ target_gid = gr->gr_gid;
+
+ daemon_log(LOG_INFO, "Found user '%s' (UID %lu) and group '%s' (GID %lu).", IVAM_USER, (unsigned long) target_uid, IVAM_GROUP, (unsigned long) target_gid);
+
+ return 0;
+}
+
int main_loop(void) {
int r = -1, retval_sent = 0;
oop_source_sys *sys = NULL;
daemon_log(LOG_INFO, "Starting up.");
+
+ if (get_target_uid_gid() < 0)
+ goto finish;
if (!(sys = oop_sys_new())) {
daemon_log(LOG_ERR, "Failed to create system source.");
@@ -55,6 +118,12 @@ int main_loop(void) {
event_source = oop_sys_source(sys);
assert(event_source);
+
+ if (modem_manager_init(args.channels_arg) < 0)
+ goto finish;
+
+ if (change_uid_gid() < 0)
+ goto finish;
if (child_process_init() < 0)
goto finish;
@@ -62,9 +131,6 @@ int main_loop(void) {
if (msntab_load(args.msntab_arg ? args.msntab_arg : DEFAULT_MSNTABLE) < 0)
goto finish;
- if (modem_manager_init(args.channels_arg) < 0)
- goto finish;
-
event_source->on_signal(event_source, SIGINT, oop_exit_cb, NULL);
event_source->on_signal(event_source, SIGTERM, oop_exit_cb, NULL);
event_source->on_signal(event_source, SIGHUP, oop_reload_cb, NULL);
@@ -177,7 +243,9 @@ int main(int argc, char*argv[]) {
ret = main_loop() < 0 ? 1 : 0;
- daemon_pid_file_remove();
+ if (daemon_pid_file_remove() < 0)
+ daemon_log(LOG_WARNING, "Failed to remove PID file (%s).", strerror(errno));
+
return ret;
}
diff --git a/src/main.h b/src/main.h
index c23d87d..6ceb7f2 100644
--- a/src/main.h
+++ b/src/main.h
@@ -7,8 +7,11 @@
extern oop_source* event_source;
-extern const char *appname, *username;
+extern const char *appname;
extern struct gengetopt_args_info args;
+extern uid_t target_uid;
+extern gid_t target_gid;
+
#endif