Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : SMB torture tester
4 : Copyright (C) Kai Blin 2012
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "torture/smbtorture.h"
22 : #include <talloc.h>
23 : #include "lib/addns/dns.h"
24 :
25 2 : static struct dns_connection *setup_connection(struct torture_context *tctx)
26 : {
27 0 : DNS_ERROR err;
28 0 : struct dns_connection *conn;
29 :
30 2 : err = dns_open_connection(getenv("DC_SERVER_IP"), DNS_TCP, tctx, &conn);
31 2 : if (!ERR_DNS_IS_OK(err)) {
32 0 : printf("Failed to open connection to DNS server\n");
33 0 : return NULL;
34 : }
35 :
36 2 : return conn;
37 : }
38 :
39 3 : static char *get_dns_domain(struct torture_context *tctx)
40 : {
41 3 : return strlower_talloc(tctx, getenv("REALM"));
42 : }
43 :
44 1 : static struct sockaddr_storage *str_to_sockaddr(TALLOC_CTX *mem_ctx, const char *ip_string)
45 : {
46 1 : struct sockaddr_storage *ss = talloc_zero(mem_ctx, struct sockaddr_storage);
47 0 : int ret;
48 :
49 1 : if (ss == NULL) {
50 0 : return NULL;
51 : }
52 :
53 1 : ss->ss_family = AF_INET;
54 :
55 1 : ret = inet_pton(AF_INET, ip_string, &(((struct sockaddr_in *)ss)->sin_addr));
56 1 : if (ret != 1) {
57 0 : return NULL;
58 : }
59 :
60 1 : return ss;
61 : }
62 :
63 1 : static bool test_internal_dns_query_self(struct torture_context *tctx)
64 : {
65 0 : struct dns_connection *conn;
66 0 : struct dns_request *req, *resp;
67 0 : char *host;
68 0 : DNS_ERROR err;
69 :
70 1 : conn = setup_connection(tctx);
71 1 : if (conn == NULL) {
72 0 : return false;
73 : }
74 :
75 1 : host = talloc_asprintf(tctx, "%s.%s", getenv("DC_SERVER"), get_dns_domain(tctx));
76 1 : if (host == NULL) {
77 0 : return false;
78 : }
79 :
80 1 : err = dns_create_query(conn, host, QTYPE_A, DNS_CLASS_IN, &req);
81 1 : if (!ERR_DNS_IS_OK(err)) {
82 0 : printf("Failed to create A record query\n");
83 0 : return false;
84 : }
85 :
86 1 : err = dns_transaction(conn, conn, req, &resp);
87 1 : if (!ERR_DNS_IS_OK(err)) {
88 0 : printf("Failed to query DNS server\n");
89 0 : return false;
90 : }
91 :
92 1 : if (dns_response_code(resp->flags) != DNS_NO_ERROR) {
93 0 : printf("Query returned %u\n", dns_response_code(resp->flags));
94 0 : return false;
95 : }
96 :
97 : /* FIXME: is there _any_ way to unmarshal the response to check this? */
98 :
99 1 : return true;
100 : }
101 :
102 1 : static bool test_internal_dns_update_self(struct torture_context *tctx)
103 : {
104 0 : struct dns_connection *conn;
105 0 : struct dns_update_request *req, *resp;
106 1 : struct dns_rrec *rec = NULL;
107 0 : char *host;
108 0 : DNS_ERROR err;
109 0 : struct sockaddr_storage *ss;
110 :
111 1 : conn = setup_connection(tctx);
112 1 : if (conn == NULL) {
113 0 : return false;
114 : }
115 :
116 1 : host = talloc_asprintf(tctx, "%s.%s", getenv("DC_SERVER"), get_dns_domain(tctx));
117 1 : if (host == NULL) {
118 0 : return false;
119 : }
120 :
121 1 : err = dns_create_update(conn, get_dns_domain(tctx), &req);
122 1 : if (!ERR_DNS_IS_OK(err)) {
123 0 : printf("Failed to update packet\n");
124 0 : return false;
125 : }
126 :
127 1 : ss = str_to_sockaddr(conn, getenv("DC_SERVER_IP"));
128 1 : if (ss == NULL) {
129 0 : printf("Converting '%s' to sockaddr_storage failed\n", getenv("DC_SERVER_IP"));
130 0 : return false;
131 : }
132 :
133 1 : err = dns_create_a_record(req, host, 300, ss, &rec);
134 1 : if (!ERR_DNS_IS_OK(err)) {
135 0 : printf("Failed to create A update record\n");
136 0 : return false;
137 : }
138 :
139 1 : err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
140 1 : if (!ERR_DNS_IS_OK(err)) {
141 0 : printf("Failed to add A update record to update packet\n");
142 0 : return false;
143 : }
144 :
145 1 : err = dns_update_transaction(conn, conn, req, &resp);
146 1 : if (!ERR_DNS_IS_OK(err)) {
147 0 : printf("Failed to send update\n");
148 0 : return false;
149 : }
150 :
151 1 : if (dns_response_code(resp->flags) != DNS_REFUSED) {
152 0 : printf("Update returned %u\n", dns_response_code(resp->flags));
153 0 : return false;
154 : }
155 :
156 : /* FIXME: is there _any_ way to unmarshal the response to check this? */
157 :
158 1 : return true;
159 : }
160 :
161 1515 : static struct torture_suite *internal_dns_suite(TALLOC_CTX *ctx)
162 : {
163 1515 : struct torture_suite *suite = torture_suite_create(ctx, "dns_internal");
164 :
165 1515 : suite->description = talloc_strdup(suite,
166 : "Tests for the internal DNS server");
167 1515 : torture_suite_add_simple_test(suite, "queryself", test_internal_dns_query_self);
168 1515 : torture_suite_add_simple_test(suite, "updateself", test_internal_dns_update_self);
169 1515 : return suite;
170 : }
171 :
172 :
173 : /* Silence silly compiler warning */
174 : NTSTATUS torture_internal_dns_init(TALLOC_CTX *);
175 :
176 : /**
177 : * DNS torture module initialization
178 : */
179 1515 : NTSTATUS torture_internal_dns_init(TALLOC_CTX *ctx)
180 : {
181 125 : struct torture_suite *suite;
182 :
183 : /* register internal DNS torture test cases */
184 1515 : suite = internal_dns_suite(ctx);
185 1515 : if (!suite) return NT_STATUS_NO_MEMORY;
186 1515 : torture_register_suite(ctx, suite);
187 :
188 1515 : return NT_STATUS_OK;
189 : }
|