aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael K. Johnson <johnsonm@redhat.com>1997-09-18 20:03:53 +0000
committerMichael K. Johnson <johnsonm@redhat.com>1997-09-18 20:03:53 +0000
commit995387d1f852c4301ef0685a91d3df38f4bcdc36 (patch)
tree078f6793517d3136a17634fa11aed0ba99df382f
parentb49499f63193f2e1be55badd92b0c7ed203e8dc7 (diff)
downloadinitscripts-995387d1f852c4301ef0685a91d3df38f4bcdc36.tar
initscripts-995387d1f852c4301ef0685a91d3df38f4bcdc36.tar.gz
initscripts-995387d1f852c4301ef0685a91d3df38f4bcdc36.tar.bz2
initscripts-995387d1f852c4301ef0685a91d3df38f4bcdc36.tar.xz
initscripts-995387d1f852c4301ef0685a91d3df38f4bcdc36.zip
Support alternative device configurations.
-rw-r--r--src/usernetctl.13
-rw-r--r--src/usernetctl.c92
2 files changed, 66 insertions, 29 deletions
diff --git a/src/usernetctl.1 b/src/usernetctl.1
index 1602f7b5..27287b68 100644
--- a/src/usernetctl.1
+++ b/src/usernetctl.1
@@ -16,3 +16,6 @@ The name of the network configuration file to read; for example, ifcfg-ppp0
.TP
up\fI|\fPdown
Attempt to bring the interface up or down.
+.SH NOTES
+Alternate device configurations may inherit the default configuration's
+permissions.
diff --git a/src/usernetctl.c b/src/usernetctl.c
index 040aa2c9..33bdaf1c 100644
--- a/src/usernetctl.c
+++ b/src/usernetctl.c
@@ -3,6 +3,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -20,11 +21,49 @@ static char * safeEnviron[] = {
NULL
};
-int userCtl(char * file, int size) {
+#define FOUND_FALSE -1
+#define NOT_FOUND 0
+#define FOUND_TRUE 1
+
+
+int testSafe(char * ifaceConfig) {
+ struct stat sb;
+
+ /* these shouldn't be symbolic links -- anal, but that's fine w/ me */
+ if (lstat(ifaceConfig, &sb)) {
+ fprintf(stderr, "failed to stat %s: %s\n", ifaceConfig,
+ strerror(errno));
+ exit(1);
+ }
+
+ /* safety checks */
+ if (!S_ISREG(sb.st_mode)) {
+ fprintf(stderr, "%s is not a normal file\n", ifaceConfig);
+ exit(1);
+ }
+
+ if (sb.st_uid) {
+ fprintf(stderr, "%s should be owned by root\n", ifaceConfig);
+ exit(1);
+ }
+
+ if (sb.st_mode & S_IWOTH) {
+ fprintf(stderr, "%s should not be world writeable\n", ifaceConfig);
+ exit(1);
+ }
+
+ return sb.st_size;
+}
+
+
+int userCtl(char * file) {
char * contents;
char * chptr;
char * end;
int fd;
+ int size;
+
+ size = testSafe(file);
contents = alloca(size + 2);
@@ -51,18 +90,21 @@ int userCtl(char * file, int size) {
while (chptr > contents && isspace(*chptr)) chptr--;
*(++chptr) = '\0';
- if (!strcmp(contents, "USERCTL=yes")) return 1;
+ if (!strcmp(contents, "USERCTL=")) {
+ if (!strcmp(contents+8, "yes")) return FOUND_TRUE;
+ else return FOUND_FALSE;
+ }
contents = end;
}
- return 0;
+ return NOT_FOUND;
}
+
int main(int argc, char ** argv) {
char * ifaceConfig;
char * chptr;
- struct stat sb;
char * cmd;
if (argc != 3) usage();
@@ -99,32 +141,24 @@ int main(int argc, char ** argv) {
ifaceConfig = temp;
}
- /* these shouldn't be symbolic links -- anal, but that's fine w/ me */
- if (lstat(ifaceConfig, &sb)) {
- fprintf(stderr, "failed to stat %s: %s\n", ifaceConfig,
- strerror(errno));
- exit(1);
- }
-
- /* safety checks */
- if (!S_ISREG(sb.st_mode)) {
- fprintf(stderr, "%s is not a normal file\n", ifaceConfig);
- exit(1);
- }
-
- if (sb.st_uid) {
- fprintf(stderr, "%s should be owned by root\n", ifaceConfig);
- exit(1);
- }
-
- if (sb.st_mode & S_IWOTH) {
- fprintf(stderr, "%s should not be world writeable\n", ifaceConfig);
- exit(1);
- }
- if (!userCtl(ifaceConfig, sb.st_size)) {
- fprintf(stderr, "Users are not allowed to control this interface.\n");
- exit(1);
+ switch (userCtl(ifaceConfig)) {
+ char * dash;
+ case NOT_FOUND:
+ /* a `-' will be found at least in "ifcfg-" */
+ dash = strrchr(ifaceConfig, '-');
+ if (*(dash-1) != 'g') {
+ /* This was a clone configuration; ask the parent config */
+ *dash = '\0';
+ if (userCtl(ifaceConfig) == FOUND_TRUE)
+ /* exit the switch; users are allowed to control */
+ break;
+ }
+ /* else fall through */
+ case FOUND_FALSE:
+ fprintf(stderr, "Users are not allowed to control this interface.\n");
+ exit(1);
+ break;
}
/* looks good to me -- let's go for it */