~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source4/kdc/kdc.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
 
1
/*
2
2
   Unix SMB/CIFS implementation.
3
3
 
4
4
   KDC Server startup
11
11
   it under the terms of the GNU General Public License as published by
12
12
   the Free Software Foundation; either version 3 of the License, or
13
13
   (at your option) any later version.
14
 
   
 
14
 
15
15
   This program is distributed in the hope that it will be useful,
16
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
18
   GNU General Public License for more details.
19
 
   
 
19
 
20
20
   You should have received a copy of the GNU General Public License
21
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
22
*/
23
23
 
24
24
#include "includes.h"
25
 
#include "smbd/service_task.h"
26
 
#include "smbd/service.h"
27
 
#include "smbd/service_stream.h"
28
25
#include "smbd/process_model.h"
29
 
#include "lib/events/events.h"
30
 
#include "lib/socket/socket.h"
31
 
#include "system/network.h"
32
 
#include "../lib/util/dlinklist.h"
 
26
#include "lib/tsocket/tsocket.h"
 
27
#include "libcli/util/tstream.h"
33
28
#include "lib/messaging/irpc.h"
34
 
#include "lib/stream/packet.h"
35
 
#include "librpc/gen_ndr/samr.h"
36
29
#include "librpc/gen_ndr/ndr_irpc.h"
37
30
#include "librpc/gen_ndr/ndr_krb5pac.h"
 
31
#include "lib/stream/packet.h"
38
32
#include "lib/socket/netif.h"
39
33
#include "param/param.h"
40
 
#include "kdc/kdc.h"
41
 
#include "librpc/gen_ndr/ndr_misc.h"
42
 
 
43
 
 
44
 
/* Disgusting hack to get a mem_ctx and lp_ctx into the hdb plugin, when 
45
 
 * used as a keytab */
46
 
TALLOC_CTX *hdb_samba4_mem_ctx;
47
 
struct tevent_context *hdb_samba4_ev_ctx;
48
 
struct loadparm_context *hdb_samba4_lp_ctx;
49
 
 
50
 
/* hold all the info needed to send a reply */
51
 
struct kdc_reply {
52
 
        struct kdc_reply *next, *prev;
53
 
        struct socket_address *dest;
54
 
        DATA_BLOB packet;
55
 
};
56
 
 
57
 
typedef bool (*kdc_process_fn_t)(struct kdc_server *kdc,
58
 
                                 TALLOC_CTX *mem_ctx, 
59
 
                                 DATA_BLOB *input, 
60
 
                                 DATA_BLOB *reply,
61
 
                                 struct socket_address *peer_addr, 
62
 
                                 struct socket_address *my_addr, 
63
 
                                 int datagram);
 
34
#include "kdc/kdc-glue.h"
 
35
#include "dsdb/samdb/samdb.h"
 
36
#include "auth/session.h"
 
37
 
 
38
extern struct krb5plugin_windc_ftable windc_plugin_table;
 
39
extern struct hdb_method hdb_samba4;
 
40
 
 
41
static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server *kdc,
 
42
                                            TALLOC_CTX *mem_ctx,
 
43
                                            DATA_BLOB *out)
 
44
{
 
45
        int kret;
 
46
        krb5_data k5_error_blob;
 
47
 
 
48
        kret = krb5_mk_error(kdc->smb_krb5_context->krb5_context,
 
49
                             KRB5KDC_ERR_SVC_UNAVAILABLE, NULL, NULL,
 
50
                             NULL, NULL, NULL, NULL, &k5_error_blob);
 
51
        if (kret != 0) {
 
52
                DEBUG(2,(__location__ ": Unable to form krb5 error reply\n"));
 
53
                return NT_STATUS_INTERNAL_ERROR;
 
54
        }
 
55
 
 
56
        *out = data_blob_talloc(mem_ctx, k5_error_blob.data, k5_error_blob.length);
 
57
        krb5_data_free(&k5_error_blob);
 
58
        if (!out->data) {
 
59
                return NT_STATUS_NO_MEMORY;
 
60
        }
 
61
 
 
62
        return NT_STATUS_OK;
 
63
}
 
64
 
 
65
typedef enum kdc_process_ret (*kdc_process_fn_t)(struct kdc_server *kdc,
 
66
                                                 TALLOC_CTX *mem_ctx,
 
67
                                                 DATA_BLOB *input,
 
68
                                                 DATA_BLOB *reply,
 
69
                                                 struct tsocket_address *peer_addr,
 
70
                                                 struct tsocket_address *my_addr,
 
71
                                                 int datagram);
64
72
 
65
73
/* hold information about one kdc socket */
66
74
struct kdc_socket {
67
 
        struct socket_context *sock;
68
75
        struct kdc_server *kdc;
69
 
        struct tevent_fd *fde;
70
 
 
71
 
        /* a queue of outgoing replies that have been deferred */
72
 
        struct kdc_reply *send_queue;
73
 
 
 
76
        struct tsocket_address *local_address;
74
77
        kdc_process_fn_t process;
75
78
};
 
79
 
 
80
struct kdc_tcp_call {
 
81
        struct kdc_tcp_connection *kdc_conn;
 
82
        DATA_BLOB in;
 
83
        DATA_BLOB out;
 
84
        uint8_t out_hdr[4];
 
85
        struct iovec out_iov[2];
 
86
};
 
87
 
76
88
/*
77
89
  state of an open tcp connection
78
90
*/
81
93
        struct stream_connection *conn;
82
94
 
83
95
        /* the kdc_server the connection belongs to */
84
 
        struct kdc_server *kdc;
85
 
 
86
 
        struct packet_context *packet;
87
 
 
88
 
        kdc_process_fn_t process;
 
96
        struct kdc_socket *kdc_socket;
 
97
 
 
98
        struct tstream_context *tstream;
 
99
 
 
100
        struct tevent_queue *send_queue;
89
101
};
90
102
 
91
 
/*
92
 
  handle fd send events on a KDC socket
93
 
*/
94
 
static void kdc_send_handler(struct kdc_socket *kdc_socket)
95
 
{
96
 
        while (kdc_socket->send_queue) {
97
 
                struct kdc_reply *rep = kdc_socket->send_queue;
98
 
                NTSTATUS status;
99
 
                size_t sendlen;
100
 
 
101
 
                status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen,
102
 
                                       rep->dest);
103
 
                if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
104
 
                        break;
105
 
                }
106
 
                if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_BUFFER_SIZE)) {
107
 
                        /* Replace with a krb err, response to big */
108
 
                }
109
 
                
110
 
                DLIST_REMOVE(kdc_socket->send_queue, rep);
111
 
                talloc_free(rep);
112
 
        }
113
 
 
114
 
        if (kdc_socket->send_queue == NULL) {
115
 
                EVENT_FD_NOT_WRITEABLE(kdc_socket->fde);
116
 
        }
117
 
}
118
 
 
119
 
 
120
 
/*
121
 
  handle fd recv events on a KDC socket
122
 
*/
123
 
static void kdc_recv_handler(struct kdc_socket *kdc_socket)
124
 
