İçeriğe geç
academia.sh

Ders 04 / 11

Dosya İzinleri ve Sahiplik

Aynı 70 erişim isteğinin iki izin modelinde koşturulması: izin bitleri modelinin gevşek ifadesinin 6 fazla izin, sıkı ifadesinin 6 fazla ret üretmesi, iki ifadenin birbirinden 12 istekte ayrılması, erişim denetim listesinin politikayı tam ifade etmesi ama girdi sırası değiştiğinde 6 isteğin sonucunun dönmesi ve sahipliğin iki modelin de dışında kalması.

İçindekiler

Önceki ders temiz kurulumun bıraktığı 17 riskli kalemi saydı ve birkaçının doğrudan izin düzenini ayarladığını belirtti. Kurulum bittiğinde makinede bir izin düzeni vardır: hesaplar, gruplar ve nesnelerin kimin neyine açık olduğu.

Bu ders o düzenin içine iner. İzin bitlerinin mekaniği — üç sınıf, üç erişim türü, sekizlik gösterim, sınıf seçiminin dışlayıcılığı — Linux’a Giriş kursunda kurulmuştu ve burada tekrarlanmaz. Buradaki soru başkadır: aynı politika iki ayrı izin modelinde ifade edildiğinde kaç istekte farklı sonuç çıkar ve hangi model hangi isteği hiç ifade edemez.

Ölçülen Şey Mekanik Değil, İfade Gücü

Bir izin modeli iki işi birden yapar. Birincisi bir erişim isteğine yanıt vermektir; bu, mekaniktir ve öğrenilir. İkincisi, kurumun aklındaki politikayı taşıyabilmektir; bu, modelin ifade gücüdür ve sınırlıdır.

İki iş karıştırıldığında ölçüm kaybolur. “İzinler doğru ayarlandı” cümlesi mekanik iştir. Karar taşıyan cümle şudur: bu politika bu modelde tam olarak ifade edilebiliyor mu, edilemiyorsa en yakın ifadenin bedeli kaç istektir ve bu bedel hangi yöne düşer — fazladan verilen izne mi, fazladan yapılan reddin engellediği meşru işe mi.

Politika, İki Model ve 70 İstek

Örnek, kurgu bölgesel ölçüm ağının şube sunucusundaki beş dosyasıdır. Özneler, dosyalar ve politika kurgudur; aşağıdaki değerlendirme bir modeldir, gerçek bir sistem ya da ürün yoktur.

DI17: yedi özne, beş nesne ve iki işlem 70 istek üretir; niyet, politikanın istediği sonuçtur. DI18: izin bitleri modeli üç sınıf taşır ve sınıf seçimi dışlayıcıdır. DI19: her nesne için grup, sapması en az olan grup seçilir; modele en iyi şans verilir. DI20: iki ifade stratejisi denenir — gevsek, diğerleri sınıfına dışarıdaki ihtiyaçların birleşimini verir; siki, diğerleri sınıfını boş bırakır. DI21: erişim denetim listesi modelinde ilk eşleşen girdi karar verir; liste yazıldığı sırayla ve ters sırayla değerlendirilir. DI22: sapma iki yönlü sayılır — fazla izin ve fazla ret ayrı sütunlardır.

// bt/izin.mjs — ayni erisim istegi kumesinin iki izin modelindeki sonucu (model): kurgu olcum
// aginin dosyalari, gercek bir sistem ya da urun yok. Rastgelelik yok.

export const OZNE = { "saha-teknisyeni": "saha", "sube-yoneticisi": "sube",
  "toplayici-servis": "servis", "faturalama-servisi": "servis", "veri-analisti": "analiz",
  "denetci": "denetim", "misafir-cihaz": "misafir" };
export const GRUP = [...new Set(Object.values(OZNE))];
export const ISLEM = ["r", "w"];

