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;
strdur(duration)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
strdate(when)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
kadmin_parse_name(name,principal)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
extended_com_err_fn(const char * myprog,errcode_t code,const char * fmt,va_list args)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 }
kadmin_startup(argc,argv)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
quit()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
kadmin_lock(argc,argv)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
kadmin_unlock(argc,argv)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
kadmin_delprinc(argc,argv)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
kadmin_cpw(argc,argv)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
kadmin_free_tl_data(kadm5_principal_ent_t princ)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
kadmin_parse_princ_args(argc,argv,oprinc,mask,pass,randkey,ks_tuple,n_ks_tuple,caller)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
kadmin_addprinc_usage(func)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
kadmin_modprinc_usage(func)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
kadmin_addprinc(argc,argv)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
kadmin_modprinc(argc,argv)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
kadmin_getprinc(argc,argv)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
kadmin_getprincs(argc,argv)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
kadmin_parse_policy_args(argc,argv,policy,mask,caller)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
kadmin_addmodpol_usage(func)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
kadmin_addpol(argc,argv)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
kadmin_modpol(argc,argv)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
kadmin_delpol(argc,argv)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
kadmin_getpol(argc,argv)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
kadmin_getpols(argc,argv)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