{
125
 
        NTSTATUS status;
126
 
        TALLOC_CTX *tmp_ctx = talloc_new(kdc_socket);
127
 
        DATA_BLOB blob;
128
 
        struct kdc_reply *rep;
129
 
        DATA_BLOB reply;
130
 
        size_t nread, dsize;
131
 
        struct socket_address *src;
132
 
        struct socket_address *my_addr;
133
 
        int ret;
134
 
 
135
 
        status = socket_pending(kdc_socket->sock, &dsize);
136
 
        if (!NT_STATUS_IS_OK(status)) {
137
 
                talloc_free(tmp_ctx);
138
 
                return;
139
 
        }
140
 
 
141
 
        blob = data_blob_talloc(tmp_ctx, NULL, dsize);
142
 
        if (blob.data == NULL) {
143
 
                /* hope this is a temporary low memory condition */
144
 
                talloc_free(tmp_ctx);
145
 
                return;
146
 
        }
147
 
 
148
 
        status = socket_recvfrom(kdc_socket->sock, blob.data, blob.length, &nread,
149
 
                                 tmp_ctx, &src);
150
 
        if (!NT_STATUS_IS_OK(status)) {
151
 
                talloc_free(tmp_ctx);
152
 
                return;
153
 
        }
154
 
        blob.length = nread;
155
 
        
156
 
        DEBUG(10,("Received krb5 UDP packet of length %lu from %s:%u\n", 
157
 
                 (long)blob.length, src->addr, (uint16_t)src->port));
158
 
        
159
 
        my_addr = socket_get_my_addr(kdc_socket->sock, tmp_ctx);
160
 
        if (!my_addr) {
161
 
                talloc_free(tmp_ctx);
162
 
                return;
163
 
        }
164
 
 
165
 
 
166
 
        /* Call krb5 */
167
 
        ret = kdc_socket->process(kdc_socket->kdc, 
168
 
                                  tmp_ctx, 
169
 
                                  &blob,  
170
 
                                  &reply,
171
 
                                  src, my_addr,
172
 
                                  1 /* Datagram */);
173
 
        if (!ret) {
174
 
                talloc_free(tmp_ctx);
175
 
                return;
176
 
        }
177
 
 
178
 
        /* queue a pending reply */
179
 
        rep = talloc(kdc_socket, struct kdc_reply);
180
 
        if (rep == NULL) {
181
 
                talloc_free(tmp_ctx);
182
 
                return;
183
 
        }
184
 
        rep->dest         = talloc_steal(rep, src);
185
 
        rep->packet       = reply;
186
 
        talloc_steal(rep, reply.data);
187
 
 
188
 
        if (rep->packet.data == NULL) {
189
 
                talloc_free(rep);
190
 
                talloc_free(tmp_ctx);
191
 
                return;
192
 
        }
193
 
 
194
 
        DLIST_ADD_END(kdc_socket->send_queue, rep, struct kdc_reply *);
195
 
        EVENT_FD_WRITEABLE(kdc_socket->fde);
196
 
        talloc_free(tmp_ctx);
197
 
}
198
 
 
199
 
/*
200
 
  handle fd events on a KDC socket
201
 
*/
202
 
static void kdc_socket_handler(struct tevent_context *ev, struct tevent_fd *fde,
203
 
                               uint16_t flags, void *private_data)
204
 
{
205
 
        struct kdc_socket *kdc_socket = talloc_get_type(private_data, struct kdc_socket);
206
 
        if (flags & EVENT_FD_WRITE) {
207
 
                kdc_send_handler(kdc_socket);
208
 
        } 
209
 
        if (flags & EVENT_FD_READ) {
210
 
                kdc_recv_handler(kdc_socket);
211
 
        }
212
 
}
213
103
 
214
104
static void kdc_tcp_terminate_connection(struct kdc_tcp_connection *kdcconn, const char *reason)
215
105
{
216
106
        stream_terminate_connection(kdcconn->conn, reason);
217
107
}
218
108
 
219
 
/*
220
 
  receive a full packet on a KDC connection
221
 
*/
222
 
static NTSTATUS kdc_tcp_recv(void *private_data, DATA_BLOB blob)
223
 
{
224
 
        struct kdc_tcp_connection *kdcconn = talloc_get_type(private_data,
225
 
                                                             struct kdc_tcp_connection);
226
 
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
227
 
        TALLOC_CTX *tmp_ctx = talloc_new(kdcconn);
228
 
        int ret;
229
 
        DATA_BLOB input, reply;
230
 
        struct socket_address *src_addr;
231
 
        struct socket_address *my_addr;
232
 
 
233
 
        talloc_steal(tmp_ctx, blob.data);
234
 
 
235
 
        src_addr = socket_get_peer_addr(kdcconn->conn->socket, tmp_ctx);
236
 
        if (!src_addr) {
237
 
                talloc_free(tmp_ctx);
238
 
                return NT_STATUS_NO_MEMORY;
239
 
        }
240
 
 
241
 
        my_addr = socket_get_my_addr(kdcconn->conn->socket, tmp_ctx);
242
 
        if (!my_addr) {
243
 
                talloc_free(tmp_ctx);
244
 
                return NT_STATUS_NO_MEMORY;
245
 
        }
246
 
 
247
 
        /* Call krb5 */
248
 
        input = data_blob_const(blob.data + 4, blob.length - 4); 
249
 
 
250
 
        ret = kdcconn->process(kdcconn->kdc, 
251
 
                               tmp_ctx,
252
 
                               &input,
253
 
                               &reply,
254
 
                               src_addr,
255
 
                               my_addr,
256
 
                               0 /* Not datagram */);
257
 
        if (!ret) {
258
 
                talloc_free(tmp_ctx);
259
 
                return NT_STATUS_INTERNAL_ERROR;
260
 
        }
261
 
 
262
 
        /* and now encode the reply */
263
 
        blob = data_blob_talloc(kdcconn, NULL, reply.length + 4);
264
 
        if (!blob.data) {
265
 
                talloc_free(tmp_ctx);
266
 
                return NT_STATUS_NO_MEMORY;
267
 
        }
268
 
 
269
 
        RSIVAL(blob.data, 0, reply.length);
270
 
        memcpy(blob.data + 4, reply.data, reply.length);        
271
 
 
272
 
        status = packet_send(kdcconn->packet, blob);
273
 
        if (!NT_STATUS_IS_OK(status)) {
274
 
                talloc_free(tmp_ctx);
275
 
                return status;
276
 
        }
277
 
 
278
 
        /* the call isn't needed any more */
279
 
        talloc_free(tmp_ctx);
280
 
        return NT_STATUS_OK;
281
 
}
282
 
 
283
 
/*
284
 
  receive some data on a KDC connection
285
 
*/
286
 
static void kdc_tcp_recv_handler(struct stream_connection *conn, uint16_t flags)
 
109
static void kdc_tcp_recv(struct stream_connection *conn, uint16_t flags)
287
110
{
288
111
        struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data,
289
112
                                                             struct kdc_tcp_connection);
290
 
        packet_recv(kdcconn->packet);
291
 
}
292
 
 
293
 
/*
294
 
  called on a tcp recv error
295
 
*/
296
 
static void kdc_tcp_recv_error(void *private_data, NTSTATUS status)
297
 
{
298
 
        struct kdc_tcp_connection *kdcconn = talloc_get_type(private_data,
299
 
                                             struct kdc_tcp_connection);
300
 
        kdc_tcp_terminate_connection(kdcconn, nt_errstr(status));
301
 
}
302
 
 
303
 
/*
304
 
  called when we can write to a connection
305
 
*/
 
113
        /* this should never be triggered! */
 
114
        kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_recv: called");
 
115
}
 
116
 
306
117
static void kdc_tcp_send(struct stream_connection *conn, uint16_t flags)
307
118
{
308
119
        struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data,
309
120
                                                             struct kdc_tcp_connection);
310
 
        packet_queue_run(kdcconn->packet);
 
121
        /* this should never be triggered! */
 
122
        kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_send: called");
311
123
}
312
124
 
313
125
/**
315
127
   calling conventions
316
128
*/
317
129
 
318
 