// niyet: politikanin istedigi erisim. acl: yoneticinin yazdigi liste (ret girdileri once).
export const NESNE = [
  { ad: "okuma-ham", sahip: "toplayici-servis",
    niyet: { "toplayici-servis": "rw", "saha-teknisyeni": "r", "sube-yoneticisi": "r",
      "veri-analisti": "r", "denetci": "r" },
    acl: [["ret", "faturalama-servisi", "rw"], ["izin", "servis", "rw"], ["izin", "saha", "r"],
      ["izin", "sube", "r"], ["izin", "analiz", "r"], ["izin", "denetim", "r"]] },
  { ad: "okuma-dogrulanmis", sahip: "veri-analisti",
    niyet: { "veri-analisti": "rw", "faturalama-servisi": "r", "sube-yoneticisi": "r",
      "denetci": "r" },
    acl: [["ret", "toplayici-servis", "rw"], ["izin", "servis", "r"], ["izin", "analiz", "rw"],
      ["izin", "sube", "r"], ["izin", "denetim", "r"]] },
  { ad: "fatura-taslak", sahip: "faturalama-servisi",
    niyet: { "faturalama-servisi": "rw", "sube-yoneticisi": "r", "denetci": "r" },
    acl: [["ret", "toplayici-servis", "rw"], ["izin", "servis", "rw"], ["izin", "sube", "r"],
      ["izin", "denetim", "r"]] },
  { ad: "anahtar-dosyasi", sahip: "toplayici-servis",
    niyet: { "toplayici-servis": "r" },
    acl: [["ret", "faturalama-servisi", "rw"], ["izin", "servis", "r"]] },
  { ad: "denetim-gunlugu", sahip: "denetci",
    niyet: { "denetci": "r", "toplayici-servis": "w", "faturalama-servisi": "w" },
    acl: [["izin", "servis", "w"], ["izin", "denetim", "r"]] },
];

export const ISTEK = Object.keys(OZNE).flatMap((o) =>
  NESNE.flatMap((n) => ISLEM.map((i) => ({ o, n, i }))));
export const niyet = (n, o, i) => (n.niyet[o] || "").includes(i);

// Izin bitleri modeli: uc sinif, sinif secimi dislayicidir (M03/K01'de kurulmustur).
const birlestir = (n, kim) => kim.filter((o) => o !== n.sahip)
  .map((o) => n.niyet[o] || "").join("");
export function bitler(n, grup, gevsek) {
  const uye = Object.keys(OZNE).filter((o) => OZNE[o] === grup);
  const dis = Object.keys(OZNE).filter((o) => OZNE[o] !== grup && o !== n.sahip);
  return { grup, sahip: n.niyet[n.sahip] || "", g: birlestir(n, uye),
    d: gevsek ? birlestir(n, dis) : "" };
}
export const bitSonuc = (b, n, o, i) =>
  (o === n.sahip ? b.sahip : OZNE[o] === b.grup ? b.g : b.d).includes(i);

// En iyi grup secimi: sapmasi en az olan grup. Sapma = fazla izin + fazla ret.
export function enIyi(n, gevsek) {
  return GRUP.map((g) => bitler(n, g, gevsek))
    .map((b) => ({ b, ...sapma((o, i) => bitSonuc(b, n, o, i), [n]) }))
    .reduce((a, x) => (x.fazlaIzin + x.fazlaRet < a.fazlaIzin + a.fazlaRet ? x : a));
}

// Erisim denetim listesi modeli: ilk eslesen girdi karar verir.
export const aclSonuc = (n, o, i, tersSira) => {
  const l = tersSira ? [...n.acl].reverse() : n.acl;
  const g = l.find(([, kim, ops]) => (kim === o || kim === OZNE[o]) && ops.includes(i));
  return g ? g[0] === "izin" : false;
};

export function sapma(f, nesneler = NESNE) {
  const k = ISTEK.filter((x) => nesneler.includes(x.n));
  return { fazlaIzin: k.filter((x) => f(x.o, x.i, x.n) && !niyet(x.n, x.o, x.i)).length,
    fazlaRet: k.filter((x) => !f(x.o, x.i, x.n) && niyet(x.n, x.o, x.i)).length };
}
// bt/izinolc.mjs — ayni istek kumesi iki izin modelinde: kac istekte fark, kac istek ifade edilemiyor.
import { OZNE, NESNE, ISTEK, niyet, bitSonuc, enIyi, aclSonuc, sapma } from "./izin.mjs";

