Hello,
although vblade's codebase is not very large, I felt that it was
desirable to have most of it run as a non-privileged user.
Here is a set of patches against vblade-19 that provide enable vblade
to drop root privileges after it has bound the raw socket. This
behavior can be enabled
* by installing vblade setuid root and calling it as a "normal" user
* or by specifying the user with the new `-u' switch on the command line.
I have tested this on an x86-64 Debian/sid box.
Cheers,
-Hilko
commit 482f712585c6eab6e2afde5ff0c13a561f613a3c
Author: Hilko Bengen <ben...@hilluzination.de>
Date: Tue Jan 13 14:52:25 2009 +0100
Added `-u` (user) parameter that allows vblade to be run with reduced privileges
diff --git a/aoe.c b/aoe.c
index 776a5ff..4c45555 100644
--- a/aoe.c
+++ b/aoe.c
@@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
+#include <pwd.h>
#include "dat.h"
#include "fns.h"
@@ -206,7 +207,7 @@ aoe(void)
if ((pagesz = sysconf(_SC_PAGESIZE)) < 0) {
perror("sysconf");
exit(1);
- }
+ }
if ((buf = malloc(bufsz + pagesz)) == NULL) {
perror("malloc");
exit(1);
@@ -244,7 +245,7 @@ aoe(void)
void
usage(void)
{
- fprintf(stderr, "usage: %s [-b bufcnt] [-d ] [-s] [-r] [ -m mac[,mac...] ] shelf slot netif filename\n",
+ fprintf(stderr, "usage: %s [-b bufcnt] [-d ] [-s] [-r] [-m mac[,mac...]] [-u user] shelf slot netif filename\n",
progname);
exit(1);
}
@@ -305,12 +306,14 @@ int
main(int argc, char **argv)
{
int ch, omode = 0, readonly = 0;
+ char *user = NULL;
+ struct passwd *pass = NULL;
bufcnt = Bufcount;
setbuf(stdin, NULL);
atainit();
progname = *argv;
- while ((ch = getopt(argc, argv, "b:dsrm:")) != -1) {
+ while ((ch = getopt(argc, argv, "b:dsrm:u:")) != -1) {
switch (ch) {
case 'b':
bufcnt = atoi(optarg);
@@ -329,6 +332,9 @@ main(int argc, char **argv)
case 'm':
setmask(optarg);
break;
+ case 'u':
+ user = strdup(optarg);
+ break;
case '?':
default:
usage();
@@ -338,21 +344,51 @@ main(int argc, char **argv)
argv += optind;
if (argc != 4 || bufcnt <= 0)
usage();
+ shelf = atoi(argv[0]);
+ slot = atoi(argv[1]);
+ ifname = argv[2];
+ sfd = dial(ifname, bufcnt);
+ getea(sfd, ifname, mac);
+ /*
+ If called as a setuid program, drop privileges to that of
+ calling user after opening raw socket.
+
+ Otherwise obey the -u switch (which will fail if the calling
+ process does not hav CAP_SETUID).
+ */
+ if (getuid() != geteuid()) {
+ pass = getpwuid(getuid());
+ if (pass == NULL) {
+ perror("getpwuid");
+ exit(1);
+ }
+ } else if (user != NULL) {
+ pass = getpwnam(user);
+ if (pass == NULL) {
+ perror("getpwnam");
+ exit(1);
+ }
+ }
+ if (pass != NULL) {
+ if (setgid(pass->pw_gid) != 0) {
+ perror("setgid");
+ exit(1);
+ }
+ if (setuid(pass->pw_uid) != 0) {
+ perror("setuid");
+ exit(1);
+ }
+ }
omode |= readonly ? O_RDONLY : O_RDWR;
bfd = open(argv[3], omode);
if (bfd == -1) {
perror("open");
exit(1);
}
- shelf = atoi(argv[0]);
- slot = atoi(argv[1]);
size = getsize(bfd);
size /= 512;
- ifname = argv[2];
- sfd = dial(ifname, bufcnt);
- getea(sfd, ifname, mac);
- printf("pid %ld: e%d.%d, %lld sectors %s\n",
- (long) getpid(), shelf, slot, size,
+ printf("pid %ld (euid %d): e%d.%d, %lld sectors %s\n",
+ (long) getpid(), geteuid(), shelf, slot, size,
readonly ? "O_RDONLY" : "O_RDWR");
fflush(stdout);
aoe();
diff --git a/ata.c b/ata.c
index 608f257..b99dee4 100644
--- a/ata.c
+++ b/ata.c
@@ -79,7 +79,7 @@ setlba48(ushort *ident, vlong lba)
*cp++ = lba >>= 8;
*cp++ = lba >>= 8;
}
-
+
void
atainit(void)
{
diff --git a/config.h b/config.h
index c40d514..649a44d 100644
--- a/config.h
+++ b/config.h
@@ -1,2 +1,2 @@
-#define _FILE_OFFSET_BITS 64
+#define _FILE_OFFSET_BITS 64
typedef unsigned long long u64;
diff --git a/config/config.h.in b/config/config.h.in
index 6b49a0b..16cd24f 100644
--- a/config/config.h.in
+++ b/config/config.h.in
@@ -1,2 +1,2 @@
-#define _FILE_OFFSET_BITS 64
+#define _FILE_OFFSET_BITS 64
//u64 typedef unsigned long long u64;
diff --git a/freebsd.c b/freebsd.c
index 586dc68..37ae7a5 100644
--- a/freebsd.c
+++ b/freebsd.c
@@ -102,7 +102,7 @@ dial(char *eth, int bufcnt)
}
}
if (v == 0) {
- fprintf(stderr,
+ fprintf(stderr,
"BIOCSBLEN: %s: No buffer size worked\n", eth);
goto bad;
}
@@ -152,7 +152,7 @@ dial(char *eth, int bufcnt)
if (ioctl(fd, BIOCSETF, (caddr_t)bpf_program) < 0) {
perror("BIOSETF");
goto bad;
- }
+ }
free_bpf_program(bpf_program);
return(fd);
@@ -195,7 +195,7 @@ getea(int s, char *eth, uchar *ea)
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sdl = (struct sockaddr_dl *)(ifm + 1);
- if (strncmp(&sdl->sdl_data[0], eth,
+ if (strncmp(&sdl->sdl_data[0], eth,
sdl->sdl_nlen) == 0) {
memcpy(ea, LLADDR(sdl), ETHER_ADDR_LEN);
break;
@@ -231,7 +231,7 @@ getpkt(int fd, uchar *buf, int sz)
register struct bpf_hdr *bh;
register int pktlen, retlen;
- if (pktn <= 0) {
+ if (pktn <= 0) {
if ((pktn = read(fd, pktbuf, pktbufsz)) < 0) {
perror("read");
exit(1);
@@ -241,15 +241,15 @@ getpkt(int fd, uchar *buf, int sz)
bh = (struct bpf_hdr *) pktbp;
retlen = (int) bh->bh_caplen;
- /* This memcpy() is currently needed */
+ /* This memcpy() is currently needed */
memcpy(buf, (void *)(pktbp + bh->bh_hdrlen),
retlen > sz ? sz : retlen);
- pktlen = bh->bh_hdrlen + bh->bh_caplen;
+ pktlen = bh->bh_hdrlen + bh->bh_caplen;
pktbp = pktbp + BPF_WORDALIGN(pktlen);
pktn -= (int) BPF_WORDALIGN(pktlen);
- return retlen;
+ return retlen;
}
int
@@ -273,7 +273,7 @@ getsize(int fd)
struct disklabel lab;
// Try getting disklabel from block dev
- if ((n = ioctl(fd, DIOCGDINFO, lab)) != -1) {
+ if ((n = ioctl(fd, DIOCGDINFO, lab)) != -1) {
size = lab.d_secsize * lab.d_secperunit;
} else {
// must not be a block special dev
diff --git a/vblade.8 b/vblade.8
index 2cd2b2c..345f1ce 100644
--- a/vblade.8
+++ b/vblade.8
@@ -3,7 +3,7 @@
vblade, vbladed \- export data via ATA over Ethernet
.SH SYNOPSIS
.nf
-.B vblade [ -m mac[,mac...] ] shelf slot netif filename
+.B vblade [ -m mac[,mac...]] [ -u user ] shelf slot netif filename
.fi
.SH DESCRIPTION
The
@@ -55,6 +55,13 @@ The -r flag restricts the export of the device to be read-only.
The -m flag takes an argument, a comma separated list of MAC addresses
permitted access to the vblade. A MAC address can be specified in upper
or lower case, with or without colons.
+.TP
+\fB-u\fP
+The -u flag takes an argument, the name of the user that vblade should
+run as after successfully opening the network socket and before
+opening the file or block device that is exported. If vblade is called
+as a setuid program, it will drop its privileges to that of the
+calling user.
.SH EXAMPLE
In this example, the root user on a host named
.I nai
commit 316d55cdfbd3852e5749d63b713e8693b74386c5
Author: Hilko Bengen <ben...@hilluzination.de>
Date: Tue Jan 13 14:53:58 2009 +0100
Added -Wextra and fixed signed/unsigned comparision warnings
diff --git a/aoe.c b/aoe.c
index 4c45555..39c1e3c 100644
--- a/aoe.c
+++ b/aoe.c
@@ -168,7 +168,7 @@ doaoe(Aoehdr *p, int n)
switch (p->cmd) {
case ATAcmd:
- if (n < sizeof(Ata))
+ if (n < (int)sizeof(Ata))
return;
len = aoeata((Ata*)p, n);
break;
@@ -224,7 +224,7 @@ aoe(void)
perror("read network");
exit(1);
}
- if (n < sizeof(Aoehdr))
+ if (n < (int)sizeof(Aoehdr))
continue;
p = (Aoehdr *) buf;
if (ntohs(p->type) != 0x88a2)
diff --git a/makefile b/makefile
index 9613087..64c6260 100644
--- a/makefile
+++ b/makefile
@@ -10,6 +10,7 @@ mandir = ${sharedir}/man
O=aoe.o bpf.o ${PLATFORM}.o ata.o
CFLAGS += -Wall -g -O2
+CFLAGS += -Wextra
CC = gcc
vblade: $O
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Aoetools-discuss mailing list
Aoetools-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/aoetools-discuss