static bool kdc_process(struct kdc_server *kdc,
319
 
                        TALLOC_CTX *mem_ctx, 
320
 
                        DATA_BLOB *input, 
321
 
                        DATA_BLOB *reply,
322
 
                        struct socket_address *peer_addr, 
323
 
                        struct socket_address *my_addr,
324
 
                        int datagram_reply)
 
130
static enum kdc_process_ret kdc_process(struct kdc_server *kdc,
 
131
                                        TALLOC_CTX *mem_ctx,
 
132
                                        DATA_BLOB *input,
 
133
                                        DATA_BLOB *reply,
 
134
                                        struct tsocket_address *peer_addr,
 
135
                                        struct tsocket_address *my_addr,
 
136
                                        int datagram_reply)
325
137
{
326
 
        int ret;        
 
138
        int ret;
 
139
        char *pa;
 
140
        struct sockaddr_storage ss;
327
141
        krb5_data k5_reply;
328
142
        krb5_data_zero(&k5_reply);
329
143
 
330
144
        krb5_kdc_update_time(NULL);
331
145
 
332
 
        DEBUG(10,("Received KDC packet of length %lu from %s:%d\n", 
333
 
                  (long)input->length - 4, peer_addr->addr, peer_addr->port));
334
 
 
335
 
        ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context, 
 
146
        ret = tsocket_address_bsd_sockaddr(peer_addr, (struct sockaddr *) &ss,
 
147
                                sizeof(struct sockaddr_storage));
 
148
        if (ret < 0) {
 
149
                return KDC_PROCESS_FAILED;
 
150
        }
 
151
        pa = tsocket_address_string(peer_addr, mem_ctx);
 
152
        if (pa == NULL) {
 
153
                return KDC_PROCESS_FAILED;
 
154
        }
 
155
 
 
156
        DEBUG(10,("Received KDC packet of length %lu from %s\n",
 
157
                                (long)input->length - 4, pa));
 
158
 
 
159
        ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context,
336
160
                                            kdc->config,
337
161
                                            input->data, input->length,
338
162
                                            &k5_reply,
339
 
                                            peer_addr->addr,
340
 
                                            peer_addr->sockaddr,
 
163
                                            pa,
 
164
                                            (struct sockaddr *) &ss,
341
165
                                            datagram_reply);
342
166
        if (ret == -1) {
343
167
                *reply = data_blob(NULL, 0);
344
 
                return false;
345
 
        }
 
168
                return KDC_PROCESS_FAILED;
 
169
        }
 
170
 
 
171
        if (ret == HDB_ERR_NOT_FOUND_HERE) {
 
172
                *reply = data_blob(NULL, 0);
 
173
                return KDC_PROCESS_PROXY;
 
174
        }
 
175
 
346
176
        if (k5_reply.length) {
347
177
                *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
348
178
                krb5_data_free(&k5_reply);
349
179
        } else {
350
 
                *reply = data_blob(NULL, 0);    
351
 
        }
352
 
        return true;
 
180
                *reply = data_blob(NULL, 0);
 
181
        }
 
182
        return KDC_PROCESS_OK;
 
183
}
 
184
 
 
185
static void kdc_tcp_call_proxy_done(struct tevent_req *subreq);
 
186
static void kdc_tcp_call_writev_done(struct tevent_req *subreq);
 
187
 
 
188
static void kdc_tcp_call_loop(struct tevent_req *subreq)
 
189
{
 
190
        struct kdc_tcp_connection *kdc_conn = tevent_req_callback_data(subreq,
 
191
                                      struct kdc_tcp_connection);
 
192
        struct kdc_tcp_call *call;
 
193
        NTSTATUS status;
 
194
        enum kdc_process_ret ret;
 
195
 
 
196
        call = talloc(kdc_conn, struct kdc_tcp_call);
 
197
        if (call == NULL) {
 
198
                kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
 
199
                                "no memory for kdc_tcp_call");
 
200
                return;
 
201
        }
 
202
        call->kdc_conn = kdc_conn;
 
203
 
 
204
        status = tstream_read_pdu_blob_recv(subreq,
 
205
                                            call,
 
206
                                            &call->in);
 
207
        TALLOC_FREE(subreq);
 
208
        if (!NT_STATUS_IS_OK(status)) {
 
209
                const char *reason;
 
210
 
 
211
                reason = talloc_asprintf(call, "kdc_tcp_call_loop: "
 
212
                                         "tstream_read_pdu_blob_recv() - %s",
 
213
                                         nt_errstr(status));
 
214
                if (!reason) {
 
215
                        reason = nt_errstr(status);
 
216
                }
 
217
 
 
218
                kdc_tcp_terminate_connection(kdc_conn, reason);
 
219
                return;
 
220
        }
 
221
 
 
222
        DEBUG(10,("Received krb5 TCP packet of length %lu from %s\n",
 
223
                 (long) call->in.length,
 
224
                 tsocket_address_string(kdc_conn->conn->remote_address, call)));
 
225
 
 
226
        /* skip length header */
 
227
        call->in.data +=4;
 
228
        call->in.length -= 4;
 
229
 
 
230
        /* Call krb5 */
 
231
        ret = kdc_conn->kdc_socket->process(kdc_conn->kdc_socket->kdc,
 
232
                                           call,
 
233
                                           &call->in,
 
234
                                           &call->out,
 
235
                                           kdc_conn->conn->remote_address,
 
236
                                           kdc_conn->conn->local_address,
 
237
                                           0 /* Stream */);
 
238
        if (ret == KDC_PROCESS_FAILED) {
 
239
                kdc_tcp_terminate_connection(kdc_conn,
 
240
                                "kdc_tcp_call_loop: process function failed");
 
241
                return;
 
242
        }
 
243
 
 
244
        if (ret == KDC_PROCESS_PROXY) {
 
245
                uint16_t port;
 
246
 
 
247
                if (!kdc_conn->kdc_socket->kdc->am_rodc) {
 
248
                        kdc_tcp_terminate_connection(kdc_conn,
 
249
                                                     "kdc_tcp_call_loop: proxying requested when not RODC");
 
250
                        return;
 
251
                }
 
252
                port = tsocket_address_inet_port(kdc_conn->conn->local_address);
 
253
 
 
254
                subreq = kdc_tcp_proxy_send(call,
 
255
                                            kdc_conn->conn->event.ctx,
 
256
                                            kdc_conn->kdc_socket->kdc,
 
257
                                            port,
 
258
                                            call->in);
 
259
                if (subreq == NULL) {
 
260
                        kdc_tcp_terminate_connection(kdc_conn,
 
261
                                "kdc_tcp_call_loop: kdc_tcp_proxy_send failed");
 
262
                        return;
 
263
                }
 
264
                tevent_req_set_callback(subreq, kdc_tcp_call_proxy_done, call);
 
265
                return;
 
266
        }
 
267
 
 
268
        /* First add the length of the out buffer */
 
269
        RSIVAL(call->out_hdr, 0, call->out.length);
 
270
        call->out_iov[0].iov_base = (char *) call->out_hdr;
 
271
        call->out_iov[0].iov_len = 4;
 
272
 
 
273
        call->out_iov[1].iov_base = (char *) call->out.data;
 
274
        call->out_iov[1].iov_len = call->out.length;
 
275
 
 
276
        subreq = tstream_writev_queue_send(call,
 
277
                                           kdc_conn->conn->event.ctx,
 
278
                                           kdc_conn->tstream,
 
279
                                           kdc_conn->send_queue,
 
280
                                           call->out_iov, 2);
 
281
        if (subreq == NULL) {
 
282
                kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
 
283
                                "no memory for tstream_writev_queue_send");
 
284
                return;
 
285
        }
 
286
        tevent_req_set_callback(subreq, kdc_tcp_call_writev_done, call);
 
