X-Git-Url: https://git.distorted.org.uk/~mdw/checkpath/blobdiff_plain/724621554ef66263f2530e17fd6d8f4074b6475c..d7b5ee0cc2a612023bb20492a75af4a7a23e856b:/checkpath.c diff --git a/checkpath.c b/checkpath.c index 4cf0e8f..993cce2 100644 --- a/checkpath.c +++ b/checkpath.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: checkpath.c,v 1.3 1999/05/21 22:07:20 mdw Exp $ + * $Id: checkpath.c,v 1.5 2003/01/25 23:58:44 mdw Exp $ * * Check a path for safety * @@ -29,6 +29,12 @@ /*----- Revision history --------------------------------------------------* * * $Log: checkpath.c,v $ + * Revision 1.5 2003/01/25 23:58:44 mdw + * Make guts into official library. + * + * Revision 1.4 2001/01/25 22:16:02 mdw + * Make flags be unsigned. + * * Revision 1.3 1999/05/21 22:07:20 mdw * Take advantage of new dynamic string macros. * @@ -58,7 +64,7 @@ #include #include -#include "path.h" +#include "checkpath.h" /*----- Data structures ---------------------------------------------------*/ @@ -75,13 +81,9 @@ struct elt { char e_name[1]; /* Name of the directory */ }; -enum { - f_sticky = 1 /* Directory has sticky bit set */ -}; +#define f_sticky 1u /* Directory has sticky bit set */ -enum { - f_last = 1 /* This is the final item to check */ -}; +#define f_last 1u /* This is the final item to check */ /*----- Static variables --------------------------------------------------*/ @@ -195,8 +197,8 @@ static void push(struct elt *e) /* --- @report@ --- * * - * Arguments: @struct chkpath *cp@ = pointer to context - * @int what@ = what sort of report is this? + * Arguments: @const struct checkpath *cp@ = pointer to context + * @unsigned what@ = what sort of report is this? * @int verbose@ = how verbose is this? * @const char *p@ = what path does it refer to? * @const char *msg@ = the message to give to the user @@ -206,7 +208,7 @@ static void push(struct elt *e) * Use: Formats and presents messages to the client. */ -static void report(struct chkpath *cp, int what, int verbose, +static void report(const struct checkpath *cp, unsigned what, int verbose, const char *p, const char *msg, ...) { /* --- Decide whether to bin this message --- */ @@ -284,7 +286,7 @@ static void report(struct chkpath *cp, int what, int verbose, * * Arguments: @const char *p@ = name of directory to check * @struct stat *st@ = pointer to @stat@(2) block for it - * @struct chkpath *cp@ = pointer to caller parameters + * @const struct checkpath *cp@ = pointer to caller parameters * @unsigned f@ = various flags * * Returns: Zero if everything's OK, else bitmask of problems. @@ -292,16 +294,20 @@ static void report(struct chkpath *cp, int what, int verbose, * Use: Performs the main load of sanity-checking on a directory. */ -static int sanity(const char *p, struct stat *st, - struct chkpath *cp, unsigned f) +static unsigned sanity(const char *p, struct stat *st, + const struct checkpath *cp, unsigned f) { - int bad = 0; - int sticky = (cp->cp_what & CP_STICKYOK) || !(f & f_last) ? 01000 : 0; + unsigned bad = 0; + int stickyok = 0; + + if (S_ISDIR(st->st_mode) && + (!(f & f_last) || (cp->cp_what & CP_STICKYOK))) + stickyok = 01000; /* --- Check for world-writability --- */ if ((cp->cp_what & CP_WRWORLD) && - (st->st_mode & (0002 | sticky)) == 0002) { + (st->st_mode & (0002 | stickyok)) == 0002) { bad |= CP_WRWORLD; report(cp, CP_WRWORLD, 1, p, "** world writable **"); } @@ -309,19 +315,21 @@ static int sanity(const char *p, struct stat *st, /* --- Check for group-writability --- */ if ((cp->cp_what & (CP_WRGRP | CP_WROTHGRP)) && - (st->st_mode & (0020 | sticky)) == 0020) { - if (cp->cp_what & CP_WRGRP) { - bad |= CP_WRGRP; - report(cp, CP_WRGRP, 1, p, "writable by group %g", st->st_gid); - } else { - int i; + (st->st_mode & (0020 | stickyok)) == 0020) { + int i; + unsigned b = CP_WRGRP; + + if (cp->cp_what & CP_WROTHGRP) { + b = CP_WROTHGRP; for (i = 0; i < cp->cp_gids; i++) { if (st->st_gid == cp->cp_gid[i]) - goto good_gid; + b = cp->cp_what & CP_WRGRP; } - bad |= CP_WROTHGRP; - report(cp, CP_WROTHGRP, 1, p, "writable by group %g", st->st_gid); - good_gid:; + } + if (b) { + bad |= b; + report(cp, b, 1, p, "writable by %sgroup %g", + (b == CP_WROTHGRP) ? "other " : "", st->st_gid); } } @@ -339,10 +347,10 @@ static int sanity(const char *p, struct stat *st, return (bad); } -/* --- @path_check@ --- * +/* --- @checkpath@ --- * * * Arguments: @const char *p@ = directory name which needs checking - * @struct chkpath *cp@ = caller parameters for the check + * @const struct checkpath *cp@ = parameters for the check * * Returns: Zero if all is well, otherwise bitmask of problems. * @@ -350,12 +358,12 @@ static int sanity(const char *p, struct stat *st, * users could do to it. */ -int path_check(const char *p, struct chkpath *cp) +unsigned checkpath(const char *p, const struct checkpath *cp) { char cwd[PATH_MAX]; struct elt *e, *ee; struct stat st; - int bad = 0; + unsigned bad = 0; /* --- Initialize stack pointer and path string --- */ @@ -495,16 +503,16 @@ int path_check(const char *p, struct chkpath *cp) return (bad); } -/* --- @path_setids@ --- * +/* --- @checkpath_setids@ --- * * - * Arguments: @struct chkpath *cp@ = pointer to block to fill in + * Arguments: @struct checkpath *cp@ = pointer to block to fill in * - * Returns: Zero if OK, else @-1@. + * Returns: --- * * Use: Fills in the user ids and things in the structure. */ -void path_setids(struct chkpath *cp) +void checkpath_setids(struct checkpath *cp) { int n, i; gid_t g = getgid();