chiark / gitweb /
keys/tripe-keys.in, keys/tripe-keys.conf.5.in: Allow setting attributes.
[tripe] / common / util.c
index d78dd78d032a3a587fce1dc2b9adb75dc6e3f15c..3de554d72a35d1530f09bc86b7af0b54604ac79f 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <pwd.h>
+#include <grp.h>
+
 #include <mLib/dstr.h>
+#include <mLib/report.h>
 
 #include "util.h"
 
@@ -63,6 +70,88 @@ void u_quotify(dstr *d, const char *p)
     }
     dstr_putc(d, '\"');
   }
+  dstr_putz(d);
+}
+
+/* --- @u_getuser@ --- *
+ *
+ * Arguments:  @const char *name@ = user name or id requested
+ *             @gid_t *gg@ = where to store corresponding gid
+ *
+ * Returns:    Corresponding uid.
+ *
+ * Use:                Resolves a user name into a uid.  Dies on failure; suitable
+ *             for use in argument parsing.
+ */
+
+uid_t u_getuser(const char *name, gid_t *gg)
+{
+  struct passwd *pw;
+  char *p;
+  unsigned long i = strtoul(name, &p, 0);
+
+  if (!*p)
+    pw = getpwuid(i);
+  else
+    pw = getpwnam(name);
+  if (!pw)
+    die(EXIT_FAILURE, "user `%s' not found", name);
+  if (gg && *gg == -1)
+    *gg = pw->pw_gid;
+  return (pw->pw_uid);
+}
+
+/* --- @u_getgroup@ --- *
+ *
+ * Arguments:  @const char *name@ = user name or id requested
+ *
+ * Returns:    Corresponding gid.
+ *
+ * Use:                Resolves a group name into a gid.  Dies on failure; suitable
+ *             for use in argument parsing.
+ */
+
+gid_t u_getgroup(const char *name)
+{
+  struct group *gr;
+  char *p;
+  unsigned long i = strtoul(name, &p, 0);
+
+  if (!*p)
+    gr = getgrgid(i);
+  else
+    gr = getgrnam(name);
+  if (!gr)
+    die(EXIT_FAILURE, "group `%s' not found", name);
+  return (gr->gr_gid);
+}
+
+/* --- @u_setugid@ --- *
+ *
+ * Arguments:  @uid_t u@ = user to set
+ *             @gid_t g@ = group to set
+ *
+ * Returns:    ---
+ *
+ * Use:                Sets user and group to the given values; aborts on failure.
+ */
+
+void u_setugid(uid_t u, gid_t g)
+{
+  uid_t cu = geteuid();
+
+  if (cu == 0 && g != (gid_t)-1) {
+    if (setgid(g) || (getuid() == 0 && setgroups(1, &g))) {
+      die(EXIT_FAILURE, "couldn't setgid to %u: %s",
+         (unsigned)g, strerror(errno));
+    }
+  }
+  if (u != (uid_t)-1) {
+    if (setuid(u)) {
+      die(EXIT_FAILURE, "couldn't setuid to %u: %s",
+         (unsigned)u, strerror(errno));
+    }
+  }
 }
 
 /*----- That's all, folks -------------------------------------------------*/