287
 
 
288
        /*
 
289
         * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
 
290
         * packet_full_request_u32 provides the pdu length then.
 
291
         */
 
292
        subreq = tstream_read_pdu_blob_send(kdc_conn,
 
293
                                            kdc_conn->conn->event.ctx,
 
294
                                            kdc_conn->tstream,
 
295
                                            4, /* initial_read_size */
 
296
                                            packet_full_request_u32,
 
297
                                            kdc_conn);
 
298
        if (subreq == NULL) {
 
299
                kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
 
300
                                "no memory for tstream_read_pdu_blob_send");
 
301
                return;
 
302
        }
 
303
        tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
 
304
}
 
305
 
 
306
static void kdc_tcp_call_proxy_done(struct tevent_req *subreq)
 
307
{
 
308
        struct kdc_tcp_call *call = tevent_req_callback_data(subreq,
 
309
                        struct kdc_tcp_call);
 
310
        struct kdc_tcp_connection *kdc_conn = call->kdc_conn;
 
311
        NTSTATUS status;
 
312
 
 
313
        status = kdc_tcp_proxy_recv(subreq, call, &call->out);
 
314
        TALLOC_FREE(subreq);
 
315
        if (!NT_STATUS_IS_OK(status)) {
 
316
                /* generate an error packet */
 
317
                status = kdc_proxy_unavailable_error(kdc_conn->kdc_socket->kdc,
 
318
                                                     call, &call->out);
 
319
        }
 
320
 
 
321
        if (!NT_STATUS_IS_OK(status)) {
 
322
                const char *reason;
 
323
 
 
324
                reason = talloc_asprintf(call, "kdc_tcp_call_proxy_done: "
 
325
                                         "kdc_proxy_unavailable_error - %s",
 
326
                                         nt_errstr(status));
 
327
                if (!reason) {
 
328
                        reason = "kdc_tcp_call_proxy_done: kdc_proxy_unavailable_error() failed";
 
329
                }
 
330
 
 
331
                kdc_tcp_terminate_connection(call->kdc_conn, reason);
 
332
                return;
 
333
        }
 
334
 
 
335
        /* First add the length of the out buffer */
 
336
        RSIVAL(call->out_hdr, 0, call->out.length);
 
337
        call->out_iov[0].iov_base = (char *) call->out_hdr;
 
338
        call->out_iov[0].iov_len = 4;
 
339
 
 
340
        call->out_iov[1].iov_base = (char *) call->out.data;
 
341
        call->out_iov[1].iov_len = call->out.length;
 
342
 
 
343
        subreq = tstream_writev_queue_send(call,
 
344
                                           kdc_conn->conn->event.ctx,
 
345
                                           kdc_conn->tstream,
 
346
                                           kdc_conn->send_queue,
 
347
                                           call->out_iov, 2);
 
348
        if (subreq == NULL) {
 
349
                kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
 
350
                                "no memory for tstream_writev_queue_send");
 
351
                return;
 
352
        }
 
353
        tevent_req_set_callback(subreq, kdc_tcp_call_writev_done, call);
 
354
 
 
355
        /*
 
356
         * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
 
357
         * packet_full_request_u32 provides the pdu length then.
 
358
         */
 
359
        subreq = tstream_read_pdu_blob_send(kdc_conn,
 
360
                                            kdc_conn->conn->event.ctx,
 
361
                                            kdc_conn->tstream,
 
362
                                            4, /* initial_read_size */
 
363
                                            packet_full_request_u32,
 
364
                                            kdc_conn);
 
365
        if (subreq == NULL) {
 
366
                kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
 
367
                                "no memory for tstream_read_pdu_blob_send");
 
368
                return;
 
369
        }
 
370
        tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
 
371
}
 
372
 
 
373
static void kdc_tcp_call_writev_done(struct tevent_req *subreq)
 
374
{
 
375
        struct kdc_tcp_call *call = tevent_req_callback_data(subreq,
 
376
                        struct kdc_tcp_call);
 
377
        int sys_errno;
 
378
        int rc;
 
379
 
 
380
        rc = tstream_writev_queue_recv(subreq, &sys_errno);
 
381
        TALLOC_FREE(subreq);
 
382
        if (rc == -1) {
 
383
                const char *reason;
 
384
 
 
385
                reason = talloc_asprintf(call, "kdc_tcp_call_writev_done: "
 
386
                                         "tstream_writev_queue_recv() - %d:%s",
 
387
                                         sys_errno, strerror(sys_errno));
 
388
                if (!reason) {
 
389
                        reason = "kdc_tcp_call_writev_done: tstream_writev_queue_recv() failed";
 
390
                }
 
391
 
 
392
                kdc_tcp_terminate_connection(call->kdc_conn, reason);
 
393
                return;
 
394
        }
 
395
 
 
396
        /* We don't care about errors */
 
397
 
 
398
        talloc_free(call);
353
399
}
354
400
 
355
401
/*
356
402
  called when we get a new connection
357
403
*/
358
 
static void kdc_tcp_generic_accept(struct stream_connection *conn, kdc_process_fn_t process_fn)
359
 
{
360
 
        struct kdc_server *kdc = talloc_get_type(conn->private_data, struct kdc_server);
361
 
        struct kdc_tcp_connection *kdcconn;
362
 
 
363
 
        kdcconn = talloc_zero(conn, struct kdc_tcp_connection);
364
 
        if (!kdcconn) {
365
 
                stream_terminate_connection(conn, "kdc_tcp_accept: out of memory");
366
 
                return;
367
 
        }
368
 
        kdcconn->conn    = conn;
369
 
        kdcconn->kdc     = kdc;
370
 
        kdcconn->process = process_fn;
371
 
        conn->private_data    = kdcconn;
372
 
 
373
 
        kdcconn->packet = packet_init(kdcconn);
374
 
        if (kdcconn->packet == NULL) {
375
 
                kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory");
376
 
                return;
377
 
        }
378
 
        packet_set_private(kdcconn->packet, kdcconn);
379
 
        packet_set_socket(kdcconn->packet, conn->socket);
380
 
        packet_set_callback(kdcconn->packet, kdc_tcp_recv);
381
 
        packet_set_full_request(kdcconn->packet, packet_full_request_u32);
382
 
        packet_set_error_handler(kdcconn->packet, kdc_tcp_recv_error);
383
 
        packet_set_event_context(kdcconn->packet, conn->event.ctx);
384
 
        packet_set_fde(kdcconn->packet, conn->event.fde);
385
 
        packet_set_serialise(kdcconn->packet);
386
 
}
387
 
 
388
404
static void kdc_tcp_accept(struct stream_connection *conn)
389
405
{
390
 
        kdc_tcp_generic_accept(conn, kdc_process);
 
406
        struct kdc_socket *kdc_socket;
 
407
        struct kdc_tcp_connection *kdc_conn;
 
408
        struct tevent_req *subreq;
 
409
        int rc;
 
410
 
 
411
        kdc_conn = talloc_zero(conn, struct kdc_tcp_connection);
 
412
        if (kdc_conn == NULL) {
 
413
                stream_terminate_connection(conn,
 
414
                                "kdc_tcp_accept: out of memory");
 
415
                return;
 
416
        }
 
417
 
 
418
        kdc_conn->send_queue = tevent_queue_create(conn, "kdc_tcp_accept");
 
419
        if (kdc_conn->send_queue == NULL) {
 
420
                stream_terminate_connection(conn,
 
421
                                "kdc_tcp_accept: out of memory");
 
422
                return;
 
423
        }
 
424
 
 
425
        kdc_socket = talloc_get_type(conn->private_data, struct kdc_socket);
 
426
 
 
427
        TALLOC_FREE(conn->event.fde);
 
428
 
 
429
        rc = tstream_bsd_existing_socket(kdc_conn,
 
430
                        socket_get_fd(conn->socket),
 
431
                        &kdc_conn->tstream);
 
432
        if (rc < 0) {
 
433
                stream_terminate_connection(conn,
 
434
                                "kdc_tcp_accept: out of memory");
 
435
                return;
 
436
        }
 
437
 
 
438
        kdc_conn->conn = conn;
 
439
        kdc_conn->kdc_socket = kdc_socket;
 
440
        conn->private_data = kdc_conn;
 
441
 
 
442
        /*
 
443
         * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
 
444
         * packet_full_request_u32 provides the pdu length then.
 
445
         */
 
446
        subreq = tstream_read_pdu_blob_send(kdc_conn,
 
447
                                            kdc_conn->conn->event.ctx,
 
448
                                            kdc_conn->tstream,
 
449
                                            4, /* initial_read_size */
 
450
                                            packet_full_request_u32,
 
451
                                            kdc_conn);
 
452
        if (subreq == NULL) {
 
453
                kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_accept: "
 
454
                                "no memory for tstream_read_pdu_blob_send");
 
455
                return;
 
456
        }
 
