sudo useradd yuadi
sudo useradd irwandi
sudo mkdir shared_files
sudo mkdir public
sudo mkdir private_yuadi
sudo mkdir private_irwandi
sudo passwd yuadi
sudo passwd irwandi
cd public
sudo nano materi_kuliah.txt
cd private_yuadi
sudo nano tugas_yuadi.txt
cd private_irwandi
sudo nano tugas_irwandi.txt
sudo: menggunakan hak akses super user
useradd: menambahkan user yuadi dan irwandi untuk mengakses file system
mkdir: membuat direktori untuk sumber file
passwd: membuat password untuk yuadi dan irwandi
cd: masuk ke masing masing direktori untuk menambahkan file
nano: membuat dan mengisi file di nano
sudo mkdir -p /mnt/secure_fs
mkdir: membuat direktori yang akan digunakan sebagai mount point -p: membuat jika tidak ada direktori dibuat di root
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
library dari template github
const char *source_dir = "/home/shared_files";
static char fullpath[4096];
void build_full_path(char *buf, const char *path) {
snprintf(buf, sizeof(fullpath), "%s%s", source_dir, path);
}
const char *: pointer ke path, menggunakan const karena isi tidak boleh diubah source_dir: string yang menyimpan path sumber Static char fullpath: buffer global untuk menyimpan path void build_full_path: fungsi untk membuat path penuh di file host snprintf: menyusun string path
static int fs_mkdir(const char *path, mode_t mode); i
static int fs_rmdir(const char *path);
static int fs_unlink(const char *path);
static int fs_rename(const char *from, const char *to);
static int fs_chmod(const char *path, mode_t mode);
static int fs_chown(const char *path, uid_t uid, gid_t gid);
static int fs_create(const char *path, mode_t mode, struct fuse_file_info *fi);
static int fs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
static int fs_truncate(const char *path, off_t size);
static int fs_utimens(const char *path, const struct timespec ts[2]);
inisialisasi fungsi FUSE
static struct fuse_operations fs_oper = {
.getattr = fs_getattr,
.readdir = fs_readdir,
.open = fs_open,
.read = fs_read,
.mkdir = fs_mkdir,
.rmdir = fs_rmdir,
.unlink = fs_unlink,
.rename = fs_rename,
.chmod = fs_chmod,
.chown = fs_chown,
.create = fs_create,
.write = fs_write,
.truncate = fs_truncate,
.utimens = fs_utimens,
};
Mapping fungsi ke FUSE
static int fs_mkdir(const char *path, mode_t mode) { return -EROFS; }
static int fs_rmdir(const char *path) { return -EROFS; }
static int fs_unlink(const char *path) { return -EROFS; }
static int fs_rename(const char *from, const char *to) { return -EROFS; }
static int fs_chmod(const char *path, mode_t mode) { return -EROFS; }
static int fs_chown(const char *path, uid_t uid, gid_t gid) { return -EROFS; }
static int fs_create(const char *path, mode_t mode, struct fuse_file_info *fi) { return -EROFS; }
static int fs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { return -EROFS; }
static int fs_truncate(const char *path, off_t size) { return -EROFS; }
static int fs_utimens(const char *path, const struct timespec ts[2]) { return -EROFS; }
mematikan fungsi membuat dan menghapus direktori dan file, mengubah kepemilikan direktori, mengubah isi file,
int is_private_denied(const char *path, uid_t uid) {
struct passwd *pw = getpwuid(uid);
if (!pw) return 1;
if (strncmp(path, "/private_yuadi/", 15) == 0 && strcmp(pw->pw_name, "yuadi") != 0)
return 1;
if (strncmp(path, "/private_irwandi/", 17) == 0 && strcmp(pw->pw_name, "irwandi") != 0)
return 1;
return 0;
}
Fungsi untuk memastikan privasi folder jika fungsi bernilai 1 maka akses ke dalam folder tidak diperbolehkan menggunakan getpwuid untuk mendapatkan nformasi user berdasarkan UID, jika tidak ditemukan maka dan akses tidak diperbolehkan Fungsi mengecek menggunakan strcmp untuk mendeteksi user dan folder yang ingin dibuka Fungsi mengambil path untuk folder private_yuadi dan private_irwandi dari path yang sudah dibuat menggunakan fungsi build_full_path, jika salah satu dari user atau path tidak sesuai maka akses tidak diperbolehkan
static int fs_getattr(const char *path, struct stat *stbuf) {
int res;
build_full_path(fullpath, path);
res = lstat(fullpath, stbuf);
if (res == -1) return -errno;
return 0;
}
fungsi untuk mendapatkan atribut file atau direktori seperti ketika menggunakan fungsi [ls -l] dipanggil ketika meminta informasi tentang path struct stat *stbuf: struct buffer untuk menyimpan informasi tentang path build_full_path menggabungkan path dari source ke path dari fuse lalu menyimpan hasil di variabel global fullpath menggunakan lstat untuk mendapatkan atribut file atau direktori lalu menyimpan atribut ke stbuf jika lstat gagal maka akan akan mengembalikan kode error
static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) {
DIR *dp;
struct dirent *de;
(void) offset;
(void) fi;
build_full_path(fullpath, path);
dp = opendir(fullpath);
if (dp == NULL) return -errno;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
while ((de = readdir(dp)) != NULL) {
struct stat st = {0};
st.st_ino = de->d_ino;
st.st_mode = de->d_type << 12;
filler(buf, de->d_name, &st, 0);
}
closedir(dp);
return 0;
}
fungsi untuk menampilkan isi direktori menyimpan informasi file kedalam buf menggunakan fungsi filler untuk menambahkan nama file kedalam buffer DIR *dp merupakan pointer ke direktori dirent *de merupakan pointer ke strukter dirent untuk menyimpan satu entry dalam direktori offset dan fi di set ke void untuk menghindari peringatan kompilasi dari parameter yang tidak dipakai build_full_path menggabungkan path dari source ke path dari fuse lalu menyimpan hasil di variabel global fullpath membuka direktori fullpath dengan opendir jika file atau direktori tidak ada maka mengembalikan kode error tambahkan entri . (diri sendiri) dan .. (parent directory) dengan fungsi filler agar navigasi direktori tetap berfungsi normal
static int fs_open(const char *path, struct fuse_file_info *fi) {
build_full_path(fullpath, path);
if ((fi->flags & O_ACCMODE) != O_RDONLY) return -EROFS;
if (is_private_denied(path, fuse_get_context()->uid)) return -EACCES;
int res = open(fullpath, O_RDONLY);
if (res == -1) return -errno;
close(res);
return 0;
}
static int fs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
int fd;
int res;
if (is_private_denied(path, fuse_get_context()->uid)) return -EACCES;
build_full_path(fullpath, path);
fd = open(fullpath, O_RDONLY);
if (fd == -1) return -errno;
res = pread(fd, buf, size, offset);
if (res == -1) res = -errno;
close(fd);
return res;
}
Menyusun path absolut (fullpath) dari path relatif (path) yang diberikan oleh FUSE. Biasanya ini menggabungkan direktori root asli dengan path FUSE. Mengecek apakah mode akses bukan read-only (O_RDONLY). Jika ada permintaan untuk write atau read-write, dikembalikan error: -EROFS (read-only filesystem). Mengecek apakah user tidak punya izin akses (misal ke folder/file private_user tertentu). fuse_get_context()->uid memberikan ID user yang sedang mengakses. Jika tidak diizinkan, kembalikan -EACCES (Permission Denied). Mencoba membuka file secara read-only. Kalau gagal, return error sesuai kode errno (misal file tidak ditemukan, permission denied, dll). File ditutup langsung karena tujuan open() ini hanya untuk validasi. Kembalikan 0 menandakan sukses. pastikan user diizinkan mengakses file. Susun path absolut file sebenarnya dari path FUSE. Buka file dalam mode read-only. Jika gagal membuka file, return error. Membaca size byte dari file, dimulai dari posisi offset, dan menyimpannya di buf. pread digunakan agar thread-safe (tidak mengubah file pointer seperti read). Jika pembacaan gagal, simpan error code. tutp
int main(int argc, char *argv[]) {
umask(0);
return fuse_main(argc, argv, &fs_oper, NULL);
}
Menonaktifkan pembatasan permission default dari sistem saat membuat file atau folder. Ini penting agar permission bisa diatur penuh oleh FUSE. fuse_main(...) Fungsi utama dari FUSE untuk menjalankan filesystem. fs_oper adalah struktur yang berisi pointer ke fungsi-fungsi operasi file seperti fs_open, fs_read, dll.