17c478bd9Sstevel@tonic-gate /* 2*08e8465eSPeter Shoults * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 37c478bd9Sstevel@tonic-gate */ 47c478bd9Sstevel@tonic-gate 57c478bd9Sstevel@tonic-gate /* 67c478bd9Sstevel@tonic-gate * Copyright 1994 by the Massachusetts Institute of Technology. 77c478bd9Sstevel@tonic-gate * All Rights Reserved. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 107c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 117c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 127c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 157c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 167c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 177c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 187c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 197c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 207c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 217c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 227c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 237c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 247c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 257c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 267c478bd9Sstevel@tonic-gate * or implied warranty. 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * kadmin.c: base functions for a kadmin command line interface using 297c478bd9Sstevel@tonic-gate * the OVSecure library 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <kadm5/admin.h> 3356a424ccSmp153739 #include <krb5/adm_proto.h> 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate #include <string.h> 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <math.h> 387c478bd9Sstevel@tonic-gate #include <unistd.h> 397c478bd9Sstevel@tonic-gate #include <pwd.h> 407c478bd9Sstevel@tonic-gate /* #include <sys/timeb.h> */ 417c478bd9Sstevel@tonic-gate #include <time.h> 4254925bf6Swillf #include "kadmin.h" 437c478bd9Sstevel@tonic-gate #include <libintl.h> 44159d09a2SMark Phalan #include <krb5.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * Solaris: the following are needed for paging 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate #include <signal.h> 507c478bd9Sstevel@tonic-gate #include <sys/wait.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* command name when called "locally" (i.e. non-networked client ) */ 537c478bd9Sstevel@tonic-gate #define KADMIN_LOCAL_NAME "kadmin.local" 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* functions defined in remote/local specific files */ 567c478bd9Sstevel@tonic-gate extern void usage(const char *); 577c478bd9Sstevel@tonic-gate 5856a424ccSmp153739 /* special struct to convert flag names for principals 5956a424ccSmp153739 to actual krb5_flags for a principal */ 607c478bd9Sstevel@tonic-gate struct pflag { 617c478bd9Sstevel@tonic-gate char *flagname; /* name of flag as typed to CLI */ 627c478bd9Sstevel@tonic-gate int flaglen; /* length of string (not counting -,+) */ 637c478bd9Sstevel@tonic-gate krb5_flags theflag; /* actual principal flag to set/clear */ 647c478bd9Sstevel@tonic-gate int set; /* 0 means clear, 1 means set (on '-') */ 657c478bd9Sstevel@tonic-gate }; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate static struct pflag flags[] = { 687c478bd9Sstevel@tonic-gate {"allow_postdated", 15, KRB5_KDB_DISALLOW_POSTDATED, 1}, 697c478bd9Sstevel@tonic-gate {"allow_forwardable", 17, KRB5_KDB_DISALLOW_FORWARDABLE, 1}, 707c478bd9Sstevel@tonic-gate {"allow_tgs_req", 13, KRB5_KDB_DISALLOW_TGT_BASED, 1}, 717c478bd9Sstevel@tonic-gate {"allow_renewable", 15, KRB5_KDB_DISALLOW_RENEWABLE, 1}, 727c478bd9Sstevel@tonic-gate {"allow_proxiable", 15, KRB5_KDB_DISALLOW_PROXIABLE, 1}, 737c478bd9Sstevel@tonic-gate {"allow_dup_skey", 14, KRB5_KDB_DISALLOW_DUP_SKEY, 1}, 747c478bd9Sstevel@tonic-gate {"allow_tix", 9, KRB5_KDB_DISALLOW_ALL_TIX, 1}, 757c478bd9Sstevel@tonic-gate {"requires_preauth", 16, KRB5_KDB_REQUIRES_PRE_AUTH, 0}, 767c478bd9Sstevel@tonic-gate {"requires_hwauth", 15, KRB5_KDB_REQUIRES_HW_AUTH, 0}, 777c478bd9Sstevel@tonic-gate {"needchange", 10, KRB5_KDB_REQUIRES_PWCHANGE, 0}, 787c478bd9Sstevel@tonic-gate {"allow_svr", 9, KRB5_KDB_DISALLOW_SVR, 1}, 797c478bd9Sstevel@tonic-gate {"password_changing_service", 25, KRB5_KDB_PWCHANGE_SERVICE, 0 }, 807c478bd9Sstevel@tonic-gate {"support_desmd5", 14, KRB5_KDB_SUPPORT_DESMD5, 0 } 817c478bd9Sstevel@tonic-gate }; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static char *prflags[] = { 847c478bd9Sstevel@tonic-gate "DISALLOW_POSTDATED", /* 0x00000001 */ 857c478bd9Sstevel@tonic-gate "DISALLOW_FORWARDABLE", /* 0x00000002 */ 867c478bd9Sstevel@tonic-gate "DISALLOW_TGT_BASED", /* 0x00000004 */ 877c478bd9Sstevel@tonic-gate "DISALLOW_RENEWABLE", /* 0x00000008 */ 887c478bd9Sstevel@tonic-gate "DISALLOW_PROXIABLE", /* 0x00000010 */ 897c478bd9Sstevel@tonic-gate "DISALLOW_DUP_SKEY", /* 0x00000020 */ 907c478bd9Sstevel@tonic-gate "DISALLOW_ALL_TIX", /* 0x00000040 */ 917c478bd9Sstevel@tonic-gate "REQUIRES_PRE_AUTH", /* 0x00000080 */ 927c478bd9Sstevel@tonic-gate "REQUIRES_HW_AUTH", /* 0x00000100 */ 937c478bd9Sstevel@tonic-gate "REQUIRES_PWCHANGE", /* 0x00000200 */ 947c478bd9Sstevel@tonic-gate "UNKNOWN_0x00000400", /* 0x00000400 */ 957c478bd9Sstevel@tonic-gate "UNKNOWN_0x00000800", /* 0x00000800 */ 967c478bd9Sstevel@tonic-gate "DISALLOW_SVR", /* 0x00001000 */ 977c478bd9Sstevel@tonic-gate "PWCHANGE_SERVICE", /* 0x00002000 */ 987c478bd9Sstevel@tonic-gate "SUPPORT_DESMD5", /* 0x00004000 */ 997c478bd9Sstevel@tonic-gate "NEW_PRINC", /* 0x00008000 */ 1007c478bd9Sstevel@tonic-gate }; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate char *getenv(); 1037c478bd9Sstevel@tonic-gate int exit_status = 0; 1047c478bd9Sstevel@tonic-gate char *def_realm = NULL; 1057c478bd9Sstevel@tonic-gate char *whoami = NULL; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate void *handle = NULL; 1087c478bd9Sstevel@tonic-gate krb5_context context; 1097c478bd9Sstevel@tonic-gate char *ccache_name = NULL; 1107c478bd9Sstevel@tonic-gate 11156a424ccSmp153739 int locked = 0; 11256a424ccSmp153739 static char *strdur(duration) 1137c478bd9Sstevel@tonic-gate time_t duration; 1147c478bd9Sstevel@tonic-gate { 11556a424ccSmp153739 static char out[50]; 11656a424ccSmp153739 int neg, days, hours, minutes, seconds; 1177c478bd9Sstevel@tonic-gate 11856a424ccSmp153739 if (duration < 0) { 11956a424ccSmp153739 duration *= -1; 12056a424ccSmp153739 neg = 1; 12156a424ccSmp153739 } else 12256a424ccSmp153739 neg = 0; 1237c478bd9Sstevel@tonic-gate days = duration / (24 * 3600); 1247c478bd9Sstevel@tonic-gate duration %= 24 * 3600; 1257c478bd9Sstevel@tonic-gate hours = duration / 3600; 1267c478bd9Sstevel@tonic-gate duration %= 3600; 1277c478bd9Sstevel@tonic-gate minutes = duration / 60; 1287c478bd9Sstevel@tonic-gate duration %= 60; 1297c478bd9Sstevel@tonic-gate seconds = duration; 13056a424ccSmp153739 snprintf(out, sizeof (out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "", 13156a424ccSmp153739 days, days == 1 ? gettext("day") : gettext("days"), 13256a424ccSmp153739 hours, minutes, seconds); 13356a424ccSmp153739 return out; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 13656a424ccSmp153739 static char *strdate(when) 1377c478bd9Sstevel@tonic-gate krb5_timestamp when; 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate struct tm *tm; 14056a424ccSmp153739 static char out[40]; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate time_t lcltim = when; 1437c478bd9Sstevel@tonic-gate tm = localtime(&lcltim); 14456a424ccSmp153739 strftime(out, sizeof(out), gettext("%a %b %d %H:%M:%S %Z %Y"), tm); 14556a424ccSmp153739 return out; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 14856a424ccSmp153739 /* this is a wrapper to go around krb5_parse_principal so we can set 14956a424ccSmp153739 the default realm up properly */ 15056a424ccSmp153739 static krb5_error_code 1517c478bd9Sstevel@tonic-gate kadmin_parse_name(name, principal) 1527c478bd9Sstevel@tonic-gate char *name; 1537c478bd9Sstevel@tonic-gate krb5_principal *principal; 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate char *cp, *fullname; 1567c478bd9Sstevel@tonic-gate krb5_error_code retval; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (name == NULL) 1597c478bd9Sstevel@tonic-gate return (EINVAL); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate /* assumes def_realm is initialized! */ 1627c478bd9Sstevel@tonic-gate fullname = (char *)malloc(strlen(name) + 1 + strlen(def_realm) + 1); 1637c478bd9Sstevel@tonic-gate if (fullname == NULL) 16456a424ccSmp153739 return ENOMEM; 1657c478bd9Sstevel@tonic-gate strcpy(fullname, name); 1667c478bd9Sstevel@tonic-gate cp = strchr(fullname, '@'); 1677c478bd9Sstevel@tonic-gate while (cp) { 1687c478bd9Sstevel@tonic-gate if (cp - fullname && *(cp - 1) != '\\') 1697c478bd9Sstevel@tonic-gate break; 1707c478bd9Sstevel@tonic-gate else 17156a424ccSmp153739 cp = strchr(cp + 1, '@'); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate if (cp == NULL) { 1747c478bd9Sstevel@tonic-gate strcat(fullname, "@"); 1757c478bd9Sstevel@tonic-gate strcat(fullname, def_realm); 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate retval = krb5_parse_name(context, fullname, principal); 1787c478bd9Sstevel@tonic-gate free(fullname); 17956a424ccSmp153739 return retval; 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 18254925bf6Swillf static void extended_com_err_fn (const char *myprog, errcode_t code, 18354925bf6Swillf const char *fmt, va_list args) 18454925bf6Swillf { 18554925bf6Swillf if (code) { 18654925bf6Swillf const char *emsg; 18754925bf6Swillf emsg = krb5_get_error_message (context, code); 18854925bf6Swillf fprintf (stderr, "%s: %s ", myprog, emsg); 18954925bf6Swillf krb5_free_error_message (context, emsg); 19054925bf6Swillf } else { 19154925bf6Swillf fprintf (stderr, "%s: ", myprog); 19254925bf6Swillf } 19354925bf6Swillf vfprintf (stderr, fmt, args); 19454925bf6Swillf fprintf (stderr, "\n"); 19554925bf6Swillf } 19656a424ccSmp153739 char *kadmin_startup(argc, argv) 1977c478bd9Sstevel@tonic-gate int argc; 1987c478bd9Sstevel@tonic-gate char *argv[]; 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate extern char *optarg; 2017c478bd9Sstevel@tonic-gate char *princstr = NULL, *keytab_name = NULL, *query = NULL; 2027c478bd9Sstevel@tonic-gate char *password = NULL; 2037c478bd9Sstevel@tonic-gate char *luser, *canon, *cp; 20456a424ccSmp153739 int optchar, freeprinc = 0, use_keytab = 0; 2057c478bd9Sstevel@tonic-gate struct passwd *pw; 2067c478bd9Sstevel@tonic-gate kadm5_ret_t retval; 2077c478bd9Sstevel@tonic-gate krb5_ccache cc; 2087c478bd9Sstevel@tonic-gate krb5_principal princ; 2097c478bd9Sstevel@tonic-gate kadm5_config_params params; 21054925bf6Swillf char **db_args = NULL; 21154925bf6Swillf int db_args_size = 0; 21254925bf6Swillf char *db_name = NULL; 21356a424ccSmp153739 char *svcname = NULL; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate memset((char *) ¶ms, 0, sizeof(params)); 2167c478bd9Sstevel@tonic-gate 21754925bf6Swillf if (strcmp (whoami, "kadmin.local") == 0) 21854925bf6Swillf set_com_err_hook(extended_com_err_fn); 21954925bf6Swillf 22054925bf6Swillf retval = kadm5_init_krb5_context(&context); 22156a424ccSmp153739 if (retval) { 22254925bf6Swillf com_err(whoami, retval, gettext("while initializing krb5 library")); 2237c478bd9Sstevel@tonic-gate exit(1); 2247c478bd9Sstevel@tonic-gate } 22556a424ccSmp153739 22654925bf6Swillf while ((optchar = getopt(argc, argv, "x:r:p:kq:w:d:s:mc:t:e:ON")) != EOF) { 2277c478bd9Sstevel@tonic-gate switch (optchar) { 22854925bf6Swillf case 'x': 22954925bf6Swillf db_args_size++; 23054925bf6Swillf { 23154925bf6Swillf char **temp = realloc(db_args, sizeof(char*) * (db_args_size+1)); 23254925bf6Swillf if (temp == NULL) { 23354925bf6Swillf fprintf(stderr, gettext("%s: Cannot initialize. Not enough memory\n"), 23454925bf6Swillf argv[0]); 23554925bf6Swillf exit(1); 23654925bf6Swillf } 23754925bf6Swillf 23854925bf6Swillf db_args = temp; 23954925bf6Swillf } 24054925bf6Swillf db_args[db_args_size-1] = optarg; 24154925bf6Swillf db_args[db_args_size] = NULL; 24254925bf6Swillf break; 24354925bf6Swillf 2447c478bd9Sstevel@tonic-gate case 'r': 2457c478bd9Sstevel@tonic-gate def_realm = optarg; 2467c478bd9Sstevel@tonic-gate break; 2477c478bd9Sstevel@tonic-gate case 'p': 24856a424ccSmp153739 princstr = optarg; 2497c478bd9Sstevel@tonic-gate break; 2507c478bd9Sstevel@tonic-gate case 'c': 2517c478bd9Sstevel@tonic-gate ccache_name = optarg; 2527c478bd9Sstevel@tonic-gate break; 2537c478bd9Sstevel@tonic-gate case 'k': 2547c478bd9Sstevel@tonic-gate use_keytab++; 2557c478bd9Sstevel@tonic-gate break; 2567c478bd9Sstevel@tonic-gate case 't': 2577c478bd9Sstevel@tonic-gate keytab_name = optarg; 2587c478bd9Sstevel@tonic-gate break; 2597c478bd9Sstevel@tonic-gate case 'w': 2607c478bd9Sstevel@tonic-gate password = optarg; 2617c478bd9Sstevel@tonic-gate break; 2627c478bd9Sstevel@tonic-gate case 'q': 2637c478bd9Sstevel@tonic-gate query = optarg; 2647c478bd9Sstevel@tonic-gate break; 2657c478bd9Sstevel@tonic-gate case 'd': 26654925bf6Swillf /* now db_name is not a seperate argument. It has to be passed as part of the db_args */ 26754925bf6Swillf if (!db_name) { 26854925bf6Swillf db_name = malloc(strlen(optarg) + sizeof("dbname=")); 26954925bf6Swillf } else { 27054925bf6Swillf db_name = realloc(db_name, strlen(optarg) + sizeof("dbname=")); 27154925bf6Swillf } 27254925bf6Swillf 27354925bf6Swillf strcpy(db_name, "dbname="); 27454925bf6Swillf strcat(db_name, optarg); 27554925bf6Swillf 27654925bf6Swillf db_args_size++; 27754925bf6Swillf { 27854925bf6Swillf char **temp = realloc(db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */ 27954925bf6Swillf if (temp == NULL) { 28054925bf6Swillf fprintf(stderr, 28154925bf6Swillf gettext("%s: Cannot initialize. Not enough memory\n"), 28254925bf6Swillf argv[0]); 28354925bf6Swillf exit(1); 28454925bf6Swillf } 28554925bf6Swillf 28654925bf6Swillf db_args = temp; 28754925bf6Swillf } 28854925bf6Swillf db_args[db_args_size-1] = db_name; 28954925bf6Swillf db_args[db_args_size] = NULL; 2907c478bd9Sstevel@tonic-gate break; 2917c478bd9Sstevel@tonic-gate case 's': 2927c478bd9Sstevel@tonic-gate params.admin_server = optarg; 2937c478bd9Sstevel@tonic-gate params.mask |= KADM5_CONFIG_ADMIN_SERVER; 2947c478bd9Sstevel@tonic-gate break; 2957c478bd9Sstevel@tonic-gate case 'm': 2967c478bd9Sstevel@tonic-gate params.mkey_from_kbd = 1; 2977c478bd9Sstevel@tonic-gate params.mask |= KADM5_CONFIG_MKEY_FROM_KBD; 2987c478bd9Sstevel@tonic-gate break; 2997c478bd9Sstevel@tonic-gate case 'e': 3007c478bd9Sstevel@tonic-gate retval = krb5_string_to_keysalts(optarg, 30156a424ccSmp153739 ", \t", 30256a424ccSmp153739 ":.-", 30356a424ccSmp153739 0, 3047c478bd9Sstevel@tonic-gate ¶ms.keysalts, 3057c478bd9Sstevel@tonic-gate ¶ms.num_keysalts); 3067c478bd9Sstevel@tonic-gate if (retval) { 3077c478bd9Sstevel@tonic-gate com_err(whoami, retval, 3087c478bd9Sstevel@tonic-gate gettext("while parsing keysalts %s"), optarg); 3097c478bd9Sstevel@tonic-gate exit(1); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate params.mask |= KADM5_CONFIG_ENCTYPES; 3127c478bd9Sstevel@tonic-gate break; 31356a424ccSmp153739 case 'O': /* Undocumented option for testing only */ 31456a424ccSmp153739 svcname = KADM5_ADMIN_SERVICE_P; 31556a424ccSmp153739 break; 3167c478bd9Sstevel@tonic-gate default: 3177c478bd9Sstevel@tonic-gate usage(whoami); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate if ((ccache_name && use_keytab) || 3217c478bd9Sstevel@tonic-gate (keytab_name && !use_keytab)) 3227c478bd9Sstevel@tonic-gate usage(whoami); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate if (def_realm == NULL && krb5_get_default_realm(context, &def_realm)) { 32556a424ccSmp153739 if (freeprinc) 3267c478bd9Sstevel@tonic-gate free(princstr); 3277c478bd9Sstevel@tonic-gate fprintf(stderr, 3287c478bd9Sstevel@tonic-gate gettext("%s: unable to get default realm\n"), whoami); 3297c478bd9Sstevel@tonic-gate exit(1); 3307c478bd9Sstevel@tonic-gate } 33156a424ccSmp153739 3327c478bd9Sstevel@tonic-gate params.mask |= KADM5_CONFIG_REALM; 3337c478bd9Sstevel@tonic-gate params.realm = def_realm; 3347c478bd9Sstevel@tonic-gate 33556a424ccSmp153739 if (svcname == NULL) { 3367c478bd9Sstevel@tonic-gate if (kadm5_get_adm_host_srv_name(context, 33756a424ccSmp153739 def_realm, &svcname)) { 3387c478bd9Sstevel@tonic-gate fprintf(stderr, 3397c478bd9Sstevel@tonic-gate gettext("%s: unable to get host based " 3407c478bd9Sstevel@tonic-gate "service name for realm %s\n"), 3417c478bd9Sstevel@tonic-gate whoami, def_realm); 34256a424ccSmp153739 if (freeprinc) 3437c478bd9Sstevel@tonic-gate free(princstr); 3447c478bd9Sstevel@tonic-gate exit(1); 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate /* 3497c478bd9Sstevel@tonic-gate * Set cc to an open credentials cache, either specified by the -c 3507c478bd9Sstevel@tonic-gate * argument or the default. 3517c478bd9Sstevel@tonic-gate */ 3527c478bd9Sstevel@tonic-gate if (ccache_name == NULL) { 35356a424ccSmp153739 if ((retval = krb5_cc_default(context, &cc))) { 3547c478bd9Sstevel@tonic-gate com_err(whoami, retval, 3557c478bd9Sstevel@tonic-gate gettext("while opening default " 3567c478bd9Sstevel@tonic-gate "credentials cache")); 3577c478bd9Sstevel@tonic-gate exit(1); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate } else { 36056a424ccSmp153739 if ((retval = krb5_cc_resolve(context, ccache_name, &cc))) { 3617c478bd9Sstevel@tonic-gate com_err(whoami, retval, 3627c478bd9Sstevel@tonic-gate gettext("while opening credentials cache %s"), 3637c478bd9Sstevel@tonic-gate ccache_name); 3647c478bd9Sstevel@tonic-gate exit(1); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate /* 36956a424ccSmp153739 * If no principal name is specified: If a ccache was specified 37056a424ccSmp153739 * and its primary principal name can be read, it is used, else if 37156a424ccSmp153739 * a keytab was specified, the principal name is host/hostname, 3727c478bd9Sstevel@tonic-gate * otherwise append "/admin" to the primary name of the default 3737c478bd9Sstevel@tonic-gate * ccache, $USER, or pw_name. 3747c478bd9Sstevel@tonic-gate * 3757c478bd9Sstevel@tonic-gate * Gee, 100+ lines to figure out the client principal name. This 3767c478bd9Sstevel@tonic-gate * should be compressed... 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate if (princstr == NULL) { 3807c478bd9Sstevel@tonic-gate if (ccache_name != NULL && 3817c478bd9Sstevel@tonic-gate !krb5_cc_get_principal(context, cc, &princ)) { 38256a424ccSmp153739 if ((retval = krb5_unparse_name(context, princ, &princstr))) { 3837c478bd9Sstevel@tonic-gate com_err(whoami, retval, 3847c478bd9Sstevel@tonic-gate gettext("while canonicalizing principal name")); 3857c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 3867c478bd9Sstevel@tonic-gate exit(1); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 38956a424ccSmp153739 freeprinc++; 3907c478bd9Sstevel@tonic-gate } else if (use_keytab != 0) { 39156a424ccSmp153739 if ((retval = krb5_sname_to_principal(context, NULL, 39256a424ccSmp153739 "host", 39356a424ccSmp153739 KRB5_NT_SRV_HST, 39456a424ccSmp153739 &princ))) { 3957c478bd9Sstevel@tonic-gate com_err(whoami, retval, 3967c478bd9Sstevel@tonic-gate gettext("creating host service principal")); 3977c478bd9Sstevel@tonic-gate exit(1); 3987c478bd9Sstevel@tonic-gate } 39956a424ccSmp153739 if ((retval = krb5_unparse_name(context, princ, &princstr))) { 4007c478bd9Sstevel@tonic-gate com_err(whoami, retval, 40154925bf6Swillf gettext("while canonicalizing principal name")); 4027c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 4037c478bd9Sstevel@tonic-gate exit(1); 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 40656a424ccSmp153739 freeprinc++; 4077c478bd9Sstevel@tonic-gate } else if (!krb5_cc_get_principal(context, cc, &princ)) { 4087c478bd9Sstevel@tonic-gate char *realm = NULL; 4097c478bd9Sstevel@tonic-gate if (krb5_unparse_name(context, princ, &canon)) { 4107c478bd9Sstevel@tonic-gate fprintf(stderr, 4117c478bd9Sstevel@tonic-gate gettext("%s: unable to canonicalize " 4127c478bd9Sstevel@tonic-gate "principal\n"), whoami); 4137c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 4147c478bd9Sstevel@tonic-gate exit(1); 4157c478bd9Sstevel@tonic-gate } 41656a424ccSmp153739 /* strip out realm of principal if it's there */ 41756a424ccSmp153739 realm = strchr(canon, '@'); 41856a424ccSmp153739 while (realm) { 41956a424ccSmp153739 if (realm - canon && *(realm - 1) != '\\') 42056a424ccSmp153739 break; 42156a424ccSmp153739 else 422eda50310Smp153739 realm = strchr(realm+1, '@'); 42356a424ccSmp153739 } 42456a424ccSmp153739 if (realm) 42556a424ccSmp153739 *realm++ = '\0'; 42656a424ccSmp153739 cp = strchr(canon, '/'); 42756a424ccSmp153739 while (cp) { 42856a424ccSmp153739 if (cp - canon && *(cp - 1) != '\\') 42956a424ccSmp153739 break; 43056a424ccSmp153739 else 431eda50310Smp153739 cp = strchr(cp+1, '/'); 43256a424ccSmp153739 } 43356a424ccSmp153739 if (cp != NULL) 43456a424ccSmp153739 *cp = '\0'; 43556a424ccSmp153739 princstr = (char*)malloc(strlen(canon) + 6 /* "/admin" */ + 43656a424ccSmp153739 (realm ? 1 + strlen(realm) : 0) + 1); 43756a424ccSmp153739 if (princstr == NULL) { 43856a424ccSmp153739 fprintf(stderr, 43956a424ccSmp153739 gettext("%s: out of memory\n"), 44056a424ccSmp153739 whoami); 44156a424ccSmp153739 exit(1); 44256a424ccSmp153739 } 44356a424ccSmp153739 strcpy(princstr, canon); 44456a424ccSmp153739 strcat(princstr, "/admin"); 44556a424ccSmp153739 if (realm) { 44656a424ccSmp153739 strcat(princstr, "@"); 44756a424ccSmp153739 strcat(princstr, realm); 44856a424ccSmp153739 } 4497c478bd9Sstevel@tonic-gate free(canon); 45056a424ccSmp153739 krb5_free_principal(context, princ); 45156a424ccSmp153739 freeprinc++; 45256a424ccSmp153739 } else if ((luser = getenv("USER"))) { 45356a424ccSmp153739 princstr = (char *) malloc(strlen(luser) + 7 /* "/admin@" */ 45456a424ccSmp153739 + strlen(def_realm) + 1); 45556a424ccSmp153739 if (princstr == NULL) { 45656a424ccSmp153739 fprintf(stderr, 45756a424ccSmp153739 gettext("%s: out of memory\n"), 45856a424ccSmp153739 whoami); 45956a424ccSmp153739 exit(1); 46056a424ccSmp153739 } 46156a424ccSmp153739 strcpy(princstr, luser); 46256a424ccSmp153739 strcat(princstr, "/admin"); 46356a424ccSmp153739 strcat(princstr, "@"); 46456a424ccSmp153739 strcat(princstr, def_realm); 46556a424ccSmp153739 freeprinc++; 46656a424ccSmp153739 } else if ((pw = getpwuid(getuid()))) { 46756a424ccSmp153739 princstr = (char *) malloc(strlen(pw->pw_name) + 7 /* "/admin@" */ 46856a424ccSmp153739 + strlen(def_realm) + 1); 46956a424ccSmp153739 if (princstr == NULL) { 47056a424ccSmp153739 fprintf(stderr, 47156a424ccSmp153739 gettext("%s: out of memory\n"), 47256a424ccSmp153739 whoami); 47356a424ccSmp153739 exit(1); 47456a424ccSmp153739 } 47556a424ccSmp153739 strcpy(princstr, pw->pw_name); 47656a424ccSmp153739 strcat(princstr, "/admin@"); 47756a424ccSmp153739 strcat(princstr, def_realm); 47856a424ccSmp153739 freeprinc++; 4797c478bd9Sstevel@tonic-gate } else { 4807c478bd9Sstevel@tonic-gate fprintf(stderr, 4817c478bd9Sstevel@tonic-gate gettext("%s: unable to figure out " 4827c478bd9Sstevel@tonic-gate "a principal name\n"), 4837c478bd9Sstevel@tonic-gate whoami); 4847c478bd9Sstevel@tonic-gate exit(1); 4857c478bd9Sstevel@tonic-gate } 48656a424ccSmp153739 } 4877c478bd9Sstevel@tonic-gate 48856a424ccSmp153739 retval = krb5_klog_init(context, "admin_server", whoami, 0); 48956a424ccSmp153739 if (retval) { 49056a424ccSmp153739 com_err(whoami, retval, "while setting up logging"); 4917c478bd9Sstevel@tonic-gate exit(1); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate /* 49556a424ccSmp153739 * Initialize the kadm5 connection. If we were given a ccache, 49656a424ccSmp153739 * use it. Otherwise, use/prompt for the password. 4977c478bd9Sstevel@tonic-gate */ 498d51f1d33Smp153739 499d51f1d33Smp153739 /* Solaris Kerberos: 500d51f1d33Smp153739 * Send warnings to stderr 501d51f1d33Smp153739 */ 5027c478bd9Sstevel@tonic-gate if (ccache_name) { 50354925bf6Swillf fprintf(stderr, gettext("Authenticating as principal %s with existing credentials.\n"), 5047c478bd9Sstevel@tonic-gate princstr); 5057c478bd9Sstevel@tonic-gate retval = kadm5_init_with_creds(princstr, cc, 50656a424ccSmp153739 svcname, 5077c478bd9Sstevel@tonic-gate ¶ms, 5087c478bd9Sstevel@tonic-gate KADM5_STRUCT_VERSION, 5097c478bd9Sstevel@tonic-gate KADM5_API_VERSION_2, 51054925bf6Swillf db_args, 5117c478bd9Sstevel@tonic-gate &handle); 5127c478bd9Sstevel@tonic-gate } else if (use_keytab) { 5137c478bd9Sstevel@tonic-gate if (keytab_name) 514d51f1d33Smp153739 fprintf(stderr, gettext("Authenticating as principal %s with keytab %s.\n"), 5157c478bd9Sstevel@tonic-gate princstr, keytab_name); 5167c478bd9Sstevel@tonic-gate else 51754925bf6Swillf fprintf(stderr, gettext("Authenticating as principal %s with default keytab.\n"), 5187c478bd9Sstevel@tonic-gate princstr); 5197c478bd9Sstevel@tonic-gate retval = kadm5_init_with_skey(princstr, keytab_name, 52056a424ccSmp153739 svcname, 5217c478bd9Sstevel@tonic-gate ¶ms, 5227c478bd9Sstevel@tonic-gate KADM5_STRUCT_VERSION, 5237c478bd9Sstevel@tonic-gate KADM5_API_VERSION_2, 52454925bf6Swillf db_args, 5257c478bd9Sstevel@tonic-gate &handle); 5267c478bd9Sstevel@tonic-gate } else { 527d51f1d33Smp153739 fprintf(stderr, gettext("Authenticating as principal %s with password.\n"), 5287c478bd9Sstevel@tonic-gate princstr); 5297c478bd9Sstevel@tonic-gate retval = kadm5_init_with_password(princstr, password, 53056a424ccSmp153739 svcname, 53156a424ccSmp153739 ¶ms, 5327c478bd9Sstevel@tonic-gate KADM5_STRUCT_VERSION, 5337c478bd9Sstevel@tonic-gate KADM5_API_VERSION_2, 53454925bf6Swillf db_args, 5357c478bd9Sstevel@tonic-gate &handle); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate if (retval) { 5387c478bd9Sstevel@tonic-gate if (retval == KADM5_RPC_ERROR_CANTENCODEARGS || 5397c478bd9Sstevel@tonic-gate retval == KADM5_RPC_ERROR_CANTDECODEARGS) { 5407c478bd9Sstevel@tonic-gate com_err(whoami, KADM5_RPC_ERROR, 5417c478bd9Sstevel@tonic-gate gettext("while initializing %s interface"), whoami); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate /* privacy-enabled mech probably not installed/configed */ 5447c478bd9Sstevel@tonic-gate com_err(whoami, retval, gettext("."), whoami); 5457c478bd9Sstevel@tonic-gate } else { 5467c478bd9Sstevel@tonic-gate com_err(whoami, retval, 5477c478bd9Sstevel@tonic-gate gettext("while initializing %s interface"), whoami); 5487c478bd9Sstevel@tonic-gate if (retval == KADM5_BAD_CLIENT_PARAMS || 5497c478bd9Sstevel@tonic-gate retval == KADM5_BAD_SERVER_PARAMS) 5507c478bd9Sstevel@tonic-gate usage(whoami); 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate exit(1); 5537c478bd9Sstevel@tonic-gate } 55456a424ccSmp153739 if (freeprinc) 5557c478bd9Sstevel@tonic-gate free(princstr); 5567c478bd9Sstevel@tonic-gate 55754925bf6Swillf if (db_name) 55854925bf6Swillf free(db_name), db_name=NULL; 55954925bf6Swillf 56054925bf6Swillf if (db_args) 56154925bf6Swillf free(db_args), db_args=NULL; 56254925bf6Swillf 56356a424ccSmp153739 if ((retval = krb5_cc_close(context, cc))) { 5647c478bd9Sstevel@tonic-gate com_err(whoami, retval, gettext("while closing ccache %s"), 5657c478bd9Sstevel@tonic-gate ccache_name); 5667c478bd9Sstevel@tonic-gate exit(1); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate 56956a424ccSmp153739 /* register the WRFILE keytab type and set it as the default */ 57056a424ccSmp153739 { 571159d09a2SMark Phalan #define DEFAULT_KEYTAB "WRFILE:/etc/krb5/krb5.keytab" 57256a424ccSmp153739 /* XXX krb5_defkeyname is an internal library global and 57356a424ccSmp153739 should go away */ 57456a424ccSmp153739 extern char *krb5_defkeyname; 5757c478bd9Sstevel@tonic-gate krb5_defkeyname = DEFAULT_KEYTAB; 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate if ((retval = kadm5_init_iprop(handle)) != 0) { 5797c478bd9Sstevel@tonic-gate com_err(whoami, retval, gettext("while mapping update log")); 5807c478bd9Sstevel@tonic-gate exit(1); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate /* Solaris kerberos: fix memory leak */ 58456a424ccSmp153739 if (svcname) 58556a424ccSmp153739 free(svcname); 5867c478bd9Sstevel@tonic-gate 58756a424ccSmp153739 return query; 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate 59056a424ccSmp153739 int quit() 5917c478bd9Sstevel@tonic-gate { 59256a424ccSmp153739 kadm5_ret_t retval; 5937c478bd9Sstevel@tonic-gate 59456a424ccSmp153739 if (locked) { 59556a424ccSmp153739 retval = kadm5_unlock(handle); 59656a424ccSmp153739 if (retval) { 59756a424ccSmp153739 com_err("quit", retval, gettext("while unlocking locked database")); 59856a424ccSmp153739 return 1; 5997c478bd9Sstevel@tonic-gate } 60056a424ccSmp153739 locked = 0; 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate kadm5_destroy(handle); 6047c478bd9Sstevel@tonic-gate if (ccache_name != NULL) { 6057c478bd9Sstevel@tonic-gate fprintf(stderr, 6067c478bd9Sstevel@tonic-gate gettext("\n\a\a\aAdministration credentials " 6077c478bd9Sstevel@tonic-gate "NOT DESTROYED.\n")); 6087c478bd9Sstevel@tonic-gate } 60956a424ccSmp153739 6107c478bd9Sstevel@tonic-gate /* insert more random cleanup here */ 61156a424ccSmp153739 krb5_klog_close(context); 6127c478bd9Sstevel@tonic-gate krb5_free_context(context); 6137c478bd9Sstevel@tonic-gate context = NULL; 61456a424ccSmp153739 return 0; 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 61756a424ccSmp153739 void kadmin_lock(argc, argv) 61856a424ccSmp153739 int argc; 61956a424ccSmp153739 char *argv[]; 62056a424ccSmp153739 { 62156a424ccSmp153739 kadm5_ret_t retval; 62256a424ccSmp153739 62356a424ccSmp153739 if (locked) 62456a424ccSmp153739 return; 62556a424ccSmp153739 retval = kadm5_lock(handle); 62656a424ccSmp153739 if (retval) { 62756a424ccSmp153739 com_err("lock", retval, ""); 62856a424ccSmp153739 return; 62956a424ccSmp153739 } 63056a424ccSmp153739 locked = 1; 63156a424ccSmp153739 } 63256a424ccSmp153739 63356a424ccSmp153739 void kadmin_unlock(argc, argv) 63456a424ccSmp153739 int argc; 63556a424ccSmp153739 char *argv[]; 63656a424ccSmp153739 { 63756a424ccSmp153739 kadm5_ret_t retval; 63856a424ccSmp153739 63956a424ccSmp153739 if (!locked) 64056a424ccSmp153739 return; 64156a424ccSmp153739 retval = kadm5_unlock(handle); 64256a424ccSmp153739 if (retval) { 64356a424ccSmp153739 com_err("unlock", retval, ""); 64456a424ccSmp153739 return; 64556a424ccSmp153739 } 64656a424ccSmp153739 locked = 0; 64756a424ccSmp153739 } 64856a424ccSmp153739 64956a424ccSmp153739 void kadmin_delprinc(argc, argv) 6507c478bd9Sstevel@tonic-gate int argc; 6517c478bd9Sstevel@tonic-gate char *argv[]; 6527c478bd9Sstevel@tonic-gate { 6537c478bd9Sstevel@tonic-gate kadm5_ret_t retval; 6547c478bd9Sstevel@tonic-gate krb5_principal princ; 6557c478bd9Sstevel@tonic-gate char *canon; 6567c478bd9Sstevel@tonic-gate char reply[32]; 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate if (! (argc == 2 || 65956a424ccSmp153739 (argc == 3 && !strcmp("-force", argv[1])))) { 6607c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: delete_principal [-force] %s\n", 6617c478bd9Sstevel@tonic-gate gettext("usage"), gettext("principal")); 6627c478bd9Sstevel@tonic-gate return; 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate retval = kadmin_parse_name(argv[argc - 1], &princ); 6657c478bd9Sstevel@tonic-gate if (retval) { 6667c478bd9Sstevel@tonic-gate com_err("delete_principal", retval, 6677c478bd9Sstevel@tonic-gate gettext("while parsing principal name")); 6687c478bd9Sstevel@tonic-gate return; 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate retval = krb5_unparse_name(context, princ, &canon); 6717c478bd9Sstevel@tonic-gate if (retval) { 6727c478bd9Sstevel@tonic-gate com_err("delete_principal", retval, 6737c478bd9Sstevel@tonic-gate gettext("while canonicalizing principal")); 6747c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 6757c478bd9Sstevel@tonic-gate return; 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate if (argc == 2) { 6787c478bd9Sstevel@tonic-gate printf(gettext("Are you sure you want to delete " 6797c478bd9Sstevel@tonic-gate "the principal \"%s\"? (yes/no): "), canon); 6807c478bd9Sstevel@tonic-gate fgets(reply, sizeof (reply), stdin); 6817c478bd9Sstevel@tonic-gate if (strncmp(gettext("yes\n"), reply, sizeof (reply)) && 6827c478bd9Sstevel@tonic-gate strncmp(gettext("y\n"), reply, sizeof (reply)) && 6837c478bd9Sstevel@tonic-gate strncmp(gettext("Y\n"), reply, sizeof (reply))) { 6847c478bd9Sstevel@tonic-gate fprintf(stderr, 6857c478bd9Sstevel@tonic-gate gettext("Principal \"%s\" not deleted\n"), 6867c478bd9Sstevel@tonic-gate canon); 6877c478bd9Sstevel@tonic-gate free(canon); 6887c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 6897c478bd9Sstevel@tonic-gate return; 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate } 6927c478bd9Sstevel@tonic-gate retval = kadm5_delete_principal(handle, princ); 6937c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 6947c478bd9Sstevel@tonic-gate if (retval) { 6957c478bd9Sstevel@tonic-gate com_err("delete_principal", retval, 6967c478bd9Sstevel@tonic-gate gettext("while deleting principal \"%s\""), canon); 6977c478bd9Sstevel@tonic-gate free(canon); 6987c478bd9Sstevel@tonic-gate return; 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate printf(gettext("Principal \"%s\" deleted.\n"), canon); 7017c478bd9Sstevel@tonic-gate printf(gettext("Make sure that you have removed this principal " 7027c478bd9Sstevel@tonic-gate "from all ACLs before reusing.\n")); 7037c478bd9Sstevel@tonic-gate free(canon); 70456a424ccSmp153739 return; 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate 70756a424ccSmp153739 void kadmin_cpw(argc, argv) 7087c478bd9Sstevel@tonic-gate int argc; 7097c478bd9Sstevel@tonic-gate char *argv[]; 7107c478bd9Sstevel@tonic-gate { 7117c478bd9Sstevel@tonic-gate kadm5_ret_t retval; 7127c478bd9Sstevel@tonic-gate static char newpw[1024]; 7137c478bd9Sstevel@tonic-gate static char prompt1[1024], prompt2[1024]; 7147c478bd9Sstevel@tonic-gate char *canon; 7157c478bd9Sstevel@tonic-gate char *pwarg = NULL; 71656a424ccSmp153739 int n_ks_tuple = 0, randkey = 0; 71756a424ccSmp153739 krb5_boolean keepold = FALSE; 7187c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *ks_tuple = NULL; 7197c478bd9Sstevel@tonic-gate krb5_principal princ; 72054925bf6Swillf char **db_args = NULL; 72154925bf6Swillf int db_args_size = 0; 722bcfd778bSwillf int local_kadmin = 0; 723bcfd778bSwillf 724bcfd778bSwillf local_kadmin = (strcmp(whoami, KADMIN_LOCAL_NAME) == 0); 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate if (argc < 2) { 7277c478bd9Sstevel@tonic-gate goto usage; 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate for (argv++, argc--; argc > 1; argc--, argv++) { 73054925bf6Swillf if (!strcmp("-x", *argv)) { 73154925bf6Swillf argc--; 73254925bf6Swillf if (argc < 1) { 73354925bf6Swillf fprintf(stderr, gettext("change_password: missing db argument\n")); 73454925bf6Swillf goto usage; 73554925bf6Swillf } 73654925bf6Swillf db_args_size++; 73754925bf6Swillf { 73854925bf6Swillf char **temp = realloc(db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */ 73954925bf6Swillf if (temp == NULL) { 74054925bf6Swillf fprintf(stderr, gettext("change_password: Not enough memory\n")); 74154925bf6Swillf free(db_args), db_args = NULL; 74254925bf6Swillf exit(1); 74354925bf6Swillf } 74454925bf6Swillf 74554925bf6Swillf db_args = temp; 74654925bf6Swillf } 74754925bf6Swillf db_args[db_args_size-1] = *++argv; 74854925bf6Swillf db_args[db_args_size] = NULL; 74954925bf6Swillf continue; 75054925bf6Swillf } 7517c478bd9Sstevel@tonic-gate if (!strcmp("-pw", *argv)) { 7527c478bd9Sstevel@tonic-gate argc--; 7537c478bd9Sstevel@tonic-gate if (argc < 1) { 7547c478bd9Sstevel@tonic-gate fprintf(stderr, "change_password: %s", 7557c478bd9Sstevel@tonic-gate gettext("missing password arg\n")); 7567c478bd9Sstevel@tonic-gate goto usage; 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate pwarg = *++argv; 7597c478bd9Sstevel@tonic-gate continue; 7607c478bd9Sstevel@tonic-gate } 7617c478bd9Sstevel@tonic-gate if (!strcmp("-randkey", *argv)) { 7627c478bd9Sstevel@tonic-gate randkey++; 7637c478bd9Sstevel@tonic-gate continue; 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate if (!strcmp("-keepold", *argv)) { 76656a424ccSmp153739 keepold = TRUE; 7677c478bd9Sstevel@tonic-gate continue; 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate if (!strcmp("-e", *argv)) { 7707c478bd9Sstevel@tonic-gate argc--; 7717c478bd9Sstevel@tonic-gate if (argc < 1) { 7727c478bd9Sstevel@tonic-gate fprintf(stderr, "change_password: %s", 7737c478bd9Sstevel@tonic-gate gettext("missing keysaltlist arg\n")); 7747c478bd9Sstevel@tonic-gate goto usage; 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate retval = krb5_string_to_keysalts(*++argv, ", \t", ":.-", 0, 7777c478bd9Sstevel@tonic-gate &ks_tuple, &n_ks_tuple); 7787c478bd9Sstevel@tonic-gate if (retval) { 7797c478bd9Sstevel@tonic-gate com_err("change_password", retval, 7807c478bd9Sstevel@tonic-gate gettext("while parsing keysalts %s"), *argv); 7817c478bd9Sstevel@tonic-gate return; 7827c478bd9Sstevel@tonic-gate } 7837c478bd9Sstevel@tonic-gate continue; 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate goto usage; 7867c478bd9Sstevel@tonic-gate } 78754925bf6Swillf if (*argv == NULL) { 78854925bf6Swillf com_err("change_password", 0, "missing principal name"); 78954925bf6Swillf goto usage; 79054925bf6Swillf } 7917c478bd9Sstevel@tonic-gate retval = kadmin_parse_name(*argv, &princ); 7927c478bd9Sstevel@tonic-gate if (retval) { 7937c478bd9Sstevel@tonic-gate com_err("change_password", retval, 7947c478bd9Sstevel@tonic-gate gettext("while parsing principal name")); 7957c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 7967c478bd9Sstevel@tonic-gate free(ks_tuple); 79754925bf6Swillf if (db_args) free(db_args); 7987c478bd9Sstevel@tonic-gate goto usage; 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate retval = krb5_unparse_name(context, princ, &canon); 8017c478bd9Sstevel@tonic-gate if (retval) { 8027c478bd9Sstevel@tonic-gate com_err("change_password", retval, 8037c478bd9Sstevel@tonic-gate gettext("while canonicalizing principal")); 8047c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 8057c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 8067c478bd9Sstevel@tonic-gate free(ks_tuple); 80754925bf6Swillf if (db_args) free(db_args); 8087c478bd9Sstevel@tonic-gate return; 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate if (pwarg != NULL) { 8117c478bd9Sstevel@tonic-gate if (keepold || ks_tuple != NULL) { 8127c478bd9Sstevel@tonic-gate retval = kadm5_chpass_principal_3(handle, princ, keepold, 8137c478bd9Sstevel@tonic-gate n_ks_tuple, ks_tuple, pwarg); 8147c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 8157c478bd9Sstevel@tonic-gate free(ks_tuple); 8167c478bd9Sstevel@tonic-gate } else { 8177c478bd9Sstevel@tonic-gate retval = kadm5_chpass_principal(handle, princ, pwarg); 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 8207c478bd9Sstevel@tonic-gate if (retval) { 8217c478bd9Sstevel@tonic-gate com_err("change_password", retval, 8227c478bd9Sstevel@tonic-gate gettext("while changing password for \"%s\"."), 8237c478bd9Sstevel@tonic-gate canon); 8247c478bd9Sstevel@tonic-gate free(canon); 82554925bf6Swillf if (db_args) free(db_args); 8267c478bd9Sstevel@tonic-gate return; 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate printf(gettext("Password for \"%s\" changed.\n"), canon); 8297c478bd9Sstevel@tonic-gate free(canon); 83054925bf6Swillf if (db_args) free(db_args); 8317c478bd9Sstevel@tonic-gate return; 8327c478bd9Sstevel@tonic-gate } else if (randkey) { 833bcfd778bSwillf if (keepold || ks_tuple != NULL || local_kadmin) { 8347c478bd9Sstevel@tonic-gate retval = kadm5_randkey_principal_3(handle, princ, keepold, 8357c478bd9Sstevel@tonic-gate n_ks_tuple, ks_tuple, 8367c478bd9Sstevel@tonic-gate NULL, NULL); 8377c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 8387c478bd9Sstevel@tonic-gate free(ks_tuple); 8397c478bd9Sstevel@tonic-gate } else { 8407c478bd9Sstevel@tonic-gate retval = kadm5_randkey_principal(handle, princ, NULL, NULL); 8417c478bd9Sstevel@tonic-gate } 8427c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 8437c478bd9Sstevel@tonic-gate if (retval) { 8447c478bd9Sstevel@tonic-gate com_err("change_password", retval, 8457c478bd9Sstevel@tonic-gate gettext("while randomizing key for \"%s\"."), 8467c478bd9Sstevel@tonic-gate canon); 8477c478bd9Sstevel@tonic-gate free(canon); 84854925bf6Swillf if (db_args) free(db_args); 8497c478bd9Sstevel@tonic-gate return; 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate printf(gettext("Key for \"%s\" randomized.\n"), canon); 8527c478bd9Sstevel@tonic-gate free(canon); 85354925bf6Swillf if (db_args) free(db_args); 8547c478bd9Sstevel@tonic-gate return; 8557c478bd9Sstevel@tonic-gate } else if (argc == 1) { 8567c478bd9Sstevel@tonic-gate unsigned int i = sizeof (newpw) - 1; 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate snprintf(prompt1, sizeof (prompt1), 859e49962a0Ssemery gettext("Enter password for principal \"%.900s\""), 8607c478bd9Sstevel@tonic-gate *argv); 8617c478bd9Sstevel@tonic-gate snprintf(prompt2, sizeof (prompt2), 862e49962a0Ssemery gettext("Re-enter password for principal \"%.900s\""), 8637c478bd9Sstevel@tonic-gate *argv); 8647c478bd9Sstevel@tonic-gate retval = krb5_read_password(context, prompt1, prompt2, 8657c478bd9Sstevel@tonic-gate newpw, &i); 8667c478bd9Sstevel@tonic-gate if (retval) { 8677c478bd9Sstevel@tonic-gate com_err("change_password", retval, 8687c478bd9Sstevel@tonic-gate gettext("while reading password for \"%s\"."), 8697c478bd9Sstevel@tonic-gate canon); 8707c478bd9Sstevel@tonic-gate free(canon); 8717c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 8727c478bd9Sstevel@tonic-gate free(ks_tuple); 8737c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 87454925bf6Swillf if (db_args) free(db_args); 8757c478bd9Sstevel@tonic-gate return; 8767c478bd9Sstevel@tonic-gate } 8777c478bd9Sstevel@tonic-gate if (keepold || ks_tuple != NULL) { 8787c478bd9Sstevel@tonic-gate retval = kadm5_chpass_principal_3(handle, princ, keepold, 8797c478bd9Sstevel@tonic-gate n_ks_tuple, ks_tuple, 8807c478bd9Sstevel@tonic-gate newpw); 8817c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 8827c478bd9Sstevel@tonic-gate free(ks_tuple); 8837c478bd9Sstevel@tonic-gate } else { 8847c478bd9Sstevel@tonic-gate retval = kadm5_chpass_principal(handle, princ, newpw); 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 8877c478bd9Sstevel@tonic-gate memset(newpw, 0, sizeof (newpw)); 8887c478bd9Sstevel@tonic-gate if (retval) { 8897c478bd9Sstevel@tonic-gate com_err("change_password", retval, 8907c478bd9Sstevel@tonic-gate gettext("while changing password for \"%s\"."), 8917c478bd9Sstevel@tonic-gate canon); 8927c478bd9Sstevel@tonic-gate free(canon); 89354925bf6Swillf if (db_args) free(db_args); 8947c478bd9Sstevel@tonic-gate return; 8957c478bd9Sstevel@tonic-gate } 8967c478bd9Sstevel@tonic-gate printf(gettext("Password for \"%s\" changed.\n"), canon); 8977c478bd9Sstevel@tonic-gate free(canon); 89854925bf6Swillf if (db_args) free(db_args); 8997c478bd9Sstevel@tonic-gate return; 9007c478bd9Sstevel@tonic-gate } else { 9017c478bd9Sstevel@tonic-gate free(canon); 9027c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 9037c478bd9Sstevel@tonic-gate usage: 90456a424ccSmp153739 if (ks_tuple != NULL) 90556a424ccSmp153739 free(ks_tuple); 9067c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: change_password [-randkey] [-keepold] " 9077c478bd9Sstevel@tonic-gate "[-e keysaltlist] [-pw password] %s\n", 9087c478bd9Sstevel@tonic-gate gettext("usage"), gettext("principal")); 9097c478bd9Sstevel@tonic-gate return; 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate } 9127c478bd9Sstevel@tonic-gate 91354925bf6Swillf static void 91454925bf6Swillf kadmin_free_tl_data(kadm5_principal_ent_t princ) 91554925bf6Swillf { 91654925bf6Swillf krb5_tl_data *tl_data = princ->tl_data; 91754925bf6Swillf int n_tl_data = princ->n_tl_data; 91854925bf6Swillf int i; 91954925bf6Swillf 92054925bf6Swillf princ->n_tl_data = 0; 92154925bf6Swillf princ->tl_data = NULL; 92254925bf6Swillf 92354925bf6Swillf for (i = 0; tl_data && (i < n_tl_data); i++) { 92454925bf6Swillf krb5_tl_data *next = tl_data->tl_data_next; 92554925bf6Swillf if (tl_data->tl_data_contents) 92654925bf6Swillf free(tl_data->tl_data_contents); 92754925bf6Swillf free(tl_data); 92854925bf6Swillf tl_data = next; 92954925bf6Swillf } 93054925bf6Swillf } 93154925bf6Swillf 93254925bf6Swillf #define KRB5_TL_DB_ARGS 0x7fff 93356a424ccSmp153739 static int 93456a424ccSmp153739 kadmin_parse_princ_args(argc, argv, oprinc, mask, pass, randkey, 9357c478bd9Sstevel@tonic-gate ks_tuple, n_ks_tuple, caller) 9367c478bd9Sstevel@tonic-gate int argc; 9377c478bd9Sstevel@tonic-gate char *argv[]; 9387c478bd9Sstevel@tonic-gate kadm5_principal_ent_t oprinc; 9397c478bd9Sstevel@tonic-gate long *mask; 9407c478bd9Sstevel@tonic-gate char **pass; 9417c478bd9Sstevel@tonic-gate int *randkey; 9427c478bd9Sstevel@tonic-gate krb5_key_salt_tuple **ks_tuple; 9437c478bd9Sstevel@tonic-gate int *n_ks_tuple; 9447c478bd9Sstevel@tonic-gate char *caller; 9457c478bd9Sstevel@tonic-gate { 9467c478bd9Sstevel@tonic-gate int i, j, attrib_set; 9477c478bd9Sstevel@tonic-gate time_t date; 9487c478bd9Sstevel@tonic-gate time_t now; 9497c478bd9Sstevel@tonic-gate krb5_error_code retval; 95054925bf6Swillf krb5_tl_data *tl_data, *tail = NULL; 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate *mask = 0; 9537c478bd9Sstevel@tonic-gate *pass = NULL; 9547c478bd9Sstevel@tonic-gate *n_ks_tuple = 0; 9557c478bd9Sstevel@tonic-gate *ks_tuple = NULL; 9567c478bd9Sstevel@tonic-gate time(&now); 9577c478bd9Sstevel@tonic-gate *randkey = 0; 9587c478bd9Sstevel@tonic-gate for (i = 1; i < argc - 1; i++) { 9597c478bd9Sstevel@tonic-gate attrib_set = 0; 96054925bf6Swillf if (strlen(argv[i]) == 2 && 96154925bf6Swillf !strcmp("-x",argv[i])) { 96254925bf6Swillf if (++i > argc - 2) 96354925bf6Swillf return -1; 96454925bf6Swillf 96554925bf6Swillf tl_data = malloc(sizeof(krb5_tl_data)); 96654925bf6Swillf if (tl_data == NULL) { 96754925bf6Swillf fprintf(stderr, gettext("Not enough memory\n")); 96854925bf6Swillf return ENOMEM; 96954925bf6Swillf } 97054925bf6Swillf 97154925bf6Swillf memset(tl_data, 0, sizeof(krb5_tl_data)); 97254925bf6Swillf tl_data->tl_data_type = KRB5_TL_DB_ARGS; 97354925bf6Swillf tl_data->tl_data_length = strlen(argv[i])+1; 97454925bf6Swillf tl_data->tl_data_contents = (unsigned char*)strdup(argv[i]); 97554925bf6Swillf 97654925bf6Swillf if (tail) { 97754925bf6Swillf tail->tl_data_next = tl_data; 97854925bf6Swillf } else { 97954925bf6Swillf oprinc->tl_data = tl_data; 98054925bf6Swillf } 98154925bf6Swillf tail = tl_data; 98254925bf6Swillf oprinc->n_tl_data++; 98354925bf6Swillf 98454925bf6Swillf if (tl_data->tl_data_contents == NULL) { 98554925bf6Swillf fprintf(stderr, gettext("Not enough memory\n")); 98654925bf6Swillf return ENOMEM; 98754925bf6Swillf } 98854925bf6Swillf *mask |= KADM5_TL_DATA; 98954925bf6Swillf continue; 99054925bf6Swillf } 9917c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 7 && 99254925bf6Swillf !strcmp("-expire", argv[i])) { 9937c478bd9Sstevel@tonic-gate if (++i > argc - 2) 99456a424ccSmp153739 return -1; 9957c478bd9Sstevel@tonic-gate else { 99656a424ccSmp153739 date = get_date(argv[i]); 9977c478bd9Sstevel@tonic-gate if (date == (time_t)-1) { 9987c478bd9Sstevel@tonic-gate fprintf(stderr, 9997c478bd9Sstevel@tonic-gate gettext("Invalid date " 10007c478bd9Sstevel@tonic-gate "specification " 10017c478bd9Sstevel@tonic-gate "\"%s\".\n"), 10027c478bd9Sstevel@tonic-gate argv[i]); 100356a424ccSmp153739 return -1; 10047c478bd9Sstevel@tonic-gate } 10057c478bd9Sstevel@tonic-gate oprinc->princ_expire_time = date; 10067c478bd9Sstevel@tonic-gate *mask |= KADM5_PRINC_EXPIRE_TIME; 10077c478bd9Sstevel@tonic-gate continue; 10087c478bd9Sstevel@tonic-gate } 10097c478bd9Sstevel@tonic-gate } 10107c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 9 && 101156a424ccSmp153739 !strcmp("-pwexpire", argv[i])) { 10127c478bd9Sstevel@tonic-gate if (++i > argc - 2) 101356a424ccSmp153739 return -1; 10147c478bd9Sstevel@tonic-gate else { 101556a424ccSmp153739 date = get_date(argv[i]); 10167c478bd9Sstevel@tonic-gate if (date == (time_t)-1) { 10177c478bd9Sstevel@tonic-gate fprintf(stderr, 10187c478bd9Sstevel@tonic-gate gettext("Invalid date " 10197c478bd9Sstevel@tonic-gate "specification " 10207c478bd9Sstevel@tonic-gate "\"%s\".\n"), 10217c478bd9Sstevel@tonic-gate argv[i]); 102256a424ccSmp153739 return -1; 10237c478bd9Sstevel@tonic-gate } 10247c478bd9Sstevel@tonic-gate oprinc->pw_expiration = date; 10257c478bd9Sstevel@tonic-gate *mask |= KADM5_PW_EXPIRATION; 10267c478bd9Sstevel@tonic-gate continue; 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 8 && 103056a424ccSmp153739 !strcmp("-maxlife", argv[i])) { 10317c478bd9Sstevel@tonic-gate if (++i > argc - 2) 103256a424ccSmp153739 return -1; 10337c478bd9Sstevel@tonic-gate else { 103456a424ccSmp153739 date = get_date(argv[i]); 10357c478bd9Sstevel@tonic-gate if (date == (time_t)-1) { 10367c478bd9Sstevel@tonic-gate fprintf(stderr, 10377c478bd9Sstevel@tonic-gate gettext("Invalid date " 10387c478bd9Sstevel@tonic-gate "specification " 10397c478bd9Sstevel@tonic-gate "\"%s\".\n"), 10407c478bd9Sstevel@tonic-gate argv[i]); 104156a424ccSmp153739 return -1; 10427c478bd9Sstevel@tonic-gate } 10437c478bd9Sstevel@tonic-gate oprinc->max_life = date - now; 10447c478bd9Sstevel@tonic-gate *mask |= KADM5_MAX_LIFE; 10457c478bd9Sstevel@tonic-gate continue; 10467c478bd9Sstevel@tonic-gate } 10477c478bd9Sstevel@tonic-gate } 10487c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 13 && 104956a424ccSmp153739 !strcmp("-maxrenewlife", argv[i])) { 10507c478bd9Sstevel@tonic-gate if (++i > argc - 2) 105156a424ccSmp153739 return -1; 10527c478bd9Sstevel@tonic-gate else { 105356a424ccSmp153739 date = get_date(argv[i]); 10547c478bd9Sstevel@tonic-gate if (date == (time_t)-1) { 10557c478bd9Sstevel@tonic-gate fprintf(stderr, 10567c478bd9Sstevel@tonic-gate gettext("Invalid date " 10577c478bd9Sstevel@tonic-gate "specification " 10587c478bd9Sstevel@tonic-gate "\"%s\".\n"), 10597c478bd9Sstevel@tonic-gate argv[i]); 106056a424ccSmp153739 return -1; 10617c478bd9Sstevel@tonic-gate } 10627c478bd9Sstevel@tonic-gate oprinc->max_renewable_life = date - now; 10637c478bd9Sstevel@tonic-gate *mask |= KADM5_MAX_RLIFE; 10647c478bd9Sstevel@tonic-gate continue; 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate } 10677c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 5 && 106856a424ccSmp153739 !strcmp("-kvno", argv[i])) { 10697c478bd9Sstevel@tonic-gate if (++i > argc - 2) 107056a424ccSmp153739 return -1; 10717c478bd9Sstevel@tonic-gate else { 10727c478bd9Sstevel@tonic-gate oprinc->kvno = atoi(argv[i]); 10737c478bd9Sstevel@tonic-gate *mask |= KADM5_KVNO; 10747c478bd9Sstevel@tonic-gate continue; 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 7 && 107856a424ccSmp153739 !strcmp("-policy", argv[i])) { 10797c478bd9Sstevel@tonic-gate if (++i > argc - 2) 108056a424ccSmp153739 return -1; 10817c478bd9Sstevel@tonic-gate else { 10827c478bd9Sstevel@tonic-gate oprinc->policy = argv[i]; 10837c478bd9Sstevel@tonic-gate *mask |= KADM5_POLICY; 10847c478bd9Sstevel@tonic-gate continue; 10857c478bd9Sstevel@tonic-gate } 10867c478bd9Sstevel@tonic-gate } 10877c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 12 && 108856a424ccSmp153739 !strcmp("-clearpolicy", argv[i])) { 10897c478bd9Sstevel@tonic-gate oprinc->policy = NULL; 10907c478bd9Sstevel@tonic-gate *mask |= KADM5_POLICY_CLR; 10917c478bd9Sstevel@tonic-gate continue; 10927c478bd9Sstevel@tonic-gate } 10937c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 3 && 109456a424ccSmp153739 !strcmp("-pw", argv[i])) { 10957c478bd9Sstevel@tonic-gate if (++i > argc - 2) 109656a424ccSmp153739 return -1; 10977c478bd9Sstevel@tonic-gate else { 10987c478bd9Sstevel@tonic-gate *pass = argv[i]; 10997c478bd9Sstevel@tonic-gate continue; 11007c478bd9Sstevel@tonic-gate } 11017c478bd9Sstevel@tonic-gate } 11027c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 8 && 110356a424ccSmp153739 !strcmp("-randkey", argv[i])) { 11047c478bd9Sstevel@tonic-gate ++*randkey; 11057c478bd9Sstevel@tonic-gate continue; 11067c478bd9Sstevel@tonic-gate } 11077c478bd9Sstevel@tonic-gate if (!strcmp("-e", argv[i])) { 11087c478bd9Sstevel@tonic-gate if (++i > argc - 2) 11097c478bd9Sstevel@tonic-gate return -1; 11107c478bd9Sstevel@tonic-gate else { 11117c478bd9Sstevel@tonic-gate retval = krb5_string_to_keysalts(argv[i], ", \t", ":.-", 0, 11127c478bd9Sstevel@tonic-gate ks_tuple, n_ks_tuple); 11137c478bd9Sstevel@tonic-gate if (retval) { 11147c478bd9Sstevel@tonic-gate com_err(caller, retval, 11157c478bd9Sstevel@tonic-gate gettext("while parsing keysalts %s"), argv[i]); 11167c478bd9Sstevel@tonic-gate return -1; 11177c478bd9Sstevel@tonic-gate } 11187c478bd9Sstevel@tonic-gate } 11197c478bd9Sstevel@tonic-gate continue; 11207c478bd9Sstevel@tonic-gate } 11217c478bd9Sstevel@tonic-gate for (j = 0; j < sizeof (flags) / sizeof (struct pflag); j++) { 11227c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == flags[j].flaglen + 1 && 112356a424ccSmp153739 !strcmp(flags[j].flagname, 112456a424ccSmp153739 &argv[i][1] /* strip off leading + or - */)) { 112556a424ccSmp153739 if ((flags[j].set && argv[i][0] == '-') || 112656a424ccSmp153739 (!flags[j].set && argv[i][0] == '+')) { 11277c478bd9Sstevel@tonic-gate oprinc->attributes |= flags[j].theflag; 11287c478bd9Sstevel@tonic-gate *mask |= KADM5_ATTRIBUTES; 11297c478bd9Sstevel@tonic-gate attrib_set++; 11307c478bd9Sstevel@tonic-gate break; 113156a424ccSmp153739 } else if ((flags[j].set && argv[i][0] == '+') || 113256a424ccSmp153739 (!flags[j].set && argv[i][0] == '-')) { 11337c478bd9Sstevel@tonic-gate oprinc->attributes &= ~flags[j].theflag; 11347c478bd9Sstevel@tonic-gate *mask |= KADM5_ATTRIBUTES; 11357c478bd9Sstevel@tonic-gate attrib_set++; 11367c478bd9Sstevel@tonic-gate break; 11377c478bd9Sstevel@tonic-gate } else { 113856a424ccSmp153739 return -1; 11397c478bd9Sstevel@tonic-gate } 11407c478bd9Sstevel@tonic-gate } 11417c478bd9Sstevel@tonic-gate } 11427c478bd9Sstevel@tonic-gate if (!attrib_set) 114356a424ccSmp153739 return -1; /* nothing was parsed */ 11447c478bd9Sstevel@tonic-gate } 11457c478bd9Sstevel@tonic-gate if (i != argc - 1) { 114656a424ccSmp153739 return -1; 11477c478bd9Sstevel@tonic-gate } 11487c478bd9Sstevel@tonic-gate retval = kadmin_parse_name(argv[i], &oprinc->principal); 11497c478bd9Sstevel@tonic-gate if (retval) { 11507c478bd9Sstevel@tonic-gate com_err(caller, retval, gettext("while parsing principal")); 115156a424ccSmp153739 return -1; 11527c478bd9Sstevel@tonic-gate } 115356a424ccSmp153739 return 0; 11547c478bd9Sstevel@tonic-gate } 11557c478bd9Sstevel@tonic-gate 115656a424ccSmp153739 static void 11577c478bd9Sstevel@tonic-gate kadmin_addprinc_usage(func) 11587c478bd9Sstevel@tonic-gate char *func; 11597c478bd9Sstevel@tonic-gate { 11607c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s %s\n", gettext("usage"), func, 11617c478bd9Sstevel@tonic-gate gettext("[options] principal")); 11627c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("\toptions are:\n")); 11637c478bd9Sstevel@tonic-gate fprintf(stderr, "\t\t[-expire expdate] [-pwexpire pwexpdate] " 11647c478bd9Sstevel@tonic-gate "[-maxlife maxtixlife]\n\t\t[-kvno kvno] [-policy policy] " 11657c478bd9Sstevel@tonic-gate "[-randkey] [-pw password]\n\t\t[-maxrenewlife maxrenewlife] " 11667c478bd9Sstevel@tonic-gate "[-e keysaltlist] [{+|-}attribute]\n"); 11677c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("\tattributes are:\n")); 11687c478bd9Sstevel@tonic-gate fprintf(stderr, "%s%s%s", 11697c478bd9Sstevel@tonic-gate "\t\tallow_postdated allow_forwardable allow_tgs_req " 11707c478bd9Sstevel@tonic-gate "allow_renewable\n", 11717c478bd9Sstevel@tonic-gate "\t\tallow_proxiable allow_dup_skey allow_tix " 11727c478bd9Sstevel@tonic-gate "requires_preauth\n", 11737c478bd9Sstevel@tonic-gate "\t\trequires_hwauth needchange allow_svr " 11747c478bd9Sstevel@tonic-gate "password_changing_service\n"); 11757c478bd9Sstevel@tonic-gate } 11767c478bd9Sstevel@tonic-gate 117756a424ccSmp153739 static void 11787c478bd9Sstevel@tonic-gate kadmin_modprinc_usage(func) 11797c478bd9Sstevel@tonic-gate char *func; 11807c478bd9Sstevel@tonic-gate { 11817c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s %s\n", gettext("usage"), func, 11827c478bd9Sstevel@tonic-gate gettext("[options] principal")); 11837c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("\toptions are:\n")); 11847c478bd9Sstevel@tonic-gate fprintf(stderr, "\t\t[-expire expdate] [-pwexpire pwexpdate] " 11857c478bd9Sstevel@tonic-gate "[-maxlife maxtixlife]\n\t\t[-kvno kvno] [-policy policy] " 11867c478bd9Sstevel@tonic-gate "[-clearpolicy]\n\t\t[-maxrenewlife maxrenewlife] " 11877c478bd9Sstevel@tonic-gate "[{+|-}attribute]\n"); 11887c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("\tattributes are:\n")); 11897c478bd9Sstevel@tonic-gate fprintf(stderr, "%s%s%s", 11907c478bd9Sstevel@tonic-gate "\t\tallow_postdated allow_forwardable allow_tgs_req " 11917c478bd9Sstevel@tonic-gate "allow_renewable\n", 11927c478bd9Sstevel@tonic-gate "\t\tallow_proxiable allow_dup_skey allow_tix " 11937c478bd9Sstevel@tonic-gate "requires_preauth\n", 11947c478bd9Sstevel@tonic-gate "\t\trequires_hwauth needchange allow_svr " 11957c478bd9Sstevel@tonic-gate "password_changing_service\n"); 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate 119856a424ccSmp153739 void kadmin_addprinc(argc, argv) 11997c478bd9Sstevel@tonic-gate int argc; 12007c478bd9Sstevel@tonic-gate char *argv[]; 12017c478bd9Sstevel@tonic-gate { 12027c478bd9Sstevel@tonic-gate kadm5_principal_ent_rec princ, dprinc; 12037c478bd9Sstevel@tonic-gate kadm5_policy_ent_rec defpol; 12047c478bd9Sstevel@tonic-gate long mask; 12057c478bd9Sstevel@tonic-gate int randkey = 0, i; 12067c478bd9Sstevel@tonic-gate int n_ks_tuple; 12077c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *ks_tuple; 12087c478bd9Sstevel@tonic-gate char *pass, *canon; 12097c478bd9Sstevel@tonic-gate krb5_error_code retval; 12107c478bd9Sstevel@tonic-gate static char newpw[1024], dummybuf[256]; 12117c478bd9Sstevel@tonic-gate static char prompt1[1024], prompt2[1024]; 12127c478bd9Sstevel@tonic-gate int local_kadmin = 0; 12137c478bd9Sstevel@tonic-gate 12147c478bd9Sstevel@tonic-gate local_kadmin = (strcmp(whoami, KADMIN_LOCAL_NAME) == 0); 12157c478bd9Sstevel@tonic-gate 12167c478bd9Sstevel@tonic-gate if (dummybuf[0] == 0) { 12177c478bd9Sstevel@tonic-gate for (i = 0; i < 256; i++) 12187c478bd9Sstevel@tonic-gate dummybuf[i] = (i+1) % 256; 12197c478bd9Sstevel@tonic-gate } 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate /* Zero all fields in request structure */ 12227c478bd9Sstevel@tonic-gate memset(&princ, 0, sizeof(princ)); 12237c478bd9Sstevel@tonic-gate memset(&dprinc, 0, sizeof(dprinc)); 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate princ.attributes = dprinc.attributes = 0; 12267c478bd9Sstevel@tonic-gate if (kadmin_parse_princ_args(argc, argv, 12277c478bd9Sstevel@tonic-gate &princ, &mask, &pass, &randkey, 12287c478bd9Sstevel@tonic-gate &ks_tuple, &n_ks_tuple, 12297c478bd9Sstevel@tonic-gate "add_principal")) { 12307c478bd9Sstevel@tonic-gate kadmin_addprinc_usage("add_principal"); 123154925bf6Swillf kadmin_free_tl_data(&princ); /* need to free ks_tuple also??? */ 12327c478bd9Sstevel@tonic-gate return; 12337c478bd9Sstevel@tonic-gate } 12347c478bd9Sstevel@tonic-gate 12357c478bd9Sstevel@tonic-gate retval = krb5_unparse_name(context, princ.principal, &canon); 12367c478bd9Sstevel@tonic-gate if (retval) { 123754925bf6Swillf com_err("add_principal", 123854925bf6Swillf retval, gettext("while canonicalizing principal")); 12397c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 12407c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 12417c478bd9Sstevel@tonic-gate free(ks_tuple); 124254925bf6Swillf kadmin_free_tl_data(&princ); 12437c478bd9Sstevel@tonic-gate return; 12447c478bd9Sstevel@tonic-gate } 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate /* 12477c478bd9Sstevel@tonic-gate * If -policy was not specified, and -clearpolicy was not 12487c478bd9Sstevel@tonic-gate * specified, and the policy "default" exists, assign it. If 12497c478bd9Sstevel@tonic-gate * -clearpolicy was specified, then KADM5_POLICY_CLR should be 12507c478bd9Sstevel@tonic-gate * unset, since it is never valid for kadm5_create_principal. 12517c478bd9Sstevel@tonic-gate */ 12527c478bd9Sstevel@tonic-gate if ((! (mask & KADM5_POLICY)) && 12537c478bd9Sstevel@tonic-gate (! (mask & KADM5_POLICY_CLR))) { 12547c478bd9Sstevel@tonic-gate if (! kadm5_get_policy(handle, "default", &defpol)) { 12557c478bd9Sstevel@tonic-gate fprintf(stderr, 125654925bf6Swillf gettext("NOTICE: no policy specified for %s; assigning \"default\"\n"), 12577c478bd9Sstevel@tonic-gate canon); 12587c478bd9Sstevel@tonic-gate princ.policy = "default"; 12597c478bd9Sstevel@tonic-gate mask |= KADM5_POLICY; 12607c478bd9Sstevel@tonic-gate (void) kadm5_free_policy_ent(handle, &defpol); 12617c478bd9Sstevel@tonic-gate } else 126254925bf6Swillf fprintf(stderr, 126354925bf6Swillf gettext("WARNING: no policy specified for %s; defaulting to no policy\n"), 126456a424ccSmp153739 canon); 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate mask &= ~KADM5_POLICY_CLR; 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate /* 12697c478bd9Sstevel@tonic-gate * Set 'notix' for randkey principals and also for principals which have 12707c478bd9Sstevel@tonic-gate * specified flag options on the cmdline. This is because we want to apply 12717c478bd9Sstevel@tonic-gate * generic flag settings from 'default_principal_flags' first (during 12727c478bd9Sstevel@tonic-gate * principal creation), followed by a kadm5_modify_principal() which 12737c478bd9Sstevel@tonic-gate * correctly applies the cli flag options. So, we do *not* want any tix 12747c478bd9Sstevel@tonic-gate * issued in the interim. 12757c478bd9Sstevel@tonic-gate */ 12767c478bd9Sstevel@tonic-gate if (randkey || (mask & KADM5_ATTRIBUTES)) 12777c478bd9Sstevel@tonic-gate princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate if (randkey) { 12807c478bd9Sstevel@tonic-gate mask |= KADM5_ATTRIBUTES; 128156a424ccSmp153739 pass = dummybuf; 12827c478bd9Sstevel@tonic-gate } else if (pass == NULL) { 128356a424ccSmp153739 unsigned int sz = sizeof (newpw) - 1; 12847c478bd9Sstevel@tonic-gate snprintf(prompt1, sizeof (prompt1), 1285e49962a0Ssemery gettext("Enter password for principal \"%.900s\""), 12867c478bd9Sstevel@tonic-gate canon); 12877c478bd9Sstevel@tonic-gate snprintf(prompt2, sizeof (prompt1), 1288e49962a0Ssemery gettext("Re-enter password for principal \"%.900s\""), 12897c478bd9Sstevel@tonic-gate canon); 12907c478bd9Sstevel@tonic-gate retval = krb5_read_password(context, prompt1, prompt2, 129156a424ccSmp153739 newpw, &sz); 12927c478bd9Sstevel@tonic-gate if (retval) { 12937c478bd9Sstevel@tonic-gate com_err("add_principal", retval, 12947c478bd9Sstevel@tonic-gate gettext("while reading password for \"%s\"."), canon); 12957c478bd9Sstevel@tonic-gate free(canon); 12967c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 129754925bf6Swillf kadmin_free_tl_data(&princ); 12987c478bd9Sstevel@tonic-gate return; 12997c478bd9Sstevel@tonic-gate } 13007c478bd9Sstevel@tonic-gate pass = newpw; 13017c478bd9Sstevel@tonic-gate } 13027c478bd9Sstevel@tonic-gate mask |= KADM5_PRINCIPAL; 13037c478bd9Sstevel@tonic-gate 13047c478bd9Sstevel@tonic-gate /* 13057c478bd9Sstevel@tonic-gate * If the client being used is local, always use the new 13067c478bd9Sstevel@tonic-gate * API so we get the full set of enctype support. 13077c478bd9Sstevel@tonic-gate */ 13087c478bd9Sstevel@tonic-gate if (ks_tuple != NULL || local_kadmin) { 13097c478bd9Sstevel@tonic-gate retval = kadm5_create_principal_3(handle, &princ, mask, 13107c478bd9Sstevel@tonic-gate n_ks_tuple, ks_tuple, pass); 13117c478bd9Sstevel@tonic-gate } else { 13127c478bd9Sstevel@tonic-gate retval = kadm5_create_principal(handle, &princ, mask, pass); 13137c478bd9Sstevel@tonic-gate } 13147c478bd9Sstevel@tonic-gate if (retval) { 13157c478bd9Sstevel@tonic-gate com_err("add_principal", retval, 13167c478bd9Sstevel@tonic-gate gettext("while creating \"%s\"."), canon); 13177c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 13187c478bd9Sstevel@tonic-gate free(canon); 13197c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 13207c478bd9Sstevel@tonic-gate free(ks_tuple); 132154925bf6Swillf kadmin_free_tl_data(&princ); 13227c478bd9Sstevel@tonic-gate return; 13237c478bd9Sstevel@tonic-gate } 13247c478bd9Sstevel@tonic-gate if (randkey) { /* more special stuff for -randkey */ 13257c478bd9Sstevel@tonic-gate if (ks_tuple != NULL || local_kadmin) { 13267c478bd9Sstevel@tonic-gate retval = kadm5_randkey_principal_3(handle, princ.principal, 13277c478bd9Sstevel@tonic-gate FALSE, 13287c478bd9Sstevel@tonic-gate n_ks_tuple, ks_tuple, 13297c478bd9Sstevel@tonic-gate NULL, NULL); 13307c478bd9Sstevel@tonic-gate } else { 13317c478bd9Sstevel@tonic-gate retval = kadm5_randkey_principal(handle, princ.principal, 13327c478bd9Sstevel@tonic-gate NULL, NULL); 13337c478bd9Sstevel@tonic-gate } 13347c478bd9Sstevel@tonic-gate if (retval) { 13357c478bd9Sstevel@tonic-gate com_err("add_principal", retval, 13367c478bd9Sstevel@tonic-gate gettext("while randomizing key for \"%s\"."), canon); 13377c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 13387c478bd9Sstevel@tonic-gate free(canon); 13397c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 13407c478bd9Sstevel@tonic-gate free(ks_tuple); 134154925bf6Swillf kadmin_free_tl_data(&princ); 13427c478bd9Sstevel@tonic-gate return; 13437c478bd9Sstevel@tonic-gate } 13447c478bd9Sstevel@tonic-gate } 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate /* 13477c478bd9Sstevel@tonic-gate * We now retrieve the intersection set of the generic flag settings and 13487c478bd9Sstevel@tonic-gate * the ones specified on the cli & re-parse the princ args, just to make 13497c478bd9Sstevel@tonic-gate * sure we account for conflicts between 'default_principal_flags' and 13507c478bd9Sstevel@tonic-gate * the cmdline flag args. While we are here, also clear 'notix'. 13517c478bd9Sstevel@tonic-gate */ 13527c478bd9Sstevel@tonic-gate if (randkey || (mask & KADM5_ATTRIBUTES)) { 13537c478bd9Sstevel@tonic-gate retval = kadm5_get_principal(handle, princ.principal, &dprinc, 13547c478bd9Sstevel@tonic-gate KADM5_PRINCIPAL_NORMAL_MASK); 13557c478bd9Sstevel@tonic-gate if (retval == 0) { 13567c478bd9Sstevel@tonic-gate if (dprinc.attributes != 0) 13577c478bd9Sstevel@tonic-gate princ.attributes = dprinc.attributes; 13587c478bd9Sstevel@tonic-gate } else { 13597c478bd9Sstevel@tonic-gate com_err("add_principal", retval, 13607c478bd9Sstevel@tonic-gate gettext("while doing a get_principal on \"%s\"."), canon); 13617c478bd9Sstevel@tonic-gate printf(gettext("\nWarning: Principal \"%s\" could have incomplete " 13627c478bd9Sstevel@tonic-gate "flag settings, as a result of a failed get_principal.\n" 13637c478bd9Sstevel@tonic-gate "Check the 'default_principal_flags' setting in kdc.conf(4).\n" 13647c478bd9Sstevel@tonic-gate "If there is a mismatch, use modprinc in kadmin(1M) to rectify " 13657c478bd9Sstevel@tonic-gate "the same.\n\n"), canon); 13667c478bd9Sstevel@tonic-gate } 13677c478bd9Sstevel@tonic-gate 13681fceb383Ssemery /* 13691fceb383Ssemery * Solaris Kerberos: We unset KRB5_KDB_DISALLOW_ALL_TIX before 13701fceb383Ssemery * kadmin_parse_princ_args is called, because -allow_tix may 13711fceb383Ssemery * have been an argument. We still have to unset here because 13721fceb383Ssemery * kadmin_parse_princ_args will not reset the attribute unless 13731fceb383Ssemery * it is was explicity defined. 13741fceb383Ssemery */ 13751fceb383Ssemery princ.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX; 13767c478bd9Sstevel@tonic-gate (void) kadmin_parse_princ_args(argc, argv, &princ, &mask, &pass, 13777c478bd9Sstevel@tonic-gate &randkey, &ks_tuple, &n_ks_tuple, "add_principal"); 13787c478bd9Sstevel@tonic-gate mask = KADM5_ATTRIBUTES; 13797c478bd9Sstevel@tonic-gate retval = kadm5_modify_principal(handle, &princ, mask); 13807c478bd9Sstevel@tonic-gate if (retval) { 13817c478bd9Sstevel@tonic-gate com_err("add_principal", retval, 13827c478bd9Sstevel@tonic-gate gettext("while doing a modify_principal to restore flag " 13837c478bd9Sstevel@tonic-gate "settings for \"%s\"."), canon); 13847c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 13857c478bd9Sstevel@tonic-gate free(canon); 13867c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 13877c478bd9Sstevel@tonic-gate free(ks_tuple); 138854925bf6Swillf kadmin_free_tl_data(&princ); 13897c478bd9Sstevel@tonic-gate return; 13907c478bd9Sstevel@tonic-gate } 13917c478bd9Sstevel@tonic-gate } 13927c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 13937c478bd9Sstevel@tonic-gate printf(gettext("Principal \"%s\" created.\n"), canon); 13947c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) 13957c478bd9Sstevel@tonic-gate free(ks_tuple); 13967c478bd9Sstevel@tonic-gate free(canon); 139754925bf6Swillf kadmin_free_tl_data(&princ); 139854925bf6Swillf 13997c478bd9Sstevel@tonic-gate } 14007c478bd9Sstevel@tonic-gate 140156a424ccSmp153739 void kadmin_modprinc(argc, argv) 14027c478bd9Sstevel@tonic-gate int argc; 14037c478bd9Sstevel@tonic-gate char *argv[]; 14047c478bd9Sstevel@tonic-gate { 14057c478bd9Sstevel@tonic-gate kadm5_principal_ent_rec princ, oldprinc; 14067c478bd9Sstevel@tonic-gate krb5_principal kprinc; 14077c478bd9Sstevel@tonic-gate long mask; 14087c478bd9Sstevel@tonic-gate krb5_error_code retval; 14097c478bd9Sstevel@tonic-gate char *pass, *canon; 14107c478bd9Sstevel@tonic-gate int randkey = 0; 14117c478bd9Sstevel@tonic-gate int n_ks_tuple = 0; 14127c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *ks_tuple; 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate if (argc < 2) { 14157c478bd9Sstevel@tonic-gate kadmin_modprinc_usage("modify_principal"); 14167c478bd9Sstevel@tonic-gate return; 14177c478bd9Sstevel@tonic-gate } 14187c478bd9Sstevel@tonic-gate 14197c478bd9Sstevel@tonic-gate memset(&oldprinc, 0, sizeof(oldprinc)); 14207c478bd9Sstevel@tonic-gate memset(&princ, 0, sizeof(princ)); 14217c478bd9Sstevel@tonic-gate 14227c478bd9Sstevel@tonic-gate retval = kadmin_parse_name(argv[argc - 1], &kprinc); 14237c478bd9Sstevel@tonic-gate if (retval) { 14247c478bd9Sstevel@tonic-gate com_err("modify_principal", retval, 14257c478bd9Sstevel@tonic-gate gettext("while parsing principal")); 14267c478bd9Sstevel@tonic-gate return; 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate retval = krb5_unparse_name(context, kprinc, &canon); 14297c478bd9Sstevel@tonic-gate if (retval) { 14307c478bd9Sstevel@tonic-gate com_err("modify_principal", retval, 14317c478bd9Sstevel@tonic-gate gettext("while canonicalizing principal")); 14327c478bd9Sstevel@tonic-gate krb5_free_principal(context, kprinc); 14337c478bd9Sstevel@tonic-gate return; 14347c478bd9Sstevel@tonic-gate } 14357c478bd9Sstevel@tonic-gate retval = kadm5_get_principal(handle, kprinc, &oldprinc, 14367c478bd9Sstevel@tonic-gate KADM5_PRINCIPAL_NORMAL_MASK); 14377c478bd9Sstevel@tonic-gate krb5_free_principal(context, kprinc); 14387c478bd9Sstevel@tonic-gate if (retval) { 14397c478bd9Sstevel@tonic-gate com_err("modify_principal", retval, 14407c478bd9Sstevel@tonic-gate gettext("while getting \"%s\"."), canon); 14417c478bd9Sstevel@tonic-gate free(canon); 14427c478bd9Sstevel@tonic-gate return; 14437c478bd9Sstevel@tonic-gate } 14447c478bd9Sstevel@tonic-gate princ.attributes = oldprinc.attributes; 14457c478bd9Sstevel@tonic-gate kadm5_free_principal_ent(handle, &oldprinc); 14467c478bd9Sstevel@tonic-gate retval = kadmin_parse_princ_args(argc, argv, 14477c478bd9Sstevel@tonic-gate &princ, &mask, 14487c478bd9Sstevel@tonic-gate &pass, &randkey, 14497c478bd9Sstevel@tonic-gate &ks_tuple, &n_ks_tuple, 14507c478bd9Sstevel@tonic-gate "modify_principal"); 14517c478bd9Sstevel@tonic-gate if (ks_tuple != NULL) { 14527c478bd9Sstevel@tonic-gate free(ks_tuple); 14537c478bd9Sstevel@tonic-gate kadmin_modprinc_usage("modify_principal"); 14547c478bd9Sstevel@tonic-gate free(canon); 145554925bf6Swillf kadmin_free_tl_data(&princ); 14567c478bd9Sstevel@tonic-gate return; 14577c478bd9Sstevel@tonic-gate } 14587c478bd9Sstevel@tonic-gate if (retval) { 14597c478bd9Sstevel@tonic-gate kadmin_modprinc_usage("modify_principal"); 14607c478bd9Sstevel@tonic-gate free(canon); 146154925bf6Swillf kadmin_free_tl_data(&princ); 14627c478bd9Sstevel@tonic-gate return; 14637c478bd9Sstevel@tonic-gate } 14647c478bd9Sstevel@tonic-gate if (randkey) { 14657c478bd9Sstevel@tonic-gate fprintf(stderr, "modify_principal: -randkey %s ", 14667c478bd9Sstevel@tonic-gate gettext("not allowed\n")); 14677c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 14687c478bd9Sstevel@tonic-gate free(canon); 146954925bf6Swillf kadmin_free_tl_data(&princ); 14707c478bd9Sstevel@tonic-gate return; 14717c478bd9Sstevel@tonic-gate } 14727c478bd9Sstevel@tonic-gate if (pass) { 14737c478bd9Sstevel@tonic-gate fprintf(stderr, 14747c478bd9Sstevel@tonic-gate "modify_principal: -pw %s change_password\n", 14757c478bd9Sstevel@tonic-gate gettext("not allowed; use")); 14767c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 14777c478bd9Sstevel@tonic-gate free(canon); 147854925bf6Swillf kadmin_free_tl_data(&princ); 14797c478bd9Sstevel@tonic-gate return; 14807c478bd9Sstevel@tonic-gate } 14817c478bd9Sstevel@tonic-gate retval = kadm5_modify_principal(handle, &princ, mask); 14827c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ.principal); 14837c478bd9Sstevel@tonic-gate if (retval) { 14847c478bd9Sstevel@tonic-gate com_err("modify_principal", retval, 14857c478bd9Sstevel@tonic-gate gettext("while modifying \"%s\"."), canon); 14867c478bd9Sstevel@tonic-gate free(canon); 148754925bf6Swillf kadmin_free_tl_data(&princ); 14887c478bd9Sstevel@tonic-gate return; 14897c478bd9Sstevel@tonic-gate } 14907c478bd9Sstevel@tonic-gate printf(gettext("Principal \"%s\" modified.\n"), canon); 149154925bf6Swillf kadmin_free_tl_data(&princ); 14927c478bd9Sstevel@tonic-gate free(canon); 14937c478bd9Sstevel@tonic-gate } 14947c478bd9Sstevel@tonic-gate 149556a424ccSmp153739 void kadmin_getprinc(argc, argv) 14967c478bd9Sstevel@tonic-gate int argc; 14977c478bd9Sstevel@tonic-gate char *argv[]; 14987c478bd9Sstevel@tonic-gate { 14997c478bd9Sstevel@tonic-gate kadm5_principal_ent_rec dprinc; 15007c478bd9Sstevel@tonic-gate krb5_principal princ; 15017c478bd9Sstevel@tonic-gate krb5_error_code retval; 15027c478bd9Sstevel@tonic-gate char *canon, *modcanon; 15037c478bd9Sstevel@tonic-gate int i; 15047c478bd9Sstevel@tonic-gate 15057c478bd9Sstevel@tonic-gate if (! (argc == 2 || 150656a424ccSmp153739 (argc == 3 && !strcmp("-terse", argv[1])))) { 15077c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: get_principal [-terse] %s\n", 15087c478bd9Sstevel@tonic-gate gettext("usage"), gettext("principal")); 15097c478bd9Sstevel@tonic-gate return; 15107c478bd9Sstevel@tonic-gate } 151156a424ccSmp153739 151256a424ccSmp153739 15137c478bd9Sstevel@tonic-gate memset(&dprinc, 0, sizeof(dprinc)); 15147c478bd9Sstevel@tonic-gate memset(&princ, 0, sizeof(princ)); 15157c478bd9Sstevel@tonic-gate 15167c478bd9Sstevel@tonic-gate retval = kadmin_parse_name(argv[argc - 1], &princ); 15177c478bd9Sstevel@tonic-gate if (retval) { 15187c478bd9Sstevel@tonic-gate com_err("get_principal", retval, 15197c478bd9Sstevel@tonic-gate gettext("while parsing principal")); 15207c478bd9Sstevel@tonic-gate return; 15217c478bd9Sstevel@tonic-gate } 15227c478bd9Sstevel@tonic-gate retval = krb5_unparse_name(context, princ, &canon); 15237c478bd9Sstevel@tonic-gate if (retval) { 15247c478bd9Sstevel@tonic-gate com_err("get_principal", retval, 15257c478bd9Sstevel@tonic-gate gettext("while canonicalizing principal")); 15267c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 15277c478bd9Sstevel@tonic-gate return; 15287c478bd9Sstevel@tonic-gate } 15297c478bd9Sstevel@tonic-gate retval = kadm5_get_principal(handle, princ, &dprinc, 15307c478bd9Sstevel@tonic-gate KADM5_PRINCIPAL_NORMAL_MASK | KADM5_KEY_DATA); 15317c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 15327c478bd9Sstevel@tonic-gate if (retval) { 15337c478bd9Sstevel@tonic-gate com_err("get_principal", retval, 15347c478bd9Sstevel@tonic-gate gettext("while retrieving \"%s\"."), canon); 15357c478bd9Sstevel@tonic-gate free(canon); 15367c478bd9Sstevel@tonic-gate return; 15377c478bd9Sstevel@tonic-gate } 15387c478bd9Sstevel@tonic-gate retval = krb5_unparse_name(context, dprinc.mod_name, &modcanon); 15397c478bd9Sstevel@tonic-gate if (retval) { 15407c478bd9Sstevel@tonic-gate com_err("get_principal", retval, 15417c478bd9Sstevel@tonic-gate gettext("while unparsing modname")); 15427c478bd9Sstevel@tonic-gate kadm5_free_principal_ent(handle, &dprinc); 15437c478bd9Sstevel@tonic-gate free(canon); 15447c478bd9Sstevel@tonic-gate return; 15457c478bd9Sstevel@tonic-gate } 15467c478bd9Sstevel@tonic-gate if (argc == 2) { 15477c478bd9Sstevel@tonic-gate printf(gettext("Principal: %s\n"), canon); 15487c478bd9Sstevel@tonic-gate printf(gettext("Expiration date: %s\n"), 15497c478bd9Sstevel@tonic-gate dprinc.princ_expire_time ? 15507c478bd9Sstevel@tonic-gate strdate(dprinc.princ_expire_time) : 15517c478bd9Sstevel@tonic-gate gettext("[never]")); 15527c478bd9Sstevel@tonic-gate printf(gettext("Last password change: %s\n"), 15537c478bd9Sstevel@tonic-gate dprinc.last_pwd_change ? 15547c478bd9Sstevel@tonic-gate strdate(dprinc.last_pwd_change) : 15557c478bd9Sstevel@tonic-gate gettext("[never]")); 15567c478bd9Sstevel@tonic-gate printf(gettext("Password expiration date: %s\n"), 15577c478bd9Sstevel@tonic-gate dprinc.pw_expiration ? 15587c478bd9Sstevel@tonic-gate strdate(dprinc.pw_expiration) : gettext("[none]")); 15597c478bd9Sstevel@tonic-gate printf(gettext("Maximum ticket life: %s\n"), 15607c478bd9Sstevel@tonic-gate strdur(dprinc.max_life)); 15617c478bd9Sstevel@tonic-gate printf(gettext("Maximum renewable life: %s\n"), 15627c478bd9Sstevel@tonic-gate strdur(dprinc.max_renewable_life)); 15637c478bd9Sstevel@tonic-gate printf(gettext("Last modified: %s (%s)\n"), 15647c478bd9Sstevel@tonic-gate strdate(dprinc.mod_date), modcanon); 15657c478bd9Sstevel@tonic-gate printf(gettext("Last successful authentication: %s\n"), 15667c478bd9Sstevel@tonic-gate dprinc.last_success ? strdate(dprinc.last_success) : 15677c478bd9Sstevel@tonic-gate gettext("[never]")); 15687c478bd9Sstevel@tonic-gate printf(gettext("Last failed authentication: %s\n"), 15697c478bd9Sstevel@tonic-gate dprinc.last_failed ? strdate(dprinc.last_failed) : 15707c478bd9Sstevel@tonic-gate gettext("[never]")); 15717c478bd9Sstevel@tonic-gate printf(gettext("Failed password attempts: %d\n"), 15727c478bd9Sstevel@tonic-gate dprinc.fail_auth_count); 15737c478bd9Sstevel@tonic-gate printf(gettext("Number of keys: %d\n"), dprinc.n_key_data); 15747c478bd9Sstevel@tonic-gate for (i = 0; i < dprinc.n_key_data; i++) { 15757c478bd9Sstevel@tonic-gate krb5_key_data *key_data = &dprinc.key_data[i]; 15767c478bd9Sstevel@tonic-gate char enctype[BUFSIZ], salttype[BUFSIZ]; 15777c478bd9Sstevel@tonic-gate 15787c478bd9Sstevel@tonic-gate if (krb5_enctype_to_string(key_data->key_data_type[0], 15797c478bd9Sstevel@tonic-gate enctype, sizeof(enctype))) 158054925bf6Swillf snprintf(enctype, sizeof (enctype), gettext("<Encryption type 0x%x>"), 15817c478bd9Sstevel@tonic-gate key_data->key_data_type[0]); 158254925bf6Swillf printf("Key: vno %d, %s, ", key_data->key_data_kvno, enctype); 15837c478bd9Sstevel@tonic-gate if (key_data->key_data_ver > 1) { 158454925bf6Swillf if (krb5_salttype_to_string(key_data->key_data_type[1], 15857c478bd9Sstevel@tonic-gate salttype, sizeof(salttype))) 158654925bf6Swillf snprintf(salttype, sizeof(salttype), gettext("<Salt type 0x%x>"), 15877c478bd9Sstevel@tonic-gate key_data->key_data_type[1]); 15887c478bd9Sstevel@tonic-gate printf("%s\n", salttype); 15897c478bd9Sstevel@tonic-gate } else 15907c478bd9Sstevel@tonic-gate printf(gettext("no salt\n")); 15917c478bd9Sstevel@tonic-gate } 15927c478bd9Sstevel@tonic-gate 15937c478bd9Sstevel@tonic-gate printf(gettext("Attributes:")); 15947c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (prflags) / sizeof (char *); i++) { 15957c478bd9Sstevel@tonic-gate if (dprinc.attributes & (krb5_flags) 1 << i) 15967c478bd9Sstevel@tonic-gate printf(" %s", prflags[i]); 15977c478bd9Sstevel@tonic-gate } 15987c478bd9Sstevel@tonic-gate printf("\n"); 15997c478bd9Sstevel@tonic-gate printf(gettext("Policy: %s\n"), 16007c478bd9Sstevel@tonic-gate dprinc.policy ? dprinc.policy : gettext("[none]")); 16017c478bd9Sstevel@tonic-gate } else { 16027c478bd9Sstevel@tonic-gate printf("\"%s\"\t%d\t%d\t%d\t%d\t\"%s\"\t%d\t%d\t%d\t%d\t\"%s\"" 16037c478bd9Sstevel@tonic-gate "\t%d\t%d\t%d\t%d\t%d", 16047c478bd9Sstevel@tonic-gate canon, dprinc.princ_expire_time, dprinc.last_pwd_change, 16057c478bd9Sstevel@tonic-gate dprinc.pw_expiration, dprinc.max_life, modcanon, 16067c478bd9Sstevel@tonic-gate dprinc.mod_date, dprinc.attributes, dprinc.kvno, 160754925bf6Swillf dprinc.mkvno, dprinc.policy ? dprinc.policy : gettext("[none]"), 16087c478bd9Sstevel@tonic-gate dprinc.max_renewable_life, dprinc.last_success, 16097c478bd9Sstevel@tonic-gate dprinc.last_failed, dprinc.fail_auth_count, 16107c478bd9Sstevel@tonic-gate dprinc.n_key_data); 16117c478bd9Sstevel@tonic-gate for (i = 0; i < dprinc.n_key_data; i++) 16127c478bd9Sstevel@tonic-gate printf("\t%d\t%d\t%d\t%d", 16137c478bd9Sstevel@tonic-gate dprinc.key_data[i].key_data_ver, 16147c478bd9Sstevel@tonic-gate dprinc.key_data[i].key_data_kvno, 16157c478bd9Sstevel@tonic-gate dprinc.key_data[i].key_data_type[0], 16167c478bd9Sstevel@tonic-gate dprinc.key_data[i].key_data_type[1]); 16177c478bd9Sstevel@tonic-gate printf("\n"); 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate free(modcanon); 16207c478bd9Sstevel@tonic-gate kadm5_free_principal_ent(handle, &dprinc); 16217c478bd9Sstevel@tonic-gate free(canon); 16227c478bd9Sstevel@tonic-gate } 16237c478bd9Sstevel@tonic-gate 162456a424ccSmp153739 void kadmin_getprincs(argc, argv) 16257c478bd9Sstevel@tonic-gate int argc; 16267c478bd9Sstevel@tonic-gate char *argv[]; 16277c478bd9Sstevel@tonic-gate { 16287c478bd9Sstevel@tonic-gate krb5_error_code retval; 162956a424ccSmp153739 char *expr, **names; 16307c478bd9Sstevel@tonic-gate int i, count; 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate FILE *output; 16337c478bd9Sstevel@tonic-gate int fd; 16347c478bd9Sstevel@tonic-gate struct sigaction nsig, osig; 16357c478bd9Sstevel@tonic-gate sigset_t nmask, omask; 16367c478bd9Sstevel@tonic-gate int waitb; 16377c478bd9Sstevel@tonic-gate 163856a424ccSmp153739 expr = NULL; 163956a424ccSmp153739 if (! (argc == 1 || (argc == 2 && (expr = argv[1])))) { 16407c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: get_principals %s\n", 16417c478bd9Sstevel@tonic-gate gettext("usage"), gettext("[expression]")); 16427c478bd9Sstevel@tonic-gate return; 16437c478bd9Sstevel@tonic-gate } 164456a424ccSmp153739 retval = kadm5_get_principals(handle, expr, &names, &count); 16457c478bd9Sstevel@tonic-gate if (retval) { 16467c478bd9Sstevel@tonic-gate com_err("get_principals", retval, 16477c478bd9Sstevel@tonic-gate gettext("while retrieving list.")); 16487c478bd9Sstevel@tonic-gate return; 16497c478bd9Sstevel@tonic-gate } 16507c478bd9Sstevel@tonic-gate 16517c478bd9Sstevel@tonic-gate /* 16527c478bd9Sstevel@tonic-gate * Solaris: the following code is used for paging 16537c478bd9Sstevel@tonic-gate */ 16547c478bd9Sstevel@tonic-gate 16557c478bd9Sstevel@tonic-gate sigemptyset(&nmask); 16567c478bd9Sstevel@tonic-gate sigaddset(&nmask, SIGINT); 16577c478bd9Sstevel@tonic-gate sigprocmask(SIG_BLOCK, &nmask, &omask); 16587c478bd9Sstevel@tonic-gate 16597c478bd9Sstevel@tonic-gate nsig.sa_handler = SIG_IGN; 16607c478bd9Sstevel@tonic-gate sigemptyset(&nsig.sa_mask); 16617c478bd9Sstevel@tonic-gate nsig.sa_flags = 0; 16627c478bd9Sstevel@tonic-gate sigaction(SIGINT, &nsig, &osig); 16637c478bd9Sstevel@tonic-gate 16647c478bd9Sstevel@tonic-gate fd = ss_pager_create(); 16657c478bd9Sstevel@tonic-gate output = fdopen(fd, "w"); 16667c478bd9Sstevel@tonic-gate 16677c478bd9Sstevel@tonic-gate sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); 16687c478bd9Sstevel@tonic-gate 16697c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) 16707c478bd9Sstevel@tonic-gate fprintf(output, "%s\n", names[i]); 16717c478bd9Sstevel@tonic-gate 16727c478bd9Sstevel@tonic-gate fclose(output); 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate wait(&waitb); 16757c478bd9Sstevel@tonic-gate 1676d51f1d33Smp153739 /* Solaris Kerberos: 1677d51f1d33Smp153739 * Restore the original handler for SIGINT 1678d51f1d33Smp153739 */ 1679d51f1d33Smp153739 if (sigaction(SIGINT, &osig, (struct sigaction *)0) == -1) { 1680d51f1d33Smp153739 perror("sigaction"); 1681d51f1d33Smp153739 } 1682d51f1d33Smp153739 16837c478bd9Sstevel@tonic-gate kadm5_free_name_list(handle, names, count); 16847c478bd9Sstevel@tonic-gate } 16857c478bd9Sstevel@tonic-gate 168656a424ccSmp153739 static int 16877c478bd9Sstevel@tonic-gate kadmin_parse_policy_args(argc, argv, policy, mask, caller) 16887c478bd9Sstevel@tonic-gate int argc; 16897c478bd9Sstevel@tonic-gate char *argv[]; 16907c478bd9Sstevel@tonic-gate kadm5_policy_ent_t policy; 16917c478bd9Sstevel@tonic-gate long *mask; 16927c478bd9Sstevel@tonic-gate char *caller; 16937c478bd9Sstevel@tonic-gate { 16947c478bd9Sstevel@tonic-gate int i; 16957c478bd9Sstevel@tonic-gate time_t now; 16967c478bd9Sstevel@tonic-gate time_t date; 16977c478bd9Sstevel@tonic-gate 16987c478bd9Sstevel@tonic-gate time(&now); 16997c478bd9Sstevel@tonic-gate *mask = 0; 17007c478bd9Sstevel@tonic-gate for (i = 1; i < argc - 1; i++) { 17017c478bd9Sstevel@tonic-gate if (strlen(argv[i]) == 8 && 170256a424ccSmp153739 !strcmp(argv[i], "-maxlife")) { 17037c478bd9Sstevel@tonic-gate if (++i > argc -2) 170456a424ccSmp153739 return -1; 17057c478bd9Sstevel@tonic-gate else { 170656a424ccSmp153739 date = get_date(argv[i]); 17077c478bd9Sstevel@tonic-gate if (date == (time_t)-1) { 170854925bf6Swillf fprintf(stderr, gettext("Invalid date specification \"%s\".\n"), 17097c478bd9Sstevel@tonic-gate argv[i]); 171056a424ccSmp153739 return -1; 17117c478bd9Sstevel@tonic-gate } 17127c478bd9Sstevel@tonic-gate policy->pw_max_life = date - now; 17137c478bd9Sstevel@tonic-gate *mask |= KADM5_PW_MAX_LIFE; 17147c478bd9Sstevel@tonic-gate continue; 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate } else if (strlen(argv[i]) == 8 && 171756a424ccSmp153739 !strcmp(argv[i], "-minlife")) { 17187c478bd9Sstevel@tonic-gate if (++i > argc - 2) 171956a424ccSmp153739 return -1; 17207c478bd9Sstevel@tonic-gate else { 172156a424ccSmp153739 date = get_date(argv[i]); 17227c478bd9Sstevel@tonic-gate if (date == (time_t)-1) { 172354925bf6Swillf fprintf(stderr, gettext("Invalid date specification \"%s\".\n"), 17247c478bd9Sstevel@tonic-gate argv[i]); 172556a424ccSmp153739 return -1; 17267c478bd9Sstevel@tonic-gate } 17277c478bd9Sstevel@tonic-gate policy->pw_min_life = date - now; 17287c478bd9Sstevel@tonic-gate *mask |= KADM5_PW_MIN_LIFE; 17297c478bd9Sstevel@tonic-gate continue; 17307c478bd9Sstevel@tonic-gate } 17317c478bd9Sstevel@tonic-gate } else if (strlen(argv[i]) == 10 && 173256a424ccSmp153739 !strcmp(argv[i], "-minlength")) { 17337c478bd9Sstevel@tonic-gate if (++i > argc - 2) 173456a424ccSmp153739 return -1; 17357c478bd9Sstevel@tonic-gate else { 17367c478bd9Sstevel@tonic-gate policy->pw_min_length = atoi(argv[i]); 17377c478bd9Sstevel@tonic-gate *mask |= KADM5_PW_MIN_LENGTH; 17387c478bd9Sstevel@tonic-gate continue; 17397c478bd9Sstevel@tonic-gate } 17407c478bd9Sstevel@tonic-gate } else if (strlen(argv[i]) == 11 && 174156a424ccSmp153739 !strcmp(argv[i], "-minclasses")) { 17427c478bd9Sstevel@tonic-gate if (++i > argc - 2) 174356a424ccSmp153739 return -1; 17447c478bd9Sstevel@tonic-gate else { 17457c478bd9Sstevel@tonic-gate policy->pw_min_classes = atoi(argv[i]); 17467c478bd9Sstevel@tonic-gate *mask |= KADM5_PW_MIN_CLASSES; 17477c478bd9Sstevel@tonic-gate continue; 17487c478bd9Sstevel@tonic-gate } 17497c478bd9Sstevel@tonic-gate } else if (strlen(argv[i]) == 8 && 175056a424ccSmp153739 !strcmp(argv[i], "-history")) { 17517c478bd9Sstevel@tonic-gate if (++i > argc - 2) 175256a424ccSmp153739 return -1; 17537c478bd9Sstevel@tonic-gate else { 17547c478bd9Sstevel@tonic-gate policy->pw_history_num = atoi(argv[i]); 17557c478bd9Sstevel@tonic-gate *mask |= KADM5_PW_HISTORY_NUM; 17567c478bd9Sstevel@tonic-gate continue; 17577c478bd9Sstevel@tonic-gate } 17587c478bd9Sstevel@tonic-gate } else 175956a424ccSmp153739 return -1; 17607c478bd9Sstevel@tonic-gate } 17617c478bd9Sstevel@tonic-gate if (i != argc -1) { 17627c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: parser lost count!\n"), caller); 176356a424ccSmp153739 return -1; 17647c478bd9Sstevel@tonic-gate } else 176556a424ccSmp153739 return 0; 17667c478bd9Sstevel@tonic-gate } 17677c478bd9Sstevel@tonic-gate 176856a424ccSmp153739 static void 17697c478bd9Sstevel@tonic-gate kadmin_addmodpol_usage(func) 17707c478bd9Sstevel@tonic-gate char *func; 17717c478bd9Sstevel@tonic-gate { 17727c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s %s\n", gettext("usage"), func, 17737c478bd9Sstevel@tonic-gate gettext("[options] policy")); 17747c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("\toptions are:\n")); 17757c478bd9Sstevel@tonic-gate fprintf(stderr, "\t\t[-maxlife time] [-minlife time] " 17767c478bd9Sstevel@tonic-gate "[-minlength length]\n\t\t[-minclasses number] " 17777c478bd9Sstevel@tonic-gate "[-history number]\n"); 17787c478bd9Sstevel@tonic-gate } 17797c478bd9Sstevel@tonic-gate 178056a424ccSmp153739 void kadmin_addpol(argc, argv) 17817c478bd9Sstevel@tonic-gate int argc; 17827c478bd9Sstevel@tonic-gate char *argv[]; 17837c478bd9Sstevel@tonic-gate { 17847c478bd9Sstevel@tonic-gate krb5_error_code retval; 17857c478bd9Sstevel@tonic-gate long mask; 17867c478bd9Sstevel@tonic-gate kadm5_policy_ent_rec policy; 17877c478bd9Sstevel@tonic-gate 17887c478bd9Sstevel@tonic-gate memset(&policy, 0, sizeof(policy)); 178956a424ccSmp153739 if (kadmin_parse_policy_args(argc, argv, &policy, &mask, "add_policy")) { 17907c478bd9Sstevel@tonic-gate kadmin_addmodpol_usage("add_policy"); 17917c478bd9Sstevel@tonic-gate return; 17927c478bd9Sstevel@tonic-gate } else { 17937c478bd9Sstevel@tonic-gate policy.policy = argv[argc - 1]; 17947c478bd9Sstevel@tonic-gate mask |= KADM5_POLICY; 17957c478bd9Sstevel@tonic-gate retval = kadm5_create_policy(handle, &policy, mask); 17967c478bd9Sstevel@tonic-gate if (retval) { 17977c478bd9Sstevel@tonic-gate com_err("add_policy", retval, 17987c478bd9Sstevel@tonic-gate gettext("while creating policy \"%s\"."), 17997c478bd9Sstevel@tonic-gate policy.policy); 18007c478bd9Sstevel@tonic-gate return; 18017c478bd9Sstevel@tonic-gate } 18027c478bd9Sstevel@tonic-gate } 180356a424ccSmp153739 return; 18047c478bd9Sstevel@tonic-gate } 18057c478bd9Sstevel@tonic-gate 180656a424ccSmp153739 void kadmin_modpol(argc, argv) 18077c478bd9Sstevel@tonic-gate int argc; 18087c478bd9Sstevel@tonic-gate char *argv[]; 18097c478bd9Sstevel@tonic-gate { 18107c478bd9Sstevel@tonic-gate krb5_error_code retval; 18117c478bd9Sstevel@tonic-gate long mask; 18127c478bd9Sstevel@tonic-gate kadm5_policy_ent_rec policy; 18137c478bd9Sstevel@tonic-gate 18147c478bd9Sstevel@tonic-gate memset(&policy, 0, sizeof(policy)); 18157c478bd9Sstevel@tonic-gate if (kadmin_parse_policy_args(argc, argv, &policy, &mask, 18167c478bd9Sstevel@tonic-gate "modify_policy")) { 18177c478bd9Sstevel@tonic-gate kadmin_addmodpol_usage("modify_policy"); 18187c478bd9Sstevel@tonic-gate return; 18197c478bd9Sstevel@tonic-gate } else { 18207c478bd9Sstevel@tonic-gate policy.policy = argv[argc - 1]; 18217c478bd9Sstevel@tonic-gate retval = kadm5_modify_policy(handle, &policy, mask); 18227c478bd9Sstevel@tonic-gate if (retval) { 182354925bf6Swillf com_err("modify_policy", retval, gettext("while modifying policy \"%s\"."), 18247c478bd9Sstevel@tonic-gate policy.policy); 18257c478bd9Sstevel@tonic-gate return; 18267c478bd9Sstevel@tonic-gate } 18277c478bd9Sstevel@tonic-gate } 182856a424ccSmp153739 return; 18297c478bd9Sstevel@tonic-gate } 18307c478bd9Sstevel@tonic-gate 183156a424ccSmp153739 void kadmin_delpol(argc, argv) 18327c478bd9Sstevel@tonic-gate int argc; 18337c478bd9Sstevel@tonic-gate char *argv[]; 18347c478bd9Sstevel@tonic-gate { 18357c478bd9Sstevel@tonic-gate krb5_error_code retval; 18367c478bd9Sstevel@tonic-gate char reply[32]; 18377c478bd9Sstevel@tonic-gate 18387c478bd9Sstevel@tonic-gate if (! (argc == 2 || 183956a424ccSmp153739 (argc == 3 && !strcmp("-force", argv[1])))) { 18407c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: delete_policy [-force] %s\n", 18417c478bd9Sstevel@tonic-gate gettext("usage"), gettext("policy")); 18427c478bd9Sstevel@tonic-gate return; 18437c478bd9Sstevel@tonic-gate } 18447c478bd9Sstevel@tonic-gate if (argc == 2) { 18457c478bd9Sstevel@tonic-gate printf(gettext("Are you sure you want to delete the policy " 18467c478bd9Sstevel@tonic-gate "\"%s\"? (yes/no): "), argv[1]); 18477c478bd9Sstevel@tonic-gate fgets(reply, sizeof (reply), stdin); 18487c478bd9Sstevel@tonic-gate if (strncmp(gettext("yes\n"), reply, sizeof (reply)) && 18497c478bd9Sstevel@tonic-gate strncmp(gettext("y\n"), reply, sizeof (reply)) && 18507c478bd9Sstevel@tonic-gate strncmp(gettext("Y\n"), reply, sizeof (reply)) 18517c478bd9Sstevel@tonic-gate ) { 18527c478bd9Sstevel@tonic-gate fprintf(stderr, 18537c478bd9Sstevel@tonic-gate gettext("Policy \"%s\" not deleted.\n"), 18547c478bd9Sstevel@tonic-gate argv[1]); 18557c478bd9Sstevel@tonic-gate return; 18567c478bd9Sstevel@tonic-gate } 18577c478bd9Sstevel@tonic-gate } 18587c478bd9Sstevel@tonic-gate retval = kadm5_delete_policy(handle, argv[argc - 1]); 18597c478bd9Sstevel@tonic-gate if (retval) { 18607c478bd9Sstevel@tonic-gate com_err("delete_policy:", retval, 18617c478bd9Sstevel@tonic-gate gettext("while deleting policy \"%s\""), 18627c478bd9Sstevel@tonic-gate argv[argc - 1]); 18637c478bd9Sstevel@tonic-gate return; 18647c478bd9Sstevel@tonic-gate } 186556a424ccSmp153739 return; 18667c478bd9Sstevel@tonic-gate } 18677c478bd9Sstevel@tonic-gate 186856a424ccSmp153739 void kadmin_getpol(argc, argv) 18697c478bd9Sstevel@tonic-gate int argc; 18707c478bd9Sstevel@tonic-gate char *argv[]; 18717c478bd9Sstevel@tonic-gate { 18727c478bd9Sstevel@tonic-gate krb5_error_code retval; 18737c478bd9Sstevel@tonic-gate kadm5_policy_ent_rec policy; 18747c478bd9Sstevel@tonic-gate 18757c478bd9Sstevel@tonic-gate if (! (argc == 2 || 187656a424ccSmp153739 (argc == 3 && !strcmp("-terse", argv[1])))) { 18777c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: get_policy [-terse] %s\n", 18787c478bd9Sstevel@tonic-gate gettext("usage"), gettext("policy")); 18797c478bd9Sstevel@tonic-gate return; 18807c478bd9Sstevel@tonic-gate } 18817c478bd9Sstevel@tonic-gate retval = kadm5_get_policy(handle, argv[argc - 1], &policy); 18827c478bd9Sstevel@tonic-gate if (retval) { 18837c478bd9Sstevel@tonic-gate com_err("get_policy", retval, 18847c478bd9Sstevel@tonic-gate gettext("while retrieving policy \"%s\"."), 18857c478bd9Sstevel@tonic-gate argv[argc - 1]); 18867c478bd9Sstevel@tonic-gate return; 18877c478bd9Sstevel@tonic-gate } 18887c478bd9Sstevel@tonic-gate if (argc == 2) { 18897c478bd9Sstevel@tonic-gate printf(gettext("Policy: %s\n"), policy.policy); 189056a424ccSmp153739 printf(gettext("Maximum password life: %ld\n"), 18917c478bd9Sstevel@tonic-gate policy.pw_max_life); 189256a424ccSmp153739 printf(gettext("Minimum password life: %ld\n"), 18937c478bd9Sstevel@tonic-gate policy.pw_min_life); 189456a424ccSmp153739 printf(gettext("Minimum password length: %ld\n"), 18957c478bd9Sstevel@tonic-gate policy.pw_min_length); 18967c478bd9Sstevel@tonic-gate printf(gettext("Minimum number of password " 189756a424ccSmp153739 "character classes: %ld\n"), 18987c478bd9Sstevel@tonic-gate policy.pw_min_classes); 189956a424ccSmp153739 printf(gettext("Number of old keys kept: %ld\n"), 19007c478bd9Sstevel@tonic-gate policy.pw_history_num); 190156a424ccSmp153739 printf(gettext("Reference count: %ld\n"), policy.policy_refcnt); 19027c478bd9Sstevel@tonic-gate } else { 190356a424ccSmp153739 printf("\"%s\"\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld\n", 19047c478bd9Sstevel@tonic-gate policy.policy, policy.pw_max_life, policy.pw_min_life, 19057c478bd9Sstevel@tonic-gate policy.pw_min_length, policy.pw_min_classes, 19067c478bd9Sstevel@tonic-gate policy.pw_history_num, policy.policy_refcnt); 19077c478bd9Sstevel@tonic-gate } 19087c478bd9Sstevel@tonic-gate kadm5_free_policy_ent(handle, &policy); 190956a424ccSmp153739 return; 19107c478bd9Sstevel@tonic-gate } 19117c478bd9Sstevel@tonic-gate 191256a424ccSmp153739 void kadmin_getpols(argc, argv) 19137c478bd9Sstevel@tonic-gate int argc; 19147c478bd9Sstevel@tonic-gate char *argv[]; 19157c478bd9Sstevel@tonic-gate { 19167c478bd9Sstevel@tonic-gate krb5_error_code retval; 191756a424ccSmp153739 char *expr, **names; 19187c478bd9Sstevel@tonic-gate int i, count; 19197c478bd9Sstevel@tonic-gate 1920d51f1d33Smp153739 /* Solaris Kerberos: 1921d51f1d33Smp153739 * Use a pager for listing policies (similar to listing princs) 1922d51f1d33Smp153739 */ 1923d51f1d33Smp153739 FILE *output = NULL; 1924d51f1d33Smp153739 int fd; 1925d51f1d33Smp153739 struct sigaction nsig, osig; 1926d51f1d33Smp153739 sigset_t nmask, omask; 1927d51f1d33Smp153739 int waitb; 1928d51f1d33Smp153739 192956a424ccSmp153739 expr = NULL; 193056a424ccSmp153739 if (! (argc == 1 || (argc == 2 && (expr = argv[1])))) { 19317c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: get_policies %s\n", 19327c478bd9Sstevel@tonic-gate gettext("usage"), gettext("[expression]\n")); 19337c478bd9Sstevel@tonic-gate return; 19347c478bd9Sstevel@tonic-gate } 193556a424ccSmp153739 retval = kadm5_get_policies(handle, expr, &names, &count); 19367c478bd9Sstevel@tonic-gate if (retval) { 19377c478bd9Sstevel@tonic-gate com_err("get_policies", retval, 19387c478bd9Sstevel@tonic-gate gettext("while retrieving list.")); 19397c478bd9Sstevel@tonic-gate return; 19407c478bd9Sstevel@tonic-gate } 1941d51f1d33Smp153739 1942d51f1d33Smp153739 if (sigemptyset(&nmask) == -1) { 1943d51f1d33Smp153739 perror("sigemptyset"); 19447c478bd9Sstevel@tonic-gate kadm5_free_name_list(handle, names, count); 1945d51f1d33Smp153739 return; 19467c478bd9Sstevel@tonic-gate } 194756a424ccSmp153739 1948d51f1d33Smp153739 if (sigaddset(&nmask, SIGINT) == -1) { 1949d51f1d33Smp153739 perror("sigaddset"); 1950d51f1d33Smp153739 kadm5_free_name_list(handle, names, count); 1951d51f1d33Smp153739 return; 1952d51f1d33Smp153739 } 1953d51f1d33Smp153739 1954d51f1d33Smp153739 if (sigemptyset(&nsig.sa_mask) == -1) { 1955d51f1d33Smp153739 perror("sigemptyset"); 1956d51f1d33Smp153739 kadm5_free_name_list(handle, names, count); 1957d51f1d33Smp153739 return; 1958d51f1d33Smp153739 } 1959d51f1d33Smp153739 1960d51f1d33Smp153739 if (sigprocmask(SIG_BLOCK, &nmask, &omask) == -1) { 1961d51f1d33Smp153739 perror("sigprocmask"); 1962d51f1d33Smp153739 kadm5_free_name_list(handle, names, count); 1963d51f1d33Smp153739 return; 1964d51f1d33Smp153739 } 1965d51f1d33Smp153739 1966d51f1d33Smp153739 nsig.sa_handler = SIG_IGN; 1967d51f1d33Smp153739 nsig.sa_flags = 0; 1968d51f1d33Smp153739 if (sigaction(SIGINT, &nsig, &osig) == -1) { 1969d51f1d33Smp153739 perror("sigaction"); 1970d51f1d33Smp153739 if (sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0) == -1) { 1971d51f1d33Smp153739 perror("sigprocmask"); 1972d51f1d33Smp153739 } 1973d51f1d33Smp153739 kadm5_free_name_list(handle, names, count); 1974d51f1d33Smp153739 return; 1975d51f1d33Smp153739 } 1976d51f1d33Smp153739 1977d51f1d33Smp153739 fd = ss_pager_create(); 1978d51f1d33Smp153739 if (fd == -1) { 1979d51f1d33Smp153739 fprintf(stderr, "%s: failed to create pager\n", whoami); 1980d51f1d33Smp153739 if (sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0) == -1) { 1981d51f1d33Smp153739 perror("sigprocmask"); 1982d51f1d33Smp153739 } 1983d51f1d33Smp153739 1984d51f1d33Smp153739 if (sigaction(SIGINT, &osig, (struct sigaction *)0) == -1) { 1985d51f1d33Smp153739 perror("sigaction"); 1986d51f1d33Smp153739 } 1987d51f1d33Smp153739 1988d51f1d33Smp153739 kadm5_free_name_list(handle, names, count); 1989d51f1d33Smp153739 return; 1990d51f1d33Smp153739 } 1991d51f1d33Smp153739 1992d51f1d33Smp153739 output = fdopen(fd, "w"); 1993d51f1d33Smp153739 if (output == NULL) { 1994d51f1d33Smp153739 perror("fdopen"); 1995d51f1d33Smp153739 } 1996d51f1d33Smp153739 1997d51f1d33Smp153739 if (sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0) == -1) { 1998d51f1d33Smp153739 perror("sigprocmask"); 1999d51f1d33Smp153739 } 2000d51f1d33Smp153739 2001d51f1d33Smp153739 if (output != NULL) { 2002d51f1d33Smp153739 for (i = 0; i < count; i++) 2003d51f1d33Smp153739 fprintf(output, "%s\n", names[i]); 2004d51f1d33Smp153739 } 2005d51f1d33Smp153739 2006d51f1d33Smp153739 if (output != NULL && fclose(output) != 0) { 2007d51f1d33Smp153739 perror("fclose"); 2008d51f1d33Smp153739 } 2009d51f1d33Smp153739 2010d51f1d33Smp153739 if (wait(&waitb) == -1) { 2011d51f1d33Smp153739 perror("wait"); 2012d51f1d33Smp153739 } 2013d51f1d33Smp153739 2014d51f1d33Smp153739 if (sigaction(SIGINT, &osig, (struct sigaction *)0) == -1) { 2015d51f1d33Smp153739 perror("sigaction"); 2016d51f1d33Smp153739 } 2017d51f1d33Smp153739 kadm5_free_name_list(handle, names, count); 2018d51f1d33Smp153739 } 2019