457
        tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
391
458
}
392
459
 
393
460
static const struct stream_server_ops kdc_tcp_stream_ops = {
394
461
        .name                   = "kdc_tcp",
395
462
        .accept_connection      = kdc_tcp_accept,
396
 
        .recv_handler           = kdc_tcp_recv_handler,
397
 
        .send_handler           = kdc_tcp_send
398
 
};
399
 
 
400
 
static void kpasswdd_tcp_accept(struct stream_connection *conn)
401
 
{
402
 
        kdc_tcp_generic_accept(conn, kpasswdd_process);
403
 
}
404
 
 
405
 
static const struct stream_server_ops kpasswdd_tcp_stream_ops = {
406
 
        .name                   = "kpasswdd_tcp",
407
 
        .accept_connection      = kpasswdd_tcp_accept,
408
 
        .recv_handler           = kdc_tcp_recv_handler,
409
 
        .send_handler           = kdc_tcp_send
410
 
};
 
463
        .recv_handler           = kdc_tcp_recv,
 
464
        .send_handler           = kdc_tcp_send
 
465
};
 
466
 
 
467
/* hold information about one kdc/kpasswd udp socket */
 
468
struct kdc_udp_socket {
 
469
        struct kdc_socket *kdc_socket;
 
470
        struct tdgram_context *dgram;
 
471
        struct tevent_queue *send_queue;
 
472
};
 
473
 
 
474
struct kdc_udp_call {
 
475
        struct kdc_udp_socket *sock;
 
476
        struct tsocket_address *src;
 
477
        DATA_BLOB in;
 
478
        DATA_BLOB out;
 
479
};
 
480
 
 
481
static void kdc_udp_call_proxy_done(struct tevent_req *subreq);
 
482
static void kdc_udp_call_sendto_done(struct tevent_req *subreq);
 
483
 
 
484
static void kdc_udp_call_loop(struct tevent_req *subreq)
 
485
{
 
486
        struct kdc_udp_socket *sock = tevent_req_callback_data(subreq,
 
487
                                      struct kdc_udp_socket);
 
488
        struct kdc_udp_call *call;
 
489
        uint8_t *buf;
 
490
        ssize_t len;
 
491
        int sys_errno;
 
492
        enum kdc_process_ret ret;
 
493
 
 
494
        call = talloc(sock, struct kdc_udp_call);
 
495
        if (call == NULL) {
 
496
                talloc_free(call);
 
497
                goto done;
 
498
        }
 
499
        call->sock = sock;
 
500
 
 
501
        len = tdgram_recvfrom_recv(subreq, &sys_errno,
 
502
                                   call, &buf, &call->src);
 
503
        TALLOC_FREE(subreq);
 
504
        if (len == -1) {
 
505
                talloc_free(call);
 
506
                goto done;
 
507
        }
 
508
 
 
509
        call->in.data = buf;
 
510
        call->in.length = len;
 
511
 
 
512
        DEBUG(10,("Received krb5 UDP packet of length %lu from %s\n",
 
513
                 (long)call->in.length,
 
514
                 tsocket_address_string(call->src, call)));
 
515
 
 
516
        /* Call krb5 */
 
517
        ret = sock->kdc_socket->process(sock->kdc_socket->kdc,
 
518
                                       call,
 
519
                                       &call->in,
 
520
                                       &call->out,
 
521
                                       call->src,
 
522
                                       sock->kdc_socket->local_address,
 
523
                                       1 /* Datagram */);
 
524
        if (ret == KDC_PROCESS_FAILED) {
 
525
                talloc_free(call);
 
526
                goto done;
 
527
        }
 
528
 
 
529
        if (ret == KDC_PROCESS_PROXY) {
 
530
                uint16_t port;
 
531
 
 
532
                if (!sock->kdc_socket->kdc->am_rodc) {
 
533
                        DEBUG(0,("kdc_udp_call_loop: proxying requested when not RODC"));
 
534
                        talloc_free(call);
 
535
                        goto done;
 
536
                }
 
537
 
 
538
                port = tsocket_address_inet_port(sock->kdc_socket->local_address);
 
539
 
 
540
                subreq = kdc_udp_proxy_send(call,
 
541
                                            sock->kdc_socket->kdc->task->event_ctx,
 
542
                                            sock->kdc_socket->kdc,
 
543
                                            port,
 
544
                                            call->in);
 
545
                if (subreq == NULL) {
 
546
                        talloc_free(call);
 
547
                        goto done;
 
548
                }
 
549
                tevent_req_set_callback(subreq, kdc_udp_call_proxy_done, call);
 
550
                goto done;
 
551
        }
 
552
 
 
553
        subreq = tdgram_sendto_queue_send(call,
 
554
                                          sock->kdc_socket->kdc->task->event_ctx,
 
555
                                          sock->dgram,
 
556
                                          sock->send_queue,
 
557
                                          call->out.data,
 
558
                                          call->out.length,
 
559
                                          call->src);
 
560
        if (subreq == NULL) {
 
561
                talloc_free(call);
 
562
                goto done;
 
563
        }
 
564
        tevent_req_set_callback(subreq, kdc_udp_call_sendto_done, call);
 
565
 
 
566
done:
 
567
        subreq = tdgram_recvfrom_send(sock,
 
568
                                      sock->kdc_socket->kdc->task->event_ctx,
 
569
                                      sock->dgram);
 
570
        if (subreq == NULL) {
 
571
                task_server_terminate(sock->kdc_socket->kdc->task,
 
572
                                      "no memory for tdgram_recvfrom_send",
 
573
                                      true);
 
574
                return;
 
575
        }
 
576
        tevent_req_set_callback(subreq, kdc_udp_call_loop, sock);
 
577
}
 
578
 
 
579
static void kdc_udp_call_proxy_done(struct tevent_req *subreq)
 