const yaz = (g, ...s) => console.log(s.map((v, i) =>
  (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));

const B = { gevsek: {}, siki: {} };
for (const n of NESNE) for (const s of ["gevsek", "siki"]) B[s][n.ad] = enIyi(n, s === "gevsek").b;
const bitF = (s) => (o, i, n) => bitSonuc(B[s][n.ad], n, o, i);
const MODEL = [["izin-bitleri (gevsek)", bitF("gevsek")], ["izin-bitleri (siki)", bitF("siki")],
  ["erisim-listesi (ret once)", (o, i, n) => aclSonuc(n, o, i, false)],
  ["erisim-listesi (izin once)", (o, i, n) => aclSonuc(n, o, i, true)]];

const izinli = ISTEK.filter((x) => niyet(x.n, x.o, x.i)).length;
console.log(`${Object.keys(OZNE).length} ozne x ${NESNE.length} nesne x 2 islem = ` +
  `${ISTEK.length} istek; niyette izinli olan ${izinli}, reddedilen ${ISTEK.length - izinli}`);

const A = [-28, 12, 11, 14];
console.log("\n1. her model niyetten ne kadar sapiyor");
yaz(A, "model", "fazla izin", "fazla ret", "niyetle ayni");
for (const [ad, f] of MODEL) {
  const s = sapma(f);
  yaz(A, ad, s.fazlaIzin, s.fazlaRet, ISTEK.length - s.fazlaIzin - s.fazlaRet);
}

const C = [-20, -14, -12, 12, 11];
console.log("\n2. izin bitleri modelinde nesne basina artik (en iyi grup secimiyle)");
yaz(C, "nesne", "gevsek grup", "siki grup", "fazla izin", "fazla ret");
for (const n of NESNE) {
  const g = enIyi(n, true);
  const s = enIyi(n, false);
  yaz(C, n.ad, g.b.grup, s.b.grup, g.fazlaIzin, s.fazlaRet);
}

const D = [-56, 10];
console.log("\n3. modeller arasi fark (kac istekte sonuc farkli)");
yaz(D, "cift", "farkli");
for (let x = 0; x < MODEL.length; x++)
  for (let y = x + 1; y < MODEL.length; y++)
    yaz(D, `${MODEL[x][0]} / ${MODEL[y][0]}`,
      ISTEK.filter((r) => MODEL[x][1](r.o, r.i, r.n) !== MODEL[y][1](r.o, r.i, r.n)).length);

const E = [-24, 14, 14];
console.log("\n4. fazladan erisim kime gidiyor");
yaz(E, "ozne", "gevsek bitler", "izin once acl");
for (const o of Object.keys(OZNE)) {
  const f = (g) => ISTEK.filter((x) => x.o === o && g(x.o, x.i, x.n) && !niyet(x.n, x.o, x.i)).length;
  const a = f(bitF("gevsek"));
  const b = f((oz, i, n) => aclSonuc(n, oz, i, true));
  if (a || b) yaz(E, o, a, b);
}
7 ozne x 5 nesne x 2 islem = 70 istek; niyette izinli olan 19, reddedilen 51

1. her model niyetten ne kadar sapiyor
model                         fazla izin  fazla ret  niyetle ayni
izin-bitleri (gevsek)                  6          0            64
izin-bitleri (siki)                    0          6            64
erisim-listesi (ret once)              0          0            70
erisim-listesi (izin once)             6          0            64

2. izin bitleri modelinde nesne basina artik (en iyi grup secimiyle)
nesne               gevsek grup   siki grup     fazla izin  fazla ret
okuma-ham           servis        saha                   1          3
okuma-dogrulanmis   saha          sube                   2          2
fatura-taslak       saha          sube                   3          1
anahtar-dosyasi     saha          saha                   0          0
denetim-gunlugu     servis        servis                 0          0

3. modeller arasi fark (kac istekte sonuc farkli)
cift                                                        farkli
izin-bitleri (gevsek) / izin-bitleri (siki)                     12
izin-bitleri (gevsek) / erisim-listesi (ret once)                6
izin-bitleri (gevsek) / erisim-listesi (izin once)               8
izin-bitleri (siki) / erisim-listesi (ret once)                  6
izin-bitleri (siki) / erisim-listesi (izin once)                12
erisim-listesi (ret once) / erisim-listesi (izin once)           6

4. fazladan erisim kime gidiyor
ozne                     gevsek bitler izin once acl
toplayici-servis                     2             3
faturalama-servisi                   0             3
veri-analisti                        1             0
misafir-cihaz                        3             0

Sayılar ölçüm sınıfındadır; girdileri DI17–DI22’dir.

İzin Bitleri Neyi İfade Edemiyor

Birinci tablonun ilk iki satırı bu dersin ana bulgusudur. İzin bitleri modeli 70 isteğin 64’ünü niyetle aynı sonuçlandırır; kalan 6 istek her iki stratejide de yanlıştır. Yön farklıdır: gevşek ifade 6 fazla izin, sıkı ifade 6 fazla ret üretir.

Sıfır olmaması bir ayar hatası değildir. Kod her nesne için beş grubu da dener ve sapması en az olanı seçer; modele en iyi şans verilmiştir. Kalan artık, modelin yapısından gelir: üç sınıf vardır ve bir özneye ancak bu üç sınıftan biri üzerinden ulaşılabilir. Politikanın istediği ayrım üç sınıfa sığmıyorsa — dört ayrı grupta okuyucu varsa ve bir özne dışarıda tutulacaksa — geriye yalnızca yaklaşık ifade kalır.

İkinci tablo artığın nerede biriktiğini gösterir. anahtar-dosyasi ve denetim-gunlugu iki stratejide de sıfır artık verir; ikisinde de erişim kümesi tek bir sahip ile tek bir grubun içine düşer. fatura-taslak gevşek ifadede 3 fazla izin üretir, çünkü iki farklı gruptaki iki okuyucuyu kapsamanın tek yolu diğerleri sınıfını açmaktır ve o sınıfta dört özne daha vardır.

Dördüncü tablo bedelin kime gittiğini yazar. Gevşek ifadede fazladan erişim alan öznelerden biri misafir-cihaz’dır ve 3 istek kazanır. Bu özne politikada hiçbir nesneye erişmez; modelde onu dışarıda tutacak bir yer yoktur, çünkü “diğerleri” sınıfı herkesi kapsar. İzin bitleri modelinin ifade edemediği şey bir izin değil, bir istisnadır.

Yaklaşımın Yönü Seçilir, Varlığı Seçilmez

Üçüncü tablonun ilk satırı iki stratejiyi karşılaştırır: gevşek ve sıkı ifadeler birbirinden 12 istekte ayrılır. Toplam sapma her ikisinde de 6 olduğu hâlde ayrıştıkları istek sayısı iki katıdır, çünkü sapmalar farklı isteklerdedir ve zıt yönlüdür.

Bu, yaklaşık ifadenin yönetilebilir kısmıdır. Model tam ifade edemiyorsa yönetici bir yön seçer. Gevşek yön işleri durdurmaz ama 6 istekte politika dışı erişim açar. Sıkı yön hiçbir fazladan erişim vermez ama 6 meşru isteği reddeder; ölçüm ağında bu, denetçinin fatura taslağını okuyamaması ve saha teknisyeninin ham okumaya erişememesi demektir.

Seçilemeyecek olan şey sapmanın kendisidir. Toplam sapma iki yönde de 6’dır; hangi stratejinin seçildiği yalnızca bedelin nereye yazılacağını belirler. Bir izin modeli seçilirken sorulacak soru “hangisi daha güvenli” değil, “politikam bu modelde kaç istekte ifade edilemiyor ve o isteklerin bedelini hangi yöne yazabilirim” sorusudur.

Erişim Denetim Listesi Ne Getiriyor, Ne Getirmiyor

Birinci tablonun üçüncü satırı sıfırdır: erişim denetim listesi modeli, ret girdileri önce değerlendirildiğinde 70 isteğin 70’ini niyetle aynı sonuçlandırır. Özne başına girdi yazılabildiği için üç sınıf sınırı ortadan kalkar ve misafir-cihaz sorunu doğmaz.

Dördüncü satır ise bedeli gösterir. Aynı liste, girdiler ters sırada değerlendirildiğinde 6 fazla izin üretir. Üçüncü tablonun son satırı bunu doğrudan yazar: iki sıralama birbirinden 6 istekte ayrılır. Bu 6 istek, grup düzeyinde verilen bir iznin öznesi olan ama bireysel bir ret girdisiyle dışarıda tutulması gereken öznelere aittir — toplayici-servis ve faturalama-servisi, dördüncü tabloda 3’er istek kazanırlar.

Buradaki fark bir yazım hatası değil, modelin ikinci ekseninin sıra olmasıdır. İzin bitleri modelinde bir nesnenin izin durumu tek bir değerdir ve okunduğunda sonucu belirler; erişim denetim listesinde aynı politika farklı sıralarla yazılabilir ve iki liste aynı girdileri taşıdığı hâlde farklı sonuç verir. İfade gücü arttıkça sonucun okunması zorlaşır: bir listenin doğruluğu girdilerine bakılarak değil, ancak istek kümesi üzerinde koşturularak anlaşılır.

Sınırın yetmediği ikinci yer budur. Sıfır sapma, listenin doğru yazıldığı ve doğru sırada değerlendirildiği varsayımına dayanır; bu iki koşuldan biri kaybolduğunda model, izin bitleri modelinin gevşek ifadesiyle aynı sayıya — 6 fazla izne — düşer.

İkisinin de Dışında: Sahiplik

Her iki modelde de ölçülmeyen bir kalem vardır. Nesnenin sahipliği, izin kararlarının içinde değil, üstündedir: sahip, bitleri de listeyi de değiştirebilir. Modelde denetim-gunlugu dosyasının sahibi denetci’dir ve politika denetçiye yalnız okuma verir — ama sahip olduğu için kendine yazma verebilir.

Bu, kursun ölçüsüyle yazıldığında nettir. Bir nesnenin izin sınırını geçmek için gereken kalem, o nesnede politika ne derse desin, 1’dir: sahipliğin ele geçmesi. Sınır düştüğünde erişilen kalem ise o nesnenin bütün izin kararlarıdır. Bu yüzden sahiplik bir izin satırı gibi denetlenmez; ayrı sayılır. Ölçüm ağının beş dosyasında sahiplik dört ayrı özneye dağıtılmıştır ve bu dağılım, tek bir öznenin ele geçmesinin kaç dosyanın izin düzenini açtığını belirler.

Sahipliğin ayrı sayılması ölçümün üçüncü sütununu da düzeltir. İlk iki sütun — sapma sayısı ve sapmanın yönü — modelin ifade gücünü ölçer; üçüncü sütun, o ifadenin ne kadar süreyle geçerli kaldığını ölçer. Sahipliği bir öznede toplanan bir dosya kümesinde politika, o özne ele geçtiği anda geçersizdir ve sapma sayısı anlamını yitirir.

Özet

  • İzin bitleri modeli 70 isteğin 6’sını ifade edemez; gevşek ifade 6 fazla izin, sıkı ifade 6 fazla ret üretir. Artık, grup seçiminden değil, üç sınıflı yapıdan gelir.
  • Modelin ifade edemediği şey bir izin değil bir istisnadır: politikada hiçbir erişimi olmayan misafir-cihaz, gevşek ifadede 3 istek kazanır çünkü “diğerleri” sınıfı herkesi kapsar.
  • İki strateji birbirinden 12 istekte ayrılır. Sapmanın varlığı seçilemez, yalnız yönü seçilir: fazladan açılan erişim ile durdurulan meşru iş arasında.
  • Erişim denetim listesi modeli aynı politikayı 70 istekte tam ifade eder, ama ikinci bir eksen getirir: girdiler ters sırada değerlendirildiğinde 6 istek fazla izne döner.
  • İfade gücü arttıkça doğruluk okunamaz hâle gelir; bir listenin doğruluğu girdilerine bakılarak değil, istek kümesi üzerinde koşturularak anlaşılır.
  • Sahiplik iki modelin de dışındadır: izin sınırını geçmek için gereken kalem, politika ne derse desin 1’dir ve sınır düştüğünde o nesnenin bütün izin kararları açılır.

Sonraki Adım

İzin düzeni artık ölçülü: hangi modelin neyi ifade edebildiği ve edemediği sayıyla yazılı. Ancak bütün bu ölçüm, izinlerin kim tarafından ve nasıl değiştirildiğini hiç sormadı. Bir izin satırının değişmesi bir olaydır ve o olayın geriye bıraktığı iz, izin satırının kendisi kadar önemlidir.

Sonraki ders aynı işi iki yönetim biçiminde yapar — grafik arayüzle ve komut satırıyla — ve her birinin bıraktığı iz kalemini sayar: kaç kayıt düşüyor, kaçı yeniden üretilebiliyor, kaçı denetim izinde hiç görünmüyor.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat