chiark / gitweb /
server, common: Split more code into utilities.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 8 Dec 2008 12:00:14 +0000 (12:00 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 8 Dec 2008 20:11:31 +0000 (20:11 +0000)
  * Move mystrieq to server/servutil.c where it belongs.

  * Move code to resolve user and group names, and to set user and
    group, into common/util.c where the client can get at it.  (This
    will eventually be useful for privilege separation.)

common/util.c
common/util.h
server/servutil.c
server/tripe.c

index d78dd78..92b9853 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"
 
@@ -65,4 +72,83 @@ void u_quotify(dstr *d, const char *p)
   }
 }
 
+/* --- @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)
+{
+  if (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 -------------------------------------------------*/
index aaef36f..1928c04 100644 (file)
 #ifndef UTIL_H
 #define UTIL_H
 
+#ifndef CONFIG_H
+#  include "config.h"
+#endif
+
+#include <sys/types.h>
+
 #ifdef __cplusplus
   extern "C" {
 #endif
 
 extern void u_quotify(dstr */*d*/, const char */*p*/);
 
+/* --- @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.
+ */
+
+extern uid_t u_getuser(const char */*name*/, gid_t */*gg*/);
+
+/* --- @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.
+ */
+
+extern gid_t u_getgroup(const char */*name*/);
+
+/* --- @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.
+ */
+
+extern void u_setugid(uid_t /*u*/, gid_t /*g*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus
index c95b23f..1f6301a 100644 (file)
@@ -89,6 +89,23 @@ const char *timestr(time_t t)
   return ((const char *)buf_t);
 }
 
+/* --- @mystrieq@ --- *
+ *
+ * Arguments:  @const char *x, *y@ = two strings
+ *
+ * Returns:    True if @x@ and @y are equal, up to case.
+ */
+
+int mystrieq(const char *x, const char *y)
+{
+  for (;;) {
+    if (!*x && !*y) return (1);
+    if (tolower((unsigned char)*x) != tolower((unsigned char)*y))
+      return (0);
+    x++; y++;
+  }
+}
+
 /* --- @seq_reset@ --- *
  *
  * Arguments:  @seqwin *s@ = sequence-checking window
index 280878c..60ab4fd 100644 (file)
@@ -60,23 +60,6 @@ static void interval(struct timeval *tv, void *v)
   sel_addtimer(&sel, &it, &tvv, interval, v);
 }
 
-/* --- @mystrieq@ --- *
- *
- * Arguments:  @const char *x, *y@ = two strings
- *
- * Returns:    True if @x@ and @y are equal, up to case.
- */
-
-int mystrieq(const char *x, const char *y)
-{
-  for (;;) {
-    if (!*x && !*y) return (1);
-    if (tolower((unsigned char)*x) != tolower((unsigned char)*y))
-      return (0);
-    x++; y++;
-  }
-}
-
 /* --- @main@ --- *
  *
  * Arguments:  @int argc@ = number of command line arguments
@@ -200,32 +183,12 @@ int main(int argc, char *argv[])
       case 'D':
        f |= f_daemon;
        break;
-      case 'U': {
-       struct passwd *pw;
-       char *p;
-       unsigned long i = strtoul(optarg, &p, 0);
-       if (!*p)
-         pw = getpwuid(i);
-       else
-         pw = getpwnam(optarg);
-       if (!pw)
-         die(EXIT_FAILURE, "user `%s' not found", optarg);
-       u = pw->pw_uid;
-       if (g == -1)
-         g = pw->pw_gid;
-      } break;
-      case 'G': {
-       struct group *gr;
-       char *p;
-       unsigned long i = strtoul(optarg, &p, 0);
-       if (!*p)
-         gr = getgrgid(i);
-       else
-         gr = getgrnam(optarg);
-       if (!gr)
-         die(EXIT_FAILURE, "group `%s' not found", optarg);
-       g = gr->gr_gid;
-      } break;
+      case 'U':
+       u = u_getuser(optarg, &g);
+       break;
+      case 'G':
+       g = u_getgroup(optarg);
+       break;
 
       case 'b': {
        struct hostent *h = gethostbyname(optarg);
@@ -314,18 +277,7 @@ int main(int argc, char *argv[])
     a_create(STDIN_FILENO, STDOUT_FILENO, AF_WARN);
 #endif
   }
-  if (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));
-    }
-  }
+  u_setugid(u, g);
   km_init(kr_priv, kr_pub, tag_priv);
   a_init(csock);
   if (f & f_daemon) {