Print this page
6817447 libgss and various mechs are hiding both the real minor_status and the error token
6405422 Solaris acceptors fail in AD-KDC environments when using non-"host" services (e.g. "cifs")
6824434 Unable to accept context establishment initiated by Windows 2000 clients
6787343 kclient's site lookups fail in certain network environments
6692646 kclient should output errors to stderr
6525327 kinit failed when arcfour-hmac-md5-exp was used for the principal's key
6745582 SUNWkdcu missing package dependencies after kclientv2 integration


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <strings.h>
  32 #include <locale.h>
  33 #include <netdb.h>
  34 #include "k5-int.h"
  35 
  36 #define QUOTE(x)        #x
  37 #define VAL2STR(x)      QUOTE(x)
  38 
  39 static char *whoami = NULL;
  40 
  41 static void kt_add_entry(krb5_context ctx, krb5_keytab kt,
  42         const krb5_principal princ, krb5_enctype enctype, krb5_kvno kvno,
  43         const char *pw);
  44 
  45 static krb5_error_code kt_remove_entries(krb5_context ctx, krb5_keytab kt,
  46         const krb5_principal princ);
  47 
  48 static void usage();
  49 
  50 int
  51 main(int argc, char **argv)
  52 {
  53         krb5_context ctx = NULL;
  54         krb5_error_code code = 0;
  55         krb5_enctype *enctypes;
  56         int enctype_count = 0;
  57         krb5_ccache cc = NULL;
  58         krb5_keytab kt = NULL;
  59         krb5_kvno kvno = 1;
  60         krb5_principal victim;
  61         char c, *vprincstr, *ktname, *token, *lasts, *newpw;
  62         int result_code, i, len, nflag = 0;
  63         krb5_data result_code_string, result_string;
  64 
  65         (void) setlocale(LC_ALL, "");
  66 
  67 #if !defined(TEXT_DOMAIN)
  68 #define TEXT_DOMAIN "SYS_TEST"
  69 #endif /* TEXT_DOMAIN */
  70 
  71         (void) textdomain(TEXT_DOMAIN);
  72 
  73         /* Misc init stuff */
  74         (void) memset(&result_code_string, 0, sizeof (result_code_string));
  75         (void) memset(&result_string, 0, sizeof (result_string));
  76 
  77         whoami = argv[0];
  78 
  79         code = krb5_init_context(&ctx);
  80         if (code != 0) {
  81                 com_err(whoami, code, gettext("krb5_init_context() failed"));
  82                 exit(1);
  83         }
  84 
  85         while ((c = getopt(argc, argv, "v:c:k:e:n")) != -1) {
  86                 switch (c) {
  87                 case 'n':
  88                         nflag++;
  89                         break;
  90                 case 'k':
  91                         if (kt != NULL)
  92                                 usage();
  93                         len = snprintf(NULL, 0, "WRFILE:%s", optarg) + 1;
  94                         if ((ktname = malloc(len)) == NULL) {
  95                                 (void) fprintf(stderr,
  96                                     gettext("Couldn't allocate memory\n"));
  97                                 exit(1);
  98                         }
  99                         (void) snprintf(ktname, len, "WRFILE:%s", optarg);
 100                         if ((code = krb5_kt_resolve(ctx, ktname, &kt)) != 0) {
 101                                 com_err(whoami, code,
 102                                     gettext("Couldn't open/create "
 103                                     "keytab %s"), optarg);
 104                                 exit(1);
 105                         }


 130                                 if (enctypes == NULL) {
 131                                         (void) fprintf(stderr, gettext
 132                                             ("Couldn't allocate memory"));
 133                                         exit(1);
 134                                 }
 135                                 code = krb5_string_to_enctype(token,
 136                                     &enctypes[enctype_count - 1]);
 137 
 138                                 if (code != 0) {
 139                                         com_err(whoami, code, gettext("Unknown "
 140                                             "or unsupported enctype %s"),
 141                                             optarg);
 142                                         exit(1);
 143                                 }
 144                         } while ((token = strtok_r(NULL, ",\t ", &lasts)) !=
 145                             NULL);
 146                         break;
 147                 case 'v':
 148                         kvno = (krb5_kvno) atoi(optarg);
 149                         break;










 150                 default:
 151                         usage();
 152                         break;
 153                 }
 154         }
 155 
 156         if (nflag && enctype_count == 0)
 157                 usage();
 158 
 159         if (nflag == 0 && cc == NULL &&
 160             (code = krb5_cc_default(ctx, &cc)) != 0) {
 161                 com_err(whoami, code, gettext("Could not find a ccache"));
 162                 exit(1);
 163         }
 164 
 165         if (enctype_count > 0 && kt == NULL &&
 166             (code = krb5_kt_default(ctx, &kt)) != 0) {
 167                 com_err(whoami, code, gettext("No keytab specified"));
 168                 exit(1);
 169         }


 220                 }
 221                 krb5_cc_close(ctx, cc);
 222 
 223                 (void) printf("Result: %.*s (%d) %.*s\n",
 224                     result_code == 0 ?
 225                     strlen("success") : result_code_string.length,
 226                     result_code == 0 ? "success" : result_code_string.data,
 227                     result_code,
 228                     result_string.length, result_string.data);
 229 
 230                 if (result_code != 0) {
 231                         (void) fprintf(stderr, gettext("Exiting...\n"));
 232                         exit(result_code);
 233                 }
 234         }
 235 
 236         if (enctype_count && (code = kt_remove_entries(ctx, kt, victim)))
 237                 goto error;
 238 
 239         for (i = 0; i < enctype_count; i++)
 240                 kt_add_entry(ctx, kt, victim, enctypes[i], kvno, newpw);
 241 
 242 error:
 243         if (kt != NULL)
 244                 krb5_kt_close(ctx, kt);
 245 
 246         return (code ? 1 : 0);
 247 }
 248 
 249 static
 250 krb5_error_code
 251 kt_remove_entries(krb5_context ctx, krb5_keytab kt, const krb5_principal princ)
 252 {
 253         krb5_error_code code;
 254         krb5_kt_cursor cursor;
 255         krb5_keytab_entry entry;
 256 
 257         /*
 258          * This is not a fatal error, we expect this to fail in the majority
 259          * of cases (when clients are first initialized).
 260          */


 302 
 303                 krb5_kt_free_entry(ctx, &entry);
 304         }
 305 
 306         if (code && code != KRB5_KT_END) {
 307                 com_err(whoami, code, gettext("While scanning keytab"));
 308                 return (code);
 309         }
 310 
 311         if ((code = krb5_kt_end_seq_get(ctx, kt, &cursor))) {
 312                 com_err(whoami, code, gettext("While ending keytab scan"));
 313                 return (code);
 314         }
 315 
 316         return (0);
 317 }
 318 
 319 static
 320 void
 321 kt_add_entry(krb5_context ctx, krb5_keytab kt, const krb5_principal princ,
 322         krb5_enctype enctype, krb5_kvno kvno, const char *pw)

 323 {
 324         krb5_keytab_entry *entry;
 325         krb5_data password, salt;
 326         krb5_keyblock key;
 327         krb5_error_code code;
 328         char buf[100];
 329 
 330         if ((code = krb5_enctype_to_string(enctype, buf, sizeof (buf)))) {
 331                 com_err(whoami, code, gettext("Enctype %d has no name!"),
 332                     enctype);
 333                 return;
 334         }
 335         if ((entry = (krb5_keytab_entry *) malloc(sizeof (*entry))) == NULL) {
 336                 (void) fprintf(stderr, gettext("Couldn't allocate memory"));
 337                 return;
 338         }
 339 
 340         (void) memset((char *)entry, 0, sizeof (*entry));
 341 
 342         password.length = strlen(pw);
 343         password.data = (char *)pw;
 344 
 345         if ((code = krb5_principal2salt(ctx, princ, &salt)) != 0) {
 346                 com_err(whoami, code,
 347                     gettext("Could not compute salt for %s"), enctype);
 348                 return;
 349         }
 350 
 351         code = krb5_c_string_to_key(ctx, enctype, &password, &salt, &key);
 352 
 353         if (code != 0) {
 354                 com_err(whoami, code, gettext("Could not compute salt for %s"),
 355                     enctype);
 356                 krb5_xfree(salt.data);
 357                 return;
 358         }
 359 
 360         (void) memcpy(&entry->key, &key, sizeof (krb5_keyblock));
 361         entry->vno = kvno;
 362         entry->principal = princ;
 363 
 364         if ((code = krb5_kt_add_entry(ctx, kt, entry)) != 0) {
 365                 com_err(whoami, code,


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 


  27 #include <stdio.h>
  28 #include <stdlib.h>
  29 #include <strings.h>
  30 #include <locale.h>
  31 #include <netdb.h>
  32 #include "k5-int.h"
  33 
  34 #define QUOTE(x)        #x
  35 #define VAL2STR(x)      QUOTE(x)
  36 
  37 static char *whoami = NULL;
  38 
  39 static void kt_add_entry(krb5_context ctx, krb5_keytab kt,
  40         const krb5_principal princ, const krb5_principal sprinc,
  41         krb5_enctype enctype, krb5_kvno kvno, const char *pw);
  42 
  43 static krb5_error_code kt_remove_entries(krb5_context ctx, krb5_keytab kt,
  44         const krb5_principal princ);
  45 
  46 static void usage();
  47 
  48 int
  49 main(int argc, char **argv)
  50 {
  51         krb5_context ctx = NULL;
  52         krb5_error_code code = 0;
  53         krb5_enctype *enctypes;
  54         int enctype_count = 0;
  55         krb5_ccache cc = NULL;
  56         krb5_keytab kt = NULL;
  57         krb5_kvno kvno = 1;
  58         krb5_principal victim, salt;
  59         char c, *vprincstr, *ktname, *token, *lasts, *newpw;
  60         int result_code, i, len, nflag = 0;
  61         krb5_data result_code_string, result_string;
  62 
  63         (void) setlocale(LC_ALL, "");
  64 
  65 #if !defined(TEXT_DOMAIN)
  66 #define TEXT_DOMAIN "SYS_TEST"
  67 #endif /* TEXT_DOMAIN */
  68 
  69         (void) textdomain(TEXT_DOMAIN);
  70 
  71         /* Misc init stuff */
  72         (void) memset(&result_code_string, 0, sizeof (result_code_string));
  73         (void) memset(&result_string, 0, sizeof (result_string));
  74 
  75         whoami = argv[0];
  76 
  77         code = krb5_init_context(&ctx);
  78         if (code != 0) {
  79                 com_err(whoami, code, gettext("krb5_init_context() failed"));
  80                 exit(1);
  81         }
  82 
  83         while ((c = getopt(argc, argv, "v:c:k:e:ns:")) != -1) {
  84                 switch (c) {
  85                 case 'n':
  86                         nflag++;
  87                         break;
  88                 case 'k':
  89                         if (kt != NULL)
  90                                 usage();
  91                         len = snprintf(NULL, 0, "WRFILE:%s", optarg) + 1;
  92                         if ((ktname = malloc(len)) == NULL) {
  93                                 (void) fprintf(stderr,
  94                                     gettext("Couldn't allocate memory\n"));
  95                                 exit(1);
  96                         }
  97                         (void) snprintf(ktname, len, "WRFILE:%s", optarg);
  98                         if ((code = krb5_kt_resolve(ctx, ktname, &kt)) != 0) {
  99                                 com_err(whoami, code,
 100                                     gettext("Couldn't open/create "
 101                                     "keytab %s"), optarg);
 102                                 exit(1);
 103                         }


 128                                 if (enctypes == NULL) {
 129                                         (void) fprintf(stderr, gettext
 130                                             ("Couldn't allocate memory"));
 131                                         exit(1);
 132                                 }
 133                                 code = krb5_string_to_enctype(token,
 134                                     &enctypes[enctype_count - 1]);
 135 
 136                                 if (code != 0) {
 137                                         com_err(whoami, code, gettext("Unknown "
 138                                             "or unsupported enctype %s"),
 139                                             optarg);
 140                                         exit(1);
 141                                 }
 142                         } while ((token = strtok_r(NULL, ",\t ", &lasts)) !=
 143                             NULL);
 144                         break;
 145                 case 'v':
 146                         kvno = (krb5_kvno) atoi(optarg);
 147                         break;
 148                 case 's':
 149                         vprincstr = optarg;
 150                         code = krb5_parse_name(ctx, vprincstr, &salt);
 151                         if (code != 0) {
 152                                 com_err(whoami, code,
 153                                     gettext("krb5_parse_name(%s) failed"),
 154                                     vprincstr);
 155                                 exit(1);
 156                         }
 157                         break;
 158                 default:
 159                         usage();
 160                         break;
 161                 }
 162         }
 163 
 164         if (nflag && enctype_count == 0)
 165                 usage();
 166 
 167         if (nflag == 0 && cc == NULL &&
 168             (code = krb5_cc_default(ctx, &cc)) != 0) {
 169                 com_err(whoami, code, gettext("Could not find a ccache"));
 170                 exit(1);
 171         }
 172 
 173         if (enctype_count > 0 && kt == NULL &&
 174             (code = krb5_kt_default(ctx, &kt)) != 0) {
 175                 com_err(whoami, code, gettext("No keytab specified"));
 176                 exit(1);
 177         }


 228                 }
 229                 krb5_cc_close(ctx, cc);
 230 
 231                 (void) printf("Result: %.*s (%d) %.*s\n",
 232                     result_code == 0 ?
 233                     strlen("success") : result_code_string.length,
 234                     result_code == 0 ? "success" : result_code_string.data,
 235                     result_code,
 236                     result_string.length, result_string.data);
 237 
 238                 if (result_code != 0) {
 239                         (void) fprintf(stderr, gettext("Exiting...\n"));
 240                         exit(result_code);
 241                 }
 242         }
 243 
 244         if (enctype_count && (code = kt_remove_entries(ctx, kt, victim)))
 245                 goto error;
 246 
 247         for (i = 0; i < enctype_count; i++)
 248                 kt_add_entry(ctx, kt, victim, salt, enctypes[i], kvno, newpw);
 249 
 250 error:
 251         if (kt != NULL)
 252                 krb5_kt_close(ctx, kt);
 253 
 254         return (code ? 1 : 0);
 255 }
 256 
 257 static
 258 krb5_error_code
 259 kt_remove_entries(krb5_context ctx, krb5_keytab kt, const krb5_principal princ)
 260 {
 261         krb5_error_code code;
 262         krb5_kt_cursor cursor;
 263         krb5_keytab_entry entry;
 264 
 265         /*
 266          * This is not a fatal error, we expect this to fail in the majority
 267          * of cases (when clients are first initialized).
 268          */


 310 
 311                 krb5_kt_free_entry(ctx, &entry);
 312         }
 313 
 314         if (code && code != KRB5_KT_END) {
 315                 com_err(whoami, code, gettext("While scanning keytab"));
 316                 return (code);
 317         }
 318 
 319         if ((code = krb5_kt_end_seq_get(ctx, kt, &cursor))) {
 320                 com_err(whoami, code, gettext("While ending keytab scan"));
 321                 return (code);
 322         }
 323 
 324         return (0);
 325 }
 326 
 327 static
 328 void
 329 kt_add_entry(krb5_context ctx, krb5_keytab kt, const krb5_principal princ,
 330         const krb5_principal sprinc, krb5_enctype enctype, krb5_kvno kvno,
 331         const char *pw)
 332 {
 333         krb5_keytab_entry *entry;
 334         krb5_data password, salt;
 335         krb5_keyblock key;
 336         krb5_error_code code;
 337         char buf[100];
 338 
 339         if ((code = krb5_enctype_to_string(enctype, buf, sizeof (buf)))) {
 340                 com_err(whoami, code, gettext("Enctype %d has no name!"),
 341                     enctype);
 342                 return;
 343         }
 344         if ((entry = (krb5_keytab_entry *) malloc(sizeof (*entry))) == NULL) {
 345                 (void) fprintf(stderr, gettext("Couldn't allocate memory"));
 346                 return;
 347         }
 348 
 349         (void) memset((char *)entry, 0, sizeof (*entry));
 350 
 351         password.length = strlen(pw);
 352         password.data = (char *)pw;
 353 
 354         if ((code = krb5_principal2salt(ctx, sprinc, &salt)) != 0) {
 355                 com_err(whoami, code,
 356                     gettext("Could not compute salt for %s"), enctype);
 357                 return;
 358         }
 359 
 360         code = krb5_c_string_to_key(ctx, enctype, &password, &salt, &key);
 361 
 362         if (code != 0) {
 363                 com_err(whoami, code, gettext("Could not compute salt for %s"),
 364                     enctype);
 365                 krb5_xfree(salt.data);
 366                 return;
 367         }
 368 
 369         (void) memcpy(&entry->key, &key, sizeof (krb5_keyblock));
 370         entry->vno = kvno;
 371         entry->principal = princ;
 372 
 373         if ((code = krb5_kt_add_entry(ctx, kt, entry)) != 0) {
 374                 com_err(whoami, code,