da2f1975a0422fe39b27ebd85f7e4c3a4730bbb1
[linux-2.6.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         if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0)
66                 return -ENOENT;
67
68         rcu_read_lock();
69         dom_entry = netlbl_domhsh_getentry(secattr->domain);
70         if (dom_entry == NULL)
71                 goto socket_setattr_return;
72         switch (dom_entry->type) {
73         case NETLBL_NLTYPE_CIPSOV4:
74                 ret_val = cipso_v4_socket_setattr(sock,
75                                                   dom_entry->type_def.cipsov4,
76                                                   secattr);
77                 break;
78         case NETLBL_NLTYPE_UNLABELED:
79                 ret_val = 0;
80                 break;
81         default:
82                 ret_val = -ENOENT;
83         }
84
85 socket_setattr_return:
86         rcu_read_unlock();
87         return ret_val;
88 }
89
90 /**
91  * netlbl_sock_getattr - Determine the security attributes of a sock
92  * @sk: the sock
93  * @secattr: the security attributes
94  *
95  * Description:
96  * Examines the given sock to see any NetLabel style labeling has been
97  * applied to the sock, if so it parses the socket label and returns the
98  * security attributes in @secattr.  Returns zero on success, negative values
99  * on failure.
100  *
101  */
102 int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
103 {
104         int ret_val;
105
106         ret_val = cipso_v4_sock_getattr(sk, secattr);
107         if (ret_val == 0)
108                 return 0;
109
110         return netlbl_unlabel_getattr(secattr);
111 }
112
113 /**
114  * netlbl_socket_getattr - Determine the security attributes of a socket
115  * @sock: the socket
116  * @secattr: the security attributes
117  *
118  * Description:
119  * Examines the given socket to see any NetLabel style labeling has been
120  * applied to the socket, if so it parses the socket label and returns the
121  * security attributes in @secattr.  Returns zero on success, negative values
122  * on failure.
123  *
124  */
125 int netlbl_socket_getattr(const struct socket *sock,
126                           struct netlbl_lsm_secattr *secattr)
127 {
128         int ret_val;
129
130         ret_val = cipso_v4_socket_getattr(sock, secattr);
131         if (ret_val == 0)
132                 return 0;
133
134         return netlbl_unlabel_getattr(secattr);
135 }
136
137 /**
138  * netlbl_skbuff_getattr - Determine the security attributes of a packet
139  * @skb: the packet
140  * @secattr: the security attributes
141  *
142  * Description:
143  * Examines the given packet to see if a recognized form of packet labeling
144  * is present, if so it parses the packet label and returns the security
145  * attributes in @secattr.  Returns zero on success, negative values on
146  * failure.
147  *
148  */
149 int netlbl_skbuff_getattr(const struct sk_buff *skb,
150                           struct netlbl_lsm_secattr *secattr)
151 {
152         int ret_val;
153
154         ret_val = cipso_v4_skbuff_getattr(skb, secattr);
155         if (ret_val == 0)
156                 return 0;
157
158         return netlbl_unlabel_getattr(secattr);
159 }
160
161 /**
162  * netlbl_skbuff_err - Handle a LSM error on a sk_buff
163  * @skb: the packet
164  * @error: the error code
165  *
166  * Description:
167  * Deal with a LSM problem when handling the packet in @skb, typically this is
168  * a permission denied problem (-EACCES).  The correct action is determined
169  * according to the packet's labeling protocol.
170  *
171  */
172 void netlbl_skbuff_err(struct sk_buff *skb, int error)
173 {
174         if (CIPSO_V4_OPTEXIST(skb))
175                 cipso_v4_error(skb, error, 0);
176 }
177
178 /**
179  * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches
180  *
181  * Description:
182  * For all of the NetLabel protocols that support some form of label mapping
183  * cache, invalidate the cache.  Returns zero on success, negative values on
184  * error.
185  *
186  */
187 void netlbl_cache_invalidate(void)
188 {
189         cipso_v4_cache_invalidate();
190 }
191
192 /**
193  * netlbl_cache_add - Add an entry to a NetLabel protocol cache
194  * @skb: the packet
195  * @secattr: the packet's security attributes
196  *
197  * Description:
198  * Add the LSM security attributes for the given packet to the underlying
199  * NetLabel protocol's label mapping cache.  Returns zero on success, negative
200  * values on error.
201  *
202  */
203 int netlbl_cache_add(const struct sk_buff *skb,
204                      const struct netlbl_lsm_secattr *secattr)
205 {
206         if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
207                 return -ENOMSG;
208
209         if (CIPSO_V4_OPTEXIST(skb))
210                 return cipso_v4_cache_add(skb, secattr);
211
212         return -ENOMSG;
213 }
214
215 /*
216  * Setup Functions
217  */
218
219 /**
220  * netlbl_init - Initialize NetLabel
221  *
222  * Description:
223  * Perform the required NetLabel initialization before first use.
224  *
225  */
226 static int __init netlbl_init(void)
227 {
228         int ret_val;
229
230         printk(KERN_INFO "NetLabel: Initializing\n");
231         printk(KERN_INFO "NetLabel:  domain hash size = %u\n",
232                (1 << NETLBL_DOMHSH_BITSIZE));
233         printk(KERN_INFO "NetLabel:  protocols ="
234                " UNLABELED"
235                " CIPSOv4"
236                "\n");
237
238         ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE);
239         if (ret_val != 0)
240                 goto init_failure;
241
242         ret_val = netlbl_netlink_init();
243         if (ret_val != 0)
244                 goto init_failure;
245
246         ret_val = netlbl_unlabel_defconf();
247         if (ret_val != 0)
248                 goto init_failure;
249         printk(KERN_INFO "NetLabel:  unlabeled traffic allowed by default\n");
250
251         return 0;
252
253 init_failure:
254         panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
255 }
256
257 subsys_initcall(netlbl_init);