|
|
1.1 ! root 1: /* chmod_chk.c - check a stat structure based upon chmod style permissions. ! 2: * part of uucheck. ! 3: */ ! 4: ! 5: #include <sys/stat.h> ! 6: #include "morestat.h" /* The stat definitions that were left out. */ ! 7: #include "checkperms.h" ! 8: #include "y.tab.h" ! 9: ! 10: /* Test whether statptr->st_mode corresponds to a desired permission. */ ! 11: ! 12: #define TST(mask, flag) (flag && \ ! 13: ( (((statptr->st_mode) & mask)?TRUE:FALSE) != i_want)) ! 14: ! 15: boolean ! 16: chmod_chk(path, ugostrwx, statptr, msg_type) ! 17: unsigned char *path; ! 18: unsigned char *ugostrwx; ! 19: struct stat *statptr; ! 20: int msg_type; /* Error messages or just warning messages? */ ! 21: { ! 22: unsigned char *s; /* Handy loop variable for walking through stuff. */ ! 23: ! 24: boolean user_f = FALSE; ! 25: boolean group_f = FALSE; ! 26: boolean others_f = FALSE; ! 27: boolean setid_f = FALSE; ! 28: boolean sticky_f = FALSE; ! 29: boolean read_f = FALSE; ! 30: boolean write_f = FALSE; ! 31: boolean execute_f = FALSE; ! 32: boolean i_want; /* Do we want these permissions, or not? */ ! 33: boolean error = FALSE; ! 34: boolean warning = FALSE; ! 35: ! 36: /* fill in statptr if it isn't already */ ! 37: if (statptr == (struct stat *) NULL) { ! 38: statptr = (struct stat *) malloc(sizeof(struct stat)); ! 39: stat(path, statptr); ! 40: } ! 41: ! 42: /* Pick off user, group, and other. */ ! 43: for(s = ugostrwx; (*s != '+') && (*s != '-') && (*s != (unsigned char) NULL); ++s) { ! 44: switch(*s) { ! 45: case 'u': user_f = TRUE; break; ! 46: case 'g': group_f = TRUE; break; ! 47: case 'o': others_f = TRUE; break; ! 48: default: ! 49: VERBOSE("(POOrly Formed Formula) ugo\n"); ! 50: FATAL("Who POOFF: %s\n", ugostrwx); ! 51: } /* switch(*s) */ ! 52: #if 0 ! 53: /* DEBUG */ fprintf(stderr, "who: %c\n",*s); ! 54: #endif /* 0 */ ! 55: } /* for s = ugostrwx to '+' */ ! 56: ! 57: /* We should not have hit end of string yet! */ ! 58: if (*s == (char) NULL) { ! 59: VERBOSE("(POOrly Formed Formula)\n"); ! 60: FATAL("No '+' or '-' POOFF: %s\n", ugostrwx); ! 61: } /* if *s == (char) NULL */ ! 62: ! 63: /* Do we want these permissions, or do we want them not? */ ! 64: if (*s == '+') { ! 65: i_want = TRUE; ! 66: } else { ! 67: i_want = FALSE; ! 68: } ! 69: ! 70: ++s; /* Skip past the '+' or '-'. */ ! 71: ! 72: /* Pick off setid, sticky, read, write, and execute. */ ! 73: for(; (*s != '+') && (*s != (char) NULL); ++s) { ! 74: switch(*s) { ! 75: case 's': setid_f = TRUE; break; ! 76: case 't': sticky_f = TRUE; break; ! 77: case 'r': read_f = TRUE; break; ! 78: case 'w': write_f = TRUE; break; ! 79: case 'x': execute_f = TRUE; break; ! 80: default: ! 81: VERBOSE("(POOrly Formed Formula) strwx\n"); ! 82: FATAL("What POOFF: %s\n", ugostrwx); ! 83: } /* switch(*s) */ ! 84: #if 0 ! 85: /* DEBUG */ fprintf(stderr, "what: %c\n",*s); ! 86: #endif /* 0 */ ! 87: } /* for s = ugostrwx to '+' */ ! 88: ! 89: /* CHECKPOINT - Now all flags are set according to the characters ! 90: * in the chmod permissions string. ! 91: */ ! 92: ! 93: /* I don't see a good way to do the following without making this ! 94: * table flavored code. Perhaps this code should be automaticly ! 95: * generated from some table. ! 96: */ ! 97: if (user_f){ ! 98: if (TST(S_ISVTX, sticky_f)) { ! 99: sprintf(bigbuf, "%s is %ssticky.", ! 100: path, i_want?"not ":""); ! 101: notice(msg_type, bigbuf, NULL); ! 102: SETFAIL; ! 103: sprintf(command, "chmod %ct %s", ! 104: i_want?'+':'-', path); ! 105: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 106: VERBOSE(bigbuf); ! 107: FIX(system(command);); ! 108: } /* if setid_f */ ! 109: if (TST(S_IREAD, read_f)) { ! 110: sprintf(bigbuf, "%s is %sowner readable.", ! 111: path, i_want?"not ":""); ! 112: notice(msg_type, bigbuf, NULL); ! 113: SETFAIL; ! 114: sprintf(command, "chmod u%cr %s", ! 115: i_want?'+':'-', path); ! 116: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 117: VERBOSE(bigbuf); ! 118: FIX(system(command);); ! 119: } /* if read_f */ ! 120: if (TST(S_IWRITE, write_f)) { ! 121: sprintf(bigbuf, "%s is %sowner writable.", ! 122: path, i_want?"not ":""); ! 123: notice(msg_type, bigbuf, NULL); ! 124: SETFAIL; ! 125: sprintf(command, "chmod u%cw %s", ! 126: i_want?'+':'-', path); ! 127: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 128: VERBOSE(bigbuf); ! 129: FIX(system(command);); ! 130: } /* if write_f */ ! 131: if (TST(S_IEXEC, execute_f)) { ! 132: sprintf(bigbuf, "%s is %sowner executable.", ! 133: path, i_want?"not ":""); ! 134: notice(msg_type, bigbuf, NULL); ! 135: SETFAIL; ! 136: sprintf(command, "chmod u%cx %s", ! 137: i_want?'+':'-', path); ! 138: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 139: VERBOSE(bigbuf); ! 140: FIX(system(command);); ! 141: } /* if execute_f */ ! 142: /* Setuid must come last, or it will be lost. */ ! 143: if (TST(S_ISUID, setid_f)) { ! 144: sprintf(bigbuf, "%s is %ssetuid.", ! 145: path, i_want?"not ":""); ! 146: notice(msg_type, bigbuf, NULL); ! 147: SETFAIL; ! 148: sprintf(command, "chmod u%cs %s", ! 149: i_want?'+':'-', path); ! 150: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 151: VERBOSE(bigbuf); ! 152: FIX(system(command);); ! 153: } /* if setid_f */ ! 154: } /* if user_f */ ! 155: ! 156: if (group_f){ ! 157: if (TST(S_ISVTX, sticky_f)) { ! 158: sprintf(bigbuf, "%s is %ssticky.", ! 159: path, i_want?"not ":""); ! 160: notice(msg_type, bigbuf, NULL); ! 161: SETFAIL; ! 162: sprintf(command, "chmod %ct %s", ! 163: i_want?'+':'-', path); ! 164: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 165: VERBOSE(bigbuf); ! 166: FIX(system(command);); ! 167: } /* if setid_f */ ! 168: if (TST(S_IGREAD, read_f)) { ! 169: sprintf(bigbuf, "%s is %sgroup readable.", ! 170: path, i_want?"not ":""); ! 171: notice(msg_type, bigbuf, NULL); ! 172: SETFAIL; ! 173: sprintf(command, "chmod g%cr %s", ! 174: i_want?'+':'-', path); ! 175: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 176: VERBOSE(bigbuf); ! 177: FIX(system(command);); ! 178: } /* if read_f */ ! 179: if (TST(S_IGWRITE, write_f)) { ! 180: sprintf(bigbuf, "%s is %sgroup writable.", ! 181: path, i_want?"not ":""); ! 182: notice(msg_type, bigbuf, NULL); ! 183: SETFAIL; ! 184: sprintf(command, "chmod g%cw %s", ! 185: i_want?'+':'-', path); ! 186: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 187: VERBOSE(bigbuf); ! 188: FIX(system(command);); ! 189: } /* if write_f */ ! 190: if (TST(S_IGEXEC, execute_f)) { ! 191: sprintf(bigbuf, "%s is %sgroup executable.", ! 192: path, i_want?"not ":""); ! 193: notice(msg_type, bigbuf, NULL); ! 194: SETFAIL; ! 195: sprintf(command, "chmod g%cx %s", ! 196: i_want?'+':'-', path); ! 197: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 198: VERBOSE(bigbuf); ! 199: FIX(system(command);); ! 200: } /* if execute_f */ ! 201: if (TST(S_ISGID, setid_f)) { ! 202: sprintf(bigbuf, "%s is %ssetgid.", ! 203: path, i_want?"not ":""); ! 204: notice(msg_type, bigbuf, NULL); ! 205: SETFAIL; ! 206: sprintf(command, "chmod g%cs %s", ! 207: i_want?'+':'-', path); ! 208: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 209: VERBOSE(bigbuf); ! 210: FIX(system(command);); ! 211: } /* if setid_f */ ! 212: } /* if group_f */ ! 213: ! 214: if (others_f){ ! 215: if (TST(S_ISVTX, sticky_f)) { ! 216: sprintf(bigbuf, "%s is %ssticky.", ! 217: path, i_want?"not ":""); ! 218: notice(msg_type, bigbuf, NULL); ! 219: SETFAIL; ! 220: sprintf(command, "chmod %ct %s", ! 221: i_want?'+':'-', path); ! 222: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 223: VERBOSE(bigbuf); ! 224: FIX(system(command);); ! 225: } /* if setid_f */ ! 226: if (TST(S_IOREAD, read_f)) { ! 227: sprintf(bigbuf, "%s is %spublicly readable.", ! 228: path, i_want?"not ":""); ! 229: notice(msg_type, bigbuf, NULL); ! 230: SETFAIL; ! 231: sprintf(command, "chmod o%cr %s", ! 232: i_want?'+':'-', path); ! 233: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 234: VERBOSE(bigbuf); ! 235: FIX(system(command);); ! 236: } /* if read_f */ ! 237: if (TST(S_IOWRITE, write_f)) { ! 238: sprintf(bigbuf, "%s is %spublicly writable.", ! 239: path, i_want?"not ":""); ! 240: notice(msg_type, bigbuf, NULL); ! 241: SETFAIL; ! 242: sprintf(command, "chmod o%cw %s", ! 243: i_want?'+':'-', path); ! 244: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 245: VERBOSE(bigbuf); ! 246: FIX(system(command);); ! 247: } /* if write_f */ ! 248: if (TST(S_IOEXEC, execute_f)) { ! 249: sprintf(bigbuf, "%s is %spublicly executable.", ! 250: path, i_want?"not ":""); ! 251: notice(msg_type, bigbuf, NULL); ! 252: SETFAIL; ! 253: sprintf(command, "chmod o%cx %s", ! 254: i_want?'+':'-', path); ! 255: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command); ! 256: VERBOSE(bigbuf); ! 257: FIX(system(command);); ! 258: } /* if execute_f */ ! 259: } /* if other_f */ ! 260: ! 261: if (error || warning) { ! 262: return(FALSE); ! 263: } else { ! 264: return(TRUE); ! 265: } /* if error || warning */ ! 266: } /* chmod_chk() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.