~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/utils/net_dns.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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