X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fsysctl_net.c;h=53196009160a031ae4909fc5bc65e8ad098ef22c;hb=b7792e34cba641c49cd436d42fbfd2a632ff39d3;hp=a4f0ed8d0e791ba3a63df38c7676f2c8446461a1;hpb=3e37c3f9978839d91188e4ca0cc662a7245f28e4;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/sysctl_net.c b/net/sysctl_net.c index a4f0ed8..5319600 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -4,7 +4,6 @@ * Begun April 1, 1996, Mike Shaver. * Added /proc/sys/net directories for each protocol family. [MS] * - * $Log: sysctl_net.c,v $ * Revision 1.2 1996/05/08 20:24:40 shaver * Added bits for NET_BRIDGE and the NET_IPV4_ARP stuff and * NET_IPV4_IP_FORWARD. @@ -30,37 +29,59 @@ #include #endif -struct ctl_table net_table[] = { -#ifdef CONFIG_TR - { - .ctl_name = NET_TR, - .procname = "token-ring", - .mode = 0555, - .child = tr_table, - }, -#endif - { 0 }, -}; - -static struct list_head * +static struct ctl_table_set * net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) { - return &namespaces->net_ns->sysctl_table_headers; + return &namespaces->net_ns->sysctls; +} + +static int is_seen(struct ctl_table_set *set) +{ + return ¤t->nsproxy->net_ns->sysctls == set; +} + +/* Return standard mode bits for table entry. */ +static int net_ctl_permissions(struct ctl_table_root *root, + struct nsproxy *nsproxy, + struct ctl_table *table) +{ + /* Allow network administrator to have same access as root. */ + if (capable(CAP_NET_ADMIN)) { + int mode = (table->mode >> 6) & 7; + return (mode << 6) | (mode << 3) | mode; + } + return table->mode; } static struct ctl_table_root net_sysctl_root = { .lookup = net_ctl_header_lookup, + .permissions = net_ctl_permissions, }; -static int sysctl_net_init(struct net *net) +static int net_ctl_ro_header_perms(struct ctl_table_root *root, + struct nsproxy *namespaces, struct ctl_table *table) { - INIT_LIST_HEAD(&net->sysctl_table_headers); + if (net_eq(namespaces->net_ns, &init_net)) + return table->mode; + else + return table->mode & ~0222; +} + +static struct ctl_table_root net_sysctl_ro_root = { + .permissions = net_ctl_ro_header_perms, +}; + +static int __net_init sysctl_net_init(struct net *net) +{ + setup_sysctl_set(&net->sysctls, + &net_sysctl_ro_root.default_set, + is_seen); return 0; } -static void sysctl_net_exit(struct net *net) +static void __net_exit sysctl_net_exit(struct net *net) { - WARN_ON(!list_empty(&net->sysctl_table_headers)); + WARN_ON(!list_empty(&net->sysctls.list)); return; } @@ -76,6 +97,8 @@ static __init int sysctl_init(void) if (ret) goto out; register_sysctl_root(&net_sysctl_root); + setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL); + register_sysctl_root(&net_sysctl_ro_root); out: return ret; } @@ -92,8 +115,16 @@ struct ctl_table_header *register_net_sysctl_table(struct net *net, } EXPORT_SYMBOL_GPL(register_net_sysctl_table); +struct ctl_table_header *register_net_sysctl_rotable(const + struct ctl_path *path, struct ctl_table *table) +{ + return __register_sysctl_paths(&net_sysctl_ro_root, + &init_nsproxy, path, table); +} +EXPORT_SYMBOL_GPL(register_net_sysctl_rotable); + void unregister_net_sysctl_table(struct ctl_table_header *header) { - return unregister_sysctl_table(header); + unregister_sysctl_table(header); } EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);