---
 examples/tty_conv.c       |  7 +++----
 libpam/pam_modutil_priv.c | 40 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/examples/tty_conv.c b/examples/tty_conv.c
index 59bbb3b3..0a7af97c 100644
--- a/examples/tty_conv.c
+++ b/examples/tty_conv.c
@@ -8,7 +8,6 @@
 #include <unistd.h>
 #include <termios.h>
 #include <security/pam_appl.h>
-#include <sys/ioctl.h>
 
 /***************************************
  * @brief echo off/on
@@ -18,7 +17,7 @@
 static void echoOff(int fd, int off)
 {
     struct termios tty;
-    if (ioctl(fd, TCGETA, &tty) < 0)
+    if (tcgetattr(fd, &tty) < 0)
     {
         fprintf(stderr, "TCGETA failed: %s\n", strerror(errno));
         return;
@@ -27,7 +26,7 @@ static void echoOff(int fd, int off)
     if (off)
     {
         tty.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
-        if (ioctl(fd, TCSETAF, &tty) < 0)
+        if (tcsetattr(fd, TCSAFLUSH, &tty) < 0)
         {
             fprintf(stderr, "TCSETAF failed: %s\n", strerror(errno));
         }
@@ -35,7 +34,7 @@ static void echoOff(int fd, int off)
     else
     {
         tty.c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
-        if (ioctl(fd, TCSETAW, &tty) < 0)
+        if (tcsetattr(fd, TCSADRAIN, &tty) < 0)
         {
             fprintf(stderr, "TCSETAW failed: %s\n", strerror(errno));
         }
diff --git a/libpam/pam_modutil_priv.c b/libpam/pam_modutil_priv.c
index a463e06a..7df6e6b1 100644
--- a/libpam/pam_modutil_priv.c
+++ b/libpam/pam_modutil_priv.c
@@ -14,7 +14,9 @@
 #include <syslog.h>
 #include <pwd.h>
 #include <grp.h>
+#ifdef HAVE_SYS_FSUID_H
 #include <sys/fsuid.h>
+#endif /* HAVE_SYS_FSUID_H */
 
 /*
  * Two setfsuid() calls in a row are necessary to check
@@ -22,17 +24,55 @@
  */
 static int change_uid(uid_t uid, uid_t *save)
 {
+#ifdef HAVE_SYS_FSUID_H
        uid_t tmp = setfsuid(uid);
        if (save)
                *save = tmp;
        return (uid_t) setfsuid(uid) == uid ? 0 : -1;
+#else
+       uid_t euid = geteuid();
+       uid_t ruid = getuid();
+       if (save)
+               *save = ruid;
+       if (ruid == uid && uid != 0)
+               if (setreuid(euid, uid))
+                       return -1;
+       else {
+               setreuid(0, -1);
+               if (setreuid(-1, uid)) {
+                       setreuid(-1, 0);
+                       setreuid(0, -1);
+                       if (setreuid(-1, uid))
+                               return -1;
+               }
+       }
+#endif
 }
 static int change_gid(gid_t gid, gid_t *save)
 {
+#ifdef HAVE_SYS_FSUID_H
        gid_t tmp = setfsgid(gid);
        if (save)
                *save = tmp;
        return (gid_t) setfsgid(gid) == gid ? 0 : -1;
+#else
+       gid_t egid = getegid();
+       gid_t rgid = getgid();
+       if (save)
+               *save = rgid;
+       if (rgid == gid)
+               if (setregid(egid, gid))
+                       return -1;
+       else {
+               setregid(0, -1);
+               if (setregid(-1, gid)) {
+                       setregid(-1, 0);
+                       setregid(0, -1);
+                       if (setregid(-1, gid))
+                               return -1;
+               }
+       }
+#endif
 }
 
 static int cleanup(struct pam_modutil_privs *p)
-- 
Yuqian Yang <crup...@crupest.life>

Reply via email to