s4-kdc: Fix logging with the KDB driver
[samba.git] / source4 / kdc / kdc-service-mit.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Start MIT krb5kdc server within Samba AD
5
6    Copyright (c) 2014-2016 Andreas Schneider <asn@samba.org>
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "talloc.h"
24 #include "tevent.h"
25 #include "system/filesys.h"
26 #include "lib/param/param.h"
27 #include "lib/util/samba_util.h"
28 #include "source4/smbd/service.h"
29 #include "source4/smbd/process_model.h"
30 #include "kdc/kdc-service-mit.h"
31 #include "dynconfig.h"
32 #include "libds/common/roles.h"
33 #include "lib/socket/netif.h"
34 #include "samba/session.h"
35 #include "dsdb/samdb/samdb.h"
36 #include "kdc/samba_kdc.h"
37 #include "kdc/kdc-server.h"
38 #include "kdc/kpasswd-service.h"
39 #include <kadm5/admin.h>
40 #include <kdb.h>
41
42 #include "source4/kdc/mit_kdc_irpc.h"
43
44 /* PROTOTYPES */
45 static void mitkdc_server_done(struct tevent_req *subreq);
46
47 static int kdc_server_destroy(struct kdc_server *kdc)
48 {
49         if (kdc->private_data != NULL) {
50                 kadm5_destroy(kdc->private_data);
51         }
52
53         return 0;
54 }
55
56 static NTSTATUS startup_kpasswd_server(TALLOC_CTX *mem_ctx,
57                                        struct kdc_server *kdc,
58                                        struct loadparm_context *lp_ctx,
59                                        struct interface *ifaces)
60 {
61         const struct model_ops *model_ops;
62         int num_interfaces;
63         int i;
64         TALLOC_CTX *tmp_ctx;
65         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
66         uint16_t kpasswd_port;
67         bool done_wildcard = false;
68         bool ok;
69
70         kpasswd_port = lpcfg_kpasswd_port(lp_ctx);
71         if (kpasswd_port == 0) {
72                 return NT_STATUS_OK;
73         }
74
75         model_ops = process_model_startup("single");
76         if (model_ops == NULL) {
77                 DBG_ERR("Can't find 'single' process model_ops\n");
78                 return NT_STATUS_INTERNAL_ERROR;
79         }
80
81         tmp_ctx = talloc_named_const(mem_ctx, 0, "kpasswd");
82         if (tmp_ctx == NULL) {
83                 return NT_STATUS_NO_MEMORY;
84         }
85
86         num_interfaces = iface_list_count(ifaces);
87
88         ok = lpcfg_bind_interfaces_only(lp_ctx);
89         if (!ok) {
90                 int num_binds = 0;
91                 char **wcard;
92
93                 wcard = iface_list_wildcard(tmp_ctx);
94                 if (wcard == NULL) {
95                         status = NT_STATUS_NO_MEMORY;
96                         goto out;
97                 }
98
99                 for (i = 0; wcard[i] != NULL; i++) {
100                         status = kdc_add_socket(kdc,
101                                                 model_ops,
102                                                 "kpasswd",
103                                                 wcard[i],
104                                                 kpasswd_port,
105                                                 kpasswd_process,
106                                                 false);
107                         if (NT_STATUS_IS_OK(status)) {
108                                 num_binds++;
109                         }
110                 }
111                 talloc_free(wcard);
112
113                 if (num_binds == 0) {
114                         status = NT_STATUS_INVALID_PARAMETER_MIX;
115                         goto out;
116                 }
117
118                 done_wildcard = true;
119         }
120
121         for (i = 0; i < num_interfaces; i++) {
122                 const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
123
124                 status = kdc_add_socket(kdc,
125                                         model_ops,
126                                         "kpasswd",
127                                         address,
128                                         kpasswd_port,
129                                         kpasswd_process,
130                                         done_wildcard);
131                 if (NT_STATUS_IS_OK(status)) {
132                         goto out;
133                 }
134         }
135
136 out:
137         talloc_free(tmp_ctx);
138         return status;
139 }
140
141 /*
142  * Startup a copy of the krb5kdc as a child daemon
143  */
144 void mitkdc_task_init(struct task_server *task)
145 {
146         struct tevent_req *subreq;
147         const char * const *kdc_cmd;
148         struct interface *ifaces;
149         const char *kdc_config;
150         struct kdc_server *kdc;
151         krb5_error_code code;
152         NTSTATUS status;
153         kadm5_ret_t ret;
154         kadm5_config_params config;
155         void *server_handle;
156
157         task_server_set_title(task, "task[mitkdc_parent]");
158
159         switch (lpcfg_server_role(task->lp_ctx)) {
160         case ROLE_STANDALONE:
161                 task_server_terminate(task,
162                                       "The KDC is not required in standalone "
163                                       "server configuration, terminate!",
164                                       false);
165                 return;
166         case ROLE_DOMAIN_MEMBER:
167                 task_server_terminate(task,
168                                       "The KDC is not required in member "
169                                       "server configuration",
170                                       false);
171                 return;
172         case ROLE_ACTIVE_DIRECTORY_DC:
173                 /* Yes, we want to start the KDC */
174                 break;
175         }
176
177         /* Load interfaces for kpasswd */
178         load_interface_list(task, task->lp_ctx, &ifaces);
179         if (iface_list_count(ifaces) == 0) {
180                 task_server_terminate(task,
181                                       "KDC: no network interfaces configured",
182                                       false);
183                 return;
184         }
185
186         kdc_config = lpcfg_mit_kdc_config(task->lp_ctx, task);
187         if (kdc_config != NULL && kdc_config[0] != '\0') {
188                 /* Do not overwrite the variable if already set! */
189                 setenv("KRB5_KDC_PROFILE", kdc_config, 0);
190         }
191
192         /* start it as a child process */
193         kdc_cmd = lpcfg_mit_kdc_command(task->lp_ctx);
194
195         subreq = samba_runcmd_send(task,
196                                    task->event_ctx,
197                                    timeval_zero(),
198                                    1, /* stdout log level */
199                                    0, /* stderr log level */
200                                    kdc_cmd,
201                                    "-n", /* Don't go into background */
202 #if 0
203                                    "-w 2", /* Start two workers */
204 #endif
205                                    NULL);
206         if (subreq == NULL) {
207                 DEBUG(0, ("Failed to start MIT KDC as child daemon\n"));
208
209                 task_server_terminate(task,
210                                       "Failed to startup mitkdc task",
211                                       true);
212                 return;
213         }
214
215         tevent_req_set_callback(subreq, mitkdc_server_done, task);
216
217         DEBUG(5,("Started krb5kdc process\n"));
218
219         status = samba_setup_mit_kdc_irpc(task);
220         if (!NT_STATUS_IS_OK(status)) {
221                 task_server_terminate(task,
222                                       "Failed to setup kdc irpc service",
223                                       true);
224         }
225
226         DEBUG(5,("Started irpc service for kdc_server\n"));
227
228         kdc = talloc_zero(task, struct kdc_server);
229         if (kdc == NULL) {
230                 task_server_terminate(task, "KDC: Out of memory", true);
231                 return;
232         }
233         talloc_set_destructor(kdc, kdc_server_destroy);
234
235         kdc->task = task;
236
237         kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
238         if (kdc->base_ctx == NULL) {
239                 task_server_terminate(task, "KDC: Out of memory", true);
240                 return;
241         }
242
243         kdc->base_ctx->ev_ctx = task->event_ctx;
244         kdc->base_ctx->lp_ctx = task->lp_ctx;
245
246         initialize_krb5_error_table();
247
248         code = smb_krb5_init_context(kdc,
249                                      kdc->task->lp_ctx,
250                                      &kdc->smb_krb5_context);
251         if (code != 0) {
252                 task_server_terminate(task,
253                                       "KDC: Unable to initialized krb5 context",
254                                       true);
255                 return;
256         }
257
258         code = kadm5_init_krb5_context(&kdc->smb_krb5_context->krb5_context);
259         if (code != 0) {
260                 task_server_terminate(task,
261                                       "KDC: Unable to init kadm5 krb5_context",
262                                       true);
263                 return;
264         }
265
266         ZERO_STRUCT(config);
267         config.mask = KADM5_CONFIG_REALM;
268         config.realm = discard_const_p(char, lpcfg_realm(kdc->task->lp_ctx));
269
270         ret = kadm5_init(kdc->smb_krb5_context->krb5_context,
271                          discard_const_p(char, "kpasswd"),
272                          NULL, /* pass */
273                          discard_const_p(char, "kpasswd"),
274                          &config,
275                          KADM5_STRUCT_VERSION,
276                          KADM5_API_VERSION_4,
277                          NULL,
278                          &server_handle);
279         if (ret != 0) {
280                 task_server_terminate(task,
281                                       "KDC: Initialize kadm5",
282                                       true);
283                 return;
284         }
285         kdc->private_data = server_handle;
286
287         code = krb5_db_register_keytab(kdc->smb_krb5_context->krb5_context);
288         if (code != 0) {
289                 task_server_terminate(task,
290                                       "KDC: Unable to KDB",
291                                       true);
292                 return;
293         }
294
295         kdc->keytab_name = talloc_asprintf(kdc, "KDB:");
296         if (kdc->keytab_name == NULL) {
297                 task_server_terminate(task,
298                                       "KDC: Out of memory",
299                                       true);
300                 return;
301         }
302
303         kdc->samdb = samdb_connect(kdc,
304                                    kdc->task->event_ctx,
305                                    kdc->task->lp_ctx,
306                                    system_session(kdc->task->lp_ctx),
307                                    0);
308         if (kdc->samdb == NULL) {
309                 task_server_terminate(task,
310                                       "KDC: Unable to connect to sambdb",
311                                       true);
312                 return;
313         }
314
315         status = startup_kpasswd_server(kdc,
316                                     kdc,
317                                     task->lp_ctx,
318                                     ifaces);
319         if (!NT_STATUS_IS_OK(status)) {
320                 task_server_terminate(task,
321                                       "KDC: Unable to start kpasswd server",
322                                       true);
323         }
324
325         DEBUG(5,("Started kpasswd service for kdc_server\n"));
326 }
327
328 /*
329  * This gets called the kdc exits.
330  */
331 static void mitkdc_server_done(struct tevent_req *subreq)
332 {
333         struct task_server *task =
334                 tevent_req_callback_data(subreq,
335                 struct task_server);
336         int sys_errno;
337         int ret;
338
339         ret = samba_runcmd_recv(subreq, &sys_errno);
340         if (ret != 0) {
341                 DEBUG(0, ("The MIT KDC daemon died with exit status %d\n",
342                           sys_errno));
343         } else {
344                 DEBUG(0,("The MIT KDC daemon exited normally\n"));
345         }
346
347         task_server_terminate(task, "mitkdc child process exited", true);
348 }
349
350 /* Called at MIT KRB5 startup - register ourselves as a server service */
351 NTSTATUS server_service_mitkdc_init(TALLOC_CTX *mem_ctx);
352
353 NTSTATUS server_service_mitkdc_init(TALLOC_CTX *mem_ctx)
354 {
355         return register_server_service("kdc", mitkdc_task_init);
356 }