Line data Source code
1 : /*
2 : Samba Unix/Linux Dynamic DNS Update
3 : net ads commands
4 :
5 : Copyright (C) Krishna Ganugapati (krishnag@centeris.com) 2006
6 : Copyright (C) Gerald Carter 2006
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "utils/net.h"
24 : #include "../lib/addns/dns.h"
25 : #include "utils/net_dns.h"
26 :
27 : #if defined(HAVE_KRB5)
28 :
29 : /*********************************************************************
30 : *********************************************************************/
31 :
32 34 : DNS_ERROR DoDNSUpdate(char *pszServerName,
33 : const char *pszDomainName, const char *pszHostName,
34 : const struct sockaddr_storage *sslist, size_t num_addrs,
35 : uint32_t flags, bool remove_host)
36 : {
37 : DNS_ERROR err;
38 : struct dns_connection *conn;
39 : TALLOC_CTX *mem_ctx;
40 : OM_uint32 minor;
41 : struct dns_update_request *req, *resp;
42 :
43 34 : DEBUG(10,("DoDNSUpdate called with flags: 0x%08x\n", flags));
44 :
45 34 : if (!(flags & DNS_UPDATE_SIGNED) &&
46 0 : !(flags & DNS_UPDATE_UNSIGNED) &&
47 0 : !(flags & DNS_UPDATE_PROBE)) {
48 0 : return ERROR_DNS_INVALID_PARAMETER;
49 : }
50 :
51 34 : if ( !remove_host && ((num_addrs <= 0) || !sslist) ) {
52 0 : return ERROR_DNS_INVALID_PARAMETER;
53 : }
54 :
55 34 : if (!(mem_ctx = talloc_init("DoDNSUpdate"))) {
56 0 : return ERROR_DNS_NO_MEMORY;
57 : }
58 :
59 34 : err = dns_open_connection( pszServerName, DNS_TCP, mem_ctx, &conn );
60 34 : if (!ERR_DNS_IS_OK(err)) {
61 0 : goto error;
62 : }
63 :
64 34 : if (flags & DNS_UPDATE_PROBE) {
65 :
66 : /*
67 : * Probe if everything's fine
68 : */
69 :
70 34 : err = dns_create_probe(mem_ctx, pszDomainName, pszHostName,
71 : num_addrs, sslist, &req);
72 34 : if (!ERR_DNS_IS_OK(err)) goto error;
73 :
74 34 : err = dns_update_transaction(mem_ctx, conn, req, &resp);
75 :
76 34 : if (!ERR_DNS_IS_OK(err)) {
77 0 : DEBUG(3,("DoDNSUpdate: failed to probe DNS\n"));
78 0 : goto error;
79 : }
80 :
81 34 : if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
82 0 : (flags & DNS_UPDATE_PROBE_SUFFICIENT)) {
83 0 : TALLOC_FREE(mem_ctx);
84 0 : return ERROR_DNS_SUCCESS;
85 : }
86 : }
87 :
88 34 : if (flags & DNS_UPDATE_UNSIGNED) {
89 :
90 : /*
91 : * First try without signing
92 : */
93 :
94 34 : err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
95 : sslist, num_addrs, &req);
96 34 : if (!ERR_DNS_IS_OK(err)) goto error;
97 :
98 34 : err = dns_update_transaction(mem_ctx, conn, req, &resp);
99 34 : if (!ERR_DNS_IS_OK(err)) {
100 0 : DEBUG(3,("DoDNSUpdate: unsigned update failed\n"));
101 0 : goto error;
102 : }
103 :
104 34 : if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
105 0 : (flags & DNS_UPDATE_UNSIGNED_SUFFICIENT)) {
106 0 : TALLOC_FREE(mem_ctx);
107 0 : return ERROR_DNS_SUCCESS;
108 : }
109 : }
110 :
111 : /*
112 : * Okay, we have to try with signing
113 : */
114 34 : if (flags & DNS_UPDATE_SIGNED) {
115 : gss_ctx_id_t gss_context;
116 : char *keyname;
117 :
118 34 : err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
119 : sslist, num_addrs, &req);
120 34 : if (!ERR_DNS_IS_OK(err)) goto error;
121 :
122 34 : if (!(keyname = dns_generate_keyname( mem_ctx ))) {
123 0 : err = ERROR_DNS_NO_MEMORY;
124 0 : goto error;
125 : }
126 :
127 34 : err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
128 : keyname, &gss_context, DNS_SRV_ANY );
129 :
130 : /* retry using the Windows 2000 DNS hack */
131 34 : if (!ERR_DNS_IS_OK(err)) {
132 0 : err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
133 : keyname, &gss_context,
134 : DNS_SRV_WIN2000 );
135 : }
136 :
137 34 : if (!ERR_DNS_IS_OK(err))
138 0 : goto error;
139 :
140 34 : err = dns_sign_update(req, gss_context, keyname,
141 : "gss.microsoft.com", time(NULL), 3600);
142 :
143 34 : gss_delete_sec_context(&minor, &gss_context, GSS_C_NO_BUFFER);
144 :
145 34 : if (!ERR_DNS_IS_OK(err)) goto error;
146 :
147 34 : err = dns_update_transaction(mem_ctx, conn, req, &resp);
148 34 : if (!ERR_DNS_IS_OK(err)) goto error;
149 :
150 51 : err = (dns_response_code(resp->flags) == DNS_NO_ERROR) ?
151 17 : ERROR_DNS_SUCCESS : ERROR_DNS_UPDATE_FAILED;
152 :
153 34 : if (!ERR_DNS_IS_OK(err)) {
154 4 : DEBUG(3,("DoDNSUpdate: signed update failed\n"));
155 : }
156 : }
157 :
158 :
159 17 : error:
160 34 : TALLOC_FREE(mem_ctx);
161 34 : return err;
162 : }
163 :
164 : /*********************************************************************
165 : *********************************************************************/
166 :
167 26 : int get_my_ip_address( struct sockaddr_storage **pp_ss )
168 :
169 : {
170 : int i, n;
171 26 : struct sockaddr_storage *list = NULL;
172 26 : int count = 0;
173 :
174 : /* Honor the configured list of interfaces to register */
175 :
176 26 : load_interfaces();
177 26 : n = iface_count();
178 :
179 26 : if (n <= 0) {
180 0 : return -1;
181 : }
182 :
183 26 : if ( (list = SMB_MALLOC_ARRAY( struct sockaddr_storage, n )) == NULL ) {
184 0 : return -1;
185 : }
186 :
187 98 : for ( i=0; i<n; i++ ) {
188 72 : const struct sockaddr_storage *nic_sa_storage = NULL;
189 :
190 72 : if ((nic_sa_storage = iface_n_sockaddr_storage(i)) == NULL)
191 0 : continue;
192 :
193 : /* Don't register loopback addresses */
194 72 : if (is_loopback_addr((const struct sockaddr *)nic_sa_storage)) {
195 0 : continue;
196 : }
197 :
198 : /* Don't register link-local addresses */
199 72 : if (is_linklocal_addr(nic_sa_storage)) {
200 0 : continue;
201 : }
202 :
203 72 : memcpy(&list[count++], nic_sa_storage, sizeof(struct sockaddr_storage));
204 : }
205 26 : *pp_ss = list;
206 :
207 26 : return count;
208 : }
209 :
210 : #endif /* defined(HAVE_KRB5) */
|