#include <mLib/alloc.h>
#include <mLib/dstr.h>
+#include <mLib/macros.h>
#include "checkpath.h"
return (bad);
}
-/* --- @checkpath_setids@ --- *
+/* --- @checkpath_addgid@ --- *
*
* Arguments: @struct checkpath *cp@ = pointer to block to fill in
+ * @gid_t g@ = group id to add
*
- * Returns: ---
+ * Returns: Zero if successful, nonzero if the array is full.
*
- * Use: Fills in the user ids and things in the structure.
+ * Use: Adds the group @g@ to the structure.
*/
-void checkpath_setids(struct checkpath *cp)
+int checkpath_addgid(struct checkpath *cp, gid_t g)
{
- int n, i;
- gid_t g = getgid();
+ int i;
+
+ for (i = 0; i < cp->cp_gids; i++) {
+ if (cp->cp_gid[i] == g)
+ return (0);
+ }
+ if (cp->cp_gids >= N(cp->cp_gid))
+ return (-1);
+ cp->cp_gid[cp->cp_gids++] = g;
+ return (0);
+}
+
+/* --- @checkpath_setuid@ --- *
+ *
+ * Arguments: @struct checkpath *cp@ = pointer to block to fill in
+ *
+ * Returns: ---
+ *
+ * Use: Fills in the @cp_uid@ slot of the structure with the real uid
+ * of the current process.
+ */
+
+void checkpath_setuid(struct checkpath *cp) { cp->cp_uid = getuid(); }
+
+/* --- @checkpath_setgid@ --- *
+ *
+ * Arguments: @struct checkpath *cp@ = pointer to block to fill in
+ *
+ * Returns: Zero if successful, nonzero if the array is full.
+ *
+ * Use: Adds the real gid of the current process to the @cp_gid@
+ * array.
+ */
- cp->cp_uid = getuid();
- n = getgroups(sizeof(cp->cp_gid) / sizeof(cp->cp_gid[0]), cp->cp_gid);
+int checkpath_setgid(struct checkpath *cp)
+ { return (checkpath_addgid(cp, getgid())); }
+/* --- @checkpath_setgroups@ --- *
+ *
+ * Arguments: @struct checkpath *cp@ = pointer to block to fill in
+ *
+ * Returns: Zero if successful, nonzero if the array is full.
+ *
+ * Use: Adds the current process's supplementary groups to the
+ * @cp_gid@ table.
+ */
+
+int checkpath_setgroups(struct checkpath *cp)
+{
+ int i, n;
+ gid_t gg[NGROUPS_MAX];
+
+ n = getgroups(N(gg), gg);
for (i = 0; i < n; i++) {
- if (cp->cp_gid[i] == g)
- goto gid_ok;
+ if (checkpath_addgid(cp, gg[i]))
+ return (-1);
}
- cp->cp_gid[n++] = g;
-gid_ok:
- cp->cp_gids = n;
+ return (0);
+}
+
+/* --- @checkpath_setids@ --- *
+ *
+ * Arguments: @struct checkpath *cp@ = pointer to block to fill in
+ *
+ * Returns: ---
+ *
+ * Use: Fills in the user ids and things in the structure. This is
+ * equivalent to setting @cp_gids = 0@ and then calling
+ * @_setuid@, @_setgid@ and @_setgroups@. It can't fail.
+ */
+
+void checkpath_setids(struct checkpath *cp)
+{
+ cp->cp_gids = 0;
+ checkpath_setuid(cp);
+ checkpath_setgid(cp);
+ checkpath_setgroups(cp);
}
/*----- That's all, folks -------------------------------------------------*/