linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][RFC] 2.5.42 (2/2): Filesystem capabilities user tool
@ 2002-10-18 19:07 Olaf Dietsche
  2002-10-24 12:31 ` [PATCH][RFC] 2.5.44 " Olaf Dietsche
  2002-10-27 13:55 ` [PATCH][RFC] 2.5.42 " Andreas Gruenbacher
  0 siblings, 2 replies; 3+ messages in thread
From: Olaf Dietsche @ 2002-10-18 19:07 UTC (permalink / raw)
  To: linux-kernel; +Cc: torvalds, viro

This is the change capabilities tool. It is a first cut at "managing"
capabilities and not very comfortable.

You need to tell where the .capabilities file is. This must be located
in the mountpoint of the filesystem.

Given a filename, how can I locate the mountpoint of the associated
filesystem? If someone knows, how to do this, please tell me.

Example:

# chmod u-s /bin/ping
# chcap /.capabilities 0x2000 0 0x2000 /bin/ping

This sets the effective and permitted CAP_NET_RAW capability for /bin/ping.

Regards, Olaf.

--- /dev/null	Thu Mar 21 19:31:20 2002
+++ chcap.c	Fri Oct 18 21:02:15 2002
@@ -0,0 +1,74 @@
+#include <asm/types.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static const char *capfile;
+static struct stat capbuf;
+
+static void chcap(ino_t ino, __u32 *caps)
+{
+	int fd = open(capfile, O_WRONLY);
+	if (fd < 0) {
+		perror(capfile);
+		exit(1);
+	} else {
+		off_t rc = lseek(fd, ino * 3 * sizeof(*caps), SEEK_SET);
+		if (rc == -1)
+			perror(capfile);
+		else
+			write(fd, caps, 3 * sizeof(*caps));
+
+		close(fd);
+	}
+}
+
+int main(int argc, char **argv)
+{
+	__u32 caps[3];
+	int rc;
+	int i = 1;
+
+	if (argc < 6) {
+		fprintf(stderr, "usage: %s /path/to/.capabilities eff inh perm file ...\n", argv[0]);
+		exit(2);
+	}
+
+	capfile = argv[i++];
+	rc = access(capfile, F_OK);
+	if (rc != 0) {
+		int fd = open(capfile, O_CREAT | O_EXCL | O_RDONLY, 0600);
+		if (fd >= 0) {
+			close(fd);
+		} else {
+			perror(capfile);
+			exit(1);
+		}
+	}
+
+	rc = stat(capfile, &capbuf);
+	if (rc != 0) {
+		perror(capfile);
+	}
+
+	caps[0] = strtol(argv[i++], 0, 0);
+	caps[1] = strtol(argv[i++], 0, 0);
+	caps[2] = strtol(argv[i++], 0, 0);
+
+	for (; i < argc; ++i) {
+		struct stat buf;
+		rc = stat(argv[i], &buf);
+		if (rc == 0) {
+			if (buf.st_dev == capbuf.st_dev)
+				chcap(buf.st_ino, caps);
+			else
+				fprintf(stderr, "%s: %s is on different file system\n", argv[i], capfile);
+		} else {
+			perror(argv[i]);
+		}
+	}
+
+	return 0;
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][RFC] 2.5.44 (2/2): Filesystem capabilities user tool
  2002-10-18 19:07 [PATCH][RFC] 2.5.42 (2/2): Filesystem capabilities user tool Olaf Dietsche
@ 2002-10-24 12:31 ` Olaf Dietsche
  2002-10-27 13:55 ` [PATCH][RFC] 2.5.42 " Andreas Gruenbacher
  1 sibling, 0 replies; 3+ messages in thread
From: Olaf Dietsche @ 2002-10-24 12:31 UTC (permalink / raw)
  To: linux-kernel

Olaf Dietsche <olaf.dietsche#list.linux-kernel@t-online.de> writes:

> This is the change capabilities tool. It is a first cut at "managing"
> capabilities and not very comfortable.
>
> You need to tell where the .capabilities file is. This must be located
> in the mountpoint of the filesystem.
>
> Given a filename, how can I locate the mountpoint of the associated
> filesystem? If someone knows, how to do this, please tell me.

Thanks to Steve Baur, it's not necessary anymore to provide the
.capabilities file. Furthermore, chcap uses libcap now. This means,
you can give capabilities in cleartext.

Example:

# chmod u-s /bin/ping
# chcap cap_net_raw+ep /bin/ping

Regards, Olaf.

