patch-2.4.20 linux-2.4.20/net/netlink/af_netlink.c
Next file: linux-2.4.20/net/netsyms.c
Previous file: linux-2.4.20/net/khttpd/waitheaders.c
Back to the patch index
Back to the overall index
- Lines: 107
- Date:
Thu Nov 28 15:53:16 2002
- Orig file:
linux-2.4.19/net/netlink/af_netlink.c
- Orig date:
Mon Feb 25 11:38:14 2002
diff -urN linux-2.4.19/net/netlink/af_netlink.c linux-2.4.20/net/netlink/af_netlink.c
@@ -39,6 +39,7 @@
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
+#include <linux/notifier.h>
#include <net/sock.h>
#include <net/scm.h>
@@ -64,6 +65,7 @@
static struct sock *nl_table[MAX_LINKS];
static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
+static unsigned nl_nonroot[MAX_LINKS];
#ifdef NL_EMULATE_DEV
static struct socket *netlink_kernel[MAX_LINKS];
@@ -77,6 +79,8 @@
static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED;
static atomic_t nl_table_users = ATOMIC_INIT(0);
+static struct notifier_block *netlink_chain;
+
static void netlink_sock_destruct(struct sock *sk)
{
skb_queue_purge(&sk->receive_queue);
@@ -269,6 +273,12 @@
skb_queue_purge(&sk->write_queue);
+ if (sk->protinfo.af_netlink->pid && !sk->protinfo.af_netlink->groups) {
+ struct netlink_notify n = { protocol:sk->protocol,
+ pid:sk->protinfo.af_netlink->pid };
+ notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n);
+ }
+
sock_put(sk);
return 0;
}
@@ -301,6 +311,11 @@
return 0;
}
+static inline int netlink_capable(struct socket *sock, unsigned flag)
+{
+ return (nl_nonroot[sock->sk->protocol] & flag) || capable(CAP_NET_ADMIN);
+}
+
static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
struct sock *sk = sock->sk;
@@ -311,7 +326,7 @@
return -EINVAL;
/* Only superuser is allowed to listen multicasts */
- if (nladdr->nl_groups && !capable(CAP_NET_ADMIN))
+ if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_RECV))
return -EPERM;
if (sk->protinfo.af_netlink->pid) {
@@ -350,7 +365,7 @@
return -EINVAL;
/* Only superuser is allowed to send multicasts */
- if (nladdr->nl_groups && !capable(CAP_NET_ADMIN))
+ if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_SEND))
return -EPERM;
if (!sk->protinfo.af_netlink->pid)
@@ -565,7 +580,7 @@
return -EINVAL;
dst_pid = addr->nl_pid;
dst_groups = addr->nl_groups;
- if (dst_groups && !capable(CAP_NET_ADMIN))
+ if (dst_groups && !netlink_capable(sock, NL_NONROOT_SEND))
return -EPERM;
} else {
dst_pid = sk->protinfo.af_netlink->dst_pid;
@@ -715,6 +730,12 @@
return sk;
}
+void netlink_set_nonroot(int protocol, unsigned flags)
+{
+ if ((unsigned)protocol < MAX_LINKS)
+ nl_nonroot[protocol] = flags;
+}
+
static void netlink_destroy_callback(struct netlink_callback *cb)
{
if (cb->skb)
@@ -945,6 +966,16 @@
}
#endif
+int netlink_register_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_register(&netlink_chain, nb);
+}
+
+int netlink_unregister_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&netlink_chain, nb);
+}
+
struct proto_ops netlink_ops = {
family: PF_NETLINK,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)