* 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.)
#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"
}
}
+/* --- @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 -------------------------------------------------*/
#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
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
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
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);
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) {