580
{
 
581
        struct kdc_udp_call *call =
 
582
                tevent_req_callback_data(subreq,
 
583
                struct kdc_udp_call);
 
584
        NTSTATUS status;
 
585
 
 
586
        status = kdc_udp_proxy_recv(subreq, call, &call->out);
 
587
        TALLOC_FREE(subreq);
 
588
        if (!NT_STATUS_IS_OK(status)) {
 
589
                /* generate an error packet */
 
590
                status = kdc_proxy_unavailable_error(call->sock->kdc_socket->kdc,
 
591
                                                     call, &call->out);
 
592
        }
 
593
 
 
594
        if (!NT_STATUS_IS_OK(status)) {
 
595
                talloc_free(call);
 
596
                return;
 
597
        }
 
598
 
 
599
        subreq = tdgram_sendto_queue_send(call,
 
600
                                          call->sock->kdc_socket->kdc->task->event_ctx,
 
601
                                          call->sock->dgram,
 
602
                                          call->sock->send_queue,
 
603
                                          call->out.data,
 
604
                                          call->out.length,
 
605
                                          call->src);
 
606
        if (subreq == NULL) {
 
607
                talloc_free(call);
 
608
                return;
 
609
        }
 
610
 
 
611
        tevent_req_set_callback(subreq, kdc_udp_call_sendto_done, call);
 
612
}
 
613
 
 
614
static void kdc_udp_call_sendto_done(struct tevent_req *subreq)
 
615
{
 
616
        struct kdc_udp_call *call = tevent_req_callback_data(subreq,
 
617
                                       struct kdc_udp_call);
 
618
        ssize_t ret;
 
619
        int sys_errno;
 
620
 
 
621
        ret = tdgram_sendto_queue_recv(subreq, &sys_errno);
 
622
 
 
623
        /* We don't care about errors */
 
624
 
 
625
        talloc_free(call);
 
626
}
411
627
 
412
628
/*
413
629
  start listening on the given address
414
630
*/
415
 
static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
416
 
                               uint16_t kdc_port, uint16_t kpasswd_port)
 
631
static NTSTATUS kdc_add_socket(struct kdc_server *kdc,
 
632
                               const struct model_ops *model_ops,
 
633
                               const char *name,
 
634
                               const char *address,
 
635
                               uint16_t port,
 
636
                               kdc_process_fn_t process,
 
637
                               bool udp_only)
417
638
{
418
 
        const struct model_ops *model_ops;
419
 
        struct kdc_socket *kdc_socket;
420
 
        struct kdc_socket *kpasswd_socket;
421
 
        struct socket_address *kdc_address, *kpasswd_address;
 
639
        struct kdc_socket *kdc_socket;
 
640
        struct kdc_udp_socket *kdc_udp_socket;
 
641
        struct tevent_req *udpsubreq;
422
642
        NTSTATUS status;
 
643
        int ret;
423
644
 
424
645
        kdc_socket = talloc(kdc, struct kdc_socket);
425
646
        NT_STATUS_HAVE_NO_MEMORY(kdc_socket);
426
647
 
427
 
        kpasswd_socket = talloc(kdc, struct kdc_socket);
428
 
        NT_STATUS_HAVE_NO_MEMORY(kpasswd_socket);
429
 
 
430
 
        status = socket_create("ip", SOCKET_TYPE_DGRAM, &kdc_socket->sock, 0);
431
 
        if (!NT_STATUS_IS_OK(status)) {
432
 
                talloc_free(kdc_socket);
433
 
                return status;
434
 
        }
435
 
 
436
 
        status = socket_create("ip", SOCKET_TYPE_DGRAM, &kpasswd_socket->sock, 0);
437
 
        if (!NT_STATUS_IS_OK(status)) {
438
 
                talloc_free(kpasswd_socket);
439
 
                return status;
440
 
        }
441
 
 
442
648
        kdc_socket->kdc = kdc;
443
 
        kdc_socket->send_queue = NULL;
444
 
        kdc_socket->process = kdc_process;
445
 
 
446
 
        talloc_steal(kdc_socket, kdc_socket->sock);
447
 
 
448
 
        kdc_socket->fde = event_add_fd(kdc->task->event_ctx, kdc, 
449
 
                                       socket_get_fd(kdc_socket->sock), EVENT_FD_READ,
450
 
                                       kdc_socket_handler, kdc_socket);
451
 
 
452
 
        kdc_address = socket_address_from_strings(kdc_socket, kdc_socket->sock->backend_name, 
453
 
                                                  address, kdc_port);
454
 
        NT_STATUS_HAVE_NO_MEMORY(kdc_address);
455
 
 
456
 
        status = socket_listen(kdc_socket->sock, kdc_address, 0, 0);
457
 
        if (!NT_STATUS_IS_OK(status)) {
458
 
                DEBUG(0,("Failed to bind to %s:%d UDP for kdc - %s\n", 
459
 
                         address, kdc_port, nt_errstr(status)));
460
 
                talloc_free(kdc_socket);
461
 
                return status;
462
 
        }
463
 
 
464
 
        kpasswd_socket->kdc = kdc;
465
 
        kpasswd_socket->send_queue = NULL;
466
 
        kpasswd_socket->process = kpasswdd_process;
467
 
 
468
 
        talloc_steal(kpasswd_socket, kpasswd_socket->sock);
469
 
 
470
 
        kpasswd_socket->fde = event_add_fd(kdc->task->event_ctx, kdc, 
471
 
                                           socket_get_fd(kpasswd_socket->sock), EVENT_FD_READ,
472
 
                                           kdc_socket_handler, kpasswd_socket);
473
 
        
474
 
        kpasswd_address = socket_address_from_strings(kpasswd_socket, kpasswd_socket->sock->backend_name, 
475
 
                                                      address, kpasswd_port);
476
 
        NT_STATUS_HAVE_NO_MEMORY(kpasswd_address);
477
 
 
478
 
        status = socket_listen(kpasswd_socket->sock, kpasswd_address, 0, 0);
479
 
        if (!NT_STATUS_IS_OK(status)) {
480
 
                DEBUG(0,("Failed to bind to %s:%d UDP for kpasswd - %s\n", 
481
 
                         address, kpasswd_port, nt_errstr(status)));
482
 
                talloc_free(kpasswd_socket);
483
 
                return status;
484
 
        }
485
 
 
486
 
        /* within the kdc task we want to be a single process, so
487
 
           ask for the single process model ops and pass these to the
488
 
           stream_setup_socket() call. */
489
 
        model_ops = process_model_startup(kdc->task->event_ctx, "single");
490
 
        if (!model_ops) {
491
 
                DEBUG(0,("Can't find 'single' process model_ops\n"));
492
 
                talloc_free(kdc_socket);
493
 
                return NT_STATUS_INTERNAL_ERROR;
494
 
        }
495
 
 
496
 
        status = stream_setup_socket(kdc->task->event_ctx, 
497
 
                                     kdc->task->lp_ctx,
498
 
                                     model_ops, 
499
 
                                     &kdc_tcp_stream_ops, 
500
 
                                     "ip", address, &kdc_port, 
501
 
                                     lp_socket_options(kdc->task->lp_ctx), 
502
 
                                     kdc);
503
 
        if (!NT_STATUS_IS_OK(status)) {
504
 
                DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
505
 
                         address, kdc_port, nt_errstr(status)));
506
 
                talloc_free(kdc_socket);
507
 
                return status;
508
 
        }
509
 
 
510
 
        status = stream_setup_socket(kdc->task->event_ctx, 
511
 
                                     kdc->task->lp_ctx,
512
 
                                     model_ops, 
513
 
                                     &kpasswdd_tcp_stream_ops, 
514
 
                                     "ip", address, &kpasswd_port, 
515
 
                                     lp_socket_options(kdc->task->lp_ctx), 
516
 
                                     kdc);
517
 
        if (!NT_STATUS_IS_OK(status)) {
518
 
                DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
519
 
                         address, kpasswd_port, nt_errstr(status)));
520
 
                talloc_free(kdc_socket);
521
 
                return status;
522
 
        }
 
649
        kdc_socket->process = process;
 
650
 
 
651
        ret = tsocket_address_inet_from_strings(kdc_socket, "ip",
 
652
                                                address, port,
 
653
                                                &kdc_socket->local_address);
 
