ba97137cd74d4d0762bb468e94ff4c441e2fe312
[samba.git] / source4 / torture / krb5 / kdc-mit.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Validate the krb5 pac generation routines
5
6    Copyright (c) 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 "system/kerberos.h"
24 #include "system/time.h"
25 #include "torture/smbtorture.h"
26 #include "torture/winbind/proto.h"
27 #include "torture/krb5/proto.h"
28 #include "auth/credentials/credentials.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "source4/auth/kerberos/kerberos.h"
31 #include "source4/auth/kerberos/kerberos_util.h"
32 #include "lib/util/util_net.h"
33
34 #define krb5_is_app_tag(dat,tag)                          \
35         ((dat != NULL) && (dat)->length &&                \
36          ((((dat)->data[0] & ~0x20) == ((tag) | 0x40))))
37
38 #define krb5_is_as_req(dat)                   krb5_is_app_tag(dat, 10)
39 #define krb5_is_as_rep(dat)                   krb5_is_app_tag(dat, 11)
40 #define krb5_is_krb_error(dat)                krb5_is_app_tag(dat, 30)
41
42 enum torture_krb5_test {
43         TORTURE_KRB5_TEST_PLAIN,
44         TORTURE_KRB5_TEST_PAC_REQUEST,
45         TORTURE_KRB5_TEST_BREAK_PW,
46         TORTURE_KRB5_TEST_CLOCK_SKEW,
47         TORTURE_KRB5_TEST_AES,
48         TORTURE_KRB5_TEST_RC4,
49         TORTURE_KRB5_TEST_AES_RC4,
50 };
51
52 struct torture_krb5_context {
53         struct torture_context *tctx;
54         krb5_context krb5_context;
55         enum torture_krb5_test test;
56         int recv_packet_count;
57         krb5_kdc_req *as_req;
58         krb5_kdc_rep *as_rep;
59 };
60
61 krb5_error_code decode_krb5_error(const krb5_data *output, krb5_error **rep);
62
63 krb5_error_code decode_krb5_as_req(const krb5_data *output, krb5_kdc_req **req);
64 krb5_error_code decode_krb5_as_rep(const krb5_data *output, krb5_kdc_rep **rep);
65
66 krb5_error_code decode_krb5_padata_sequence(const krb5_data *output, krb5_pa_data ***rep);
67
68 void krb5_free_kdc_req(krb5_context ctx, krb5_kdc_req *req);
69 void krb5_free_kdc_rep(krb5_context ctx, krb5_kdc_rep *rep);
70 void krb5_free_pa_data(krb5_context ctx, krb5_pa_data **data);
71
72 static bool torture_check_krb5_as_req(struct torture_krb5_context *test_context,
73                                       krb5_context context,
74                                       const krb5_data *message)
75 {
76         krb5_error_code code;
77         int nktypes;
78
79         code = decode_krb5_as_req(message, &test_context->as_req);
80         torture_assert_int_equal(test_context->tctx,
81                                  code, 0,
82                                  "decode_as_req failed");
83         torture_assert_int_equal(test_context->tctx,
84                                  test_context->as_req->msg_type,
85                                  KRB5_AS_REQ,
86                                  "Not a AS REQ");
87
88         nktypes = test_context->as_req->nktypes;
89         torture_assert_int_not_equal(test_context->tctx,
90                                      nktypes, 0,
91                                      "No keytypes");
92
93         return true;
94 }
95
96 static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
97                                                   void *data,
98                                                   const krb5_data *realm,
99                                                   const krb5_data *message,
100                                                   krb5_data **new_message_out,
101                                                   krb5_data **new_reply_out)
102 {
103         bool ok;
104         struct torture_krb5_context *test_context =
105                 (struct torture_krb5_context *)data;
106
107         switch (test_context->test)
108         {
109         case TORTURE_KRB5_TEST_PLAIN:
110         case TORTURE_KRB5_TEST_PAC_REQUEST:
111         case TORTURE_KRB5_TEST_BREAK_PW:
112         case TORTURE_KRB5_TEST_CLOCK_SKEW:
113         case TORTURE_KRB5_TEST_AES:
114         case TORTURE_KRB5_TEST_RC4:
115         case TORTURE_KRB5_TEST_AES_RC4:
116                 ok = torture_check_krb5_as_req(test_context,
117                                                context,
118                                                message);
119                 if (!ok) {
120                         return KRB5KDC_ERR_BADOPTION;
121                 }
122                 break;
123         }
124
125         return 0;
126 }
127
128 /*
129  * We need these function to validate packets because our torture macros
130  * do a 'return false' on error.
131  */
132 static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
133                                      krb5_context context,
134                                      const krb5_data *reply,
135                                      krb5_error_code error_code,
136                                      bool check_pa_data)
137
138 {
139         krb5_error *krb_error;
140         krb5_error_code code;
141
142         code = decode_krb5_error(reply, &krb_error);
143         torture_assert_int_equal(test_context->tctx,
144                                  code,
145                                  0,
146                                  "decode_krb5_error failed");
147
148         torture_assert_int_equal(test_context->tctx,
149                                  krb_error->error,
150                                  error_code - KRB5KDC_ERR_NONE,
151                                  "Got wrong error code");
152
153         if (check_pa_data) {
154                 krb5_pa_data **d, **pa_data = NULL;
155                 bool timestamp_found = false;
156
157                 torture_assert_int_not_equal(test_context->tctx,
158                                              krb_error->e_data.length, 0,
159                                              "No e-data returned");
160
161                 code = decode_krb5_padata_sequence(&krb_error->e_data,
162                                                    &pa_data);
163                 torture_assert_int_equal(test_context->tctx,
164                                          code,
165                                          0,
166                                          "decode_krb5_padata_sequence failed");
167
168                 for (d = pa_data; d != NULL; d++) {
169                         if ((*d)->pa_type == KRB5_PADATA_ENC_TIMESTAMP) {
170                                 timestamp_found = true;
171                                 break;
172                         }
173                 }
174                 torture_assert(test_context->tctx,
175                                timestamp_found,
176                                "Encrypted timestamp not found");
177
178                 krb5_free_pa_data(context, pa_data);
179         }
180
181         krb5_free_error(context, krb_error);
182
183         return true;
184 }
185
186 static bool torture_check_krb5_as_rep(struct torture_krb5_context *test_context,
187                                       krb5_context context,
188                                       const krb5_data *reply)
189 {
190         krb5_error_code code;
191         bool ok;
192
193         code = decode_krb5_as_rep(reply, &test_context->as_rep);
194         torture_assert_int_equal(test_context->tctx,
195                                  code,
196                                  0,
197                                  "decode_krb5_as_rep failed");
198
199         torture_assert(test_context->tctx,
200                        test_context->as_rep->ticket->enc_part.kvno,
201                        "No KVNO set");
202
203         ok = torture_setting_bool(test_context->tctx,
204                                   "expect_cached_at_rodc",
205                                   false);
206         if (ok) {
207                 torture_assert_int_not_equal(test_context->tctx,
208                                              test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
209                                              0,
210                                              "Did not get a RODC number in the KVNO");
211         } else {
212                 torture_assert_int_equal(test_context->tctx,
213                                          test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
214                                          0,
215                                          "Unexpecedly got a RODC number in the KVNO");
216         }
217
218         return true;
219 }
220
221 static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context,
222                                               krb5_context context,
223                                               const krb5_data *reply,
224                                               krb5_enctype expected_enctype)
225 {
226         krb5_enctype reply_enctype;
227         bool ok;
228
229         ok = torture_check_krb5_as_rep(test_context,
230                                        context,
231                                        reply);
232         if (!ok) {
233                 return false;
234         }
235
236         reply_enctype = test_context->as_rep->enc_part.enctype;
237
238         torture_assert_int_equal(test_context->tctx,
239                                  reply_enctype, expected_enctype,
240                                  "Ticket encrypted with invalid algorithm");
241
242         return true;
243 }
244
245 static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
246                                                    void *data,
247                                                    krb5_error_code kdc_code,
248                                                    const krb5_data *realm,
249                                                    const krb5_data *message,
250                                                    const krb5_data *reply,
251                                                    krb5_data **new_reply_out)
252 {
253         struct torture_krb5_context *test_context =
254                 (struct torture_krb5_context *)data;
255         krb5_error_code code;
256         bool ok = true;
257
258         torture_comment(test_context->tctx,
259                         "PACKET COUNT = %d\n",
260                         test_context->recv_packet_count);
261
262         torture_comment(test_context->tctx,
263                         "KRB5_AS_REP = %d\n",
264                         krb5_is_as_req(reply));
265
266         torture_comment(test_context->tctx,
267                         "KRB5_ERROR = %d\n",
268                         krb5_is_krb_error(reply));
269
270         torture_comment(test_context->tctx,
271                         "KDC ERROR CODE = %d\n",
272                         kdc_code);
273
274         switch (test_context->test)
275         {
276         case TORTURE_KRB5_TEST_PLAIN:
277                 if (test_context->recv_packet_count == 0) {
278                         ok = torture_check_krb5_error(test_context,
279                                                       context,
280                                                       reply,
281                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
282                                                       false);
283                         torture_assert_goto(test_context->tctx,
284                                             ok,
285                                             ok,
286                                             out,
287                                             "torture_check_krb5_error failed");
288                 } else {
289                         ok = torture_check_krb5_as_rep(test_context,
290                                                        context,
291                                                        reply);
292                         torture_assert_goto(test_context->tctx,
293                                             ok,
294                                             ok,
295                                             out,
296                                             "torture_check_krb5_as_rep failed");
297                 }
298
299                 torture_assert_goto(test_context->tctx,
300                                     test_context->recv_packet_count < 2,
301                                     ok,
302                                     out,
303                                     "Too many packets");
304
305                 break;
306         case TORTURE_KRB5_TEST_PAC_REQUEST:
307                 if (test_context->recv_packet_count == 0) {
308                         ok = torture_check_krb5_error(test_context,
309                                                       context,
310                                                       reply,
311                                                       KRB5KRB_ERR_RESPONSE_TOO_BIG,
312                                                       false);
313                         torture_assert_goto(test_context->tctx,
314                                             ok,
315                                             ok,
316                                             out,
317                                             "torture_check_krb5_error failed");
318                 } else if (test_context->recv_packet_count == 1) {
319                         ok = torture_check_krb5_error(test_context,
320                                                       context,
321                                                       reply,
322                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
323                                                       false);
324                         torture_assert_goto(test_context->tctx,
325                                             ok,
326                                             ok,
327                                             out,
328                                             "torture_check_krb5_error failed");
329                 } else if (krb5_is_krb_error(reply)) {
330                         ok = torture_check_krb5_error(test_context,
331                                                       context,
332                                                       reply,
333                                                       KRB5KRB_ERR_RESPONSE_TOO_BIG,
334                                                       false);
335                         torture_assert_goto(test_context->tctx,
336                                             ok,
337                                             ok,
338                                             out,
339                                             "torture_check_krb5_error failed");
340                 } else {
341                         ok = torture_check_krb5_as_rep(test_context,
342                                                        context,
343                                                        reply);
344                         torture_assert_goto(test_context->tctx,
345                                             ok,
346                                             ok,
347                                             out,
348                                             "torture_check_krb5_as_rep failed");
349                 }
350
351                 torture_assert_goto(test_context->tctx,
352                                     test_context->recv_packet_count < 3,
353                                     ok,
354                                     out,
355                                     "Too many packets");
356                 break;
357         case TORTURE_KRB5_TEST_BREAK_PW:
358                 if (test_context->recv_packet_count == 0) {
359                         ok = torture_check_krb5_error(test_context,
360                                                       context,
361                                                       reply,
362                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
363                                                       false);
364                         torture_assert_goto(test_context->tctx,
365                                             ok,
366                                             ok,
367                                             out,
368                                             "torture_check_krb5_error failed");
369                         if (!ok) {
370                                 goto out;
371                         }
372                 } else if (test_context->recv_packet_count == 1) {
373                         ok = torture_check_krb5_error(test_context,
374                                                       context,
375                                                       reply,
376                                                       KRB5KDC_ERR_PREAUTH_FAILED,
377                                                       true);
378                         torture_assert_goto(test_context->tctx,
379                                             ok,
380                                             ok,
381                                             out,
382                                             "torture_check_krb5_error failed");
383                 }
384
385                 torture_assert_goto(test_context->tctx,
386                                     test_context->recv_packet_count < 2,
387                                     ok,
388                                     out,
389                                     "Too many packets");
390                 break;
391         case TORTURE_KRB5_TEST_CLOCK_SKEW:
392                 if (test_context->recv_packet_count == 0) {
393                         ok = torture_check_krb5_error(test_context,
394                                                       context,
395                                                       reply,
396                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
397                                                       false);
398                         torture_assert_goto(test_context->tctx,
399                                             ok,
400                                             ok,
401                                             out,
402                                             "torture_check_krb5_error failed");
403                         if (!ok) {
404                                 goto out;
405                         }
406                 } else if (test_context->recv_packet_count == 1) {
407                         /*
408                          * This only works if kdc_timesync 0 is set in krb5.conf
409                          *
410                          * See commit 5f39a4438eafd693a3eb8366bbc3901efe62e538
411                          * in the MIT Kerberos source tree.
412                          */
413                         ok = torture_check_krb5_error(test_context,
414                                                       context,
415                                                       reply,
416                                                       KRB5KRB_AP_ERR_SKEW,
417                                                       false);
418                         torture_assert_goto(test_context->tctx,
419                                             ok,
420                                             ok,
421                                             out,
422                                             "torture_check_krb5_error failed");
423                 }
424
425                 torture_assert_goto(test_context->tctx,
426                                     test_context->recv_packet_count < 2,
427                                     ok,
428                                     out,
429                                     "Too many packets");
430                 break;
431         case TORTURE_KRB5_TEST_AES:
432                 torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES\n");
433
434                 if (test_context->recv_packet_count == 0) {
435                         ok = torture_check_krb5_error(test_context,
436                                                       context,
437                                                       reply,
438                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
439                                                       false);
440                         if (!ok) {
441                                 goto out;
442                         }
443                 } else {
444                         ok = torture_check_krb5_as_rep_enctype(test_context,
445                                                                context,
446                                                                reply,
447                                                                ENCTYPE_AES256_CTS_HMAC_SHA1_96);
448                         if (!ok) {
449                                 goto out;
450                         }
451                 }
452                 break;
453         case TORTURE_KRB5_TEST_RC4:
454                 torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_RC4\n");
455
456                 if (test_context->recv_packet_count == 0) {
457                         ok = torture_check_krb5_error(test_context,
458                                                       context,
459                                                       reply,
460                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
461                                                       false);
462                         if (!ok) {
463                                 goto out;
464                         }
465                 } else {
466                         ok = torture_check_krb5_as_rep_enctype(test_context,
467                                                                context,
468                                                                reply,
469                                                                ENCTYPE_ARCFOUR_HMAC);
470                         if (!ok) {
471                                 goto out;
472                         }
473                 }
474                 break;
475         case TORTURE_KRB5_TEST_AES_RC4:
476                 torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES_RC4\n");
477
478                 if (test_context->recv_packet_count == 0) {
479                         ok = torture_check_krb5_error(test_context,
480                                                       context,
481                                                       reply,
482                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
483                                                       false);
484                         if (!ok) {
485                                 goto out;
486                         }
487                 } else {
488                         ok = torture_check_krb5_as_rep_enctype(test_context,
489                                                                context,
490                                                                reply,
491                                                                ENCTYPE_AES256_CTS_HMAC_SHA1_96);
492                         if (!ok) {
493                                 goto out;
494                         }
495                 }
496                 break;
497         }
498
499         code = kdc_code;
500 out:
501         if (!ok) {
502                 code = EINVAL;
503         }
504
505         /* Cleanup */
506         krb5_free_kdc_req(test_context->krb5_context, test_context->as_req);
507         krb5_free_kdc_rep(test_context->krb5_context, test_context->as_rep);
508
509         test_context->recv_packet_count++;
510
511         return code;
512 }
513
514 static bool torture_krb5_init_context(struct torture_context *tctx,
515                                       enum torture_krb5_test test,
516                                       struct smb_krb5_context **smb_krb5_context)
517 {
518         krb5_error_code code;
519
520         struct torture_krb5_context *test_context = talloc_zero(tctx,
521                                                                 struct torture_krb5_context);
522         torture_assert(tctx, test_context != NULL, "Failed to allocate");
523
524         test_context->test = test;
525         test_context->tctx = tctx;
526
527         code = smb_krb5_init_context(tctx, tctx->lp_ctx, smb_krb5_context);
528         torture_assert_int_equal(tctx, code, 0, "smb_krb5_init_context failed");
529
530         test_context->krb5_context = (*smb_krb5_context)->krb5_context;
531
532         krb5_set_kdc_send_hook((*smb_krb5_context)->krb5_context,
533                                torture_krb5_pre_send_test,
534                                test_context);
535
536         krb5_set_kdc_recv_hook((*smb_krb5_context)->krb5_context,
537                                torture_krb5_post_recv_test,
538                                test_context);
539
540         return true;
541 }
542 static bool torture_krb5_as_req_creds(struct torture_context *tctx,
543                                       struct cli_credentials *credentials,
544                                       enum torture_krb5_test test)
545 {
546         krb5_get_init_creds_opt *krb_options = NULL;
547         struct smb_krb5_context *smb_krb5_context;
548         enum credentials_obtained obtained;
549         const char *error_string;
550         const char *password;
551         krb5_principal principal;
552         krb5_error_code code;
553         krb5_creds my_creds;
554         bool ok;
555
556         ok = torture_krb5_init_context(tctx, test, &smb_krb5_context);
557         torture_assert(tctx, ok, "torture_krb5_init_context failed");
558
559         code = principal_from_credentials(tctx,
560                                           credentials,
561                                           smb_krb5_context,
562                                           &principal,
563                                           &obtained,
564                                           &error_string);
565         torture_assert_int_equal(tctx, code, 0, error_string);
566
567         password = cli_credentials_get_password(credentials);
568
569         switch (test)
570         {
571         case TORTURE_KRB5_TEST_PLAIN:
572                 break;
573         case TORTURE_KRB5_TEST_PAC_REQUEST:
574 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
575                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
576                                                      &krb_options);
577                 torture_assert_int_equal(tctx,
578                                          code, 0,
579                                          "krb5_get_init_creds_opt_alloc failed");
580
581                 code = krb5_get_init_creds_opt_set_pac_request(smb_krb5_context->krb5_context,
582                                                                krb_options,
583                                                                1);
584                 torture_assert_int_equal(tctx,
585                                          code, 0,
586                                          "krb5_get_init_creds_opt_set_pac_request failed");
587 #endif
588                 break;
589         case TORTURE_KRB5_TEST_BREAK_PW:
590                 password = "NOT the password";
591                 break;
592         case TORTURE_KRB5_TEST_CLOCK_SKEW:
593                 code = krb5_set_real_time(smb_krb5_context->krb5_context,
594                                           time(NULL) + 3600,
595                                           0);
596                 torture_assert_int_equal(tctx,
597                                          code, 0,
598                                          "krb5_set_real_time failed");
599                 break;
600         case TORTURE_KRB5_TEST_AES: {
601                 krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96 };
602
603                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
604                                                      &krb_options);
605                 torture_assert_int_equal(tctx,
606                                          code, 0,
607                                          "krb5_get_init_creds_opt_alloc failed");
608
609                 krb5_get_init_creds_opt_set_etype_list(krb_options,
610                                                        etype,
611                                                        1);
612                 break;
613         }
614         case TORTURE_KRB5_TEST_RC4: {
615                 krb5_enctype etype[] = { ENCTYPE_ARCFOUR_HMAC };
616
617                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
618                                                      &krb_options);
619                 torture_assert_int_equal(tctx,
620                                          code, 0,
621                                          "krb5_get_init_creds_opt_alloc failed");
622
623                 krb5_get_init_creds_opt_set_etype_list(krb_options,
624                                                        etype,
625                                                        1);
626                 break;
627         }
628         case TORTURE_KRB5_TEST_AES_RC4: {
629                 krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_ARCFOUR_HMAC };
630
631                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
632                                                      &krb_options);
633                 torture_assert_int_equal(tctx,
634                                          code, 0,
635                                          "krb5_get_init_creds_opt_alloc failed");
636
637
638                 krb5_get_init_creds_opt_set_etype_list(krb_options,
639                                                        etype,
640                                                        2);
641                 break;
642         }
643         }
644
645         code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
646                                             &my_creds,
647                                             principal,
648                                             password,
649                                             NULL,
650                                             NULL,
651                                             0,
652                                             NULL,
653                                             krb_options);
654         krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context,
655                                      krb_options);
656
657         switch (test)
658         {
659         case TORTURE_KRB5_TEST_PLAIN:
660         case TORTURE_KRB5_TEST_PAC_REQUEST:
661         case TORTURE_KRB5_TEST_AES:
662         case TORTURE_KRB5_TEST_RC4:
663         case TORTURE_KRB5_TEST_AES_RC4:
664                 torture_assert_int_equal(tctx,
665                                          code,
666                                          0,
667                                          "krb5_get_init_creds_password failed");
668                 break;
669         case TORTURE_KRB5_TEST_BREAK_PW:
670                 torture_assert_int_equal(tctx,
671                                          code,
672                                          KRB5KDC_ERR_PREAUTH_FAILED,
673                                          "krb5_get_init_creds_password should "
674                                          "have failed");
675                 return true;
676         case TORTURE_KRB5_TEST_CLOCK_SKEW:
677                 torture_assert_int_equal(tctx,
678                                          code,
679                                          KRB5KRB_AP_ERR_SKEW,
680                                          "krb5_get_init_creds_password should "
681                                          "have failed");
682                 return true;
683         }
684
685         krb5_free_cred_contents(smb_krb5_context->krb5_context,
686                                 &my_creds);
687
688         return true;
689 }
690
691 static bool torture_krb5_as_req_cmdline(struct torture_context *tctx)
692 {
693         return torture_krb5_as_req_creds(tctx,
694                                          popt_get_cmdline_credentials(),
695                                          TORTURE_KRB5_TEST_PLAIN);
696 }
697
698 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
699 static bool torture_krb5_as_req_pac_request(struct torture_context *tctx)
700 {
701         bool ok;
702
703         ok = torture_setting_bool(tctx, "expect_rodc", false);
704         if (ok) {
705                 torture_skip(tctx,
706                              "This test needs further investigation in the "
707                              "RODC case against a Windows DC, in particular "
708                              "with non-cached users");
709         }
710         return torture_krb5_as_req_creds(tctx, popt_get_cmdline_credentials(),
711                         TORTURE_KRB5_TEST_PAC_REQUEST);
712 }
713 #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST */
714
715 static bool torture_krb5_as_req_break_pw(struct torture_context *tctx)
716 {
717         return torture_krb5_as_req_creds(tctx,
718                                          popt_get_cmdline_credentials(),
719                                          TORTURE_KRB5_TEST_BREAK_PW);
720 }
721
722 static bool torture_krb5_as_req_clock_skew(struct torture_context *tctx)
723 {
724         return torture_krb5_as_req_creds(tctx,
725                                          popt_get_cmdline_credentials(),
726                                          TORTURE_KRB5_TEST_CLOCK_SKEW);
727 }
728
729 static bool torture_krb5_as_req_aes(struct torture_context *tctx)
730 {
731         return torture_krb5_as_req_creds(tctx,
732                                          popt_get_cmdline_credentials(),
733                                          TORTURE_KRB5_TEST_AES);
734 }
735
736 static bool torture_krb5_as_req_rc4(struct torture_context *tctx)
737 {
738         return torture_krb5_as_req_creds(tctx,
739                                          popt_get_cmdline_credentials(),
740                                          TORTURE_KRB5_TEST_RC4);
741 }
742
743 static bool torture_krb5_as_req_aes_rc4(struct torture_context *tctx)
744 {
745         return torture_krb5_as_req_creds(tctx,
746                                          popt_get_cmdline_credentials(),
747                                          TORTURE_KRB5_TEST_AES_RC4);
748 }
749
750 NTSTATUS torture_krb5_init(TALLOC_CTX *ctx)
751 {
752         struct torture_suite *suite =
753                 torture_suite_create(ctx, "krb5");
754         struct torture_suite *kdc_suite = torture_suite_create(suite, "kdc");
755         suite->description = talloc_strdup(suite, "Kerberos tests");
756         kdc_suite->description = talloc_strdup(kdc_suite, "Kerberos KDC tests");
757
758         torture_suite_add_simple_test(kdc_suite,
759                                       "as-req-cmdline",
760                                       torture_krb5_as_req_cmdline);
761
762 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
763         /* Only available with MIT Kerveros 1.15 and newer */
764         torture_suite_add_simple_test(kdc_suite, "as-req-pac-request",
765                                       torture_krb5_as_req_pac_request);
766 #endif
767
768         torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
769                                       torture_krb5_as_req_break_pw);
770
771         /* This only works if kdc_timesync 0 is set in krb5.conf */
772         torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
773                                       torture_krb5_as_req_clock_skew);
774
775 #if 0
776         torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
777 #endif
778         torture_suite_add_simple_test(kdc_suite,
779                                       "as-req-aes",
780                                       torture_krb5_as_req_aes);
781
782         torture_suite_add_simple_test(kdc_suite,
783                                       "as-req-rc4",
784                                       torture_krb5_as_req_rc4);
785
786         torture_suite_add_simple_test(kdc_suite,
787                                       "as-req-aes-rc4",
788                                       torture_krb5_as_req_aes_rc4);
789
790         torture_suite_add_suite(suite, kdc_suite);
791
792         torture_register_suite(ctx, suite);
793
794         return NT_STATUS_OK;
795 }