struct elt *e_link; /* Pointer to the next one along */
size_t e_offset; /* Offset of name in path string */
unsigned e_flags; /* Various useful flags */
+#define EF_STICKY 1u /* Directory has sticky bit set */
char e_name[1]; /* Name of the directory */
};
-#define f_sticky 1u /* Directory has sticky bit set */
-
-#define f_last 1u /* This is the final item to check */
/*----- Static variables --------------------------------------------------*/
-static struct elt rootnode = { 0, 0, 0 }; /* Root of the list */
+static const struct elt rootnode = { 0, 0, 0 }; /* Root of the list */
static struct elt *sp; /* Stack pointer for list */
static dstr d = DSTR_INIT; /* Current path string */
struct elt *e = sp->e_link;
d.len = sp->e_offset;
DPUTZ(&d);
- sp = e;
+ xfree(sp); sp = e;
}
}
* Arguments: @const char *p@ = name of directory to check
* @struct stat *st@ = pointer to @stat@(2) block for it
* @const struct checkpath *cp@ = pointer to caller parameters
- * @unsigned f@ = various flags
+ * @unsigned f@ = various flags (@SF_...@)
*
* Returns: Zero if everything's OK, else bitmask of problems.
*
* Use: Performs the main load of sanity-checking on a directory.
+ * If @SF_LAST@ is not set then sticky directories are always
+ * acceptable.
*/
+#define SF_LAST 1u /* This is the final item to check */
+
static unsigned sanity(const char *p, struct stat *st,
const struct checkpath *cp, unsigned f)
{
unsigned b;
if (S_ISDIR(st->st_mode) &&
- (!(f & f_last) || (cp->cp_what & CP_STICKYOK)))
+ (!(f & SF_LAST) || (cp->cp_what & CP_STICKYOK)))
stickyok = 01000;
/* --- Check for world-writability --- */
/* --- Initialize stack pointer and path string --- */
- sp = &rootnode;
+ sp = (/*unconst*/ struct elt *)&rootnode;
dstr_destroy(&d);
/* --- Try to find the current directory --- */
/* --- Strip off simple `.' elements --- */
if (strcmp(ee->e_name, ".") == 0) {
- free(ee);
+ xfree(ee);
ee = e;
continue;
}
else if (strcmp(ee->e_name, "..") == 0) {
pop();
- free(ee);
+ xfree(ee);
ee = e;
continue;
}
*/
if ((cp->cp_what & CP_WROTHUSR) &&
- (sp->e_link->e_flags & f_sticky) &&
+ (sp->e_link->e_flags & EF_STICKY) &&
st.st_uid != cp->cp_uid && st.st_uid != 0) {
bad |= CP_WROTHUSR;
report(cp, CP_WROTHUSR, 1, d.buf,
/* --- Run the sanity check on this path element --- */
- bad |= sanity(d.buf, &st, cp, ee ? 0 : f_last);
+ bad |= sanity(d.buf, &st, cp, ee ? 0 : SF_LAST);
if (S_ISDIR(st.st_mode)) {
if (st.st_mode & 01000)
- sp->e_flags |= f_sticky;
+ sp->e_flags |= EF_STICKY;
report(cp, CP_REPORT, 4, d.buf, "directory");
continue;
}
report(cp, CP_ERROR, 0, 0, "junk left over after reaching leaf");
while (ee) {
e = ee->e_link;
- free(ee);
+ xfree(ee);
ee = e;
}
}