654
        if (ret != 0) {
 
655
                status = map_nt_error_from_unix(errno);
 
656
                return status;
 
657
        }
 
658
 
 
659
        if (!udp_only) {
 
660
                status = stream_setup_socket(kdc->task,
 
661
                                             kdc->task->event_ctx,
 
662
                                             kdc->task->lp_ctx,
 
663
                                             model_ops,
 
664
                                             &kdc_tcp_stream_ops,
 
665
                                             "ip", address, &port,
 
666
                                             lpcfg_socket_options(kdc->task->lp_ctx),
 
667
                                             kdc_socket);
 
668
                if (!NT_STATUS_IS_OK(status)) {
 
669
                        DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
 
670
                                 address, port, nt_errstr(status)));
 
671
                        talloc_free(kdc_socket);
 
672
                        return status;
 
673
                }
 
674
        }
 
675
 
 
676
        kdc_udp_socket = talloc(kdc_socket, struct kdc_udp_socket);
 
677
        NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket);
 
678
 
 
679
        kdc_udp_socket->kdc_socket = kdc_socket;
 
680
 
 
681
        ret = tdgram_inet_udp_socket(kdc_socket->local_address,
 
682
                                     NULL,
 
683
                                     kdc_udp_socket,
 
684
                                     &kdc_udp_socket->dgram);
 
685
        if (ret != 0) {
 
686
                status = map_nt_error_from_unix(errno);
 
687
                DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
 
688
                         address, port, nt_errstr(status)));
 
689
                return status;
 
690
        }
 
691
 
 
692
        kdc_udp_socket->send_queue = tevent_queue_create(kdc_udp_socket,
 
693
                                                         "kdc_udp_send_queue");
 
694
        NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket->send_queue);
 
695
 
 
696
        udpsubreq = tdgram_recvfrom_send(kdc_udp_socket,
 
697
                                         kdc->task->event_ctx,
 
698
                                         kdc_udp_socket->dgram);
 
699
        NT_STATUS_HAVE_NO_MEMORY(udpsubreq);
 
700
        tevent_req_set_callback(udpsubreq, kdc_udp_call_loop, kdc_udp_socket);
523
701
 
524
702
        return NT_STATUS_OK;
525
703
}
531
709
static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx,
532
710
                                       struct interface *ifaces)
533
711
{
 
712
        const struct model_ops *model_ops;
534
713
        int num_interfaces;
535
714
        TALLOC_CTX *tmp_ctx = talloc_new(kdc);
536
715
        NTSTATUS status;
537
716
        int i;
 
717
        uint16_t kdc_port = lpcfg_krb5_port(lp_ctx);
 
718
        uint16_t kpasswd_port = lpcfg_kpasswd_port(lp_ctx);
 
719
        bool done_wildcard = false;
 
720
 
 
721
        /* within the kdc task we want to be a single process, so
 
722
           ask for the single process model ops and pass these to the
 
723
           stream_setup_socket() call. */
 
724
        model_ops = process_model_startup("single");
 
725
        if (!model_ops) {
 
726
                DEBUG(0,("Can't find 'single' process model_ops\n"));
 
727
                return NT_STATUS_INTERNAL_ERROR;
 
728
        }
538
729
 
539
730
        num_interfaces = iface_count(ifaces);
540
 
        
 
731
 
 
732
        /* if we are allowing incoming packets from any address, then
 
733
           we need to bind to the wildcard address */
 
734
        if (!lpcfg_bind_interfaces_only(lp_ctx)) {
 
735
                if (kdc_port) {
 
736
                        status = kdc_add_socket(kdc, model_ops,
 
737
                                                "kdc", "0.0.0.0", kdc_port,
 
738
                                                kdc_process, false);
 
739
                        NT_STATUS_NOT_OK_RETURN(status);
 
740
                }
 
741
 
 
742
                if (kpasswd_port) {
 
743
                        status = kdc_add_socket(kdc, model_ops,
 
744
                                                "kpasswd", "0.0.0.0", kpasswd_port,
 
745
                                                kpasswdd_process, false);
 
746
                        NT_STATUS_NOT_OK_RETURN(status);
 
747
                }
 
748
                done_wildcard = true;
 
749
        }
 
750
 
541
751
        for (i=0; i<num_interfaces; i++) {
542
752
                const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
543
 
                status = kdc_add_socket(kdc, address, lp_krb5_port(lp_ctx), 
544
 
                                        lp_kpasswd_port(lp_ctx));
545
 
                NT_STATUS_NOT_OK_RETURN(status);
 
753
 
 
754
                if (kdc_port) {
 
755
                        status = kdc_add_socket(kdc, model_ops,
 
756
                                                "kdc", address, kdc_port,
 
757
                                                kdc_process, done_wildcard);
 
758
                        NT_STATUS_NOT_OK_RETURN(status);
 
759
                }
 
760
 
 
761
                if (kpasswd_port) {
 
762
                        status = kdc_add_socket(kdc, model_ops,
 
763
                                                "kpasswd", address, kpasswd_port,
 
764
                                                kpasswdd_process, done_wildcard);
 
765
                        NT_STATUS_NOT_OK_RETURN(status);
 
766
                }
546
767
        }
547
768
 
548
769
        talloc_free(tmp_ctx);
551
772
}
552
773
 
553
774
 
554
 
static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg, 
 
775
static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
555
776
                                 struct kdc_check_generic_kerberos *r)
556
777
{
557
778
        struct PAC_Validate pac_validate;
569
790
        /* There is no reply to this request */
570
791
        r->out.generic_reply = data_blob(NULL, 0);
571
792
 
572
 
        ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, 
573
 
                                       lp_iconv_convenience(kdc->task->lp_ctx), 
574
 
                                       &pac_validate,
 
793
        ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, &pac_validate,
575
794
                                       (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
576
795
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
577
796
                return NT_STATUS_INVALID_PARAMETER;
578
797
        }
579
 
        
 
798
 
580
799
        if (pac_validate.MessageType != 3) {
581
800
                /* We don't implement any other message types - such as certificate validation - yet */
582
801
                return NT_STATUS_INVALID_PARAMETER;
587
806
            || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
588
807
                return NT_STATUS_INVALID_PARAMETER;
589
808
        }
590
 
        
591
 
        srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data, 
 
809
 
 
810
        srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
592
811
                                  pac_validate.ChecksumLength);
593
 
        
 
812
 
594
813
        if (pac_validate.SignatureType == CKSUMTYPE_HMAC_MD5) {
595
814
                etype = ETYPE_ARCFOUR_HMAC_MD5;
596
815
        } else {
601
820
                }
602
821
        }
603
822
 
604
 
        ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal, 
605
 
                                  lp_realm(kdc->task->lp_ctx), 
606
 
                                  "krbtgt", lp_realm(kdc->task->lp_ctx), 
 
823
        ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
 
824
                                  lpcfg_realm(kdc->task->lp_ctx),
 
825
                                  "krbtgt", lpcfg_realm(kdc->task->lp_ctx),
607
826
                                  NULL);
608
827
 
609
828
        if (ret != 0) {
610
829
                return NT_STATUS_NO_MEMORY;
611
830
        }
612
831
 
613
 
        ret = kdc->config->db[0]->hdb_fetch(kdc->smb_krb5_context->krb5_context, 
614
 
                                            kdc->config->db[0],
615
 
                                            principal,
616
 
                                            HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
617
 
                                            &ent);
618
 
 
 
