[{"data":1,"prerenderedAt":1859},["ShallowReactive",2],{"page-\u002Flinux\u002F04-files-directories-permissions":3},{"id":4,"title":5,"body":6,"description":16,"extension":1853,"meta":1854,"navigation":359,"path":1855,"seo":1856,"stem":1857,"__hash__":1858},"content\u002Flinux\u002F04-files-directories-permissions.md","04 — Files, Directories & Permissions",{"type":7,"value":8,"toc":1826},"minimark",[9,13,17,22,38,204,208,284,306,396,400,403,524,581,585,594,601,714,722,733,812,820,831,892,902,909,923,940,977,995,1002,1027,1031,1034,1037,1128,1131,1145,1149,1212,1216,1223,1292,1299,1306,1373,1387,1391,1488,1492,1620,1624,1627,1663,1670,1822],[10,11,5],"h1",{"id":12},"_04-files-directories-permissions",[14,15,16],"p",{},"Linux permissions control who can read, write, and execute files, and who owns them. This is the foundation of filesystem-level security. This chapter covers ownership, permission bits, special bits, ACLs, capabilities, and the traps that cause \"permission denied\" mysteries.",[18,19,21],"h2",{"id":20},"ownership-users-and-groups","Ownership: Users and Groups",[14,23,24,25,29,30,33,34,37],{},"Every file has an owner (user, by UID), a group (by GID), and permissions for three classes: ",[26,27,28],"strong",{},"owner"," (user), ",[26,31,32],{},"group",", and ",[26,35,36],{},"others",".",[39,40,42],"code-wrapper",{"language":41},"bash",[43,44,48],"pre",{"className":45,"code":46,"language":41,"meta":47,"style":47},"language-bash shiki shiki-themes github-light github-dark","$ ls -l \u002Fetc\u002Fpasswd\n-rw-r--r-- 1 root root 3218 Jun 15 10:23 \u002Fetc\u002Fpasswd\n└──┘└─┘└─┘ └──┘ └──┘\n  │   │   │    │     └ group (root)\n  │   │   │    └ owner (root)\n  │   │   └ permissions for others (r--)\n  │   └ permissions for group (r--)\n  └ permissions for owner (rw-)\n","",[49,50,51,71,99,111,135,152,174,189],"code",{"__ignoreMap":47},[52,53,56,60,64,68],"span",{"class":54,"line":55},"line",1,[52,57,59],{"class":58},"sIsaT","$",[52,61,63],{"class":62},"sJ6F3"," ls",[52,65,67],{"class":66},"snvgF"," -l",[52,69,70],{"class":62}," \u002Fetc\u002Fpasswd\n",[52,72,74,77,80,83,85,88,91,94,97],{"class":54,"line":73},2,[52,75,76],{"class":58},"-rw-r--r--",[52,78,79],{"class":66}," 1",[52,81,82],{"class":62}," root",[52,84,82],{"class":62},[52,86,87],{"class":66}," 3218",[52,89,90],{"class":62}," Jun",[52,92,93],{"class":66}," 15",[52,95,96],{"class":62}," 10:23",[52,98,70],{"class":62},[52,100,102,105,108],{"class":54,"line":101},3,[52,103,104],{"class":58},"└──┘└─┘└─┘",[52,106,107],{"class":62}," └──┘",[52,109,110],{"class":62}," └──┘\n",[52,112,114,117,120,122,125,128,131],{"class":54,"line":113},4,[52,115,116],{"class":58},"  │",[52,118,119],{"class":62},"   │",[52,121,119],{"class":62},[52,123,124],{"class":62},"    │",[52,126,127],{"class":62},"     └",[52,129,130],{"class":62}," group",[52,132,134],{"class":133},"ssxIu"," (root)\n",[52,136,138,140,142,144,147,150],{"class":54,"line":137},5,[52,139,116],{"class":58},[52,141,119],{"class":62},[52,143,119],{"class":62},[52,145,146],{"class":62},"    └",[52,148,149],{"class":62}," owner",[52,151,134],{"class":133},[52,153,155,157,159,162,165,168,171],{"class":54,"line":154},6,[52,156,116],{"class":58},[52,158,119],{"class":62},[52,160,161],{"class":62},"   └",[52,163,164],{"class":62}," permissions",[52,166,167],{"class":62}," for",[52,169,170],{"class":62}," others",[52,172,173],{"class":133}," (r--)\n",[52,175,177,179,181,183,185,187],{"class":54,"line":176},7,[52,178,116],{"class":58},[52,180,161],{"class":62},[52,182,164],{"class":62},[52,184,167],{"class":62},[52,186,130],{"class":62},[52,188,173],{"class":133},[52,190,192,195,197,199,201],{"class":54,"line":191},8,[52,193,194],{"class":58},"  └",[52,196,164],{"class":62},[52,198,167],{"class":62},[52,200,149],{"class":62},[52,202,203],{"class":133}," (rw-)\n",[18,205,207],{"id":206},"permission-bits-meaning-by-file-type","Permission Bits — Meaning by File Type",[209,210,211,227],"table",{},[212,213,214],"thead",{},[215,216,217,221,224],"tr",{},[218,219,220],"th",{},"Bit",[218,222,223],{},"Regular File",[218,225,226],{},"Directory",[228,229,230,251,267],"tbody",{},[215,231,232,238,245],{},[233,234,235],"td",{},[49,236,237],{},"r",[233,239,240,241,244],{},"Read contents (",[49,242,243],{},"cat",")",[233,246,247,248,244],{},"List entries (",[49,249,250],{},"ls",[215,252,253,258,264],{},[233,254,255],{},[49,256,257],{},"w",[233,259,260,261,244],{},"Modify contents (",[49,262,263],{},"echo >",[233,265,266],{},"Create\u002Fdelete\u002Frename entries inside",[215,268,269,274,277],{},[233,270,271],{},[49,272,273],{},"x",[233,275,276],{},"Execute (run as program)",[233,278,279,280,283],{},"Enter (",[49,281,282],{},"cd",") \u002F traverse (use in a path)",[14,285,286,287,293,294,296,297,299,300,302,303,305],{},"Key difference: ",[26,288,289,290,292],{},"directory ",[49,291,273],{}," is \"traverse\u002Fsearch\" permission",", not \"execute.\" Without ",[49,295,273],{}," on a directory, you can't ",[49,298,282],{}," into it or access files inside it by path — even if you know their names. ",[49,301,237],{}," lets you list; ",[49,304,273],{}," lets you actually access.",[39,307,308],{"language":41},[43,309,311],{"className":45,"code":310,"language":41,"meta":47,"style":47},"# Complex Implementation: demonstrate r vs x on directories\n# r but no x: can list names, can't access content\nchmod 444 somedir\u002F\nls somedir\u002F               # works (lists names)\ncat somedir\u002Ffile          # Permission denied (no x to traverse)\n\n# x but no r: can access by name, can't list\nchmod 111 somedir\u002F\ncat somedir\u002Fknownfile     # works (if you know the exact name)\nls somedir\u002F               # Permission denied (can't list)\n",[49,312,313,319,324,335,345,355,361,366,375,386],{"__ignoreMap":47},[52,314,315],{"class":54,"line":55},[52,316,318],{"class":317},"sdCPZ","# Complex Implementation: demonstrate r vs x on directories\n",[52,320,321],{"class":54,"line":73},[52,322,323],{"class":317},"# r but no x: can list names, can't access content\n",[52,325,326,329,332],{"class":54,"line":101},[52,327,328],{"class":58},"chmod",[52,330,331],{"class":66}," 444",[52,333,334],{"class":62}," somedir\u002F\n",[52,336,337,339,342],{"class":54,"line":113},[52,338,250],{"class":58},[52,340,341],{"class":62}," somedir\u002F",[52,343,344],{"class":317},"               # works (lists names)\n",[52,346,347,349,352],{"class":54,"line":137},[52,348,243],{"class":58},[52,350,351],{"class":62}," somedir\u002Ffile",[52,353,354],{"class":317},"          # Permission denied (no x to traverse)\n",[52,356,357],{"class":54,"line":154},[52,358,360],{"emptyLinePlaceholder":359},true,"\n",[52,362,363],{"class":54,"line":176},[52,364,365],{"class":317},"# x but no r: can access by name, can't list\n",[52,367,368,370,373],{"class":54,"line":191},[52,369,328],{"class":58},[52,371,372],{"class":66}," 111",[52,374,334],{"class":62},[52,376,378,380,383],{"class":54,"line":377},9,[52,379,243],{"class":58},[52,381,382],{"class":62}," somedir\u002Fknownfile",[52,384,385],{"class":317},"     # works (if you know the exact name)\n",[52,387,389,391,393],{"class":54,"line":388},10,[52,390,250],{"class":58},[52,392,341],{"class":62},[52,394,395],{"class":317},"               # Permission denied (can't list)\n",[18,397,399],{"id":398},"numeric-octal-mode","Numeric (Octal) Mode",[14,401,402],{},"Each triplet sums to 0–7:",[209,404,405,418],{},[212,406,407],{},[215,408,409,412,415],{},[218,410,411],{},"Octal",[218,413,414],{},"Symbolic",[218,416,417],{},"Meaning",[228,419,420,433,446,459,472,485,498,511],{},[215,421,422,425,430],{},[233,423,424],{},"0",[233,426,427],{},[49,428,429],{},"---",[233,431,432],{},"No access",[215,434,435,438,443],{},[233,436,437],{},"1",[233,439,440],{},[49,441,442],{},"--x",[233,444,445],{},"Execute\u002Ftraverse",[215,447,448,451,456],{},[233,449,450],{},"2",[233,452,453],{},[49,454,455],{},"-w-",[233,457,458],{},"Write",[215,460,461,464,469],{},[233,462,463],{},"3",[233,465,466],{},[49,467,468],{},"-wx",[233,470,471],{},"Write + execute",[215,473,474,477,482],{},[233,475,476],{},"4",[233,478,479],{},[49,480,481],{},"r--",[233,483,484],{},"Read",[215,486,487,490,495],{},[233,488,489],{},"5",[233,491,492],{},[49,493,494],{},"r-x",[233,496,497],{},"Read + execute",[215,499,500,503,508],{},[233,501,502],{},"6",[233,504,505],{},[49,506,507],{},"rw-",[233,509,510],{},"Read + write",[215,512,513,516,521],{},[233,514,515],{},"7",[233,517,518],{},[49,519,520],{},"rwx",[233,522,523],{},"All",[39,525,526],{"language":41},[43,527,529],{"className":45,"code":528,"language":41,"meta":47,"style":47},"chmod 644 file     # rw-r--r-- (typical file)\nchmod 755 file     # rwxr-xr-x (typical executable\u002Fdir)\nchmod 600 file     # rw------- (private file, e.g., SSH key)\nchmod 700 dir      # rwx------ (private directory)\n",[49,530,531,544,556,568],{"__ignoreMap":47},[52,532,533,535,538,541],{"class":54,"line":55},[52,534,328],{"class":58},[52,536,537],{"class":66}," 644",[52,539,540],{"class":62}," file",[52,542,543],{"class":317},"     # rw-r--r-- (typical file)\n",[52,545,546,548,551,553],{"class":54,"line":73},[52,547,328],{"class":58},[52,549,550],{"class":66}," 755",[52,552,540],{"class":62},[52,554,555],{"class":317},"     # rwxr-xr-x (typical executable\u002Fdir)\n",[52,557,558,560,563,565],{"class":54,"line":101},[52,559,328],{"class":58},[52,561,562],{"class":66}," 600",[52,564,540],{"class":62},[52,566,567],{"class":317},"     # rw------- (private file, e.g., SSH key)\n",[52,569,570,572,575,578],{"class":54,"line":113},[52,571,328],{"class":58},[52,573,574],{"class":66}," 700",[52,576,577],{"class":62}," dir",[52,579,580],{"class":317},"      # rwx------ (private directory)\n",[18,582,584],{"id":583},"special-permission-bits","Special Permission Bits",[586,587,589,590,593],"h3",{"id":588},"setuid-4000-run-as-owner","Setuid (",[49,591,592],{},"4000",") — Run as Owner",[14,595,596,597,600],{},"When set on an executable, it runs ",[26,598,599],{},"as the file's owner"," regardless of who invokes it:",[39,602,603],{"language":41},[43,604,606],{"className":45,"code":605,"language":41,"meta":47,"style":47},"ls -l \u002Fusr\u002Fbin\u002Fsudo\n# -rwsr-xr-x 1 root root ... \u002Fusr\u002Fbin\u002Fsudo\n   ↑\n   setuid (s in owner execute position)\n\nchmod 4755 program      # setuid + 755\nchmod u+s program       # symbolic\n\n# Security audit — find all setuid root binaries:\nfind \u002F -perm -4000 -type f 2>\u002Fdev\u002Fnull\n",[49,607,608,617,622,627,649,653,666,678,682,687],{"__ignoreMap":47},[52,609,610,612,614],{"class":54,"line":55},[52,611,250],{"class":58},[52,613,67],{"class":66},[52,615,616],{"class":62}," \u002Fusr\u002Fbin\u002Fsudo\n",[52,618,619],{"class":54,"line":73},[52,620,621],{"class":317},"# -rwsr-xr-x 1 root root ... \u002Fusr\u002Fbin\u002Fsudo\n",[52,623,624],{"class":54,"line":101},[52,625,626],{"class":58},"   ↑\n",[52,628,629,632,635,638,640,643,646],{"class":54,"line":113},[52,630,631],{"class":58},"   setuid",[52,633,634],{"class":133}," (s ",[52,636,637],{"class":62},"in",[52,639,149],{"class":62},[52,641,642],{"class":62}," execute",[52,644,645],{"class":62}," position",[52,647,648],{"class":133},")\n",[52,650,651],{"class":54,"line":137},[52,652,360],{"emptyLinePlaceholder":359},[52,654,655,657,660,663],{"class":54,"line":154},[52,656,328],{"class":58},[52,658,659],{"class":66}," 4755",[52,661,662],{"class":62}," program",[52,664,665],{"class":317},"      # setuid + 755\n",[52,667,668,670,673,675],{"class":54,"line":176},[52,669,328],{"class":58},[52,671,672],{"class":62}," u+s",[52,674,662],{"class":62},[52,676,677],{"class":317},"       # symbolic\n",[52,679,680],{"class":54,"line":191},[52,681,360],{"emptyLinePlaceholder":359},[52,683,684],{"class":54,"line":377},[52,685,686],{"class":317},"# Security audit — find all setuid root binaries:\n",[52,688,689,692,695,698,701,704,707,711],{"class":54,"line":388},[52,690,691],{"class":58},"find",[52,693,694],{"class":62}," \u002F",[52,696,697],{"class":66}," -perm",[52,699,700],{"class":66}," -4000",[52,702,703],{"class":66}," -type",[52,705,706],{"class":62}," f",[52,708,710],{"class":709},"svdQ7"," 2>",[52,712,713],{"class":62},"\u002Fdev\u002Fnull\n",[586,715,717,718,721],{"id":716},"setgid-2000-inherit-group-on-directories","Setgid (",[49,719,720],{},"2000",") — Inherit Group on Directories",[14,723,724,725,728,729,732],{},"On a ",[26,726,727],{},"directory",": new files\u002Fdirs inside ",[26,730,731],{},"inherit the directory's group"," (instead of the creator's primary group). Essential for shared directories:",[39,734,735],{"language":41},[43,736,738],{"className":45,"code":737,"language":41,"meta":47,"style":47},"# Complex Implementation: collaborative directory with setgid + default ACL\nsudo mkdir \u002Fshared\nsudo chown :developers \u002Fshared\nsudo chmod 2775 \u002Fshared              # setgid + rwxrwsr-x\n# Now all new files in \u002Fshared inherit the \"developers\" group\n# Add default ACL so new files also get group write (regardless of umask):\nsudo setfacl -d -m g:developers:rw \u002Fshared\n",[49,739,740,745,756,768,784,789,794],{"__ignoreMap":47},[52,741,742],{"class":54,"line":55},[52,743,744],{"class":317},"# Complex Implementation: collaborative directory with setgid + default ACL\n",[52,746,747,750,753],{"class":54,"line":73},[52,748,749],{"class":58},"sudo",[52,751,752],{"class":62}," mkdir",[52,754,755],{"class":62}," \u002Fshared\n",[52,757,758,760,763,766],{"class":54,"line":101},[52,759,749],{"class":58},[52,761,762],{"class":62}," chown",[52,764,765],{"class":62}," :developers",[52,767,755],{"class":62},[52,769,770,772,775,778,781],{"class":54,"line":113},[52,771,749],{"class":58},[52,773,774],{"class":62}," chmod",[52,776,777],{"class":66}," 2775",[52,779,780],{"class":62}," \u002Fshared",[52,782,783],{"class":317},"              # setgid + rwxrwsr-x\n",[52,785,786],{"class":54,"line":137},[52,787,788],{"class":317},"# Now all new files in \u002Fshared inherit the \"developers\" group\n",[52,790,791],{"class":54,"line":154},[52,792,793],{"class":317},"# Add default ACL so new files also get group write (regardless of umask):\n",[52,795,796,798,801,804,807,810],{"class":54,"line":176},[52,797,749],{"class":58},[52,799,800],{"class":62}," setfacl",[52,802,803],{"class":66}," -d",[52,805,806],{"class":66}," -m",[52,808,809],{"class":62}," g:developers:rw",[52,811,755],{"class":62},[586,813,815,816,819],{"id":814},"sticky-bit-1000-restricted-deletion","Sticky Bit (",[49,817,818],{},"1000",") — Restricted Deletion",[14,821,822,823,826,827,830],{},"On a directory, the sticky bit means ",[26,824,825],{},"only the file's owner (or the directory's owner, or root) can delete\u002Frename files inside"," — even if others have write permission. The canonical use is ",[49,828,829],{},"\u002Ftmp",":",[39,832,833],{"language":41},[43,834,836],{"className":45,"code":835,"language":41,"meta":47,"style":47},"ls -ld \u002Ftmp\n# drwxrwxrwt 20 root root 4096 ... \u002Ftmp\n            ↑\n            sticky bit (t in others execute position)\nchmod 1777 \u002Ftmp         # sticky + 777\n",[49,837,838,848,853,858,879],{"__ignoreMap":47},[52,839,840,842,845],{"class":54,"line":55},[52,841,250],{"class":58},[52,843,844],{"class":66}," -ld",[52,846,847],{"class":62}," \u002Ftmp\n",[52,849,850],{"class":54,"line":73},[52,851,852],{"class":317},"# drwxrwxrwt 20 root root 4096 ... \u002Ftmp\n",[52,854,855],{"class":54,"line":101},[52,856,857],{"class":58},"            ↑\n",[52,859,860,863,866,869,871,873,875,877],{"class":54,"line":113},[52,861,862],{"class":58},"            sticky",[52,864,865],{"class":62}," bit",[52,867,868],{"class":133}," (t ",[52,870,637],{"class":62},[52,872,170],{"class":62},[52,874,642],{"class":62},[52,876,645],{"class":62},[52,878,648],{"class":133},[52,880,881,883,886,889],{"class":54,"line":137},[52,882,328],{"class":58},[52,884,885],{"class":66}," 1777",[52,887,888],{"class":62}," \u002Ftmp",[52,890,891],{"class":317},"         # sticky + 777\n",[14,893,894,895,897,898,901],{},"Without the sticky bit, since ",[49,896,829],{}," is world-writable (",[49,899,900],{},"777","), any user could delete any other user's temp files.",[18,903,905,908],{"id":904},"umask-default-permissions",[49,906,907],{},"umask"," — Default Permissions",[14,910,911,913,914,917,918,922],{},[49,912,907],{}," is a ",[26,915,916],{},"mask"," (bits to ",[919,920,921],"em",{},"remove",") from the default mode:",[924,925,926,934],"ul",{},[927,928,929,930,933],"li",{},"Files default to ",[49,931,932],{},"666"," (rw-rw-rw-).",[927,935,936,937,939],{},"Directories default to ",[49,938,900],{}," (rwxrwxrwx).",[39,941,942],{"language":41},[43,943,945],{"className":45,"code":944,"language":41,"meta":47,"style":47},"umask 077        # files: 600, dirs: 700 (private)\numask 022        # files: 644, dirs: 755 (default on most systems)\numask 002        # files: 664, dirs: 775 (shared group, e.g., team dirs)\n",[49,946,947,957,967],{"__ignoreMap":47},[52,948,949,951,954],{"class":54,"line":55},[52,950,907],{"class":66},[52,952,953],{"class":66}," 077",[52,955,956],{"class":317},"        # files: 600, dirs: 700 (private)\n",[52,958,959,961,964],{"class":54,"line":73},[52,960,907],{"class":66},[52,962,963],{"class":66}," 022",[52,965,966],{"class":317},"        # files: 644, dirs: 755 (default on most systems)\n",[52,968,969,971,974],{"class":54,"line":101},[52,970,907],{"class":66},[52,972,973],{"class":66}," 002",[52,975,976],{"class":317},"        # files: 664, dirs: 775 (shared group, e.g., team dirs)\n",[14,978,979,980,983,984,987,988,991,992,37],{},"Calculation: ",[49,981,982],{},"mode = default & ~umask",". ",[49,985,986],{},"umask 022"," → files ",[49,989,990],{},"666 & ~022 = 644",", dirs ",[49,993,994],{},"777 & ~022 = 755",[586,996,998,999,1001],{"id":997},"edge-case-umask-doesnt-add-execute","Edge Case: ",[49,1000,907],{}," Doesn't Add Execute",[14,1003,1004,1005,1008,1009,1011,1012,1014,1015,1018,1019,1022,1023,1026],{},"Files are created ",[49,1006,1007],{},"666 & ~umask"," — never ",[49,1010,900],{},". So ",[49,1013,986],{}," gives files ",[49,1016,1017],{},"644"," (not executable), dirs ",[49,1020,1021],{},"755",". You must ",[49,1024,1025],{},"chmod +x"," scripts after creating them.",[18,1028,1030],{"id":1029},"acls-access-control-lists","ACLs (Access Control Lists)",[14,1032,1033],{},"Traditional permissions have only three classes. ACLs allow per-user or per-group permissions:",[14,1035,1036],{},"::code-wrapper{language=\"language=\"bash\"}",[43,1038,1040],{"className":45,"code":1039,"language":41,"meta":47,"style":47},"# Grant alice read-write, developers group read\nsetfacl -m u:alice:rw file\nsetfacl -m g:developers:r file\n\n# Set default ACL on a directory (inherited by new files)\nsetfacl -d -m g:developers:rw \u002Fshared\n\n# View\ngetfacl file\n\n# Remove all ACLs\nsetfacl -b file\n",[49,1041,1042,1047,1060,1071,1075,1080,1092,1096,1101,1108,1112,1118],{"__ignoreMap":47},[52,1043,1044],{"class":54,"line":55},[52,1045,1046],{"class":317},"# Grant alice read-write, developers group read\n",[52,1048,1049,1052,1054,1057],{"class":54,"line":73},[52,1050,1051],{"class":58},"setfacl",[52,1053,806],{"class":66},[52,1055,1056],{"class":62}," u:alice:rw",[52,1058,1059],{"class":62}," file\n",[52,1061,1062,1064,1066,1069],{"class":54,"line":101},[52,1063,1051],{"class":58},[52,1065,806],{"class":66},[52,1067,1068],{"class":62}," g:developers:r",[52,1070,1059],{"class":62},[52,1072,1073],{"class":54,"line":113},[52,1074,360],{"emptyLinePlaceholder":359},[52,1076,1077],{"class":54,"line":137},[52,1078,1079],{"class":317},"# Set default ACL on a directory (inherited by new files)\n",[52,1081,1082,1084,1086,1088,1090],{"class":54,"line":154},[52,1083,1051],{"class":58},[52,1085,803],{"class":66},[52,1087,806],{"class":66},[52,1089,809],{"class":62},[52,1091,755],{"class":62},[52,1093,1094],{"class":54,"line":176},[52,1095,360],{"emptyLinePlaceholder":359},[52,1097,1098],{"class":54,"line":191},[52,1099,1100],{"class":317},"# View\n",[52,1102,1103,1106],{"class":54,"line":377},[52,1104,1105],{"class":58},"getfacl",[52,1107,1059],{"class":62},[52,1109,1110],{"class":54,"line":388},[52,1111,360],{"emptyLinePlaceholder":359},[52,1113,1115],{"class":54,"line":1114},11,[52,1116,1117],{"class":317},"# Remove all ACLs\n",[52,1119,1121,1123,1126],{"class":54,"line":1120},12,[52,1122,1051],{"class":58},[52,1124,1125],{"class":66}," -b",[52,1127,1059],{"class":62},[14,1129,1130],{},"::",[14,1132,1133,1134,1137,1138,1141,1142,37],{},"In ",[49,1135,1136],{},"ls -l",", a ",[49,1139,1140],{},"+"," after the mode indicates an ACL is present: ",[49,1143,1144],{},"-rw-rw-r--+",[586,1146,1148],{"id":1147},"edge-case-acls-lost-on-copy","Edge Case: ACLs Lost on Copy",[39,1150,1151],{"language":41},[43,1152,1154],{"className":45,"code":1153,"language":41,"meta":47,"style":47},"# NAIVE: cp strips ACLs and capabilities\ncp file \u002Fbackup\u002Ffile              # ACLs gone, capabilities gone\n# PRODUCTION: preserve everything\ncp -a file \u002Fbackup\u002Ffile           # preserves mode, owner, timestamps, ACLs\nrsync -A -X file \u002Fbackup\u002F         # -A ACLs, -X xattrs (full preservation)\n",[49,1155,1156,1161,1174,1179,1193],{"__ignoreMap":47},[52,1157,1158],{"class":54,"line":55},[52,1159,1160],{"class":317},"# NAIVE: cp strips ACLs and capabilities\n",[52,1162,1163,1166,1168,1171],{"class":54,"line":73},[52,1164,1165],{"class":58},"cp",[52,1167,540],{"class":62},[52,1169,1170],{"class":62}," \u002Fbackup\u002Ffile",[52,1172,1173],{"class":317},"              # ACLs gone, capabilities gone\n",[52,1175,1176],{"class":54,"line":101},[52,1177,1178],{"class":317},"# PRODUCTION: preserve everything\n",[52,1180,1181,1183,1186,1188,1190],{"class":54,"line":113},[52,1182,1165],{"class":58},[52,1184,1185],{"class":66}," -a",[52,1187,540],{"class":62},[52,1189,1170],{"class":62},[52,1191,1192],{"class":317},"           # preserves mode, owner, timestamps, ACLs\n",[52,1194,1195,1198,1201,1204,1206,1209],{"class":54,"line":137},[52,1196,1197],{"class":58},"rsync",[52,1199,1200],{"class":66}," -A",[52,1202,1203],{"class":66}," -X",[52,1205,540],{"class":62},[52,1207,1208],{"class":62}," \u002Fbackup\u002F",[52,1210,1211],{"class":317},"         # -A ACLs, -X xattrs (full preservation)\n",[18,1213,1215],{"id":1214},"file-capabilities","File Capabilities",[14,1217,1218,1219,1222],{},"Instead of setuid root, grant a binary ",[26,1220,1221],{},"specific"," capabilities (fine-grained privileges):",[39,1224,1225],{"language":41},[43,1226,1228],{"className":45,"code":1227,"language":41,"meta":47,"style":47},"# Complex Implementation: allow a binary to bind to port 80 without root\n# — safer than setuid (grants only one capability, not all root powers)\nsudo setcap 'cap_net_bind_service+ep' \u002Fusr\u002Fbin\u002Fmyapp\ngetcap \u002Fusr\u002Fbin\u002Fmyapp                    # verify\nsudo setcap -r \u002Fusr\u002Fbin\u002Fmyapp            # remove\n\n# Anti-Pattern: setuid root for the same purpose\n# sudo chmod u+s \u002Fusr\u002Fbin\u002Fmyapp  → grants ALL root privileges (dangerous)\n",[49,1229,1230,1235,1240,1253,1264,1278,1282,1287],{"__ignoreMap":47},[52,1231,1232],{"class":54,"line":55},[52,1233,1234],{"class":317},"# Complex Implementation: allow a binary to bind to port 80 without root\n",[52,1236,1237],{"class":54,"line":73},[52,1238,1239],{"class":317},"# — safer than setuid (grants only one capability, not all root powers)\n",[52,1241,1242,1244,1247,1250],{"class":54,"line":101},[52,1243,749],{"class":58},[52,1245,1246],{"class":62}," setcap",[52,1248,1249],{"class":62}," 'cap_net_bind_service+ep'",[52,1251,1252],{"class":62}," \u002Fusr\u002Fbin\u002Fmyapp\n",[52,1254,1255,1258,1261],{"class":54,"line":113},[52,1256,1257],{"class":58},"getcap",[52,1259,1260],{"class":62}," \u002Fusr\u002Fbin\u002Fmyapp",[52,1262,1263],{"class":317},"                    # verify\n",[52,1265,1266,1268,1270,1273,1275],{"class":54,"line":137},[52,1267,749],{"class":58},[52,1269,1246],{"class":62},[52,1271,1272],{"class":66}," -r",[52,1274,1260],{"class":62},[52,1276,1277],{"class":317},"            # remove\n",[52,1279,1280],{"class":54,"line":154},[52,1281,360],{"emptyLinePlaceholder":359},[52,1283,1284],{"class":54,"line":176},[52,1285,1286],{"class":317},"# Anti-Pattern: setuid root for the same purpose\n",[52,1288,1289],{"class":54,"line":191},[52,1290,1291],{"class":317},"# sudo chmod u+s \u002Fusr\u002Fbin\u002Fmyapp  → grants ALL root privileges (dangerous)\n",[14,1293,1294,1295,1298],{},"Capabilities are stored in the ",[49,1296,1297],{},"security.capability"," extended attribute.",[18,1300,1302,1305],{"id":1301},"chown-change-owner",[49,1303,1304],{},"chown"," — Change Owner",[39,1307,1308],{"language":41},[43,1309,1311],{"className":45,"code":1310,"language":41,"meta":47,"style":47},"sudo chown alice file          # change owner\nsudo chown alice:staff file    # change owner and group\nsudo chown :staff file         # change group only (or use chgrp)\nsudo chown -R alice:alice dir\u002F # recursive\n",[49,1312,1313,1327,1341,1355],{"__ignoreMap":47},[52,1314,1315,1317,1319,1322,1324],{"class":54,"line":55},[52,1316,749],{"class":58},[52,1318,762],{"class":62},[52,1320,1321],{"class":62}," alice",[52,1323,540],{"class":62},[52,1325,1326],{"class":317},"          # change owner\n",[52,1328,1329,1331,1333,1336,1338],{"class":54,"line":73},[52,1330,749],{"class":58},[52,1332,762],{"class":62},[52,1334,1335],{"class":62}," alice:staff",[52,1337,540],{"class":62},[52,1339,1340],{"class":317},"    # change owner and group\n",[52,1342,1343,1345,1347,1350,1352],{"class":54,"line":101},[52,1344,749],{"class":58},[52,1346,762],{"class":62},[52,1348,1349],{"class":62}," :staff",[52,1351,540],{"class":62},[52,1353,1354],{"class":317},"         # change group only (or use chgrp)\n",[52,1356,1357,1359,1361,1364,1367,1370],{"class":54,"line":113},[52,1358,749],{"class":58},[52,1360,762],{"class":62},[52,1362,1363],{"class":66}," -R",[52,1365,1366],{"class":62}," alice:alice",[52,1368,1369],{"class":62}," dir\u002F",[52,1371,1372],{"class":317}," # recursive\n",[14,1374,1375,1376,1379,1380,1382,1383,1386],{},"Only ",[26,1377,1378],{},"root"," can change the owner (",[49,1381,1304],{},"). A regular user can ",[49,1384,1385],{},"chgrp"," to a group they belong to.",[18,1388,1390],{"id":1389},"tips-tricks","💡 Tips & Tricks",[924,1392,1393,1415,1438,1467,1476],{},[927,1394,1395,1398,1399,1402,1403,1406,1407,1409,1410,1412,1413,37],{},[26,1396,1397],{},"Idiom",": use ",[49,1400,1401],{},"install -m 755 script \u002Fusr\u002Flocal\u002Fbin\u002F"," to copy + set permissions in one step — ",[49,1404,1405],{},"install"," sets the mode explicitly (ignores ",[49,1408,907],{},"), so the result is predictable. Better than ",[49,1411,1165],{}," + ",[49,1414,328],{},[927,1416,1417,1398,1419,1422,1423,1426,1427,1430,1431,1434,1435,1437],{},[26,1418,1397],{},[49,1420,1421],{},"chmod -R"," with symbolic modes, not octal — ",[49,1424,1425],{},"chmod -R g+rw dir"," adds group read\u002Fwrite without touching other bits. ",[49,1428,1429],{},"chmod -R 644 dir"," would remove execute from ",[919,1432,1433],{},"everything"," (including subdirs, breaking ",[49,1436,282],{},").",[927,1439,1440,1442,1443,1446,1447,1450,1451,1454,1455,1458,1459,1462,1463,1466],{},[26,1441,1397],{},": set ",[49,1444,1445],{},"umask 077"," for private systems and ",[49,1448,1449],{},"umask 027"," for shared — ",[49,1452,1453],{},"077"," makes all new files ",[49,1456,1457],{},"600","\u002F",[49,1460,1461],{},"700"," (only owner). ",[49,1464,1465],{},"027"," allows group read.",[927,1468,1469,1471,1472,1475],{},[26,1470,1397],{},": prefer file capabilities over setuid root — ",[49,1473,1474],{},"setcap cap_net_bind_service+ep .\u002Fserver"," lets a binary bind to port 80 without running as root.",[927,1477,1478,1398,1481,1484,1485,1487],{},[26,1479,1480],{},"Debug",[49,1482,1483],{},"namei -l \u002Fpath\u002Fto\u002Ffile"," to see permissions on each component of a path — reveals when a \"Permission denied\" is due to a parent directory lacking ",[49,1486,273],{},", not the file itself.",[18,1489,1491],{"id":1490},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[924,1493,1494,1515,1539,1563,1581,1593,1607],{},[927,1495,1496,1502,1503,1505,1506,1508,1509,1511,1512,1514],{},[26,1497,1498,1499,1501],{},"Directory ",[49,1500,273],{}," ≠ execute",": on directories, ",[49,1504,273],{}," is \"search\u002Ftraverse\" — you need it to ",[49,1507,282],{}," in or access files by path. ",[49,1510,237],{}," alone lets you list names but not access content. ",[49,1513,273],{}," alone lets you access known files but not list.",[927,1516,1517,1523,1524,1527,1528,1531,1532,1534,1535,1538],{},[26,1518,1519,1522],{},[49,1520,1521],{},"rm"," doesn't use the trash",": deletion is permanent. There's no undo. ",[49,1525,1526],{},"rm -rf $UNSET_VAR\u002F"," with ",[49,1529,1530],{},"set +u"," can delete ",[49,1533,1458],{},". Always ",[49,1536,1537],{},"set -u"," in scripts.",[927,1540,1541,1546,1547,1550,1551,1554,1555,1558,1559,1562],{},[26,1542,1543,1545],{},[49,1544,1165],{}," silently overwrites",": ",[49,1548,1549],{},"cp important.conf old.conf.bak"," — if ",[49,1552,1553],{},"old.conf.bak"," exists, it's replaced with no warning. Use ",[49,1556,1557],{},"cp -n"," (no-clobber) or ",[49,1560,1561],{},"cp -i"," (interactive).",[927,1564,1565,1546,1568,1570,1571,1574,1575,1578,1579,37],{},[26,1566,1567],{},"Symlink permissions are meaningless",[49,1569,328],{}," on a symlink changes the ",[919,1572,1573],{},"target's"," permissions (on Linux). Symlinks always show ",[49,1576,1577],{},"lrwxrwxrwx"," in ",[49,1580,1136],{},[927,1582,1583,1546,1586,1589,1590,1592],{},[26,1584,1585],{},"setuid on scripts is ignored (on Linux)",[49,1587,1588],{},"chmod u+s script.sh"," has no effect on shell scripts — the kernel ignores setuid on interpreted scripts (a security measure). Use ",[49,1591,749],{}," or a setuid C wrapper instead.",[927,1594,1595,1598,1599,1602,1603,1606],{},[26,1596,1597],{},"Deleting a file requires write on the directory, not the file",": a file with ",[49,1600,1601],{},"r--r--r--"," (no write for anyone) can be deleted if its directory is writable by the user. The sticky bit (",[49,1604,1605],{},"+t",") prevents deleting others' files in a shared dir.",[927,1608,1609,1546,1612,1615,1616,1619],{},[26,1610,1611],{},"Hard links to directories are forbidden (on most filesystems)",[49,1613,1614],{},"ln dir\u002F link"," fails — ext4 disallows it to avoid filesystem loops. Use ",[49,1617,1618],{},"ln -s"," (symlink) for directories.",[18,1621,1623],{"id":1622},"spot-the-bug","🧠 Spot the Bug",[14,1625,1626],{},"A team sets up a shared directory. They run:",[39,1628,1629],{"language":41},[43,1630,1632],{"className":45,"code":1631,"language":41,"meta":47,"style":47},"sudo mkdir \u002Fshared\nsudo chown :developers \u002Fshared\nsudo chmod 777 \u002Fshared\n",[49,1633,1634,1642,1652],{"__ignoreMap":47},[52,1635,1636,1638,1640],{"class":54,"line":55},[52,1637,749],{"class":58},[52,1639,752],{"class":62},[52,1641,755],{"class":62},[52,1643,1644,1646,1648,1650],{"class":54,"line":73},[52,1645,749],{"class":58},[52,1647,762],{"class":62},[52,1649,765],{"class":62},[52,1651,755],{"class":62},[52,1653,1654,1656,1658,1661],{"class":54,"line":101},[52,1655,749],{"class":58},[52,1657,774],{"class":62},[52,1659,1660],{"class":66}," 777",[52,1662,755],{"class":62},[14,1664,1665,1666,1669],{},"Alice creates ",[49,1667,1668],{},"\u002Fshared\u002Freport.txt",". Bob can read it but can't edit it. The team wanted all developers to edit each other's files. What's wrong, and what are two fixes?",[1671,1672,1673,1677,1719,1725,1746,1760,1769,1803,1815],"details",{},[1674,1675,1676],"summary",{},"Answer",[14,1678,1679,1680,1683,1684,1687,1688,1691,1692,1695,1696,1699,1700,1703,1704,1706,1707,1709,1710,1712,1713,1715,1716,1718],{},"The problem: files created in ",[49,1681,1682],{},"\u002Fshared"," are owned by the ",[26,1685,1686],{},"creator's primary group"," (e.g., ",[49,1689,1690],{},"alice",", ",[49,1693,1694],{},"bob","), not ",[49,1697,1698],{},"developers",". So Alice's file is ",[49,1701,1702],{},"alice:alice",", and Bob (not in the ",[49,1705,1690],{}," group) only has ",[26,1708,36],{}," permissions — typically ",[49,1711,237],{}," (from ",[49,1714,986],{}," → ",[49,1717,1017],{},"). No group write for Bob.",[14,1720,1721,1724],{},[26,1722,1723],{},"Fix 1 — setgid directory"," (classic Unix way):",[39,1726,1727],{"language":41},[43,1728,1730],{"className":45,"code":1729,"language":41,"meta":47,"style":47},"sudo chmod 2770 \u002Fshared    # setgid + rwxrws---\n",[49,1731,1732],{"__ignoreMap":47},[52,1733,1734,1736,1738,1741,1743],{"class":54,"line":55},[52,1735,749],{"class":58},[52,1737,774],{"class":62},[52,1739,1740],{"class":66}," 2770",[52,1742,780],{"class":62},[52,1744,1745],{"class":317},"    # setgid + rwxrws---\n",[14,1747,1748,1749,1751,1752,1755,1756,1759],{},"Now new files inherit the ",[49,1750,1698],{}," group. Combined with ",[49,1753,1754],{},"umask 002"," (gives group write: ",[49,1757,1758],{},"664","), Bob can edit Alice's files.",[14,1761,1762,1765,1766,1768],{},[26,1763,1764],{},"Fix 2 — default ACL"," (more robust, doesn't depend on ",[49,1767,907],{},"):",[39,1770,1771],{"language":41},[43,1772,1774],{"className":45,"code":1773,"language":41,"meta":47,"style":47},"sudo setfacl -d -m g:developers:rw \u002Fshared\nsudo setfacl -m g:developers:rwx \u002Fshared\n",[49,1775,1776,1790],{"__ignoreMap":47},[52,1777,1778,1780,1782,1784,1786,1788],{"class":54,"line":55},[52,1779,749],{"class":58},[52,1781,800],{"class":62},[52,1783,803],{"class":66},[52,1785,806],{"class":66},[52,1787,809],{"class":62},[52,1789,755],{"class":62},[52,1791,1792,1794,1796,1798,1801],{"class":54,"line":73},[52,1793,749],{"class":58},[52,1795,800],{"class":62},[52,1797,806],{"class":66},[52,1799,1800],{"class":62}," g:developers:rwx",[52,1802,755],{"class":62},[14,1804,1805,1806,1809,1810,1812,1813,37],{},"New files automatically get ",[49,1807,1808],{},"group:developers:rw",", regardless of the creator's ",[49,1811,907],{},". This is the modern approach and works even if users keep ",[49,1814,986],{},[14,1816,1817,1818,1821],{},"The key insight: ",[26,1819,1820],{},"directory write permission lets you create\u002Fdelete files, but it doesn't grant write on files created by others"," — that depends on each file's own group and permissions.",[1823,1824,1825],"style",{},"html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}",{"title":47,"searchDepth":73,"depth":73,"links":1827},[1828,1829,1830,1831,1839,1844,1847,1848,1850,1851,1852],{"id":20,"depth":73,"text":21},{"id":206,"depth":73,"text":207},{"id":398,"depth":73,"text":399},{"id":583,"depth":73,"text":584,"children":1832},[1833,1835,1837],{"id":588,"depth":101,"text":1834},"Setuid (4000) — Run as Owner",{"id":716,"depth":101,"text":1836},"Setgid (2000) — Inherit Group on Directories",{"id":814,"depth":101,"text":1838},"Sticky Bit (1000) — Restricted Deletion",{"id":904,"depth":73,"text":1840,"children":1841},"umask — Default Permissions",[1842],{"id":997,"depth":101,"text":1843},"Edge Case: umask Doesn't Add Execute",{"id":1029,"depth":73,"text":1030,"children":1845},[1846],{"id":1147,"depth":101,"text":1148},{"id":1214,"depth":73,"text":1215},{"id":1301,"depth":73,"text":1849},"chown — Change Owner",{"id":1389,"depth":73,"text":1390},{"id":1490,"depth":73,"text":1491},{"id":1622,"depth":73,"text":1623},"md",{},"\u002Flinux\u002F04-files-directories-permissions",{"title":5,"description":16},"linux\u002F04-files-directories-permissions","gK1dStkx95s9ksydQuyQfqUcY_8HC1pb47a71BLYxuE",1789924649844]