aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-05 22:50:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-05 22:50:22 +0000
commitde59c0f58fa5dc75b753f94da61be92bfa0935ec (patch)
treefea308471e3d73fb6770ff6e4cda23da53b65bec
parent01c27fc5ac89b07821a5430880d771e3c993c1c1 (diff)
downloadbusybox-de59c0f58fa5dc75b753f94da61be92bfa0935ec.tar.gz
httpd: add -u user[:grp] support
-rw-r--r--coreutils/id.c26
-rw-r--r--e2fsprogs/ext2fs/version.c2
-rw-r--r--include/libbb.h7
-rw-r--r--include/usage.h10
-rw-r--r--libbb/safe_strncpy.c5
-rw-r--r--libpwdgrp/Kbuild2
-rw-r--r--libpwdgrp/uidgid_get.c49
-rw-r--r--networking/httpd.c30
-rw-r--r--runit/Kbuild2
-rw-r--r--runit/chpst.c46
-rw-r--r--runit/uidgid.c63
-rw-r--r--runit/uidgid.h14
12 files changed, 117 insertions, 139 deletions
diff --git a/coreutils/id.c b/coreutils/id.c
index 9e49999cd..9d605325c 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -29,11 +29,11 @@
static short printf_full(unsigned int id, const char *arg, const char prefix)
{
const char *fmt = "%cid=%u";
- short status=EXIT_FAILURE;
+ short status = EXIT_FAILURE;
- if(arg) {
+ if (arg) {
fmt = "%cid=%u(%s)";
- status=EXIT_SUCCESS;
+ status = EXIT_SUCCESS;
}
bb_printf(fmt, prefix, id, arg);
return status;
@@ -60,21 +60,21 @@ int id_main(int argc, char **argv)
gid = getgid();
}
- if(argv[optind]) {
- p=getpwnam(argv[optind]);
+ if (argv[optind]) {
+ p = getpwnam(argv[optind]);
/* bb_xgetpwnam is needed because it exits on failure */
uid = bb_xgetpwnam(argv[optind]);
gid = p->pw_gid;
/* in this case PRINT_REAL is the same */
}
- if(flags & (JUST_GROUP | JUST_USER)) {
+ if (flags & (JUST_GROUP | JUST_USER)) {
/* JUST_GROUP and JUST_USER are mutually exclusive */
- if(flags & NAME_NOT_NUMBER) {
+ if (flags & NAME_NOT_NUMBER) {
/* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */
puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 ));
} else {
- bb_printf("%u\n",(flags & JUST_USER) ? uid : gid);
+ bb_printf("%u\n", (flags & JUST_USER) ? uid : gid);
}
/* exit */
bb_fflush_stdout_and_exit(EXIT_SUCCESS);
@@ -82,13 +82,13 @@ int id_main(int argc, char **argv)
/* Print full info like GNU id */
/* bb_getpwuid doesn't exit on failure here */
- status=printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u');
+ status = printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u');
putchar(' ');
/* bb_getgrgid doesn't exit on failure here */
- status|=printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g');
+ status |= printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g');
#ifdef CONFIG_SELINUX
- if ( is_selinux_enabled() ) {
+ if (is_selinux_enabled()) {
security_context_t mysid;
char context[80];
int len = sizeof(context);
@@ -99,8 +99,8 @@ int id_main(int argc, char **argv)
len = strlen(mysid)+1;
safe_strncpy(context, mysid, len);
freecon(mysid);
- }else{
- safe_strncpy(context, "unknown",8);
+ } else {
+ safe_strncpy(context, "unknown", 8);
}
bb_printf(" context=%s", context);
}
diff --git a/e2fsprogs/ext2fs/version.c b/e2fsprogs/ext2fs/version.c
index 882e121d4..d2981e867 100644
--- a/e2fsprogs/ext2fs/version.c
+++ b/e2fsprogs/ext2fs/version.c
@@ -20,8 +20,6 @@
#include "ext2_fs.h"
#include "ext2fs.h"
-//#include "../../version.h"
-
static const char *lib_version = E2FSPROGS_VERSION;
static const char *lib_date = E2FSPROGS_DATE;
diff --git a/include/libbb.h b/include/libbb.h
index ed1d780fd..adfeca590 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -291,6 +291,13 @@ extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char pre
extern char *bb_getpwuid(char *name, long uid, int bufsize);
extern char *bb_getgrgid(char *group, long gid, int bufsize);
extern char *bb_askpass(int timeout, const char * prompt);
+/* from chpst */
+struct bb_uidgid_t {
+ uid_t uid;
+ gid_t gid;
+};
+extern unsigned uidgid_get(struct bb_uidgid_t*, const char* /*, unsigned*/);
+
extern int device_open(const char *device, int mode);
diff --git a/include/usage.h b/include/usage.h
index 34b0566cd..c9e501903 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -1167,7 +1167,7 @@ USE_FEATURE_DATE_ISOFMT( \
#define httpd_trivial_usage \
"[-c <conf file>]" \
USE_FEATURE_HTTPD_WITHOUT_INETD(" [-p <port>]") \
- USE_FEATURE_HTTPD_SETUID(" [-u user]") \
+ USE_FEATURE_HTTPD_SETUID(" [-u user[:grp]]") \
USE_FEATURE_HTTPD_BASIC_AUTH(" [-r <realm>]") \
USE_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \
" [-h home]" \
@@ -1176,12 +1176,12 @@ USE_FEATURE_DATE_ISOFMT( \
"Listens for incoming http server requests.\n\n" \
"Options:\n" \
"\t-c FILE\t\tSpecifies configuration file. (default httpd.conf)\n" \
- USE_FEATURE_HTTPD_WITHOUT_INETD("\t-p PORT\tServer port (default 80)\n") \
- USE_FEATURE_HTTPD_SETUID("\t-u USER\tSet uid to USER after listening privileges port\n") \
+ USE_FEATURE_HTTPD_WITHOUT_INETD("\t-p PORT\t\tServer port (default 80)\n") \
+ USE_FEATURE_HTTPD_SETUID("\t-u USER[:GRP]\tSet uid/gid after binding to port\n") \
USE_FEATURE_HTTPD_BASIC_AUTH("\t-r REALM\tAuthentication Realm for Basic Authentication\n") \
USE_FEATURE_HTTPD_AUTH_MD5("\t-m PASS\t\tCrypt PASS with md5 algorithm\n") \
- "\t-h HOME \tSpecifies http HOME directory (default ./)\n" \
- "\t-e STRING\tHtml encode STRING\n" \
+ "\t-h HOME\t\tSpecifies http HOME directory (default ./)\n" \
+ "\t-e STRING\tHTML encode STRING\n" \
"\t-d STRING\tURL decode STRING"
#define hwclock_trivial_usage \
diff --git a/libbb/safe_strncpy.c b/libbb/safe_strncpy.c
index add92ac9f..42bc16ea0 100644
--- a/libbb/safe_strncpy.c
+++ b/libbb/safe_strncpy.c
@@ -15,6 +15,7 @@
/* Like strncpy but make sure the resulting string is always 0 terminated. */
char * safe_strncpy(char *dst, const char *src, size_t size)
{
- dst[size-1] = '\0';
- return strncpy(dst, src, size-1);
+ if (!size) return dst;
+ dst[--size] = '\0';
+ return strncpy(dst, src, size);
}
diff --git a/libpwdgrp/Kbuild b/libpwdgrp/Kbuild
index 36a6ce393..9e60ef1e5 100644
--- a/libpwdgrp/Kbuild
+++ b/libpwdgrp/Kbuild
@@ -4,4 +4,4 @@
#
# Licensed under the GPL v2, see the file LICENSE in this tarball.
-lib-y:=pwd_grp.o
+lib-y:=pwd_grp.o uidgid_get.o
diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c
new file mode 100644
index 000000000..a2d02a84f
--- /dev/null
+++ b/libpwdgrp/uidgid_get.c
@@ -0,0 +1,49 @@
+#include "busybox.h"
+
+unsigned uidgid_get(struct bb_uidgid_t *u, const char *ug /*, unsigned dogrp */)
+{
+ struct passwd *pwd;
+ struct group *gr;
+ const char *g;
+
+ /* g = 0; if (dogrp) g = strchr(ug, ':'); */
+ g = strchr(ug, ':');
+ if (g) {
+ int sz = (++g) - ug;
+ char buf[sz];
+ safe_strncpy(buf, ug, sz);
+ pwd = getpwnam(buf);
+ } else
+ pwd = getpwnam(ug);
+ if (!pwd)
+ return 0;
+ u->uid = pwd->pw_uid;
+ u->gid = pwd->pw_gid;
+ if (g) {
+ gr = getgrnam(g);
+ if (!gr) return 0;
+ u->gid = gr->gr_gid;
+ }
+ return 1;
+}
+
+#if 0
+#include <stdio.h>
+int main()
+{
+ unsigned u;
+ struct bb_uidgid_t ug;
+ u = uidgid_get(&ug, "apache");
+ printf("%u = %u:%u\n", u, ug.uid, ug.gid);
+ ug.uid = ug.gid = 1111;
+ u = uidgid_get(&ug, "apache");
+ printf("%u = %u:%u\n", u, ug.uid, ug.gid);
+ ug.uid = ug.gid = 1111;
+ u = uidgid_get(&ug, "apache:users");
+ printf("%u = %u:%u\n", u, ug.uid, ug.gid);
+ ug.uid = ug.gid = 1111;
+ u = uidgid_get(&ug, "apache:users");
+ printf("%u = %u:%u\n", u, ug.uid, ug.gid);
+ return 0;
+}
+#endif
diff --git a/networking/httpd.c b/networking/httpd.c
index ac9eac6bf..8f985774e 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -1916,8 +1916,8 @@ int httpd_main(int argc, char *argv[])
USE_FEATURE_HTTPD_WITHOUT_INETD(const char *s_port;)
USE_FEATURE_HTTPD_WITHOUT_INETD(int server;)
- USE_FEATURE_HTTPD_SETUID(const char *s_uid;)
- USE_FEATURE_HTTPD_SETUID(long uid = -1;)
+ USE_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;)
+ USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;)
USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;)
@@ -1937,7 +1937,7 @@ int httpd_main(int argc, char *argv[])
USE_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode)
USE_FEATURE_HTTPD_BASIC_AUTH(, &(config->realm))
USE_FEATURE_HTTPD_AUTH_MD5(, &pass)
- USE_FEATURE_HTTPD_SETUID(, &s_uid)
+ USE_FEATURE_HTTPD_SETUID(, &s_ugid)
USE_FEATURE_HTTPD_WITHOUT_INETD(, &s_port)
);
@@ -1963,11 +1963,18 @@ int httpd_main(int argc, char *argv[])
#if ENABLE_FEATURE_HTTPD_SETUID
if (opt & OPT_SETUID) {
char *e;
-
- uid = strtol(s_uid, &e, 0);
+ // FIXME: what the default group should be?
+ ugid.gid = -1;
+ ugid.uid = strtoul(s_ugid, &e, 0);
+ if (*e == ':') {
+ e++;
+ ugid.gid = strtoul(e, &e, 0);
+ }
if (*e != '\0') {
/* not integer */
- uid = bb_xgetpwnam(s_uid);
+ if (!uidgid_get(&ugid, s_ugid))
+ bb_error_msg_and_die("unrecognized user[:group] "
+ "name '%s'", s_ugid);
}
}
#endif
@@ -1978,8 +1985,15 @@ int httpd_main(int argc, char *argv[])
server = openServer();
# ifdef CONFIG_FEATURE_HTTPD_SETUID
/* drop privileges */
- if (uid > 0)
- xsetuid(uid);
+ if (opt & OPT_SETUID) {
+ if (ugid.gid != (gid_t)-1) {
+ // FIXME: needed?
+ //if (setgroups(1, &ugid.gid) == -1)
+ // bb_perror_msg_and_die("setgroups");
+ xsetgid(ugid.gid);
+ }
+ xsetuid(ugid.uid);
+ }
# endif
#endif
diff --git a/runit/Kbuild b/runit/Kbuild
index 9fee84224..39a9b0229 100644
--- a/runit/Kbuild
+++ b/runit/Kbuild
@@ -5,4 +5,4 @@
# Licensed under the GPL v2, see the file LICENSE in this tarball.
lib-y:=
-lib-$(CONFIG_CHPST) += chpst.o uidgid.o
+lib-$(CONFIG_CHPST) += chpst.o
diff --git a/runit/chpst.c b/runit/chpst.c
index 1ee9b8d0f..da2f270e2 100644
--- a/runit/chpst.c
+++ b/runit/chpst.c
@@ -1,16 +1,9 @@
#include "busybox.h"
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <grp.h>
-
-#include "uidgid.h"
-
-#include <sys/types.h>
#include <dirent.h>
static unsigned option_mask;
-// Must meatch constants in chpst_main!
+// Must match constants in chpst_main!
#define OPT_verbose (option_mask & 0x2000)
#define OPT_pgrp (option_mask & 0x4000)
#define OPT_nostdin (option_mask & 0x8000)
@@ -33,34 +26,27 @@ static long limitt = -2;
static long nicelvl;
static const char *root;
-static void suidgid(char *user, unsigned dogrp)
+static void suidgid(char *user)
{
- struct uidgid ugid;
+ struct bb_uidgid_t ugid;
- if (!uidgid_get(&ugid, user, dogrp)) {
- if (dogrp)
- bb_error_msg_and_die("unknown user/group: %s", user);
- else
- bb_error_msg_and_die("unknown account: %s", user);
+ if (!uidgid_get(&ugid, user)) {
+ bb_error_msg_and_die("unknown user/group: %s", user);
}
- if (setgroups(ugid.gids, ugid.gid) == -1)
+ if (setgroups(1, &ugid.gid) == -1)
bb_perror_msg_and_die("setgroups");
- xsetgid(*ugid.gid);
+ xsetgid(ugid.gid);
xsetuid(ugid.uid);
}
-static void euidgid(char *user, unsigned dogrp)
+static void euidgid(char *user)
{
- struct uidgid ugid;
+ struct bb_uidgid_t ugid;
- if (!uidgid_get(&ugid, user, dogrp)) {
- if (dogrp)
- bb_error_msg_and_die("unknown user/group: %s", user);
- else
- bb_error_msg_and_die("unknown account: %s", user);
+ if (!uidgid_get(&ugid, user)) {
+ bb_error_msg_and_die("unknown user/group: %s", user);
}
- //FIXME: ultoa needed here!
- xsetenv("GID", utoa(*ugid.gid));
+ xsetenv("GID", utoa(ugid.gid));
xsetenv("UID", utoa(ugid.uid));
}
@@ -276,8 +262,8 @@ int chpst_main(int argc, char **argv)
if (nice(nicelvl) == -1)
bb_perror_msg_and_die("nice");
}
- if (env_user) euidgid(env_user, 1);
- if (set_user) suidgid(set_user, 1);
+ if (env_user) euidgid(env_user);
+ if (set_user) suidgid(set_user);
if (OPT_nostdin) close(0);
if (OPT_nostdout) close(1);
if (OPT_nostderr) close(2);
@@ -292,7 +278,7 @@ static void setuidgid(int argc, char **argv)
account = *++argv;
if (!account) bb_show_usage();
if (!*++argv) bb_show_usage();
- suidgid((char*)account, 0);
+ suidgid((char*)account);
execvp(argv[0], argv);
bb_perror_msg_and_die("exec %s", argv[0]);
}
@@ -304,7 +290,7 @@ static void envuidgid(int argc, char **argv)
account = *++argv;
if (!account) bb_show_usage();
if (!*++argv) bb_show_usage();
- euidgid((char*)account, 0);
+ euidgid((char*)account);
execvp(argv[0], argv);
bb_perror_msg_and_die("exec %s", argv[0]);
}
diff --git a/runit/uidgid.c b/runit/uidgid.c
deleted file mode 100644
index a8fec409d..000000000
--- a/runit/uidgid.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-#include "uidgid.h"
-
-static unsigned str_chr(const char *s, int c)
-{
- const char *t = s;
- while (t[0] && t[0] != (char)c)
- t++;
- return t - s;
-}
-
-
-unsigned uidgid_get(struct uidgid *u, char *ug, unsigned dogrp) {
- char *g = 0;
- struct passwd *pwd = 0;
- struct group *gr = 0;
- int i, d = 0;
-
- if (dogrp)
- d = str_chr(ug, ':');
- if (ug[d] == ':') {
- ug[d] = 0;
- g = ug + d + 1;
- }
- pwd = getpwnam(ug);
- if (!pwd) {
- if (g) ug[d] = ':';
- return 0;
- }
- if (g) {
- ug[d] = ':';
- for (i = 0; i < 60; ++i) {
- d = str_chr(g, ':');
- if (g[d] == ':') {
- g[d] = 0;
- gr = getgrnam(g);
- if (!gr) {
- g[d] = ':';
- return 0;
- }
- g[d] = ':';
- u->gid[i] = gr->gr_gid;
- g += d+1;
- }
- else {
- gr = getgrnam(g);
- if (!gr) return 0;
- u->gid[i++] = gr->gr_gid;
- break;
- }
- }
- u->gid[i] = 0;
- u->gids = i;
- }
- if (!g) {
- u->gid[0] = pwd->pw_gid;
- u->gids = 1;
- }
- u->uid = pwd->pw_uid;
- return 1;
-}
diff --git a/runit/uidgid.h b/runit/uidgid.h
deleted file mode 100644
index 1d47fe620..000000000
--- a/runit/uidgid.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef UIDGID_H
-#define UIDGID_H
-
-#include <sys/types.h>
-
-struct uidgid {
- uid_t uid;
- gid_t gid[61];
- int gids;
-};
-
-extern unsigned uidgid_get(struct uidgid *, char *, unsigned);
-
-#endif