832
        ret = kdc->config->db[0]->hdb_fetch_kvno(kdc->smb_krb5_context->krb5_context,
 
833
                                                 kdc->config->db[0],
 
834
                                                 principal,
 
835
                                                 HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
 
836
                                                 0,
 
837
                                                 &ent);
 
838
        
619
839
        if (ret != 0) {
620
840
                hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
621
841
                krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
622
 
        
 
842
 
623
843
                return NT_STATUS_LOGON_FAILURE;
624
844
        }
625
 
        
 
845
 
626
846
        ret = hdb_enctype2key(kdc->smb_krb5_context->krb5_context, &ent.entry, etype, &key);
627
847
 
628
848
        if (ret != 0) {
632
852
        }
633
853
 
634
854
        keyblock = key->key;
635
 
        
 
855
 
636
856
        kdc_sig.type = pac_validate.SignatureType;
637
857
        kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
638
858
                                            pac_validate.SignatureLength);
639
 
        ret = check_pac_checksum(msg, srv_sig, &kdc_sig, 
 
859
        ret = check_pac_checksum(msg, srv_sig, &kdc_sig,
640
860
                           kdc->smb_krb5_context->krb5_context, &keyblock);
641
861
 
642
862
        hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
645
865
        if (ret != 0) {
646
866
                return NT_STATUS_LOGON_FAILURE;
647
867
        }
648
 
        
 
868
 
649
869
        return NT_STATUS_OK;
650
870
}
651
871
 
659
879
        NTSTATUS status;
660
880
        krb5_error_code ret;
661
881
        struct interface *ifaces;
 
882
        int ldb_ret;
662
883
 
663
 
        switch (lp_server_role(task->lp_ctx)) {
 
884
        switch (lpcfg_server_role(task->lp_ctx)) {
664
885
        case ROLE_STANDALONE:
665
886
                task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
666
887
                return;
672
893
                break;
673
894
        }
674
895
 
675
 
        load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
 
896
        load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces);
676
897
 
677
898
        if (iface_count(ifaces) == 0) {
678
899
                task_server_terminate(task, "kdc: no network interfaces configured", false);
681
902
 
682
903
        task_server_set_title(task, "task[kdc]");
683
904
 
684
 
        kdc = talloc(task, struct kdc_server);
 
905
        kdc = talloc_zero(task, struct kdc_server);
685
906
        if (kdc == NULL) {
686
907
                task_server_terminate(task, "kdc: out of memory", true);
687
908
                return;
689
910
 
690
911
        kdc->task = task;
691
912
 
 
913
 
 
914
        /* get a samdb connection */
 
915
        kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx,
 
916
                                   system_session(kdc->task->lp_ctx), 0);
 
917
        if (!kdc->samdb) {
 
918
                DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
 
919
                task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
 
920
                return;
 
921
        }
 
922
 
 
923
        ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
 
924
        if (ldb_ret != LDB_SUCCESS) {
 
925
                DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
 
926
                          ldb_errstring(kdc->samdb)));
 
927
                task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
 
928
                return;
 
929
        }
 
930
 
 
931
        kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);
 
932
 
692
933
        initialize_krb5_error_table();
693
934
 
694
935
        ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context);
695
936
        if (ret) {
696
 
                DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n", 
 
937
                DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
697
938
                         error_message(ret)));
698
939
                task_server_terminate(task, "kdc: krb5_init_context failed", true);
699
 
                return; 
 
940
                return;
700
941
        }
701
942
 
702
943
        krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
703
944
 
704
 
        ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context, 
 
945
        ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
705
946
                                  &kdc->config);
706
947
        if(ret) {
707
948
                task_server_terminate(task, "kdc: failed to get KDC configuration", true);
708
949
                return;
709
950
        }
710
 
 
 
951
 
711
952
        kdc->config->logf = kdc->smb_krb5_context->logf;
712
953
        kdc->config->db = talloc(kdc, struct HDB *);
713
954
        if (!kdc->config->db) {
715
956
                return;
716
957
        }
717
958
        kdc->config->num_db = 1;
718
 
                
719
 
        status = hdb_samba4_create_kdc(kdc, task->event_ctx, task->lp_ctx, 
720
 
                                       kdc->smb_krb5_context->krb5_context, 
 
959
 
 
960
        /* Register hdb-samba4 hooks for use as a keytab */
 
961
 
 
962
        kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
 
963
        if (!kdc->base_ctx) {
 
964
                task_server_terminate(task, "kdc: out of memory", true);
 
965
                return;
 
966
        }
 
967
 
 
968
        kdc->base_ctx->ev_ctx = task->event_ctx;
 
969
        kdc->base_ctx->lp_ctx = task->lp_ctx;
 
970
 
 
971
        status = hdb_samba4_create_kdc(kdc->base_ctx,
 
972
                                       kdc->smb_krb5_context->krb5_context,
721
973
                                       &kdc->config->db[0]);
722
974
        if (!NT_STATUS_IS_OK(status)) {
723
975
                task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
724
 
                return; 
725
 
        }
726
 
 
727
 
        /* Register hdb-samba4 hooks for use as a keytab */
728
 
 
729
 
        kdc->hdb_samba4_context = talloc(kdc, struct hdb_samba4_context);
730
 
        if (!kdc->hdb_samba4_context) {
731
 
                task_server_terminate(task, "kdc: out of memory", true);
732
 
                return; 
733
 
        }
734
 
 
735
 
        kdc->hdb_samba4_context->ev_ctx = task->event_ctx;
736
 
        kdc->hdb_samba4_context->lp_ctx = task->lp_ctx;
737
 
 
738
 
        ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 
 
976
                return;
 
977
        }
 
978
 
 
979
        ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
739
980
                                   PLUGIN_TYPE_DATA, "hdb",
740
981
                                   &hdb_samba4);
741
982
        if(ret) {
742
 
                task_server_terminate(task, "kdc: failed to register hdb keytab", true);
 
983
                task_server_terminate(task, "kdc: failed to register hdb plugin", true);
743
984
                return;
744
985
        }
745
986
 
746
987
        ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
747
988
        if(ret) {
748
 
                task_server_terminate(task, "kdc: failed to register hdb keytab", true);
 
989
                task_server_terminate(task, "kdc: failed to register keytab plugin", true);
749
990
                return;
750
991
        }
751
992
 
752
 
        /* Registar WinDC hooks */
753
 
        ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 
 
993
        /* Register WinDC hooks */
 
994
        ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
754
995
                                   PLUGIN_TYPE_DATA, "windc",
755
996
                                   &windc_plugin_table);
756
997
        if(ret) {
757
 
                task_server_terminate(task, "kdc: failed to register hdb keytab", true);
758
 
                return;
759
 
        }
760
 
 
761
 
        krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
 
998
                task_server_terminate(task, "kdc: failed to register windc plugin", true);
 
999
                return;
 
1000
        }
 
1001
 
 
1002
        ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
 
1003
 
 
1004
        if(ret) {
 
1005
                task_server_terminate(task, "kdc: failed to init windc plugin", true);
 
1006
                return;
 
1007
        }
 
1008
 
 
1009
        ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc->config);
 
1010
 
 
1011
        if(ret) {
 
1012
                task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
 
1013
                return;
 
1014
        }
762
1015
 
763
1016
        /* start listening on the configured network interfaces */
764
1017
        status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
767
1020
                return;
768
1021
        }
769
1022
 
770
 
        status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS, 
 
1023
        status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
771
1024
                               kdc_check_generic_kerberos, kdc);
772
1025
        if (!NT_STATUS_IS_OK(status)) {
773
 
                task_server_terminate(task, "nbtd failed to setup monitoring", true);
 
1026
                task_server_terminate(task, "kdc failed to setup monitoring", true);
774
1027
                return;
775
1028
        }
776
1029