1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | create_user_tree { user = $1 mkdir /user/$user mount --rbind / /user/$user mount --make-rslave /user/$user mount --make-rshared /user/$user #create a private mount. This is to facilitate pivot_root #to temporarily place the old root here before detaching the #entire old root tree. NOTE: pivot_root will not allow old root #to be placed under a shared mount. pushd /user/$user/ mkdir -p __my_private_mnt__ mount --bind __my_private_mnt__ __my_private_mnt__ mount --make-private __my_private_mnt__ popd } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | init_per_user_namespace { #start with a clean state by marking #all mounts as private. mount --make-rprivate / #create a unbindable mount called 'user' #and have all the users to bind the entire #system tree '/' under them. mkdir /user mount --bind /user /user mount --make-rshared / mount --make-unbindable /user foreach user in existing_user { create_user_tree $user } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #ifndef MNT_DETACH #define MNT_DETACH 0x0000002 #endif #ifndef MS_REC #define MS_REC 0x4000 #endif #ifndef MS_PRIVATE #define MS_PRIVATE 1<<18 /* Private */ #endif #define DIRNAMSZ 200 int handle_login(const char *user) { int ret = 0; struct stat statbuf; char dirnam[DIRNAMSZ], oldroot[DIRNAMSZ]; snprintf(dirnam, DIRNAMSZ, "/user/%s", user); ret = stat(dirnam, &statbuf); if (ret != 0 || !S_ISDIR(statbuf.st_mode)) return PAM_SUCCESS; ret = unshare(CLONE_NEWNS); if (ret) { mysyslog(LOG_ERR, "failed to unshare mounts for %s, error %d\n", user, errno); return PAM_SESSION_ERR; } ret = chdir(dirnam); if (ret) { mysyslog(LOG_ERR, "failed to unshare mounts for %s, error %d\n", user, errno); return PAM_SESSION_ERR; } snprintf(oldroot, DIRNAMSZ, "%s/__my_private_mnt__", dirnam); ret = pivot_root(dirnam, oldroot); if (ret) { mysyslog(LOG_ERR, "failed to pivot_root for %s, error %d\n", user, errno); mysyslog(LOG_ERR, "pivot_root was (%s,%s)\n", dirnam, oldroot); return PAM_SESSION_ERR; } ret = mount("", "/__my_private_mnt__", "dontcare", MS_REC|MS_PRIVATE, ""); if (ret) { mysyslog(LOG_ERR, "failed to mark /tmp private for %s, error %d\n", user, errno); return PAM_SESSION_ERR; } ret = umount2("/__my_private_mnt__", MNT_DETACH); if (ret) { mysyslog(LOG_ERR, "failed to umount old_root %s, error %d\n", user, ret); return PAM_SESSION_ERR; } return PAM_SUCCESS; } |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |