AC_CHECK_HEADERS([utempter.h utmpx.h])
if test "x$ac_cv_header_utempter_h" = xyes; then
+ AC_CHECK_FUNCS([setresuid setresgid],[],
+ [AC_MSG_ERROR([setresuid() and setresgid() required for utmpx])])
+
AC_MSG_NOTICE([using utempter])
AC_CHECK_LIB([utempter], [utempter_add_record],
[], [AC_MSG_ERROR([utempter_add_record() required])])
AC_CHECK_LIB([utempter], [utempter_remove_record],
[], [AC_MSG_ERROR([utempter_remove_record() required])])
AC_DEFINE([USE_UTEMPTER], 1, [Define to 1 to use utempter.])
+
elif test "x$ac_cv_header_utmpx_h" = xyes; then
AC_MSG_NOTICE([using utmp])
AC_DEFINE([USE_UTMPX], 1, [Define to 1 to use utmp.])
return 1;
}
+#ifdef USE_UTMPX
+static void drop_privileges(void) {
+ uid_t uid, ruid, euid, suid;
+ gid_t gid, rgid, egid, sgid;
+
+ uid = getuid();
+ gid = getgid();
+
+ /* Drop all privileges. */
+ if (setresuid(uid, uid, uid) != 0) {
+ perror("setresuid");
+ exit(EXIT_FAILURE);
+ }
+ if (setresgid(gid, gid, gid) != 0) {
+ perror("setresgid");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Verify all privileges were dropped. */
+ if (getresuid(&ruid, &euid, &suid) != 0) {
+ perror("getresuid");
+ exit(EXIT_FAILURE);
+ }
+ if (getresgid(&rgid, &egid, &sgid) != 0) {
+ perror("getresgid");
+ exit(EXIT_FAILURE);
+ }
+ if (uid == ruid && uid == euid && uid == suid
+ && gid == rgid && gid == egid && gid == sgid) {
+ /* Everything fine. */
+ return;
+ }
+
+ fprintf(stderr, "failed to drop privileges, aborting\n");
+ exit(EXIT_FAILURE);
+}
+#endif
+
static void pass_buffer_to_program(const char *buffer, size_t length, char **argv) {
int fds[2];
FILE *fh;
} else if (pid == 0) {
/* child */
+#ifdef USE_UTMPX
+ drop_privileges();
+#endif
+
close(fds[1]); /* write side */
/* Pass read side as stdin to the program. */