httpd: add -u user[:grp] support

This commit is contained in:
Denis Vlasenko 2006-10-05 22:50:22 +00:00
parent 01c27fc5ac
commit de59c0f58f
12 changed files with 117 additions and 139 deletions

View File

@ -20,8 +20,6 @@
#include "ext2_fs.h" #include "ext2_fs.h"
#include "ext2fs.h" #include "ext2fs.h"
//#include "../../version.h"
static const char *lib_version = E2FSPROGS_VERSION; static const char *lib_version = E2FSPROGS_VERSION;
static const char *lib_date = E2FSPROGS_DATE; static const char *lib_date = E2FSPROGS_DATE;

View File

@ -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_getpwuid(char *name, long uid, int bufsize);
extern char *bb_getgrgid(char *group, long gid, int bufsize); extern char *bb_getgrgid(char *group, long gid, int bufsize);
extern char *bb_askpass(int timeout, const char * prompt); 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); extern int device_open(const char *device, int mode);

View File

@ -1167,7 +1167,7 @@ USE_FEATURE_DATE_ISOFMT( \
#define httpd_trivial_usage \ #define httpd_trivial_usage \
"[-c <conf file>]" \ "[-c <conf file>]" \
USE_FEATURE_HTTPD_WITHOUT_INETD(" [-p <port>]") \ 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_BASIC_AUTH(" [-r <realm>]") \
USE_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \ USE_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \
" [-h home]" \ " [-h home]" \
@ -1176,12 +1176,12 @@ USE_FEATURE_DATE_ISOFMT( \
"Listens for incoming http server requests.\n\n" \ "Listens for incoming http server requests.\n\n" \
"Options:\n" \ "Options:\n" \
"\t-c FILE\t\tSpecifies configuration file. (default httpd.conf)\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_WITHOUT_INETD("\t-p PORT\t\tServer port (default 80)\n") \
USE_FEATURE_HTTPD_SETUID("\t-u USER\tSet uid to USER after listening privileges port\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_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") \ 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-h HOME\t\tSpecifies http HOME directory (default ./)\n" \
"\t-e STRING\tHtml encode STRING\n" \ "\t-e STRING\tHTML encode STRING\n" \
"\t-d STRING\tURL decode STRING" "\t-d STRING\tURL decode STRING"
#define hwclock_trivial_usage \ #define hwclock_trivial_usage \

View File

@ -15,6 +15,7 @@
/* Like strncpy but make sure the resulting string is always 0 terminated. */ /* Like strncpy but make sure the resulting string is always 0 terminated. */
char * safe_strncpy(char *dst, const char *src, size_t size) char * safe_strncpy(char *dst, const char *src, size_t size)
{ {
dst[size-1] = '\0'; if (!size) return dst;
return strncpy(dst, src, size-1); dst[--size] = '\0';
return strncpy(dst, src, size);
} }

View File

@ -4,4 +4,4 @@
# #
# Licensed under the GPL v2, see the file LICENSE in this tarball. # 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

49
libpwdgrp/uidgid_get.c Normal file
View File

@ -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

View File

@ -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(const char *s_port;)
USE_FEATURE_HTTPD_WITHOUT_INETD(int server;) USE_FEATURE_HTTPD_WITHOUT_INETD(int server;)
USE_FEATURE_HTTPD_SETUID(const char *s_uid;) USE_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;)
USE_FEATURE_HTTPD_SETUID(long uid = -1;) USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;)
USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;) 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_ENCODE_URL_STR(, &url_for_encode)
USE_FEATURE_HTTPD_BASIC_AUTH(, &(config->realm)) USE_FEATURE_HTTPD_BASIC_AUTH(, &(config->realm))
USE_FEATURE_HTTPD_AUTH_MD5(, &pass) 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) USE_FEATURE_HTTPD_WITHOUT_INETD(, &s_port)
); );
@ -1963,11 +1963,18 @@ int httpd_main(int argc, char *argv[])
#if ENABLE_FEATURE_HTTPD_SETUID #if ENABLE_FEATURE_HTTPD_SETUID
if (opt & OPT_SETUID) { if (opt & OPT_SETUID) {
char *e; char *e;
// FIXME: what the default group should be?
uid = strtol(s_uid, &e, 0); ugid.gid = -1;
ugid.uid = strtoul(s_ugid, &e, 0);
if (*e == ':') {
e++;
ugid.gid = strtoul(e, &e, 0);
}
if (*e != '\0') { if (*e != '\0') {
/* not integer */ /* 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 #endif
@ -1978,8 +1985,15 @@ int httpd_main(int argc, char *argv[])
server = openServer(); server = openServer();
# ifdef CONFIG_FEATURE_HTTPD_SETUID # ifdef CONFIG_FEATURE_HTTPD_SETUID
/* drop privileges */ /* drop privileges */
if (uid > 0) if (opt & OPT_SETUID) {
xsetuid(uid); 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
#endif #endif

View File

@ -5,4 +5,4 @@
# Licensed under the GPL v2, see the file LICENSE in this tarball. # Licensed under the GPL v2, see the file LICENSE in this tarball.
lib-y:= lib-y:=
lib-$(CONFIG_CHPST) += chpst.o uidgid.o lib-$(CONFIG_CHPST) += chpst.o

View File

@ -1,16 +1,9 @@
#include "busybox.h" #include "busybox.h"
#include <sys/types.h>
#include <sys/resource.h>
#include <grp.h>
#include "uidgid.h"
#include <sys/types.h>
#include <dirent.h> #include <dirent.h>
static unsigned option_mask; static unsigned option_mask;
// Must meatch constants in chpst_main! // Must match constants in chpst_main!
#define OPT_verbose (option_mask & 0x2000) #define OPT_verbose (option_mask & 0x2000)
#define OPT_pgrp (option_mask & 0x4000) #define OPT_pgrp (option_mask & 0x4000)
#define OPT_nostdin (option_mask & 0x8000) #define OPT_nostdin (option_mask & 0x8000)
@ -33,34 +26,27 @@ static long limitt = -2;
static long nicelvl; static long nicelvl;
static const char *root; 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 (!uidgid_get(&ugid, user)) {
if (dogrp)
bb_error_msg_and_die("unknown user/group: %s", user); bb_error_msg_and_die("unknown user/group: %s", user);
else
bb_error_msg_and_die("unknown account: %s", user);
} }
if (setgroups(ugid.gids, ugid.gid) == -1) if (setgroups(1, &ugid.gid) == -1)
bb_perror_msg_and_die("setgroups"); bb_perror_msg_and_die("setgroups");
xsetgid(*ugid.gid); xsetgid(ugid.gid);
xsetuid(ugid.uid); 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 (!uidgid_get(&ugid, user)) {
if (dogrp)
bb_error_msg_and_die("unknown user/group: %s", user); bb_error_msg_and_die("unknown user/group: %s", user);
else
bb_error_msg_and_die("unknown account: %s", user);
} }
//FIXME: ultoa needed here! xsetenv("GID", utoa(ugid.gid));
xsetenv("GID", utoa(*ugid.gid));
xsetenv("UID", utoa(ugid.uid)); xsetenv("UID", utoa(ugid.uid));
} }
@ -276,8 +262,8 @@ int chpst_main(int argc, char **argv)
if (nice(nicelvl) == -1) if (nice(nicelvl) == -1)
bb_perror_msg_and_die("nice"); bb_perror_msg_and_die("nice");
} }
if (env_user) euidgid(env_user, 1); if (env_user) euidgid(env_user);
if (set_user) suidgid(set_user, 1); if (set_user) suidgid(set_user);
if (OPT_nostdin) close(0); if (OPT_nostdin) close(0);
if (OPT_nostdout) close(1); if (OPT_nostdout) close(1);
if (OPT_nostderr) close(2); if (OPT_nostderr) close(2);
@ -292,7 +278,7 @@ static void setuidgid(int argc, char **argv)
account = *++argv; account = *++argv;
if (!account) bb_show_usage(); if (!account) bb_show_usage();
if (!*++argv) bb_show_usage(); if (!*++argv) bb_show_usage();
suidgid((char*)account, 0); suidgid((char*)account);
execvp(argv[0], argv); execvp(argv[0], argv);
bb_perror_msg_and_die("exec %s", argv[0]); bb_perror_msg_and_die("exec %s", argv[0]);
} }
@ -304,7 +290,7 @@ static void envuidgid(int argc, char **argv)
account = *++argv; account = *++argv;
if (!account) bb_show_usage(); if (!account) bb_show_usage();
if (!*++argv) bb_show_usage(); if (!*++argv) bb_show_usage();
euidgid((char*)account, 0); euidgid((char*)account);
execvp(argv[0], argv); execvp(argv[0], argv);
bb_perror_msg_and_die("exec %s", argv[0]); bb_perror_msg_and_die("exec %s", argv[0]);
} }

View File

@ -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;
}

View File

@ -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