1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2011 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html * 11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * David Korn <dgk@research.att.com> * 19da2e3ebdSchin * Phong Vo <kpv@research.att.com> * 20da2e3ebdSchin * * 21da2e3ebdSchin ***********************************************************************/ 22da2e3ebdSchin #pragma prototyped 23da2e3ebdSchin /* 24da2e3ebdSchin * Glenn Fowler 25da2e3ebdSchin * AT&T Research 26da2e3ebdSchin * 27da2e3ebdSchin * apply file permission expression expr to perm 28da2e3ebdSchin * 29da2e3ebdSchin * each expression term must match 30da2e3ebdSchin * 31da2e3ebdSchin * [ugoa]*[-&+|^=]?[rwxst0-7]* 32da2e3ebdSchin * 33da2e3ebdSchin * terms may be combined using , 34da2e3ebdSchin * 35da2e3ebdSchin * if non-null, e points to the first unrecognized char in expr 36da2e3ebdSchin */ 37da2e3ebdSchin 38da2e3ebdSchin #include <ast.h> 39da2e3ebdSchin #include <ls.h> 40da2e3ebdSchin #include <modex.h> 41da2e3ebdSchin 42da2e3ebdSchin int strperm(const char * aexpr,char ** e,register int perm)43da2e3ebdSchinstrperm(const char* aexpr, char** e, register int perm) 44da2e3ebdSchin { 45da2e3ebdSchin register char* expr = (char*)aexpr; 46da2e3ebdSchin register int c; 47da2e3ebdSchin register int typ; 48da2e3ebdSchin register int who; 49da2e3ebdSchin int num; 50da2e3ebdSchin int op; 51da2e3ebdSchin int mask; 52da2e3ebdSchin int masked; 53da2e3ebdSchin 54da2e3ebdSchin if (perm == -1) 55da2e3ebdSchin { 56da2e3ebdSchin perm = 0; 57da2e3ebdSchin masked = 1; 58da2e3ebdSchin mask = ~0; 59da2e3ebdSchin } 60da2e3ebdSchin else 61da2e3ebdSchin masked = 0; 62da2e3ebdSchin for (;;) 63da2e3ebdSchin { 64da2e3ebdSchin op = num = who = typ = 0; 65da2e3ebdSchin for (;;) 66da2e3ebdSchin { 67da2e3ebdSchin switch (c = *expr++) 68da2e3ebdSchin { 69da2e3ebdSchin case 'u': 70da2e3ebdSchin who |= S_ISVTX|S_ISUID|S_IRWXU; 71da2e3ebdSchin continue; 72da2e3ebdSchin case 'g': 73da2e3ebdSchin who |= S_ISVTX|S_ISGID|S_IRWXG; 74da2e3ebdSchin continue; 75da2e3ebdSchin case 'o': 76da2e3ebdSchin who |= S_ISVTX|S_IRWXO; 77da2e3ebdSchin continue; 78da2e3ebdSchin case 'a': 79da2e3ebdSchin who = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 80da2e3ebdSchin continue; 81da2e3ebdSchin default: 82da2e3ebdSchin if (c >= '0' && c <= '7') 83da2e3ebdSchin { 84da2e3ebdSchin if (!who) 85da2e3ebdSchin who = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 86da2e3ebdSchin c = '='; 87da2e3ebdSchin } 88da2e3ebdSchin expr--; 89da2e3ebdSchin /*FALLTHROUGH*/ 90da2e3ebdSchin case '=': 91da2e3ebdSchin if (who) 92da2e3ebdSchin perm &= ~who; 93da2e3ebdSchin else 94da2e3ebdSchin perm = 0; 95da2e3ebdSchin /*FALLTHROUGH*/ 96da2e3ebdSchin case '+': 97da2e3ebdSchin case '|': 98da2e3ebdSchin case '-': 99da2e3ebdSchin case '&': 100da2e3ebdSchin case '^': 101da2e3ebdSchin op = c; 102da2e3ebdSchin for (;;) 103da2e3ebdSchin { 104da2e3ebdSchin switch (c = *expr++) 105da2e3ebdSchin { 106da2e3ebdSchin case 'r': 107da2e3ebdSchin typ |= S_IRUSR|S_IRGRP|S_IROTH; 108da2e3ebdSchin continue; 109da2e3ebdSchin case 'w': 110da2e3ebdSchin typ |= S_IWUSR|S_IWGRP|S_IWOTH; 111da2e3ebdSchin continue; 112da2e3ebdSchin case 'X': 113da2e3ebdSchin if (!S_ISDIR(perm) && !(perm & (S_IXUSR|S_IXGRP|S_IXOTH))) 114da2e3ebdSchin continue; 115da2e3ebdSchin /*FALLTHROUGH*/ 116da2e3ebdSchin case 'x': 117da2e3ebdSchin typ |= S_IXUSR|S_IXGRP|S_IXOTH; 118da2e3ebdSchin continue; 119da2e3ebdSchin case 's': 120da2e3ebdSchin typ |= S_ISUID|S_ISGID; 121da2e3ebdSchin continue; 122da2e3ebdSchin case 't': 123da2e3ebdSchin typ |= S_ISVTX; 124da2e3ebdSchin continue; 125da2e3ebdSchin case 'l': 126da2e3ebdSchin if (perm & S_IXGRP) 127da2e3ebdSchin { 128da2e3ebdSchin if (e) 129da2e3ebdSchin *e = expr - 1; 130da2e3ebdSchin return perm & S_IPERM; 131da2e3ebdSchin } 132da2e3ebdSchin typ |= S_ISGID; 133da2e3ebdSchin continue; 134da2e3ebdSchin case '=': 135da2e3ebdSchin case '+': 136da2e3ebdSchin case '|': 137da2e3ebdSchin case '-': 138da2e3ebdSchin case '&': 139da2e3ebdSchin case '^': 140da2e3ebdSchin case ',': 141da2e3ebdSchin case 0: 142da2e3ebdSchin if (who) 143da2e3ebdSchin typ &= who; 144da2e3ebdSchin else 145da2e3ebdSchin switch (op) 146da2e3ebdSchin { 147da2e3ebdSchin case '=': 148da2e3ebdSchin case '+': 149da2e3ebdSchin case '|': 150da2e3ebdSchin case '-': 151da2e3ebdSchin case '&': 152da2e3ebdSchin if (!masked) 153da2e3ebdSchin { 154da2e3ebdSchin masked = 1; 155da2e3ebdSchin umask(mask = umask(0)); 156da2e3ebdSchin mask = ~mask; 157da2e3ebdSchin } 158da2e3ebdSchin typ &= mask; 159da2e3ebdSchin break; 160da2e3ebdSchin } 161da2e3ebdSchin switch (op) 162da2e3ebdSchin { 163da2e3ebdSchin default: 164da2e3ebdSchin if (who) 165da2e3ebdSchin perm &= ~who; 166da2e3ebdSchin else 167da2e3ebdSchin perm = 0; 168da2e3ebdSchin /*FALLTHROUGH*/ 169da2e3ebdSchin case '+': 170da2e3ebdSchin case '|': 171da2e3ebdSchin perm |= typ; 172da2e3ebdSchin typ = 0; 173da2e3ebdSchin break; 174da2e3ebdSchin case '-': 175da2e3ebdSchin perm &= ~typ; 176da2e3ebdSchin typ = 0; 177da2e3ebdSchin break; 178da2e3ebdSchin case '&': 179da2e3ebdSchin perm &= typ; 180da2e3ebdSchin typ = 0; 181da2e3ebdSchin break; 182da2e3ebdSchin case '^': 183da2e3ebdSchin if (typ &= perm) 184da2e3ebdSchin { 185da2e3ebdSchin /* 186da2e3ebdSchin * propagate least restrictive to most restrictive 187da2e3ebdSchin */ 188da2e3ebdSchin 189da2e3ebdSchin if (typ & S_IXOTH) 190da2e3ebdSchin perm |= who & (S_IXUSR|S_IXGRP); 191da2e3ebdSchin if (typ & S_IWOTH) 192da2e3ebdSchin perm |= who & (S_IWUSR|S_IWGRP); 193da2e3ebdSchin if (typ & S_IROTH) 194da2e3ebdSchin perm |= who & (S_IRUSR|S_IRGRP); 195da2e3ebdSchin if (typ & S_IXGRP) 196da2e3ebdSchin perm |= who & S_IXUSR; 197da2e3ebdSchin if (typ & S_IWGRP) 198da2e3ebdSchin perm |= who & S_IWUSR; 199da2e3ebdSchin if (typ & S_IRGRP) 200da2e3ebdSchin perm |= who & S_IRUSR; 201da2e3ebdSchin 202da2e3ebdSchin /* 203da2e3ebdSchin * if any execute then read => execute 204da2e3ebdSchin */ 205da2e3ebdSchin 206da2e3ebdSchin if ((typ |= perm) & (S_IXUSR|S_IXGRP|S_IXOTH)) 207da2e3ebdSchin { 208da2e3ebdSchin if (typ & S_IRUSR) 209da2e3ebdSchin perm |= who & S_IXUSR; 210da2e3ebdSchin if (typ & S_IRGRP) 211da2e3ebdSchin perm |= who & S_IXGRP; 212da2e3ebdSchin if (typ & S_IROTH) 213da2e3ebdSchin perm |= who & S_IXOTH; 214da2e3ebdSchin } 215da2e3ebdSchin typ = 0; 216da2e3ebdSchin } 217da2e3ebdSchin break; 218da2e3ebdSchin } 219da2e3ebdSchin switch (c) 220da2e3ebdSchin { 221da2e3ebdSchin case '=': 222da2e3ebdSchin case '+': 223da2e3ebdSchin case '|': 224da2e3ebdSchin case '-': 225da2e3ebdSchin case '&': 226da2e3ebdSchin case '^': 227da2e3ebdSchin op = c; 228da2e3ebdSchin typ = 0; 229da2e3ebdSchin continue; 230da2e3ebdSchin } 231da2e3ebdSchin if (c) 232da2e3ebdSchin break; 233da2e3ebdSchin /*FALLTHROUGH*/ 234da2e3ebdSchin default: 235da2e3ebdSchin if (c < '0' || c > '7') 236da2e3ebdSchin { 237da2e3ebdSchin if (e) 238da2e3ebdSchin *e = expr - 1; 239da2e3ebdSchin if (typ) 240da2e3ebdSchin { 241da2e3ebdSchin if (who) 242da2e3ebdSchin { 243da2e3ebdSchin typ &= who; 244da2e3ebdSchin perm &= ~who; 245da2e3ebdSchin } 246da2e3ebdSchin perm |= typ; 247da2e3ebdSchin } 248da2e3ebdSchin return perm & S_IPERM; 249da2e3ebdSchin } 250da2e3ebdSchin num = (num << 3) | (c - '0'); 251da2e3ebdSchin if (!who && (op == '+' || op == '-')) 252da2e3ebdSchin who = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 253da2e3ebdSchin if (*expr < '0' || *expr > '7') 254da2e3ebdSchin { 255da2e3ebdSchin typ |= modei(num); 256da2e3ebdSchin num = 0; 257da2e3ebdSchin } 258da2e3ebdSchin continue; 259da2e3ebdSchin } 260da2e3ebdSchin break; 261da2e3ebdSchin } 262da2e3ebdSchin break; 263da2e3ebdSchin } 264da2e3ebdSchin break; 265da2e3ebdSchin } 266da2e3ebdSchin } 267da2e3ebdSchin } 268