]> granicus.if.org Git - shadow/commitdiff
Add support for detecting busy subordinate user ids
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 22 Jan 2013 09:17:50 +0000 (01:17 -0800)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 5 Aug 2013 15:08:45 +0000 (10:08 -0500)
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
libmisc/user_busy.c

index 168f9d55b66ce8a3b77f47d24aa37cc3e7222f08..04cfc31991a3f4b0b2d5507fedc9858095f6cd35 100644 (file)
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <fcntl.h>
 #include "defines.h"
 #include "prototypes.h"
+#include "subordinateio.h"
 
 #ifdef __linux__
-static int check_status (const char *sname, uid_t uid);
+static int check_status (const char *name, const char *sname, uid_t uid);
 static int user_busy_processes (const char *name, uid_t uid);
 #else                          /* !__linux__ */
 static int user_busy_utmp (const char *name);
@@ -102,7 +104,7 @@ static int user_busy_utmp (const char *name)
 #endif                         /* !__linux__ */
 
 #ifdef __linux__
-static int check_status (const char *sname, uid_t uid)
+static int check_status (const char *name, const char *sname, uid_t uid)
 {
        /* 40: /proc/xxxxxxxxxx/task/xxxxxxxxxx/status + \0 */
        char status[40];
@@ -125,7 +127,10 @@ static int check_status (const char *sname, uid_t uid)
                                    &ruid, &euid, &suid) == 3) {
                                if (   (ruid == (unsigned long) uid)
                                    || (euid == (unsigned long) uid)
-                                   || (suid == (unsigned long) uid)) {
+                                   || (suid == (unsigned long) uid)
+                                   || have_sub_uids(name, ruid, 1)
+                                   || have_sub_uids(name, euid, 1)
+                                   || have_sub_uids(name, suid, 1)) {
                                        (void) fclose (sfile);
                                        return 1;
                                }
@@ -153,6 +158,8 @@ static int user_busy_processes (const char *name, uid_t uid)
        struct stat sbroot;
        struct stat sbroot_process;
 
+       sub_uid_open (O_RDONLY);
+
        proc = opendir ("/proc");
        if (proc == NULL) {
                perror ("opendir /proc");
@@ -196,7 +203,7 @@ static int user_busy_processes (const char *name, uid_t uid)
                        continue;
                }
 
-               if (check_status (tmp_d_name, uid) != 0) {
+               if (check_status (name, tmp_d_name, uid) != 0) {
                        (void) closedir (proc);
                        fprintf (stderr,
                                 _("%s: user %s is currently used by process %d\n"),
@@ -216,7 +223,7 @@ static int user_busy_processes (const char *name, uid_t uid)
                                if (tid == pid) {
                                        continue;
                                }
-                               if (check_status (task_path+6, uid) != 0) {
+                               if (check_status (name, task_path+6, uid) != 0) {
                                        (void) closedir (proc);
                                        fprintf (stderr,
                                                 _("%s: user %s is currently used by process %d\n"),
@@ -231,6 +238,7 @@ static int user_busy_processes (const char *name, uid_t uid)
        }
 
        (void) closedir (proc);
+       sub_uid_close();
        return 0;
 }
 #endif                         /* __linux__ */