Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
dns_resolver
dns_query.c
Go to the documentation of this file.
1
/* Upcall routine, designed to work as a key type and working through
2
* /sbin/request-key to contact userspace when handling DNS queries.
3
*
4
* See Documentation/networking/dns_resolver.txt
5
*
6
* Copyright (c) 2007 Igor Mammedov
7
* Author(s): Igor Mammedov (
[email protected]
)
8
* Steve French (
[email protected]
)
9
* Wang Lei (
[email protected]
)
10
* David Howells (
[email protected]
)
11
*
12
* The upcall wrapper used to make an arbitrary DNS query.
13
*
14
* This function requires the appropriate userspace tool dns.upcall to be
15
* installed and something like the following lines should be added to the
16
* /etc/request-key.conf file:
17
*
18
* create dns_resolver * * /sbin/dns.upcall %k
19
*
20
* For example to use this module to query AFSDB RR:
21
*
22
* create dns_resolver afsdb:* * /sbin/dns.afsdb %k
23
*
24
* This library is free software; you can redistribute it and/or modify
25
* it under the terms of the GNU Lesser General Public License as published
26
* by the Free Software Foundation; either version 2.1 of the License, or
27
* (at your option) any later version.
28
*
29
* This library is distributed in the hope that it will be useful,
30
* but WITHOUT ANY WARRANTY; without even the implied warranty of
31
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
32
* the GNU Lesser General Public License for more details.
33
*
34
* You should have received a copy of the GNU Lesser General Public License
35
* along with this library; if not, write to the Free Software
36
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37
*/
38
39
#include <linux/module.h>
40
#include <linux/slab.h>
41
#include <
linux/dns_resolver.h
>
42
#include <
linux/err.h
>
43
#include <
keys/dns_resolver-type.h
>
44
#include <
keys/user-type.h
>
45
46
#include "
internal.h
"
47
70
int
dns_query
(
const
char
*
type
,
const
char
*
name
,
size_t
namelen
,
71
const
char
*
options
,
char
**_result,
time_t
*_expiry)
72
{
73
struct
key
*
rkey
;
74
struct
user_key_payload
*upayload;
75
const
struct
cred
*saved_cred;
76
size_t
typelen, desclen;
77
char
*
desc
, *
cp
;
78
int
ret
,
len
;
79
80
kenter
(
"%s,%*.*s,%zu,%s"
,
81
type, (
int
)namelen, (
int
)namelen, name, namelen, options);
82
83
if
(!name || namelen == 0 || !_result)
84
return
-
EINVAL
;
85
86
/* construct the query key description as "[<type>:]<name>" */
87
typelen = 0;
88
desclen = 0;
89
if
(type) {
90
typelen =
strlen
(type);
91
if
(typelen < 1)
92
return
-
EINVAL
;
93
desclen += typelen + 1;
94
}
95
96
if
(!namelen)
97
namelen =
strlen
(name);
98
if
(namelen < 3)
99
return
-
EINVAL
;
100
desclen += namelen + 1;
101
102
desc =
kmalloc
(desclen,
GFP_KERNEL
);
103
if
(!desc)
104
return
-
ENOMEM
;
105
106
cp = desc;
107
if
(type) {
108
memcpy
(cp, type, typelen);
109
cp += typelen;
110
*cp++ =
':'
;
111
}
112
memcpy
(cp, name, namelen);
113
cp +=
namelen
;
114
*cp =
'\0'
;
115
116
if
(!options)
117
options =
""
;
118
kdebug
(
"call request_key(,%s,%s)"
, desc, options);
119
120
/* make the upcall, using special credentials to prevent the use of
121
* add_key() to preinstall malicious redirections
122
*/
123
saved_cred =
override_creds
(
dns_resolver_cache
);
124
rkey =
request_key
(&
key_type_dns_resolver
, desc, options);
125
revert_creds
(saved_cred);
126
kfree
(desc);
127
if
(IS_ERR(rkey)) {
128
ret = PTR_ERR(rkey);
129
goto
out
;
130
}
131
132
down_read
(&rkey->sem);
133
rkey->perm |= KEY_USR_VIEW;
134
135
ret =
key_validate
(rkey);
136
if
(ret < 0)
137
goto
put
;
138
139
/* If the DNS server gave an error, return that to the caller */
140
ret = rkey->type_data.x[0];
141
if
(ret)
142
goto
put
;
143
144
upayload =
rcu_dereference_protected
(rkey->payload.data,
145
lockdep_is_held(&rkey->sem));
146
len = upayload->
datalen
;
147
148
ret = -
ENOMEM
;
149
*_result =
kmalloc
(len + 1,
GFP_KERNEL
);
150
if
(!*_result)
151
goto
put
;
152
153
memcpy
(*_result, upayload->
data
, len + 1);
154
if
(_expiry)
155
*_expiry = rkey->expiry;
156
157
ret = len;
158
put
:
159
up_read
(&rkey->sem);
160
key_put
(rkey);
161
out
:
162
kleave
(
" = %d"
, ret);
163
return
ret
;
164
}
165
EXPORT_SYMBOL
(
dns_query
);
Generated on Thu Jan 10 2013 14:58:05 for Linux Kernel by
1.8.2