[NetLabel]: core NetLabel subsystem
[pandora-kernel.git] / net / netlabel / netlabel_kapi.c
1 /*
2  * NetLabel Kernel API
3  *
4  * This file defines the kernel API for the NetLabel system.  The NetLabel
5  * system manages static and dynamic label mappings for network protocols such
6  * as CIPSO and RIPSO.
7  *
8  * Author: Paul Moore <paul.moore@hp.com>
9  *
10  */
11
12 /*
13  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
14  *
15  * This program is free software;  you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23  * the GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program;  if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28  *
29  */
30
31 #include <linux/init.h>
32 #include <linux/types.h>
33 #include <net/ip.h>
34 #include <net/netlabel.h>
35 #include <net/cipso_ipv4.h>
36 #include <asm/bug.h>
37
38 #include "netlabel_domainhash.h"
39 #include "netlabel_unlabeled.h"
40 #include "netlabel_user.h"
41
42 /*
43  * LSM Functions
44  */
45
46 /**
47  * netlbl_socket_setattr - Label a socket using the correct protocol
48  * @sock: the socket to label
49  * @secattr: the security attributes
50  *
51  * Description:
52  * Attach the correct label to the given socket using the security attributes
53  * specified in @secattr.  This function requires exclusive access to
54  * @sock->sk, which means it either needs to be in the process of being
55  * created or locked via lock_sock(sock->sk).  Returns zero on success,
56  * negative values on failure.
57  *
58  */
59 int netlbl_socket_setattr(const struct socket *sock,
60                           const struct netlbl_lsm_secattr *secattr)
61 {
62         int ret_val = -ENOENT;
63         struct netlbl_dom_map *dom_entry;
64
65         rcu_read_lock();
66         dom_entry = netlbl_domhsh_getentry(secattr->domain);
67         if (dom_entry == NULL)
68                 goto socket_setattr_return;
69         switch (dom_entry->type) {
70         case NETLBL_NLTYPE_CIPSOV4:
71                 ret_val = cipso_v4_socket_setattr(sock,
72                                                   dom_entry->type_def.cipsov4,
73                                                   secattr);
74                 break;
75         case NETLBL_NLTYPE_UNLABELED:
76                 ret_val = 0;
77                 break;
78         default:
79                 ret_val = -ENOENT;
80         }
81
82 socket_setattr_return:
83         rcu_read_unlock();
84         return ret_val;
85 }
86
87 /**
88  * netlbl_socket_getattr - Determine the security attributes of a socket
89  * @sock: the socket
90  * @secattr: the security attributes
91  *
92  * Description:
93  * Examines the given socket to see any NetLabel style labeling has been
94  * applied to the socket, if so it parses the socket label and returns the
95  * security attributes in @secattr.  Returns zero on success, negative values
96  * on failure.
97  *
98  */
99 int netlbl_socket_getattr(const struct socket *sock,
100                           struct netlbl_lsm_secattr *secattr)
101 {
102         int ret_val;
103
104         ret_val = cipso_v4_socket_getattr(sock, secattr);
105         if (ret_val == 0)
106                 return 0;
107
108         return netlbl_unlabel_getattr(secattr);
109 }
110
111 /**
112  * netlbl_skbuff_getattr - Determine the security attributes of a packet
113  * @skb: the packet
114  * @secattr: the security attributes
115  *
116  * Description:
117  * Examines the given packet to see if a recognized form of packet labeling
118  * is present, if so it parses the packet label and returns the security
119  * attributes in @secattr.  Returns zero on success, negative values on
120  * failure.
121  *
122  */
123 int netlbl_skbuff_getattr(const struct sk_buff *skb,
124                           struct netlbl_lsm_secattr *secattr)
125 {
126         int ret_val;
127
128         ret_val = cipso_v4_skbuff_getattr(skb, secattr);
129         if (ret_val == 0)
130                 return 0;
131
132         return netlbl_unlabel_getattr(secattr);
133 }
134
135 /**
136  * netlbl_skbuff_err - Handle a LSM error on a sk_buff
137  * @skb: the packet
138  * @error: the error code
139  *
140  * Description:
141  * Deal with a LSM problem when handling the packet in @skb, typically this is
142  * a permission denied problem (-EACCES).  The correct action is determined
143  * according to the packet's labeling protocol.
144  *
145  */
146 void netlbl_skbuff_err(struct sk_buff *skb, int error)
147 {
148         if (CIPSO_V4_OPTEXIST(skb))
149                 cipso_v4_error(skb, error, 0);
150 }
151
152 /**
153  * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches
154  *
155  * Description:
156  * For all of the NetLabel protocols that support some form of label mapping
157  * cache, invalidate the cache.  Returns zero on success, negative values on
158  * error.
159  *
160  */
161 void netlbl_cache_invalidate(void)
162 {
163         cipso_v4_cache_invalidate();
164 }
165
166 /**
167  * netlbl_cache_add - Add an entry to a NetLabel protocol cache
168  * @skb: the packet
169  * @secattr: the packet's security attributes
170  *
171  * Description:
172  * Add the LSM security attributes for the given packet to the underlying
173  * NetLabel protocol's label mapping cache.  Returns zero on success, negative
174  * values on error.
175  *
176  */
177 int netlbl_cache_add(const struct sk_buff *skb,
178                      const struct netlbl_lsm_secattr *secattr)
179 {
180         if (secattr->cache.data == NULL)
181                 return -ENOMSG;
182
183         if (CIPSO_V4_OPTEXIST(skb))
184                 return cipso_v4_cache_add(skb, secattr);
185
186         return -ENOMSG;
187 }
188
189 /*
190  * Setup Functions
191  */
192
193 /**
194  * netlbl_init - Initialize NetLabel
195  *
196  * Description:
197  * Perform the required NetLabel initialization before first use.
198  *
199  */
200 static int __init netlbl_init(void)
201 {
202         int ret_val;
203
204         printk(KERN_INFO "NetLabel: Initializing\n");
205         printk(KERN_INFO "NetLabel:  domain hash size = %u\n",
206                (1 << NETLBL_DOMHSH_BITSIZE));
207         printk(KERN_INFO "NetLabel:  protocols ="
208                " UNLABELED"
209                " CIPSOv4"
210                "\n");
211
212         ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE);
213         if (ret_val != 0)
214                 goto init_failure;
215
216         ret_val = netlbl_netlink_init();
217         if (ret_val != 0)
218                 goto init_failure;
219
220         ret_val = netlbl_unlabel_defconf();
221         if (ret_val != 0)
222                 goto init_failure;
223         printk(KERN_INFO "NetLabel:  unlabeled traffic allowed by default\n");
224
225         return 0;
226
227 init_failure:
228         panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
229 }
230
231 subsys_initcall(netlbl_init);