Changeset 740 for vendor/current/source4/kdc/kdc.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/kdc/kdc.c
r414 r740 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 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/>. … … 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 … … 82 94 83 95 /* the kdc_server the connection belongs to */ 84 struct kdc_s erver *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 socket93 */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 socket122 */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 socket201 */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) … … 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 … … 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) 325 { 326 int ret; 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) 137 { 138 int ret; 139 char *pa; 140 struct sockaddr_storage ss; 327 141 krb5_data k5_reply; 328 142 krb5_data_zero(&k5_reply); … … 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 p eer_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 … … 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 … … 394 461 .name = "kdc_tcp", 395 462 .accept_connection = kdc_tcp_accept, 396 .recv_handler = kdc_tcp_recv _handler,463 .recv_handler = kdc_tcp_recv, 397 464 .send_handler = kdc_tcp_send 398 465 }; 399 466 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 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; 410 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) 417 { 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; 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) 638 { 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); 648 kdc_socket->kdc = kdc; 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); 433 656 return status; 434 657 } 435 658 436 status = socket_create("ip", SOCKET_TYPE_DGRAM, &kpasswd_socket->sock, 0); 437 if (!NT_STATUS_IS_OK(status)) { 438 talloc_free(kpasswd_socket); 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))); 439 689 return status; 440 690 } 441 691 442 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 } 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; … … 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 … … 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 { … … 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 */ … … 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; … … 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 … … 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 … … 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 … … 646 866 return NT_STATUS_LOGON_FAILURE; 647 867 } 648 868 649 869 return NT_STATUS_OK; 650 870 } … … 660 880 krb5_error_code ret; 661 881 struct interface *ifaces; 662 663 switch (lp_server_role(task->lp_ctx)) { 882 int ldb_ret; 883 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); … … 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) { … … 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); … … 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) { … … 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 *); … … 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 } … … 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);749 return; 750 } 751 752 /* Regist ar WinDC hooks */753 ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 989 task_server_terminate(task, "kdc: failed to register keytab plugin", true); 990 return; 991 } 992 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 */ … … 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, " nbtdfailed to setup monitoring", true);1026 task_server_terminate(task, "kdc failed to setup monitoring", true); 774 1027 return; 775 1028 }
Note:
See TracChangeset
for help on using the changeset viewer.