1 #define PRELUDE_LML_USER "@PRELUDE_USER@"
2 #define PRELUDE_LML_PATH "@PREFIX@/bin/prelude-lml"
23 void error_sys(char *str
)
26 /* Output error message to syslog */
28 snprintf(msg
, sizeof(msg
), "run-prelude-lml : %s : %s", str
, strerror(errno
));
29 syslog(LOG_ALERT
, msg
);
34 int obtainUIDandGID(const char *name
, uid_t
*pw_uid
, gid_t
*pw_gid
)
36 /* Obtain UID and GID from passwd entry identified by name */
37 struct passwd
*pw_entry
;
40 if ((pw_entry
= getpwnam(name
)) == NULL
)
42 snprintf(msg
, sizeof(msg
), "failed to get password entry for %s", name
);
48 *pw_uid
= pw_entry
->pw_uid
;
49 *pw_gid
= pw_entry
->pw_gid
;
56 int main (int argc
, char **argv
)
71 error_sys("arg buffer too small");
77 error_sys("must be called by root");
81 /* fork child that will become prelude-lml */
82 if ((pid
= fork()) < 0)
84 error_sys("fork error");
98 /* Become session leader */
101 /* Change working directory to root directory.
102 The current working directory could be a mounted
103 filesystem; if the daemon stays on a mounted
104 filesystem it could prevent the filesystem from
108 /* Clear out file creation mask */
111 /* Close unneeded file descriptors */
112 max_fd
= (int) sysconf(_SC_OPEN_MAX
);
114 max_fd
= getdtablesize();
115 for (s
= 3; s
< max_fd
; s
++)
118 if (!obtainUIDandGID(PRELUDE_LML_USER
, &UID
, &GID
))
121 /* Drop privileges immediately */
124 /* It is VERY important to check return
125 value and not continue if setgid fails
127 error_sys ("setgid failed");
133 /* It is VERY important to check return
134 value and not continue if setuid fails
136 error_sys ("setuid failed");
140 /* Build calling argv */
141 args
[0] = PRELUDE_LML_PATH
;
148 /* Finally transform self into prelude-lml */
149 if (execvp(PRELUDE_LML_PATH
, args
) < 0)
150 error_sys("execve error");
152 ; /* avoid if-then ambiguity */