--- /dev/null	Thu Mar 21 19:31:20 2002
+++ chcap.c	Mon Oct 21 19:53:08 2002
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2002 Olaf Dietsche
+ *
+ * Filesystem capabilities for linux, user space tool.
+ *
+ * This tool uses libcap. Compile as:
+ * gcc -Wall -o chcap chcap.c -lcap
+ *
+ * usage: chcap capabilities file ...
+ * example: chcap cap_net_raw+ep /bin/ping
+ *
+ * Thanks to Steve Baur for the idea to locate_mountpoint().
+ */
+
+#include <asm/types.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/capability.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void fatal(const char *s)
+{
+	perror(s);
+	exit(1);
+}
+
+static char *locate_mountpoint(char *dir, const char *file)
+{
+	char *slash;
+	struct stat buf;
+	dev_t dev;
+	int err = stat(file, &buf);
+	if (err)
+		return NULL;
+
+	dev = buf.st_dev;
+	strcpy(dir, file);
+	do {
+		slash = strrchr(dir, '/');
+		*slash = 0;
+		err = stat(slash == dir ? "/" : dir, &buf);
+		if (err)
+			return NULL;
+	} while (buf.st_dev == dev && slash != dir);
+
+	*slash = '/';
+	if (buf.st_dev == dev)
+		dir[1] = 0;
+
+	return dir;
+}
+
+static int open_capabilities(const char *name)
+{
+	char file[PATH_MAX], mnt[PATH_MAX];
+	if (!realpath(name, file))
+		return -1;
+
+	if (!locate_mountpoint(mnt, file))
+		return -1;
+
+	strcat(mnt, "/.capabilities");
+	return open(mnt, O_CREAT | O_WRONLY, 0600);
+}
+
+static void chcap(const char *name, __u32 *caps)
+{
+	struct stat buf;
+	int fd = open_capabilities(name);
+	if (fd < 0) {
+		perror(name);
+		return;
+	}
+
+	if (access(name, W_OK) || stat(name, &buf)) {
+		perror(name);
+	} else {
+		off_t rc = lseek(fd, buf.st_ino * 3 * sizeof(*caps), SEEK_SET);
+		if (rc == -1)
+			perror(name);
+		else
+			write(fd, caps, 3 * sizeof(*caps));
+	}
+
+	close(fd);
+}
+
+static __u32 cap_to_u32(cap_t cap, cap_flag_t flag)
+{
+	__u32 c = 0;
+	int i;
+	for (i = 0; i <= 28; ++i) {
+		cap_flag_value_t on;
+		int err = cap_get_flag(cap, i, flag, &on);
+		if (err)
+			fatal("cap_to_u32()");
+
+		if (on)
+			c |= 1 << i;
+	}
+
+	return c;
+}
+
+int main(int argc, char **argv)
+{
+	cap_t cap;
+	__u32 caps[3];
+	int i;
+
+	if (argc < 3) {
+		fprintf(stderr, "usage: %s capabilities file ...\n", argv[0]);
+		exit(2);
+	}
+
+	cap = cap_from_text(argv[1]);
+	caps[0] = cap_to_u32(cap, CAP_EFFECTIVE);
+	caps[1] = cap_to_u32(cap, CAP_INHERITABLE);
+	caps[2] = cap_to_u32(cap, CAP_PERMITTED);
+
+	for (i = 2; i < argc; ++i) {
+		chcap(argv[i], caps);
+	}
+
+	return 0;
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][RFC] 2.5.42 (2/2): Filesystem capabilities user tool
  2002-10-18 19:07 [PATCH][RFC] 2.5.42 (2/2): Filesystem capabilities user tool Olaf Dietsche
  2002-10-24 12:31 ` [PATCH][RFC] 2.5.44 " Olaf Dietsche
@ 2002-10-27 13:55 ` Andreas Gruenbacher
  1 sibling, 0 replies; 3+ messages in thread
From: Andreas Gruenbacher @ 2002-10-27 13:55 UTC (permalink / raw)
  To: Olaf Dietsche; +Cc: linux-kernel

On Friday 18 October 2002 21:07, Olaf Dietsche wrote:
> This is the change capabilities tool. It is a first cut at "managing"
> capabilities and not very comfortable.

Olaf, please start with reading the capabilities sections in POSIX 
1003.1e/1003.2c draft 17 (withdrawn). There It's available online at 
<http://wt.xpilot.org/publications/posix.1e/>. A number of people have 
already spent a lot of time figuring out how this could work.

--Andreas.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-10-27 13:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-18 19:07 [PATCH][RFC] 2.5.42 (2/2): Filesystem capabilities user tool Olaf Dietsche
2002-10-24 12:31 ` [PATCH][RFC] 2.5.44 " Olaf Dietsche
2002-10-27 13:55 ` [PATCH][RFC] 2.5.42 " Andreas Gruenbacher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).