2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
6 * Copyright 1994 by the Massachusetts Institute of Technology.
9 * Export of this software from the United States of America may
10 * require a specific license from the United States Government.
11 * It is the responsibility of any person or organization contemplating
12 * export to obtain such a license before exporting.
14 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
15 * distribute this software and its documentation for any purpose and
16 * without fee is hereby granted, provided that the above copyright
17 * notice appear in all copies and that both that copyright notice and
18 * this permission notice appear in supporting documentation, and that
19 * the name of M.I.T. not be used in advertising or publicity pertaining
20 * to distribution of the software without specific, written prior
21 * permission. Furthermore if you modify this software you must label
22 * your software as modified software and not distribute it in such a
23 * fashion that it might be confused with the original M.I.T. software.
24 * M.I.T. makes no representations about the suitability of
25 * this software for any purpose. It is provided "as is" without express
26 * or implied warranty.
28 * kadmin.c: base functions for a kadmin command line interface using
29 * the OVSecure library
32 #include <kadm5/admin.h>
33 #include <krb5/adm_proto.h>
36 #include <sys/types.h>
40 /* #include <sys/timeb.h> */
47 * Solaris: the following are needed for paging
52 /* command name when called "locally" (i.e. non-networked client ) */
53 #define KADMIN_LOCAL_NAME "kadmin.local"
55 /* functions defined in remote/local specific files */
56 extern void usage(const char *);
58 /* special struct to convert flag names for principals
59 to actual krb5_flags for a principal */
61 char *flagname
; /* name of flag as typed to CLI */
62 int flaglen
; /* length of string (not counting -,+) */
63 krb5_flags theflag
; /* actual principal flag to set/clear */
64 int set
; /* 0 means clear, 1 means set (on '-') */
67 static struct pflag flags
[] = {
68 {"allow_postdated", 15, KRB5_KDB_DISALLOW_POSTDATED
, 1},
69 {"allow_forwardable", 17, KRB5_KDB_DISALLOW_FORWARDABLE
, 1},
70 {"allow_tgs_req", 13, KRB5_KDB_DISALLOW_TGT_BASED
, 1},
71 {"allow_renewable", 15, KRB5_KDB_DISALLOW_RENEWABLE
, 1},
72 {"allow_proxiable", 15, KRB5_KDB_DISALLOW_PROXIABLE
, 1},
73 {"allow_dup_skey", 14, KRB5_KDB_DISALLOW_DUP_SKEY
, 1},
74 {"allow_tix", 9, KRB5_KDB_DISALLOW_ALL_TIX
, 1},
75 {"requires_preauth", 16, KRB5_KDB_REQUIRES_PRE_AUTH
, 0},
76 {"requires_hwauth", 15, KRB5_KDB_REQUIRES_HW_AUTH
, 0},
77 {"needchange", 10, KRB5_KDB_REQUIRES_PWCHANGE
, 0},
78 {"allow_svr", 9, KRB5_KDB_DISALLOW_SVR
, 1},
79 {"password_changing_service", 25, KRB5_KDB_PWCHANGE_SERVICE
, 0 },
80 {"support_desmd5", 14, KRB5_KDB_SUPPORT_DESMD5
, 0 }
83 static char *prflags
[] = {
84 "DISALLOW_POSTDATED", /* 0x00000001 */
85 "DISALLOW_FORWARDABLE", /* 0x00000002 */
86 "DISALLOW_TGT_BASED", /* 0x00000004 */
87 "DISALLOW_RENEWABLE", /* 0x00000008 */
88 "DISALLOW_PROXIABLE", /* 0x00000010 */
89 "DISALLOW_DUP_SKEY", /* 0x00000020 */
90 "DISALLOW_ALL_TIX", /* 0x00000040 */
91 "REQUIRES_PRE_AUTH", /* 0x00000080 */
92 "REQUIRES_HW_AUTH", /* 0x00000100 */
93 "REQUIRES_PWCHANGE", /* 0x00000200 */
94 "UNKNOWN_0x00000400", /* 0x00000400 */
95 "UNKNOWN_0x00000800", /* 0x00000800 */
96 "DISALLOW_SVR", /* 0x00001000 */
97 "PWCHANGE_SERVICE", /* 0x00002000 */
98 "SUPPORT_DESMD5", /* 0x00004000 */
99 "NEW_PRINC", /* 0x00008000 */
104 char *def_realm
= NULL
;
108 krb5_context context
;
109 char *ccache_name
= NULL
;
112 static char *strdur(duration
)
116 int neg
, days
, hours
, minutes
, seconds
;
123 days
= duration
/ (24 * 3600);
124 duration
%= 24 * 3600;
125 hours
= duration
/ 3600;
127 minutes
= duration
/ 60;
130 snprintf(out
, sizeof (out
), "%s%d %s %02d:%02d:%02d", neg
? "-" : "",
131 days
, days
== 1 ? gettext("day") : gettext("days"),
132 hours
, minutes
, seconds
);
136 static char *strdate(when
)
142 time_t lcltim
= when
;
143 tm
= localtime(&lcltim
);
144 strftime(out
, sizeof(out
), gettext("%a %b %d %H:%M:%S %Z %Y"), tm
);
148 /* this is a wrapper to go around krb5_parse_principal so we can set
149 the default realm up properly */
150 static krb5_error_code
151 kadmin_parse_name(name
, principal
)
153 krb5_principal
*principal
;
156 krb5_error_code retval
;
161 /* assumes def_realm is initialized! */
162 fullname
= (char *)malloc(strlen(name
) + 1 + strlen(def_realm
) + 1);
163 if (fullname
== NULL
)
165 strcpy(fullname
, name
);
166 cp
= strchr(fullname
, '@');
168 if (cp
- fullname
&& *(cp
- 1) != '\\')
171 cp
= strchr(cp
+ 1, '@');
174 strcat(fullname
, "@");
175 strcat(fullname
, def_realm
);
177 retval
= krb5_parse_name(context
, fullname
, principal
);
182 static void extended_com_err_fn (const char *myprog
, errcode_t code
,
183 const char *fmt
, va_list args
)
187 emsg
= krb5_get_error_message (context
, code
);
188 fprintf (stderr
, "%s: %s ", myprog
, emsg
);
189 krb5_free_error_message (context
, emsg
);
191 fprintf (stderr
, "%s: ", myprog
);
193 vfprintf (stderr
, fmt
, args
);
194 fprintf (stderr
, "\n");
196 char *kadmin_startup(argc
, argv
)
201 char *princstr
= NULL
, *keytab_name
= NULL
, *query
= NULL
;
202 char *password
= NULL
;
203 char *luser
, *canon
, *cp
;
204 int optchar
, freeprinc
= 0, use_keytab
= 0;
208 krb5_principal princ
;
209 kadm5_config_params params
;
210 char **db_args
= NULL
;
211 int db_args_size
= 0;
212 char *db_name
= NULL
;
213 char *svcname
= NULL
;
215 memset((char *) ¶ms
, 0, sizeof(params
));
217 if (strcmp (whoami
, "kadmin.local") == 0)
218 set_com_err_hook(extended_com_err_fn
);
220 retval
= kadm5_init_krb5_context(&context
);
222 com_err(whoami
, retval
, gettext("while initializing krb5 library"));
226 while ((optchar
= getopt(argc
, argv
, "x:r:p:kq:w:d:s:mc:t:e:ON")) != EOF
) {
231 char **temp
= realloc(db_args
, sizeof(char*) * (db_args_size
+1));
233 fprintf(stderr
, gettext("%s: Cannot initialize. Not enough memory\n"),
240 db_args
[db_args_size
-1] = optarg
;
241 db_args
[db_args_size
] = NULL
;
251 ccache_name
= optarg
;
257 keytab_name
= optarg
;
266 /* now db_name is not a seperate argument. It has to be passed as part of the db_args */
268 db_name
= malloc(strlen(optarg
) + sizeof("dbname="));
270 db_name
= realloc(db_name
, strlen(optarg
) + sizeof("dbname="));
273 strcpy(db_name
, "dbname=");
274 strcat(db_name
, optarg
);
278 char **temp
= realloc(db_args
, sizeof(char*) * (db_args_size
+1)); /* one for NULL */
281 gettext("%s: Cannot initialize. Not enough memory\n"),
288 db_args
[db_args_size
-1] = db_name
;
289 db_args
[db_args_size
] = NULL
;
292 params
.admin_server
= optarg
;
293 params
.mask
|= KADM5_CONFIG_ADMIN_SERVER
;
296 params
.mkey_from_kbd
= 1;
297 params
.mask
|= KADM5_CONFIG_MKEY_FROM_KBD
;
300 retval
= krb5_string_to_keysalts(optarg
,
305 ¶ms
.num_keysalts
);
307 com_err(whoami
, retval
,
308 gettext("while parsing keysalts %s"), optarg
);
311 params
.mask
|= KADM5_CONFIG_ENCTYPES
;
313 case 'O': /* Undocumented option for testing only */
314 svcname
= KADM5_ADMIN_SERVICE_P
;
320 if ((ccache_name
&& use_keytab
) ||
321 (keytab_name
&& !use_keytab
))
324 if (def_realm
== NULL
&& krb5_get_default_realm(context
, &def_realm
)) {
328 gettext("%s: unable to get default realm\n"), whoami
);
332 params
.mask
|= KADM5_CONFIG_REALM
;
333 params
.realm
= def_realm
;
335 if (svcname
== NULL
) {
336 if (kadm5_get_adm_host_srv_name(context
,
337 def_realm
, &svcname
)) {
339 gettext("%s: unable to get host based "
340 "service name for realm %s\n"),
349 * Set cc to an open credentials cache, either specified by the -c
350 * argument or the default.
352 if (ccache_name
== NULL
) {
353 if ((retval
= krb5_cc_default(context
, &cc
))) {
354 com_err(whoami
, retval
,
355 gettext("while opening default "
356 "credentials cache"));
360 if ((retval
= krb5_cc_resolve(context
, ccache_name
, &cc
))) {
361 com_err(whoami
, retval
,
362 gettext("while opening credentials cache %s"),
369 * If no principal name is specified: If a ccache was specified
370 * and its primary principal name can be read, it is used, else if
371 * a keytab was specified, the principal name is host/hostname,
372 * otherwise append "/admin" to the primary name of the default
373 * ccache, $USER, or pw_name.
375 * Gee, 100+ lines to figure out the client principal name. This
376 * should be compressed...
379 if (princstr
== NULL
) {
380 if (ccache_name
!= NULL
&&
381 !krb5_cc_get_principal(context
, cc
, &princ
)) {
382 if ((retval
= krb5_unparse_name(context
, princ
, &princstr
))) {
383 com_err(whoami
, retval
,
384 gettext("while canonicalizing principal name"));
385 krb5_free_principal(context
, princ
);
388 krb5_free_principal(context
, princ
);
390 } else if (use_keytab
!= 0) {
391 if ((retval
= krb5_sname_to_principal(context
, NULL
,
395 com_err(whoami
, retval
,
396 gettext("creating host service principal"));
399 if ((retval
= krb5_unparse_name(context
, princ
, &princstr
))) {
400 com_err(whoami
, retval
,
401 gettext("while canonicalizing principal name"));
402 krb5_free_principal(context
, princ
);
405 krb5_free_principal(context
, princ
);
407 } else if (!krb5_cc_get_principal(context
, cc
, &princ
)) {
409 if (krb5_unparse_name(context
, princ
, &canon
)) {
411 gettext("%s: unable to canonicalize "
412 "principal\n"), whoami
);
413 krb5_free_principal(context
, princ
);
416 /* strip out realm of principal if it's there */
417 realm
= strchr(canon
, '@');
419 if (realm
- canon
&& *(realm
- 1) != '\\')
422 realm
= strchr(realm
+1, '@');
426 cp
= strchr(canon
, '/');
428 if (cp
- canon
&& *(cp
- 1) != '\\')
431 cp
= strchr(cp
+1, '/');
435 princstr
= (char*)malloc(strlen(canon
) + 6 /* "/admin" */ +
436 (realm
? 1 + strlen(realm
) : 0) + 1);
437 if (princstr
== NULL
) {
439 gettext("%s: out of memory\n"),
443 strcpy(princstr
, canon
);
444 strcat(princstr
, "/admin");
446 strcat(princstr
, "@");
447 strcat(princstr
, realm
);
450 krb5_free_principal(context
, princ
);
452 } else if ((luser
= getenv("USER"))) {
453 princstr
= (char *) malloc(strlen(luser
) + 7 /* "/admin@" */
454 + strlen(def_realm
) + 1);
455 if (princstr
== NULL
) {
457 gettext("%s: out of memory\n"),
461 strcpy(princstr
, luser
);
462 strcat(princstr
, "/admin");
463 strcat(princstr
, "@");
464 strcat(princstr
, def_realm
);
466 } else if ((pw
= getpwuid(getuid()))) {
467 princstr
= (char *) malloc(strlen(pw
->pw_name
) + 7 /* "/admin@" */
468 + strlen(def_realm
) + 1);
469 if (princstr
== NULL
) {
471 gettext("%s: out of memory\n"),
475 strcpy(princstr
, pw
->pw_name
);
476 strcat(princstr
, "/admin@");
477 strcat(princstr
, def_realm
);
481 gettext("%s: unable to figure out "
482 "a principal name\n"),
488 retval
= krb5_klog_init(context
, "admin_server", whoami
, 0);
490 com_err(whoami
, retval
, "while setting up logging");
495 * Initialize the kadm5 connection. If we were given a ccache,
496 * use it. Otherwise, use/prompt for the password.
500 * Send warnings to stderr
503 fprintf(stderr
, gettext("Authenticating as principal %s with existing credentials.\n"),
505 retval
= kadm5_init_with_creds(princstr
, cc
,
508 KADM5_STRUCT_VERSION
,
512 } else if (use_keytab
) {
514 fprintf(stderr
, gettext("Authenticating as principal %s with keytab %s.\n"),
515 princstr
, keytab_name
);
517 fprintf(stderr
, gettext("Authenticating as principal %s with default keytab.\n"),
519 retval
= kadm5_init_with_skey(princstr
, keytab_name
,
522 KADM5_STRUCT_VERSION
,
527 fprintf(stderr
, gettext("Authenticating as principal %s with password.\n"),
529 retval
= kadm5_init_with_password(princstr
, password
,
532 KADM5_STRUCT_VERSION
,
538 if (retval
== KADM5_RPC_ERROR_CANTENCODEARGS
||
539 retval
== KADM5_RPC_ERROR_CANTDECODEARGS
) {
540 com_err(whoami
, KADM5_RPC_ERROR
,
541 gettext("while initializing %s interface"), whoami
);
543 /* privacy-enabled mech probably not installed/configed */
544 com_err(whoami
, retval
, gettext("."), whoami
);
546 com_err(whoami
, retval
,
547 gettext("while initializing %s interface"), whoami
);
548 if (retval
== KADM5_BAD_CLIENT_PARAMS
||
549 retval
== KADM5_BAD_SERVER_PARAMS
)
558 free(db_name
), db_name
=NULL
;
561 free(db_args
), db_args
=NULL
;
563 if ((retval
= krb5_cc_close(context
, cc
))) {
564 com_err(whoami
, retval
, gettext("while closing ccache %s"),
569 /* register the WRFILE keytab type and set it as the default */
571 #define DEFAULT_KEYTAB "WRFILE:/etc/krb5/krb5.keytab"
572 /* XXX krb5_defkeyname is an internal library global and
574 extern char *krb5_defkeyname
;
575 krb5_defkeyname
= DEFAULT_KEYTAB
;
578 if ((retval
= kadm5_init_iprop(handle
)) != 0) {
579 com_err(whoami
, retval
, gettext("while mapping update log"));
583 /* Solaris kerberos: fix memory leak */
595 retval
= kadm5_unlock(handle
);
597 com_err("quit", retval
, gettext("while unlocking locked database"));
603 kadm5_destroy(handle
);
604 if (ccache_name
!= NULL
) {
606 gettext("\n\a\a\aAdministration credentials "
607 "NOT DESTROYED.\n"));
610 /* insert more random cleanup here */
611 krb5_klog_close(context
);
612 krb5_free_context(context
);
617 void kadmin_lock(argc
, argv
)
625 retval
= kadm5_lock(handle
);
627 com_err("lock", retval
, "");
633 void kadmin_unlock(argc
, argv
)
641 retval
= kadm5_unlock(handle
);
643 com_err("unlock", retval
, "");
649 void kadmin_delprinc(argc
, argv
)
654 krb5_principal princ
;
659 (argc
== 3 && !strcmp("-force", argv
[1])))) {
660 fprintf(stderr
, "%s: delete_principal [-force] %s\n",
661 gettext("usage"), gettext("principal"));
664 retval
= kadmin_parse_name(argv
[argc
- 1], &princ
);
666 com_err("delete_principal", retval
,
667 gettext("while parsing principal name"));
670 retval
= krb5_unparse_name(context
, princ
, &canon
);
672 com_err("delete_principal", retval
,
673 gettext("while canonicalizing principal"));
674 krb5_free_principal(context
, princ
);
678 printf(gettext("Are you sure you want to delete "
679 "the principal \"%s\"? (yes/no): "), canon
);
680 fgets(reply
, sizeof (reply
), stdin
);
681 if (strncmp(gettext("yes\n"), reply
, sizeof (reply
)) &&
682 strncmp(gettext("y\n"), reply
, sizeof (reply
)) &&
683 strncmp(gettext("Y\n"), reply
, sizeof (reply
))) {
685 gettext("Principal \"%s\" not deleted\n"),
688 krb5_free_principal(context
, princ
);
692 retval
= kadm5_delete_principal(handle
, princ
);
693 krb5_free_principal(context
, princ
);
695 com_err("delete_principal", retval
,
696 gettext("while deleting principal \"%s\""), canon
);
700 printf(gettext("Principal \"%s\" deleted.\n"), canon
);
701 printf(gettext("Make sure that you have removed this principal "
702 "from all ACLs before reusing.\n"));
707 void kadmin_cpw(argc
, argv
)
712 static char newpw
[1024];
713 static char prompt1
[1024], prompt2
[1024];
716 int n_ks_tuple
= 0, randkey
= 0;
717 krb5_boolean keepold
= FALSE
;
718 krb5_key_salt_tuple
*ks_tuple
= NULL
;
719 krb5_principal princ
;
720 char **db_args
= NULL
;
721 int db_args_size
= 0;
722 int local_kadmin
= 0;
724 local_kadmin
= (strcmp(whoami
, KADMIN_LOCAL_NAME
) == 0);
729 for (argv
++, argc
--; argc
> 1; argc
--, argv
++) {
730 if (!strcmp("-x", *argv
)) {
733 fprintf(stderr
, gettext("change_password: missing db argument\n"));
738 char **temp
= realloc(db_args
, sizeof(char*) * (db_args_size
+1)); /* one for NULL */
740 fprintf(stderr
, gettext("change_password: Not enough memory\n"));
741 free(db_args
), db_args
= NULL
;
747 db_args
[db_args_size
-1] = *++argv
;
748 db_args
[db_args_size
] = NULL
;
751 if (!strcmp("-pw", *argv
)) {
754 fprintf(stderr
, "change_password: %s",
755 gettext("missing password arg\n"));
761 if (!strcmp("-randkey", *argv
)) {
765 if (!strcmp("-keepold", *argv
)) {
769 if (!strcmp("-e", *argv
)) {
772 fprintf(stderr
, "change_password: %s",
773 gettext("missing keysaltlist arg\n"));
776 retval
= krb5_string_to_keysalts(*++argv
, ", \t", ":.-", 0,
777 &ks_tuple
, &n_ks_tuple
);
779 com_err("change_password", retval
,
780 gettext("while parsing keysalts %s"), *argv
);
788 com_err("change_password", 0, "missing principal name");
791 retval
= kadmin_parse_name(*argv
, &princ
);
793 com_err("change_password", retval
,
794 gettext("while parsing principal name"));
795 if (ks_tuple
!= NULL
)
797 if (db_args
) free(db_args
);
800 retval
= krb5_unparse_name(context
, princ
, &canon
);
802 com_err("change_password", retval
,
803 gettext("while canonicalizing principal"));
804 krb5_free_principal(context
, princ
);
805 if (ks_tuple
!= NULL
)
807 if (db_args
) free(db_args
);
811 if (keepold
|| ks_tuple
!= NULL
) {
812 retval
= kadm5_chpass_principal_3(handle
, princ
, keepold
,
813 n_ks_tuple
, ks_tuple
, pwarg
);
814 if (ks_tuple
!= NULL
)
817 retval
= kadm5_chpass_principal(handle
, princ
, pwarg
);
819 krb5_free_principal(context
, princ
);
821 com_err("change_password", retval
,
822 gettext("while changing password for \"%s\"."),
825 if (db_args
) free(db_args
);
828 printf(gettext("Password for \"%s\" changed.\n"), canon
);
830 if (db_args
) free(db_args
);
832 } else if (randkey
) {
833 if (keepold
|| ks_tuple
!= NULL
|| local_kadmin
) {
834 retval
= kadm5_randkey_principal_3(handle
, princ
, keepold
,
835 n_ks_tuple
, ks_tuple
,
837 if (ks_tuple
!= NULL
)
840 retval
= kadm5_randkey_principal(handle
, princ
, NULL
, NULL
);
842 krb5_free_principal(context
, princ
);
844 com_err("change_password", retval
,
845 gettext("while randomizing key for \"%s\"."),
848 if (db_args
) free(db_args
);
851 printf(gettext("Key for \"%s\" randomized.\n"), canon
);
853 if (db_args
) free(db_args
);
855 } else if (argc
== 1) {
856 unsigned int i
= sizeof (newpw
) - 1;
858 snprintf(prompt1
, sizeof (prompt1
),
859 gettext("Enter password for principal \"%.900s\""),
861 snprintf(prompt2
, sizeof (prompt2
),
862 gettext("Re-enter password for principal \"%.900s\""),
864 retval
= krb5_read_password(context
, prompt1
, prompt2
,
867 com_err("change_password", retval
,
868 gettext("while reading password for \"%s\"."),
871 if (ks_tuple
!= NULL
)
873 krb5_free_principal(context
, princ
);
874 if (db_args
) free(db_args
);
877 if (keepold
|| ks_tuple
!= NULL
) {
878 retval
= kadm5_chpass_principal_3(handle
, princ
, keepold
,
879 n_ks_tuple
, ks_tuple
,
881 if (ks_tuple
!= NULL
)
884 retval
= kadm5_chpass_principal(handle
, princ
, newpw
);
886 krb5_free_principal(context
, princ
);
887 memset(newpw
, 0, sizeof (newpw
));
889 com_err("change_password", retval
,
890 gettext("while changing password for \"%s\"."),
893 if (db_args
) free(db_args
);
896 printf(gettext("Password for \"%s\" changed.\n"), canon
);
898 if (db_args
) free(db_args
);
902 krb5_free_principal(context
, princ
);
904 if (ks_tuple
!= NULL
)
906 fprintf(stderr
, "%s: change_password [-randkey] [-keepold] "
907 "[-e keysaltlist] [-pw password] %s\n",
908 gettext("usage"), gettext("principal"));
914 kadmin_free_tl_data(kadm5_principal_ent_t princ
)
916 krb5_tl_data
*tl_data
= princ
->tl_data
;
917 int n_tl_data
= princ
->n_tl_data
;
920 princ
->n_tl_data
= 0;
921 princ
->tl_data
= NULL
;
923 for (i
= 0; tl_data
&& (i
< n_tl_data
); i
++) {
924 krb5_tl_data
*next
= tl_data
->tl_data_next
;
925 if (tl_data
->tl_data_contents
)
926 free(tl_data
->tl_data_contents
);
932 #define KRB5_TL_DB_ARGS 0x7fff
934 kadmin_parse_princ_args(argc
, argv
, oprinc
, mask
, pass
, randkey
,
935 ks_tuple
, n_ks_tuple
, caller
)
938 kadm5_principal_ent_t oprinc
;
942 krb5_key_salt_tuple
**ks_tuple
;
946 int i
, j
, attrib_set
;
949 krb5_error_code retval
;
950 krb5_tl_data
*tl_data
, *tail
= NULL
;
958 for (i
= 1; i
< argc
- 1; i
++) {
960 if (strlen(argv
[i
]) == 2 &&
961 !strcmp("-x",argv
[i
])) {
965 tl_data
= malloc(sizeof(krb5_tl_data
));
966 if (tl_data
== NULL
) {
967 fprintf(stderr
, gettext("Not enough memory\n"));
971 memset(tl_data
, 0, sizeof(krb5_tl_data
));
972 tl_data
->tl_data_type
= KRB5_TL_DB_ARGS
;
973 tl_data
->tl_data_length
= strlen(argv
[i
])+1;
974 tl_data
->tl_data_contents
= (unsigned char*)strdup(argv
[i
]);
977 tail
->tl_data_next
= tl_data
;
979 oprinc
->tl_data
= tl_data
;
984 if (tl_data
->tl_data_contents
== NULL
) {
985 fprintf(stderr
, gettext("Not enough memory\n"));
988 *mask
|= KADM5_TL_DATA
;
991 if (strlen(argv
[i
]) == 7 &&
992 !strcmp("-expire", argv
[i
])) {
996 date
= get_date(argv
[i
]);
997 if (date
== (time_t)-1) {
999 gettext("Invalid date "
1005 oprinc
->princ_expire_time
= date
;
1006 *mask
|= KADM5_PRINC_EXPIRE_TIME
;
1010 if (strlen(argv
[i
]) == 9 &&
1011 !strcmp("-pwexpire", argv
[i
])) {
1015 date
= get_date(argv
[i
]);
1016 if (date
== (time_t)-1) {
1018 gettext("Invalid date "
1024 oprinc
->pw_expiration
= date
;
1025 *mask
|= KADM5_PW_EXPIRATION
;
1029 if (strlen(argv
[i
]) == 8 &&
1030 !strcmp("-maxlife", argv
[i
])) {
1034 date
= get_date(argv
[i
]);
1035 if (date
== (time_t)-1) {
1037 gettext("Invalid date "
1043 oprinc
->max_life
= date
- now
;
1044 *mask
|= KADM5_MAX_LIFE
;
1048 if (strlen(argv
[i
]) == 13 &&
1049 !strcmp("-maxrenewlife", argv
[i
])) {
1053 date
= get_date(argv
[i
]);
1054 if (date
== (time_t)-1) {
1056 gettext("Invalid date "
1062 oprinc
->max_renewable_life
= date
- now
;
1063 *mask
|= KADM5_MAX_RLIFE
;
1067 if (strlen(argv
[i
]) == 5 &&
1068 !strcmp("-kvno", argv
[i
])) {
1072 oprinc
->kvno
= atoi(argv
[i
]);
1073 *mask
|= KADM5_KVNO
;
1077 if (strlen(argv
[i
]) == 7 &&
1078 !strcmp("-policy", argv
[i
])) {
1082 oprinc
->policy
= argv
[i
];
1083 *mask
|= KADM5_POLICY
;
1087 if (strlen(argv
[i
]) == 12 &&
1088 !strcmp("-clearpolicy", argv
[i
])) {
1089 oprinc
->policy
= NULL
;
1090 *mask
|= KADM5_POLICY_CLR
;
1093 if (strlen(argv
[i
]) == 3 &&
1094 !strcmp("-pw", argv
[i
])) {
1102 if (strlen(argv
[i
]) == 8 &&
1103 !strcmp("-randkey", argv
[i
])) {
1107 if (!strcmp("-e", argv
[i
])) {
1111 retval
= krb5_string_to_keysalts(argv
[i
], ", \t", ":.-", 0,
1112 ks_tuple
, n_ks_tuple
);
1114 com_err(caller
, retval
,
1115 gettext("while parsing keysalts %s"), argv
[i
]);
1121 for (j
= 0; j
< sizeof (flags
) / sizeof (struct pflag
); j
++) {
1122 if (strlen(argv
[i
]) == flags
[j
].flaglen
+ 1 &&
1123 !strcmp(flags
[j
].flagname
,
1124 &argv
[i
][1] /* strip off leading + or - */)) {
1125 if ((flags
[j
].set
&& argv
[i
][0] == '-') ||
1126 (!flags
[j
].set
&& argv
[i
][0] == '+')) {
1127 oprinc
->attributes
|= flags
[j
].theflag
;
1128 *mask
|= KADM5_ATTRIBUTES
;
1131 } else if ((flags
[j
].set
&& argv
[i
][0] == '+') ||
1132 (!flags
[j
].set
&& argv
[i
][0] == '-')) {
1133 oprinc
->attributes
&= ~flags
[j
].theflag
;
1134 *mask
|= KADM5_ATTRIBUTES
;
1143 return -1; /* nothing was parsed */
1145 if (i
!= argc
- 1) {
1148 retval
= kadmin_parse_name(argv
[i
], &oprinc
->principal
);
1150 com_err(caller
, retval
, gettext("while parsing principal"));
1157 kadmin_addprinc_usage(func
)
1160 fprintf(stderr
, "%s: %s %s\n", gettext("usage"), func
,
1161 gettext("[options] principal"));
1162 fprintf(stderr
, gettext("\toptions are:\n"));
1163 fprintf(stderr
, "\t\t[-expire expdate] [-pwexpire pwexpdate] "
1164 "[-maxlife maxtixlife]\n\t\t[-kvno kvno] [-policy policy] "
1165 "[-randkey] [-pw password]\n\t\t[-maxrenewlife maxrenewlife] "
1166 "[-e keysaltlist] [{+|-}attribute]\n");
1167 fprintf(stderr
, gettext("\tattributes are:\n"));
1168 fprintf(stderr
, "%s%s%s",
1169 "\t\tallow_postdated allow_forwardable allow_tgs_req "
1170 "allow_renewable\n",
1171 "\t\tallow_proxiable allow_dup_skey allow_tix "
1172 "requires_preauth\n",
1173 "\t\trequires_hwauth needchange allow_svr "
1174 "password_changing_service\n");
1178 kadmin_modprinc_usage(func
)
1181 fprintf(stderr
, "%s: %s %s\n", gettext("usage"), func
,
1182 gettext("[options] principal"));
1183 fprintf(stderr
, gettext("\toptions are:\n"));
1184 fprintf(stderr
, "\t\t[-expire expdate] [-pwexpire pwexpdate] "
1185 "[-maxlife maxtixlife]\n\t\t[-kvno kvno] [-policy policy] "
1186 "[-clearpolicy]\n\t\t[-maxrenewlife maxrenewlife] "
1187 "[{+|-}attribute]\n");
1188 fprintf(stderr
, gettext("\tattributes are:\n"));
1189 fprintf(stderr
, "%s%s%s",
1190 "\t\tallow_postdated allow_forwardable allow_tgs_req "
1191 "allow_renewable\n",
1192 "\t\tallow_proxiable allow_dup_skey allow_tix "
1193 "requires_preauth\n",
1194 "\t\trequires_hwauth needchange allow_svr "
1195 "password_changing_service\n");
1198 void kadmin_addprinc(argc
, argv
)
1202 kadm5_principal_ent_rec princ
, dprinc
;
1203 kadm5_policy_ent_rec defpol
;
1207 krb5_key_salt_tuple
*ks_tuple
;
1209 krb5_error_code retval
;
1210 static char newpw
[1024], dummybuf
[256];
1211 static char prompt1
[1024], prompt2
[1024];
1212 int local_kadmin
= 0;
1214 local_kadmin
= (strcmp(whoami
, KADMIN_LOCAL_NAME
) == 0);
1216 if (dummybuf
[0] == 0) {
1217 for (i
= 0; i
< 256; i
++)
1218 dummybuf
[i
] = (i
+1) % 256;
1221 /* Zero all fields in request structure */
1222 memset(&princ
, 0, sizeof(princ
));
1223 memset(&dprinc
, 0, sizeof(dprinc
));
1225 princ
.attributes
= dprinc
.attributes
= 0;
1226 if (kadmin_parse_princ_args(argc
, argv
,
1227 &princ
, &mask
, &pass
, &randkey
,
1228 &ks_tuple
, &n_ks_tuple
,
1230 kadmin_addprinc_usage("add_principal");
1231 kadmin_free_tl_data(&princ
); /* need to free ks_tuple also??? */
1235 retval
= krb5_unparse_name(context
, princ
.principal
, &canon
);
1237 com_err("add_principal",
1238 retval
, gettext("while canonicalizing principal"));
1239 krb5_free_principal(context
, princ
.principal
);
1240 if (ks_tuple
!= NULL
)
1242 kadmin_free_tl_data(&princ
);
1247 * If -policy was not specified, and -clearpolicy was not
1248 * specified, and the policy "default" exists, assign it. If
1249 * -clearpolicy was specified, then KADM5_POLICY_CLR should be
1250 * unset, since it is never valid for kadm5_create_principal.
1252 if ((! (mask
& KADM5_POLICY
)) &&
1253 (! (mask
& KADM5_POLICY_CLR
))) {
1254 if (! kadm5_get_policy(handle
, "default", &defpol
)) {
1256 gettext("NOTICE: no policy specified for %s; assigning \"default\"\n"),
1258 princ
.policy
= "default";
1259 mask
|= KADM5_POLICY
;
1260 (void) kadm5_free_policy_ent(handle
, &defpol
);
1263 gettext("WARNING: no policy specified for %s; defaulting to no policy\n"),
1266 mask
&= ~KADM5_POLICY_CLR
;
1269 * Set 'notix' for randkey principals and also for principals which have
1270 * specified flag options on the cmdline. This is because we want to apply
1271 * generic flag settings from 'default_principal_flags' first (during
1272 * principal creation), followed by a kadm5_modify_principal() which
1273 * correctly applies the cli flag options. So, we do *not* want any tix
1274 * issued in the interim.
1276 if (randkey
|| (mask
& KADM5_ATTRIBUTES
))
1277 princ
.attributes
|= KRB5_KDB_DISALLOW_ALL_TIX
;
1280 mask
|= KADM5_ATTRIBUTES
;
1282 } else if (pass
== NULL
) {
1283 unsigned int sz
= sizeof (newpw
) - 1;
1284 snprintf(prompt1
, sizeof (prompt1
),
1285 gettext("Enter password for principal \"%.900s\""),
1287 snprintf(prompt2
, sizeof (prompt1
),
1288 gettext("Re-enter password for principal \"%.900s\""),
1290 retval
= krb5_read_password(context
, prompt1
, prompt2
,
1293 com_err("add_principal", retval
,
1294 gettext("while reading password for \"%s\"."), canon
);
1296 krb5_free_principal(context
, princ
.principal
);
1297 kadmin_free_tl_data(&princ
);
1302 mask
|= KADM5_PRINCIPAL
;
1305 * If the client being used is local, always use the new
1306 * API so we get the full set of enctype support.
1308 if (ks_tuple
!= NULL
|| local_kadmin
) {
1309 retval
= kadm5_create_principal_3(handle
, &princ
, mask
,
1310 n_ks_tuple
, ks_tuple
, pass
);
1312 retval
= kadm5_create_principal(handle
, &princ
, mask
, pass
);
1315 com_err("add_principal", retval
,
1316 gettext("while creating \"%s\"."), canon
);
1317 krb5_free_principal(context
, princ
.principal
);
1319 if (ks_tuple
!= NULL
)
1321 kadmin_free_tl_data(&princ
);
1324 if (randkey
) { /* more special stuff for -randkey */
1325 if (ks_tuple
!= NULL
|| local_kadmin
) {
1326 retval
= kadm5_randkey_principal_3(handle
, princ
.principal
,
1328 n_ks_tuple
, ks_tuple
,
1331 retval
= kadm5_randkey_principal(handle
, princ
.principal
,
1335 com_err("add_principal", retval
,
1336 gettext("while randomizing key for \"%s\"."), canon
);
1337 krb5_free_principal(context
, princ
.principal
);
1339 if (ks_tuple
!= NULL
)
1341 kadmin_free_tl_data(&princ
);
1347 * We now retrieve the intersection set of the generic flag settings and
1348 * the ones specified on the cli & re-parse the princ args, just to make
1349 * sure we account for conflicts between 'default_principal_flags' and
1350 * the cmdline flag args. While we are here, also clear 'notix'.
1352 if (randkey
|| (mask
& KADM5_ATTRIBUTES
)) {
1353 retval
= kadm5_get_principal(handle
, princ
.principal
, &dprinc
,
1354 KADM5_PRINCIPAL_NORMAL_MASK
);
1356 if (dprinc
.attributes
!= 0)
1357 princ
.attributes
= dprinc
.attributes
;
1359 com_err("add_principal", retval
,
1360 gettext("while doing a get_principal on \"%s\"."), canon
);
1361 printf(gettext("\nWarning: Principal \"%s\" could have incomplete "
1362 "flag settings, as a result of a failed get_principal.\n"
1363 "Check the 'default_principal_flags' setting in kdc.conf(4).\n"
1364 "If there is a mismatch, use modprinc in kadmin(1M) to rectify "
1365 "the same.\n\n"), canon
);
1369 * Solaris Kerberos: We unset KRB5_KDB_DISALLOW_ALL_TIX before
1370 * kadmin_parse_princ_args is called, because -allow_tix may
1371 * have been an argument. We still have to unset here because
1372 * kadmin_parse_princ_args will not reset the attribute unless
1373 * it is was explicity defined.
1375 princ
.attributes
&= ~KRB5_KDB_DISALLOW_ALL_TIX
;
1376 (void) kadmin_parse_princ_args(argc
, argv
, &princ
, &mask
, &pass
,
1377 &randkey
, &ks_tuple
, &n_ks_tuple
, "add_principal");
1378 mask
= KADM5_ATTRIBUTES
;
1379 retval
= kadm5_modify_principal(handle
, &princ
, mask
);
1381 com_err("add_principal", retval
,
1382 gettext("while doing a modify_principal to restore flag "
1383 "settings for \"%s\"."), canon
);
1384 krb5_free_principal(context
, princ
.principal
);
1386 if (ks_tuple
!= NULL
)
1388 kadmin_free_tl_data(&princ
);
1392 krb5_free_principal(context
, princ
.principal
);
1393 printf(gettext("Principal \"%s\" created.\n"), canon
);
1394 if (ks_tuple
!= NULL
)
1397 kadmin_free_tl_data(&princ
);
1401 void kadmin_modprinc(argc
, argv
)
1405 kadm5_principal_ent_rec princ
, oldprinc
;
1406 krb5_principal kprinc
;
1408 krb5_error_code retval
;
1412 krb5_key_salt_tuple
*ks_tuple
;
1415 kadmin_modprinc_usage("modify_principal");
1419 memset(&oldprinc
, 0, sizeof(oldprinc
));
1420 memset(&princ
, 0, sizeof(princ
));
1422 retval
= kadmin_parse_name(argv
[argc
- 1], &kprinc
);
1424 com_err("modify_principal", retval
,
1425 gettext("while parsing principal"));
1428 retval
= krb5_unparse_name(context
, kprinc
, &canon
);
1430 com_err("modify_principal", retval
,
1431 gettext("while canonicalizing principal"));
1432 krb5_free_principal(context
, kprinc
);
1435 retval
= kadm5_get_principal(handle
, kprinc
, &oldprinc
,
1436 KADM5_PRINCIPAL_NORMAL_MASK
);
1437 krb5_free_principal(context
, kprinc
);
1439 com_err("modify_principal", retval
,
1440 gettext("while getting \"%s\"."), canon
);
1444 princ
.attributes
= oldprinc
.attributes
;
1445 kadm5_free_principal_ent(handle
, &oldprinc
);
1446 retval
= kadmin_parse_princ_args(argc
, argv
,
1449 &ks_tuple
, &n_ks_tuple
,
1450 "modify_principal");
1451 if (ks_tuple
!= NULL
) {
1453 kadmin_modprinc_usage("modify_principal");
1455 kadmin_free_tl_data(&princ
);
1459 kadmin_modprinc_usage("modify_principal");
1461 kadmin_free_tl_data(&princ
);
1465 fprintf(stderr
, "modify_principal: -randkey %s ",
1466 gettext("not allowed\n"));
1467 krb5_free_principal(context
, princ
.principal
);
1469 kadmin_free_tl_data(&princ
);
1474 "modify_principal: -pw %s change_password\n",
1475 gettext("not allowed; use"));
1476 krb5_free_principal(context
, princ
.principal
);
1478 kadmin_free_tl_data(&princ
);
1481 retval
= kadm5_modify_principal(handle
, &princ
, mask
);
1482 krb5_free_principal(context
, princ
.principal
);
1484 com_err("modify_principal", retval
,
1485 gettext("while modifying \"%s\"."), canon
);
1487 kadmin_free_tl_data(&princ
);
1490 printf(gettext("Principal \"%s\" modified.\n"), canon
);
1491 kadmin_free_tl_data(&princ
);
1495 void kadmin_getprinc(argc
, argv
)
1499 kadm5_principal_ent_rec dprinc
;
1500 krb5_principal princ
;
1501 krb5_error_code retval
;
1502 char *canon
, *modcanon
;
1506 (argc
== 3 && !strcmp("-terse", argv
[1])))) {
1507 fprintf(stderr
, "%s: get_principal [-terse] %s\n",
1508 gettext("usage"), gettext("principal"));
1513 memset(&dprinc
, 0, sizeof(dprinc
));
1514 memset(&princ
, 0, sizeof(princ
));
1516 retval
= kadmin_parse_name(argv
[argc
- 1], &princ
);
1518 com_err("get_principal", retval
,
1519 gettext("while parsing principal"));
1522 retval
= krb5_unparse_name(context
, princ
, &canon
);
1524 com_err("get_principal", retval
,
1525 gettext("while canonicalizing principal"));
1526 krb5_free_principal(context
, princ
);
1529 retval
= kadm5_get_principal(handle
, princ
, &dprinc
,
1530 KADM5_PRINCIPAL_NORMAL_MASK
| KADM5_KEY_DATA
);
1531 krb5_free_principal(context
, princ
);
1533 com_err("get_principal", retval
,
1534 gettext("while retrieving \"%s\"."), canon
);
1538 retval
= krb5_unparse_name(context
, dprinc
.mod_name
, &modcanon
);
1540 com_err("get_principal", retval
,
1541 gettext("while unparsing modname"));
1542 kadm5_free_principal_ent(handle
, &dprinc
);
1547 printf(gettext("Principal: %s\n"), canon
);
1548 printf(gettext("Expiration date: %s\n"),
1549 dprinc
.princ_expire_time
?
1550 strdate(dprinc
.princ_expire_time
) :
1551 gettext("[never]"));
1552 printf(gettext("Last password change: %s\n"),
1553 dprinc
.last_pwd_change
?
1554 strdate(dprinc
.last_pwd_change
) :
1555 gettext("[never]"));
1556 printf(gettext("Password expiration date: %s\n"),
1557 dprinc
.pw_expiration
?
1558 strdate(dprinc
.pw_expiration
) : gettext("[none]"));
1559 printf(gettext("Maximum ticket life: %s\n"),
1560 strdur(dprinc
.max_life
));
1561 printf(gettext("Maximum renewable life: %s\n"),
1562 strdur(dprinc
.max_renewable_life
));
1563 printf(gettext("Last modified: %s (%s)\n"),
1564 strdate(dprinc
.mod_date
), modcanon
);
1565 printf(gettext("Last successful authentication: %s\n"),
1566 dprinc
.last_success
? strdate(dprinc
.last_success
) :
1567 gettext("[never]"));
1568 printf(gettext("Last failed authentication: %s\n"),
1569 dprinc
.last_failed
? strdate(dprinc
.last_failed
) :
1570 gettext("[never]"));
1571 printf(gettext("Failed password attempts: %d\n"),
1572 dprinc
.fail_auth_count
);
1573 printf(gettext("Number of keys: %d\n"), dprinc
.n_key_data
);
1574 for (i
= 0; i
< dprinc
.n_key_data
; i
++) {
1575 krb5_key_data
*key_data
= &dprinc
.key_data
[i
];
1576 char enctype
[BUFSIZ
], salttype
[BUFSIZ
];
1578 if (krb5_enctype_to_string(key_data
->key_data_type
[0],
1579 enctype
, sizeof(enctype
)))
1580 snprintf(enctype
, sizeof (enctype
), gettext("<Encryption type 0x%x>"),
1581 key_data
->key_data_type
[0]);
1582 printf("Key: vno %d, %s, ", key_data
->key_data_kvno
, enctype
);
1583 if (key_data
->key_data_ver
> 1) {
1584 if (krb5_salttype_to_string(key_data
->key_data_type
[1],
1585 salttype
, sizeof(salttype
)))
1586 snprintf(salttype
, sizeof(salttype
), gettext("<Salt type 0x%x>"),
1587 key_data
->key_data_type
[1]);
1588 printf("%s\n", salttype
);
1590 printf(gettext("no salt\n"));
1593 printf(gettext("Attributes:"));
1594 for (i
= 0; i
< sizeof (prflags
) / sizeof (char *); i
++) {
1595 if (dprinc
.attributes
& (krb5_flags
) 1 << i
)
1596 printf(" %s", prflags
[i
]);
1599 printf(gettext("Policy: %s\n"),
1600 dprinc
.policy
? dprinc
.policy
: gettext("[none]"));
1602 printf("\"%s\"\t%d\t%d\t%d\t%d\t\"%s\"\t%d\t%d\t%d\t%d\t\"%s\""
1603 "\t%d\t%d\t%d\t%d\t%d",
1604 canon
, dprinc
.princ_expire_time
, dprinc
.last_pwd_change
,
1605 dprinc
.pw_expiration
, dprinc
.max_life
, modcanon
,
1606 dprinc
.mod_date
, dprinc
.attributes
, dprinc
.kvno
,
1607 dprinc
.mkvno
, dprinc
.policy
? dprinc
.policy
: gettext("[none]"),
1608 dprinc
.max_renewable_life
, dprinc
.last_success
,
1609 dprinc
.last_failed
, dprinc
.fail_auth_count
,
1611 for (i
= 0; i
< dprinc
.n_key_data
; i
++)
1612 printf("\t%d\t%d\t%d\t%d",
1613 dprinc
.key_data
[i
].key_data_ver
,
1614 dprinc
.key_data
[i
].key_data_kvno
,
1615 dprinc
.key_data
[i
].key_data_type
[0],
1616 dprinc
.key_data
[i
].key_data_type
[1]);
1620 kadm5_free_principal_ent(handle
, &dprinc
);
1624 void kadmin_getprincs(argc
, argv
)
1628 krb5_error_code retval
;
1629 char *expr
, **names
;
1634 struct sigaction nsig
, osig
;
1635 sigset_t nmask
, omask
;
1639 if (! (argc
== 1 || (argc
== 2 && (expr
= argv
[1])))) {
1640 fprintf(stderr
, "%s: get_principals %s\n",
1641 gettext("usage"), gettext("[expression]"));
1644 retval
= kadm5_get_principals(handle
, expr
, &names
, &count
);
1646 com_err("get_principals", retval
,
1647 gettext("while retrieving list."));
1652 * Solaris: the following code is used for paging
1655 sigemptyset(&nmask
);
1656 sigaddset(&nmask
, SIGINT
);
1657 sigprocmask(SIG_BLOCK
, &nmask
, &omask
);
1659 nsig
.sa_handler
= SIG_IGN
;
1660 sigemptyset(&nsig
.sa_mask
);
1662 sigaction(SIGINT
, &nsig
, &osig
);
1664 fd
= ss_pager_create();
1665 output
= fdopen(fd
, "w");
1667 sigprocmask(SIG_SETMASK
, &omask
, (sigset_t
*)0);
1669 for (i
= 0; i
< count
; i
++)
1670 fprintf(output
, "%s\n", names
[i
]);
1676 /* Solaris Kerberos:
1677 * Restore the original handler for SIGINT
1679 if (sigaction(SIGINT
, &osig
, (struct sigaction
*)0) == -1) {
1680 perror("sigaction");
1683 kadm5_free_name_list(handle
, names
, count
);
1687 kadmin_parse_policy_args(argc
, argv
, policy
, mask
, caller
)
1690 kadm5_policy_ent_t policy
;
1700 for (i
= 1; i
< argc
- 1; i
++) {
1701 if (strlen(argv
[i
]) == 8 &&
1702 !strcmp(argv
[i
], "-maxlife")) {
1706 date
= get_date(argv
[i
]);
1707 if (date
== (time_t)-1) {
1708 fprintf(stderr
, gettext("Invalid date specification \"%s\".\n"),
1712 policy
->pw_max_life
= date
- now
;
1713 *mask
|= KADM5_PW_MAX_LIFE
;
1716 } else if (strlen(argv
[i
]) == 8 &&
1717 !strcmp(argv
[i
], "-minlife")) {
1721 date
= get_date(argv
[i
]);
1722 if (date
== (time_t)-1) {
1723 fprintf(stderr
, gettext("Invalid date specification \"%s\".\n"),
1727 policy
->pw_min_life
= date
- now
;
1728 *mask
|= KADM5_PW_MIN_LIFE
;
1731 } else if (strlen(argv
[i
]) == 10 &&
1732 !strcmp(argv
[i
], "-minlength")) {
1736 policy
->pw_min_length
= atoi(argv
[i
]);
1737 *mask
|= KADM5_PW_MIN_LENGTH
;
1740 } else if (strlen(argv
[i
]) == 11 &&
1741 !strcmp(argv
[i
], "-minclasses")) {
1745 policy
->pw_min_classes
= atoi(argv
[i
]);
1746 *mask
|= KADM5_PW_MIN_CLASSES
;
1749 } else if (strlen(argv
[i
]) == 8 &&
1750 !strcmp(argv
[i
], "-history")) {
1754 policy
->pw_history_num
= atoi(argv
[i
]);
1755 *mask
|= KADM5_PW_HISTORY_NUM
;
1762 fprintf(stderr
, gettext("%s: parser lost count!\n"), caller
);
1769 kadmin_addmodpol_usage(func
)
1772 fprintf(stderr
, "%s: %s %s\n", gettext("usage"), func
,
1773 gettext("[options] policy"));
1774 fprintf(stderr
, gettext("\toptions are:\n"));
1775 fprintf(stderr
, "\t\t[-maxlife time] [-minlife time] "
1776 "[-minlength length]\n\t\t[-minclasses number] "
1777 "[-history number]\n");
1780 void kadmin_addpol(argc
, argv
)
1784 krb5_error_code retval
;
1786 kadm5_policy_ent_rec policy
;
1788 memset(&policy
, 0, sizeof(policy
));
1789 if (kadmin_parse_policy_args(argc
, argv
, &policy
, &mask
, "add_policy")) {
1790 kadmin_addmodpol_usage("add_policy");
1793 policy
.policy
= argv
[argc
- 1];
1794 mask
|= KADM5_POLICY
;
1795 retval
= kadm5_create_policy(handle
, &policy
, mask
);
1797 com_err("add_policy", retval
,
1798 gettext("while creating policy \"%s\"."),
1806 void kadmin_modpol(argc
, argv
)
1810 krb5_error_code retval
;
1812 kadm5_policy_ent_rec policy
;
1814 memset(&policy
, 0, sizeof(policy
));
1815 if (kadmin_parse_policy_args(argc
, argv
, &policy
, &mask
,
1817 kadmin_addmodpol_usage("modify_policy");
1820 policy
.policy
= argv
[argc
- 1];
1821 retval
= kadm5_modify_policy(handle
, &policy
, mask
);
1823 com_err("modify_policy", retval
, gettext("while modifying policy \"%s\"."),
1831 void kadmin_delpol(argc
, argv
)
1835 krb5_error_code retval
;
1839 (argc
== 3 && !strcmp("-force", argv
[1])))) {
1840 fprintf(stderr
, "%s: delete_policy [-force] %s\n",
1841 gettext("usage"), gettext("policy"));
1845 printf(gettext("Are you sure you want to delete the policy "
1846 "\"%s\"? (yes/no): "), argv
[1]);
1847 fgets(reply
, sizeof (reply
), stdin
);
1848 if (strncmp(gettext("yes\n"), reply
, sizeof (reply
)) &&
1849 strncmp(gettext("y\n"), reply
, sizeof (reply
)) &&
1850 strncmp(gettext("Y\n"), reply
, sizeof (reply
))
1853 gettext("Policy \"%s\" not deleted.\n"),
1858 retval
= kadm5_delete_policy(handle
, argv
[argc
- 1]);
1860 com_err("delete_policy:", retval
,
1861 gettext("while deleting policy \"%s\""),
1868 void kadmin_getpol(argc
, argv
)
1872 krb5_error_code retval
;
1873 kadm5_policy_ent_rec policy
;
1876 (argc
== 3 && !strcmp("-terse", argv
[1])))) {
1877 fprintf(stderr
, "%s: get_policy [-terse] %s\n",
1878 gettext("usage"), gettext("policy"));
1881 retval
= kadm5_get_policy(handle
, argv
[argc
- 1], &policy
);
1883 com_err("get_policy", retval
,
1884 gettext("while retrieving policy \"%s\"."),
1889 printf(gettext("Policy: %s\n"), policy
.policy
);
1890 printf(gettext("Maximum password life: %ld\n"),
1891 policy
.pw_max_life
);
1892 printf(gettext("Minimum password life: %ld\n"),
1893 policy
.pw_min_life
);
1894 printf(gettext("Minimum password length: %ld\n"),
1895 policy
.pw_min_length
);
1896 printf(gettext("Minimum number of password "
1897 "character classes: %ld\n"),
1898 policy
.pw_min_classes
);
1899 printf(gettext("Number of old keys kept: %ld\n"),
1900 policy
.pw_history_num
);
1901 printf(gettext("Reference count: %ld\n"), policy
.policy_refcnt
);
1903 printf("\"%s\"\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld\n",
1904 policy
.policy
, policy
.pw_max_life
, policy
.pw_min_life
,
1905 policy
.pw_min_length
, policy
.pw_min_classes
,
1906 policy
.pw_history_num
, policy
.policy_refcnt
);
1908 kadm5_free_policy_ent(handle
, &policy
);
1912 void kadmin_getpols(argc
, argv
)
1916 krb5_error_code retval
;
1917 char *expr
, **names
;
1920 /* Solaris Kerberos:
1921 * Use a pager for listing policies (similar to listing princs)
1923 FILE *output
= NULL
;
1925 struct sigaction nsig
, osig
;
1926 sigset_t nmask
, omask
;
1930 if (! (argc
== 1 || (argc
== 2 && (expr
= argv
[1])))) {
1931 fprintf(stderr
, "%s: get_policies %s\n",
1932 gettext("usage"), gettext("[expression]\n"));
1935 retval
= kadm5_get_policies(handle
, expr
, &names
, &count
);
1937 com_err("get_policies", retval
,
1938 gettext("while retrieving list."));
1942 if (sigemptyset(&nmask
) == -1) {
1943 perror("sigemptyset");
1944 kadm5_free_name_list(handle
, names
, count
);
1948 if (sigaddset(&nmask
, SIGINT
) == -1) {
1949 perror("sigaddset");
1950 kadm5_free_name_list(handle
, names
, count
);
1954 if (sigemptyset(&nsig
.sa_mask
) == -1) {
1955 perror("sigemptyset");
1956 kadm5_free_name_list(handle
, names
, count
);
1960 if (sigprocmask(SIG_BLOCK
, &nmask
, &omask
) == -1) {
1961 perror("sigprocmask");
1962 kadm5_free_name_list(handle
, names
, count
);
1966 nsig
.sa_handler
= SIG_IGN
;
1968 if (sigaction(SIGINT
, &nsig
, &osig
) == -1) {
1969 perror("sigaction");
1970 if (sigprocmask(SIG_SETMASK
, &omask
, (sigset_t
*)0) == -1) {
1971 perror("sigprocmask");
1973 kadm5_free_name_list(handle
, names
, count
);
1977 fd
= ss_pager_create();
1979 fprintf(stderr
, "%s: failed to create pager\n", whoami
);
1980 if (sigprocmask(SIG_SETMASK
, &omask
, (sigset_t
*)0) == -1) {
1981 perror("sigprocmask");
1984 if (sigaction(SIGINT
, &osig
, (struct sigaction
*)0) == -1) {
1985 perror("sigaction");
1988 kadm5_free_name_list(handle
, names
, count
);
1992 output
= fdopen(fd
, "w");
1993 if (output
== NULL
) {
1997 if (sigprocmask(SIG_SETMASK
, &omask
, (sigset_t
*)0) == -1) {
1998 perror("sigprocmask");
2001 if (output
!= NULL
) {
2002 for (i
= 0; i
< count
; i
++)
2003 fprintf(output
, "%s\n", names
[i
]);
2006 if (output
!= NULL
&& fclose(output
) != 0) {
2010 if (wait(&waitb
) == -1) {
2014 if (sigaction(SIGINT
, &osig
, (struct sigaction
*)0) == -1) {
2015 perror("sigaction");
2017 kadm5_free_name_list(handle
, names
, count
);