krb5 commit: Support kadmin script mode
Greg Hudson
ghudson at mit.edu
Thu Feb 19 12:46:23 EST 2015
https://github.com/krb5/krb5/commit/040fe97758bdf53b6c00815b0306410eb88ea5ec
commit 040fe97758bdf53b6c00815b0306410eb88ea5ec
Author: Greg Hudson <ghudson at mit.edu>
Date: Fri Jan 30 12:48:15 2015 -0500
Support kadmin script mode
Add support for a command and argments to be specified on the kadmin
command line, with script-friendly behavior. kadmin_startup() now
yields either a request string or a request argv array, and sets
script_mode in the argv array case. Informational messages now go
through info() and are suppressed if script_mode is set. Prompts and
warning messages are also suppressed in script mode. Error messages
indicating a failure now go through error() and set exit_status if
script_mode is set. The extended com_err() hook is always installed
so that com_err messages go through error() and set exit_status.
getopt() is now invoked with a leading '+' to suppress Gnu getopt
argument reordering behavior, so that invokers don't need to pass "--"
to prevent query options from being treated as kadmin options.
Non-Gnu getopt implementations should harmlessly treat '+' as a valid
flag option, which has no effect as it will reach the same default
label in the switch statement.
ticket: 7991
doc/admin/admin_commands/kadmin_local.rst | 23 ++-
src/kadmin/cli/kadmin.c | 351 ++++++++++++++++-------------
src/kadmin/cli/kadmin.h | 3 +-
src/kadmin/cli/ss_wrapper.c | 18 +-
4 files changed, 224 insertions(+), 171 deletions(-)
diff --git a/doc/admin/admin_commands/kadmin_local.rst b/doc/admin/admin_commands/kadmin_local.rst
index faf7105..5572b34 100644
--- a/doc/admin/admin_commands/kadmin_local.rst
+++ b/doc/admin/admin_commands/kadmin_local.rst
@@ -16,6 +16,7 @@ SYNOPSIS
[[**-c** *cache_name*]\|[**-k** [**-t** *keytab*]]\|\ **-n**]
[**-w** *password*]
[**-s** *admin_server*\ [:*port*]]
+[command args...]
**kadmin.local**
[**-r** *realm*]
@@ -25,6 +26,7 @@ SYNOPSIS
[**-e** *enc*:*salt* ...]
[**-m**]
[**-x** *db_args*]
+[command args...]
.. _kadmin_synopsis_end:
@@ -112,8 +114,7 @@ OPTIONS
via the process list.
**-q** *query*
- Perform the specified query and then exit. This can be useful for
- writing scripts.
+ Perform the specified query and then exit.
**-d** *dbname*
Specifies the name of the KDC database. This option does not
@@ -143,6 +144,24 @@ OPTIONS
.. _kadmin_options_end:
+Starting with release 1.14, if any command-line arguments remain after
+the options, they will be treated as a single query to be executed.
+This mode of operation is intended for scripts and behaves differently
+from the interactive mode in several respects:
+
+* Query arguments are split by the shell, not by kadmin.
+* Informational and warning messages are suppressed. Error messages
+ and query output (e.g. for **get_principal**) will still be
+ displayed.
+* Confirmation prompts are disabled (as if **-force** was given).
+ Password prompts will still be issued as required.
+* The exit status will be non-zero if the query fails.
+
+The **-q** option does not carry these behavior differences; the query
+will be processed as if it was entered interactively. The **-q**
+option cannot be used in combination with a query in the remaining
+arguments.
+
.. _dboptions:
DATABASE OPTIONS
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index a81036c..defc0fe 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -101,6 +101,7 @@ static char *prflags[] = {
"NO_AUTH_DATA_REQUIRED", /* 0x00400000 */
};
+static krb5_boolean script_mode = FALSE;
int exit_status = 0;
char *def_realm = NULL;
char *whoami = NULL;
@@ -112,19 +113,59 @@ char *ccache_name = NULL;
int locked = 0;
static void
+info(const char *fmt, ...)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+ __attribute__((__format__(__printf__, 1, 2)))
+#endif
+ ;
+
+static void
+error(const char *fmt, ...)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+ __attribute__((__format__(__printf__, 1, 2)))
+#endif
+ ;
+
+/* Like printf, but suppressed if script_mode is set. */
+static void
+info(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (script_mode)
+ return;
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
+/* Like fprintf to stderr; also set exit_status if script_mode is set. */
+static void
+error(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (script_mode)
+ exit_status = 1;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+static void
usage()
{
- fprintf(stderr,
- _("Usage: %s [-r realm] [-p principal] [-q query] "
- "[clnt|local args]\n"
- "\tclnt args: [-s admin_server[:port]] "
- "[[-c ccache]|[-k [-t keytab]]]|[-n]\n"
- "\tlocal args: [-x db_args]* [-d dbname] "
- "[-e \"enc:salt ...\"] [-m]\n"
- "where,\n\t[-x db_args]* - any number of database specific "
- "arguments.\n"
- "\t\t\tLook at each database documentation for supported "
- "arguments\n"), whoami);
+ error(_("Usage: %s [-r realm] [-p principal] [-q query] "
+ "[clnt|local args]\n"
+ " [command args...]\n"
+ "\tclnt args: [-s admin_server[:port]] "
+ "[[-c ccache]|[-k [-t keytab]]]|[-n]\n"
+ "\tlocal args: [-x db_args]* [-d dbname] "
+ "[-e \"enc:salt ...\"] [-m]"
+ "where,\n\t[-x db_args]* - any number of database specific "
+ "arguments.\n"
+ "\t\t\tLook at each database documentation for supported "
+ "arguments\n"), whoami);
exit(1);
}
@@ -200,13 +241,13 @@ extended_com_err_fn(const char *myprog, errcode_t code,
if (code) {
emsg = krb5_get_error_message(context, code);
- fprintf(stderr, "%s: %s ", myprog, emsg);
+ error("%s: %s ", myprog, emsg);
krb5_free_error_message(context, emsg);
} else {
- fprintf(stderr, "%s: ", myprog);
+ error("%s: ", myprog);
}
vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
+ error("\n");
}
/* Create a principal using the oldest appropriate kadm5 API. */
@@ -252,8 +293,8 @@ policy_exists(const char *name)
return TRUE;
}
-char *
-kadmin_startup(int argc, char *argv[])
+void
+kadmin_startup(int argc, char *argv[], char **request_out, char ***args_out)
{
extern char *optarg;
char *princstr = NULL, *keytab_name = NULL, *query = NULL;
@@ -272,8 +313,7 @@ kadmin_startup(int argc, char *argv[])
memset(¶ms, 0, sizeof(params));
- if (strcmp(whoami, "kadmin.local") == 0)
- set_com_err_hook(extended_com_err_fn);
+ set_com_err_hook(extended_com_err_fn);
retval = kadm5_init_krb5_context(&context);
if (retval) {
@@ -282,15 +322,13 @@ kadmin_startup(int argc, char *argv[])
}
while ((optchar = getopt(argc, argv,
- "x:r:p:knq:w:d:s:mc:t:e:ON")) != EOF) {
+ "+x:r:p:knq:w:d:s:mc:t:e:ON")) != EOF) {
switch (optchar) {
case 'x':
db_args_size++;
db_args = realloc(db_args, sizeof(char*) * (db_args_size + 1));
if (db_args == NULL) {
- fprintf(stderr,
- _("%s: Cannot initialize. Not enough memory\n"),
- argv[0]);
+ error(_("%s: Cannot initialize. Not enough memory\n"), whoami);
exit(1);
}
db_args[db_args_size - 1] = optarg;
@@ -329,9 +367,7 @@ kadmin_startup(int argc, char *argv[])
db_args_size++;
db_args = realloc(db_args, sizeof(char*) * (db_args_size + 1));
if (db_args == NULL) {
- fprintf(stderr,
- _("%s: Cannot initialize. Not enough memory\n"),
- argv[0]);
+ error(_("%s: Cannot initialize. Not enough memory\n"), whoami);
exit(1);
}
db_args[db_args_size - 1] = db_name;
@@ -372,8 +408,16 @@ kadmin_startup(int argc, char *argv[])
(use_anonymous && use_keytab))
usage();
+ if (query != NULL && argv[optind] != NULL) {
+ error(_("%s: -q is exclusive with command-line query"), whoami);
+ usage();
+ }
+
+ if (argv[optind] != NULL)
+ script_mode = TRUE;
+
if (def_realm == NULL && krb5_get_default_realm(context, &def_realm)) {
- fprintf(stderr, _("%s: unable to get default realm\n"), whoami);
+ error(_("%s: unable to get default realm\n"), whoami);
exit(1);
}
@@ -421,7 +465,7 @@ kadmin_startup(int argc, char *argv[])
if (use_anonymous) {
if (asprintf(&princstr, "%s/%s@%s", KRB5_WELLKNOWN_NAMESTR,
KRB5_ANONYMOUS_PRINCSTR, def_realm) < 0) {
- fprintf(stderr, _("%s: out of memory\n"), whoami);
+ error(_("%s: out of memory\n"), whoami);
exit(1);
}
freeprinc++;
@@ -452,8 +496,7 @@ kadmin_startup(int argc, char *argv[])
freeprinc++;
} else if (!krb5_cc_get_principal(context, cc, &princ)) {
if (krb5_unparse_name(context, princ, &canon)) {
- fprintf(stderr, _("%s: unable to canonicalize principal\n"),
- whoami);
+ error(_("%s: unable to canonicalize principal\n"), whoami);
exit(1);
}
/* Strip out realm of principal if it's there. */
@@ -476,7 +519,7 @@ kadmin_startup(int argc, char *argv[])
if (asprintf(&princstr, "%s/admin%s%s", canon,
(realm) ? "@" : "",
(realm) ? realm : "") < 0) {
- fprintf(stderr, _("%s: out of memory\n"), whoami);
+ error(_("%s: out of memory\n"), whoami);
exit(1);
}
free(canon);
@@ -484,20 +527,19 @@ kadmin_startup(int argc, char *argv[])
freeprinc++;
} else if ((luser = getenv("USER"))) {
if (asprintf(&princstr, "%s/admin@%s", luser, def_realm) < 0) {
- fprintf(stderr, _("%s: out of memory\n"), whoami);
+ error(_("%s: out of memory\n"), whoami);
exit(1);
}
freeprinc++;
} else if ((pw = getpwuid(getuid()))) {
if (asprintf(&princstr, "%s/admin@%s", pw->pw_name,
def_realm) < 0) {
- fprintf(stderr, _("%s: out of memory\n"), whoami);
+ error(_("%s: out of memory\n"), whoami);
exit(1);
}
freeprinc++;
} else {
- fprintf(stderr, _("%s: unable to figure out a principal name\n"),
- whoami);
+ error(_("%s: unable to figure out a principal name\n"), whoami);
exit(1);
}
}
@@ -513,30 +555,31 @@ kadmin_startup(int argc, char *argv[])
* use it. Otherwise, use/prompt for the password.
*/
if (ccache_name) {
- printf(_("Authenticating as principal %s with existing "
- "credentials.\n"), princstr);
+ info(_("Authenticating as principal %s with existing "
+ "credentials.\n"), princstr);
retval = kadm5_init_with_creds(context, princstr, cc, svcname, ¶ms,
KADM5_STRUCT_VERSION,
KADM5_API_VERSION_4, db_args, &handle);
} else if (use_anonymous) {
- printf(_("Authenticating as principal %s with password; "
- "anonymous requested.\n"), princstr);
+ info(_("Authenticating as principal %s with password; "
+ "anonymous requested.\n"), princstr);
retval = kadm5_init_anonymous(context, princstr, svcname, ¶ms,
KADM5_STRUCT_VERSION,
KADM5_API_VERSION_4, db_args, &handle);
} else if (use_keytab) {
- if (keytab_name)
- printf(_("Authenticating as principal %s with keytab %s.\n"),
- princstr, keytab_name);
- else
- printf(_("Authenticating as principal %s with default keytab.\n"),
- princstr);
+ if (keytab_name != NULL) {
+ info(_("Authenticating as principal %s with keytab %s.\n"),
+ princstr, keytab_name);
+ } else {
+ info(_("Authenticating as principal %s with default keytab.\n"),
+ princstr);
+ }
retval = kadm5_init_with_skey(context, princstr, keytab_name, svcname,
¶ms, KADM5_STRUCT_VERSION,
KADM5_API_VERSION_4, db_args, &handle);
} else {
- printf(_("Authenticating as principal %s with password.\n"),
- princstr);
+ info(_("Authenticating as principal %s with password.\n"),
+ princstr);
retval = kadm5_init_with_password(context, princstr, password, svcname,
¶ms, KADM5_STRUCT_VERSION,
KADM5_API_VERSION_4, db_args,
@@ -567,7 +610,8 @@ kadmin_startup(int argc, char *argv[])
exit(1);
}
- return query;
+ *request_out = query;
+ *args_out = argv + optind;
}
int
@@ -585,7 +629,7 @@ quit()
}
kadm5_destroy(handle);
- if (ccache_name != NULL) {
+ if (ccache_name != NULL && !script_mode) {
fprintf(stderr, "\n\a\a\a%s",
_("Administration credentials NOT DESTROYED.\n"));
}
@@ -636,7 +680,7 @@ kadmin_delprinc(int argc, char *argv[])
if (! (argc == 2 ||
(argc == 3 && !strcmp("-force", argv[1])))) {
- fprintf(stderr, _("usage: delete_principal [-force] principal\n"));
+ error(_("usage: delete_principal [-force] principal\n"));
return;
}
retval = kadmin_parse_name(argv[argc - 1], &princ);
@@ -650,7 +694,7 @@ kadmin_delprinc(int argc, char *argv[])
_("while canonicalizing principal"));
goto cleanup;
}
- if (argc == 2) {
+ if (argc == 2 && !script_mode) {
printf(_("Are you sure you want to delete the principal \"%s\"? "
"(yes/no): "), canon);
fgets(reply, sizeof (reply), stdin);
@@ -665,9 +709,9 @@ kadmin_delprinc(int argc, char *argv[])
_("while deleting principal \"%s\""), canon);
goto cleanup;
}
- printf(_("Principal \"%s\" deleted.\n"), canon);
- printf(_("Make sure that you have removed this principal from all ACLs "
- "before reusing.\n"));
+ info(_("Principal \"%s\" deleted.\n"), canon);
+ info(_("Make sure that you have removed this principal from all ACLs "
+ "before reusing.\n"));
cleanup:
krb5_free_principal(context, princ);
@@ -683,8 +727,8 @@ kadmin_renameprinc(int argc, char *argv[])
char reply[5];
if (!(argc == 3 || (argc == 4 && !strcmp("-force", argv[1])))) {
- fprintf(stderr, _("usage: rename_principal [-force] old_principal "
- "new_principal\n"));
+ error(_("usage: rename_principal [-force] old_principal "
+ "new_principal\n"));
return;
}
retval = kadmin_parse_name(argv[argc - 2], &oprinc);
@@ -711,7 +755,7 @@ kadmin_renameprinc(int argc, char *argv[])
_("while canonicalizing new principal"));
goto cleanup;
}
- if (argc == 3) {
+ if (argc == 3 && !script_mode) {
printf(_("Are you sure you want to rename the principal \"%s\" "
"to \"%s\"? (yes/no): "), ocanon, ncanon);
fgets(reply, sizeof(reply), stdin);
@@ -727,9 +771,9 @@ kadmin_renameprinc(int argc, char *argv[])
ocanon, ncanon);
goto cleanup;
}
- printf(_("Principal \"%s\" renamed to \"%s\".\n"), ocanon, ncanon);
- printf(_("Make sure that you have removed the old principal from all ACLs "
- "before reusing.\n"));
+ info(_("Principal \"%s\" renamed to \"%s\".\n"), ocanon, ncanon);
+ info(_("Make sure that you have removed the old principal from all ACLs "
+ "before reusing.\n"));
cleanup:
krb5_free_principal(context, nprinc);
@@ -742,9 +786,9 @@ static void
cpw_usage(const char *str)
{
if (str)
- fprintf(stderr, "%s\n", str);
- fprintf(stderr, _("usage: change_password [-randkey] [-keepold] "
- "[-e keysaltlist] [-pw password] principal\n"));
+ error("%s\n", str);
+ error(_("usage: change_password [-randkey] [-keepold] "
+ "[-e keysaltlist] [-pw password] principal\n"));
}
void
@@ -775,7 +819,7 @@ kadmin_cpw(int argc, char *argv[])
db_args_size++;
db_args = realloc(db_args, sizeof(char*) * (db_args_size + 1));
if (db_args == NULL) {
- fprintf(stderr, _("change_password: Not enough memory\n"));
+ error(_("change_password: Not enough memory\n"));
exit(1);
}
db_args[db_args_size - 1] = *++argv;
@@ -837,7 +881,7 @@ kadmin_cpw(int argc, char *argv[])
_("while changing password for \"%s\"."), canon);
goto cleanup;
}
- printf(_("Password for \"%s\" changed.\n"), canon);
+ info(_("Password for \"%s\" changed.\n"), canon);
} else if (randkey) {
retval = randkey_princ(handle, princ, keepold, n_ks_tuple, ks_tuple,
NULL, NULL);
@@ -846,7 +890,7 @@ kadmin_cpw(int argc, char *argv[])
_("while randomizing key for \"%s\"."), canon);
goto cleanup;
}
- printf(_("Key for \"%s\" randomized.\n"), canon);
+ info(_("Key for \"%s\" randomized.\n"), canon);
} else {
unsigned int i = sizeof (newpw) - 1;
@@ -874,7 +918,7 @@ kadmin_cpw(int argc, char *argv[])
_("while changing password for \"%s\"."), canon);
goto cleanup;
}
- printf(_("Password for \"%s\" changed.\n"), canon);
+ info(_("Password for \"%s\" changed.\n"), canon);
}
cleanup:
free(canon);
@@ -912,7 +956,7 @@ add_tl_data(krb5_int16 *n_tl_datap, krb5_tl_data **tl_datap,
copy = malloc(len);
tl_data = calloc(1, sizeof(*tl_data));
if (copy == NULL || tl_data == NULL) {
- fprintf(stderr, _("Not enough memory\n"));
+ error(_("Not enough memory\n"));
exit(1);
}
memcpy(copy, contents, len);
@@ -991,8 +1035,7 @@ kadmin_parse_princ_args(int argc, char *argv[], kadm5_principal_ent_t oprinc,
return -1;
date = get_date(argv[i]);
if (date == (time_t)-1) {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
oprinc->princ_expire_time = date;
@@ -1004,8 +1047,7 @@ kadmin_parse_princ_args(int argc, char *argv[], kadm5_principal_ent_t oprinc,
return -1;
date = get_date(argv[i]);
if (date == (time_t)-1) {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
oprinc->pw_expiration = date;
@@ -1017,8 +1059,7 @@ kadmin_parse_princ_args(int argc, char *argv[], kadm5_principal_ent_t oprinc,
return -1;
date = get_date(argv[i]);
if (date == (time_t)-1) {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
oprinc->max_life = date - now;
@@ -1030,8 +1071,7 @@ kadmin_parse_princ_args(int argc, char *argv[], kadm5_principal_ent_t oprinc,
return -1;
date = get_date(argv[i]);
if (date == (time_t)-1) {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
oprinc->max_renewable_life = date - now;
@@ -1124,55 +1164,46 @@ kadmin_parse_princ_args(int argc, char *argv[], kadm5_principal_ent_t oprinc,
static void
kadmin_addprinc_usage()
{
- fprintf(stderr, _("usage: add_principal [options] principal\n"));
- fprintf(stderr, _("\toptions are:\n"));
- fprintf(stderr,
- _("\t\t[-randkey|-nokey] [-x db_princ_args]* [-expire expdate] "
- "[-pwexpire pwexpdate] [-maxlife maxtixlife]\n"
- "\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n"
- "\t\t[-pw password] [-maxrenewlife maxrenewlife]\n"
- "\t\t[-e keysaltlist]\n\t\t[{+|-}attribute]\n")
- );
- fprintf(stderr, _("\tattributes are:\n"));
- fprintf(stderr,
- _("\t\tallow_postdated allow_forwardable allow_tgs_req "
- "allow_renewable\n"
- "\t\tallow_proxiable allow_dup_skey allow_tix requires_preauth\n"
- "\t\trequires_hwauth needchange allow_svr "
- "password_changing_service\n"
- "\t\tok_as_delegate ok_to_auth_as_delegate "
- "no_auth_data_required\n"
- "\nwhere,\n\t[-x db_princ_args]* - any number of database "
- "specific arguments.\n"
- "\t\t\tLook at each database documentation for supported "
- "arguments\n"));
+ error(_("usage: add_principal [options] principal\n"));
+ error(_("\toptions are:\n"));
+ error(_("\t\t[-randkey|-nokey] [-x db_princ_args]* [-expire expdate] "
+ "[-pwexpire pwexpdate] [-maxlife maxtixlife]\n"
+ "\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n"
+ "\t\t[-pw password] [-maxrenewlife maxrenewlife]\n"
+ "\t\t[-e keysaltlist]\n\t\t[{+|-}attribute]\n"));
+ error(_("\tattributes are:\n"));
+ error(_("\t\tallow_postdated allow_forwardable allow_tgs_req "
+ "allow_renewable\n"
+ "\t\tallow_proxiable allow_dup_skey allow_tix requires_preauth\n"
+ "\t\trequires_hwauth needchange allow_svr "
+ "password_changing_service\n"
+ "\t\tok_as_delegate ok_to_auth_as_delegate no_auth_data_required\n"
+ "\nwhere,\n\t[-x db_princ_args]* - any number of database "
+ "specific arguments.\n"
+ "\t\t\tLook at each database documentation for supported "
+ "arguments\n"));
}
static void
kadmin_modprinc_usage()
{
- fprintf(stderr, _("usage: modify_principal [options] principal\n"));
- fprintf(stderr, _("\toptions are:\n"));
- fprintf(stderr,
- _("\t\t[-x db_princ_args]* [-expire expdate] "
- "[-pwexpire pwexpdate] [-maxlife maxtixlife]\n"
- "\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n"
- "\t\t[-maxrenewlife maxrenewlife] [-unlock] "
- "[{+|-}attribute]\n"));
- fprintf(stderr, "\tattributes are:\n");
- fprintf(stderr,
- _("\t\tallow_postdated allow_forwardable allow_tgs_req "
- "allow_renewable\n"
- "\t\tallow_proxiable allow_dup_skey allow_tix "
- "requires_preauth\n"
- "\t\trequires_hwauth needchange allow_svr "
- "password_changing_service\n"
- "\t\tok_as_delegate ok_to_auth_as_delegate "
- "no_auth_data_required\n"
- "\nwhere,\n\t[-x db_princ_args]* - any number of database "
- "specific arguments.\n"
- "\t\t\tLook at each database documentation for supported "
- "arguments\n"));
+ error(_("usage: modify_principal [options] principal\n"));
+ error(_("\toptions are:\n"));
+ error(_("\t\t[-x db_princ_args]* [-expire expdate] "
+ "[-pwexpire pwexpdate] [-maxlife maxtixlife]\n"
+ "\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n"
+ "\t\t[-maxrenewlife maxrenewlife] [-unlock] [{+|-}attribute]\n"));
+ error(_("\tattributes are:\n"));
+ error(_("\t\tallow_postdated allow_forwardable allow_tgs_req "
+ "allow_renewable\n"
+ "\t\tallow_proxiable allow_dup_skey allow_tix requires_preauth\n"
+ "\t\trequires_hwauth needchange allow_svr "
+ "password_changing_service\n"
+ "\t\tok_as_delegate ok_to_auth_as_delegate no_auth_data_required\n"
+ "\nwhere,\n\t[-x db_princ_args]* - any number of database "
+ "specific arguments.\n"
+ "\t\t\tLook at each database documentation for supported "
+ "arguments\n"));
}
/* Create a dummy password for old-style (pre-1.8) randkey creation. */
@@ -1220,20 +1251,23 @@ kadmin_addprinc(int argc, char *argv[])
if (mask & KADM5_POLICY) {
/* Warn if the specified policy does not exist. */
- if (!policy_exists(princ.policy)) {
+ if (!script_mode && !policy_exists(princ.policy)) {
fprintf(stderr, _("WARNING: policy \"%s\" does not exist\n"),
princ.policy);
}
} else if (!(mask & KADM5_POLICY_CLR)) {
/* If the policy "default" exists, assign it. */
if (policy_exists("default")) {
- fprintf(stderr, _("NOTICE: no policy specified for %s; "
- "assigning \"default\"\n"), canon);
+ if (!script_mode) {
+ fprintf(stderr, _("NOTICE: no policy specified for %s; "
+ "assigning \"default\"\n"), canon);
+ }
princ.policy = "default";
mask |= KADM5_POLICY;
- } else
+ } else if (!script_mode) {
fprintf(stderr, _("WARNING: no policy specified for %s; "
"defaulting to no policy\n"), canon);
+ }
}
/* Don't send KADM5_POLICY_CLR to the server. */
mask &= ~KADM5_POLICY_CLR;
@@ -1273,8 +1307,8 @@ kadmin_addprinc(int argc, char *argv[])
old_style_randkey = 1;
}
if (retval == KADM5_BAD_MASK && nokey) {
- fprintf(stderr, _("Admin server does not support -nokey while "
- "creating \"%s\"\n"), canon);
+ error(_("Admin server does not support -nokey while creating "
+ "\"%s\"\n"), canon);
goto cleanup;
}
if (retval) {
@@ -1299,7 +1333,7 @@ kadmin_addprinc(int argc, char *argv[])
goto cleanup;
}
}
- printf("Principal \"%s\" created.\n", canon);
+ info("Principal \"%s\" created.\n", canon);
cleanup:
krb5_free_principal(context, princ.principal);
@@ -1358,7 +1392,7 @@ kadmin_modprinc(int argc, char *argv[])
}
if (mask & KADM5_POLICY) {
/* Warn if the specified policy does not exist. */
- if (!policy_exists(princ.policy)) {
+ if (!script_mode && !policy_exists(princ.policy)) {
fprintf(stderr, _("WARNING: policy \"%s\" does not exist\n"),
princ.policy);
}
@@ -1372,7 +1406,7 @@ kadmin_modprinc(int argc, char *argv[])
canon);
goto cleanup;
}
- printf(_("Principal \"%s\" modified.\n"), canon);
+ info(_("Principal \"%s\" modified.\n"), canon);
cleanup:
krb5_free_principal(context, kprinc);
krb5_free_principal(context, princ.principal);
@@ -1393,7 +1427,7 @@ kadmin_getprinc(int argc, char *argv[])
size_t j;
if (!(argc == 2 || (argc == 3 && !strcmp("-terse", argv[1])))) {
- fprintf(stderr, _("usage: get_principal [-terse] principal\n"));
+ error(_("usage: get_principal [-terse] principal\n"));
return;
}
@@ -1514,7 +1548,7 @@ kadmin_getprincs(int argc, char *argv[])
expr = NULL;
if (!(argc == 1 || (argc == 2 && (expr = argv[1])))) {
- fprintf(stderr, _("usage: get_principals [expression]\n"));
+ error(_("usage: get_principals [expression]\n"));
return;
}
retval = kadm5_get_principals(handle, expr, &names, &count);
@@ -1543,8 +1577,7 @@ kadmin_parse_policy_args(int argc, char *argv[], kadm5_policy_ent_t policy,
return -1;
date = get_date(argv[i]);
if (date == (time_t)-1) {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
policy->pw_max_life = date - now;
@@ -1555,8 +1588,7 @@ kadmin_parse_policy_args(int argc, char *argv[], kadm5_policy_ent_t policy,
return -1;
date = get_date(argv[i]);
if (date == (time_t)-1) {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
policy->pw_min_life = date - now;
@@ -1598,8 +1630,7 @@ kadmin_parse_policy_args(int argc, char *argv[], kadm5_policy_ent_t policy,
else if (isdigit(*argv[i]))
policy->pw_failcnt_interval = atoi(argv[i]);
else {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
*mask |= KADM5_PW_FAILURE_COUNT_INTERVAL;
@@ -1615,8 +1646,7 @@ kadmin_parse_policy_args(int argc, char *argv[], kadm5_policy_ent_t policy,
else if (isdigit(*argv[i]))
policy->pw_lockout_duration = atoi(argv[i]);
else {
- fprintf(stderr, _("Invalid date specification \"%s\".\n"),
- argv[i]);
+ error(_("Invalid date specification \"%s\".\n"), argv[i]);
return -1;
}
*mask |= KADM5_PW_LOCKOUT_DURATION;
@@ -1644,7 +1674,7 @@ kadmin_parse_policy_args(int argc, char *argv[], kadm5_policy_ent_t policy,
return -1;
}
if (i != argc -1) {
- fprintf(stderr, _("%s: parser lost count!\n"), caller);
+ error(_("%s: parser lost count!\n"), caller);
return -1;
} else
return 0;
@@ -1653,14 +1683,13 @@ kadmin_parse_policy_args(int argc, char *argv[], kadm5_policy_ent_t policy,
static void
kadmin_addmodpol_usage(char *func)
{
- fprintf(stderr, _("usage; %s [options] policy\n"), func);
- fprintf(stderr, _("\toptions are:\n"));
- fprintf(stderr,
- _("\t\t[-maxlife time] [-minlife time] [-minlength length]\n"
- "\t\t[-minclasses number] [-history number]\n"
- "\t\t[-maxfailure number] [-failurecountinterval time]\n"
- "\t\t[-allowedkeysalts keysalts]\n"));
- fprintf(stderr, _("\t\t[-lockoutduration time]\n"));
+ error(_("usage; %s [options] policy\n"), func);
+ error(_("\toptions are:\n"));
+ error(_("\t\t[-maxlife time] [-minlife time] [-minlength length]\n"
+ "\t\t[-minclasses number] [-history number]\n"
+ "\t\t[-maxfailure number] [-failurecountinterval time]\n"
+ "\t\t[-allowedkeysalts keysalts]\n"));
+ error(_("\t\t[-lockoutduration time]\n"));
}
void
@@ -1712,10 +1741,10 @@ kadmin_delpol(int argc, char *argv[])
char reply[5];
if (!(argc == 2 || (argc == 3 && !strcmp("-force", argv[1])))) {
- fprintf(stderr, _("usage: delete_policy [-force] policy\n"));
+ error(_("usage: delete_policy [-force] policy\n"));
return;
}
- if (argc == 2) {
+ if (argc == 2 && !script_mode) {
printf(_("Are you sure you want to delete the policy \"%s\"? "
"(yes/no): "), argv[1]);
fgets(reply, sizeof(reply), stdin);
@@ -1738,7 +1767,7 @@ kadmin_getpol(int argc, char *argv[])
kadm5_policy_ent_rec policy;
if (!(argc == 2 || (argc == 3 && !strcmp("-terse", argv[1])))) {
- fprintf(stderr, _("usage: get_policy [-terse] policy\n"));
+ error(_("usage: get_policy [-terse] policy\n"));
return;
}
retval = kadm5_get_policy(handle, argv[argc - 1], &policy);
@@ -1786,7 +1815,7 @@ kadmin_getpols(int argc, char *argv[])
expr = NULL;
if (!(argc == 1 || (argc == 2 && (expr = argv[1])))) {
- fprintf(stderr, _("usage: get_policies [expression]\n"));
+ error(_("usage: get_policies [expression]\n"));
return;
}
retval = kadm5_get_policies(handle, expr, &names, &count);
@@ -1808,7 +1837,7 @@ kadmin_getprivs(int argc, char *argv[])
long plist;
if (argc != 1) {
- fprintf(stderr, _("usage: get_privs\n"));
+ error(_("usage: get_privs\n"));
return;
}
retval = kadm5_get_privs(handle, &plist);
@@ -1842,8 +1871,8 @@ kadmin_purgekeys(int argc, char *argv[])
pname = argv[1];
}
if (pname == NULL) {
- fprintf(stderr, _("usage: purgekeys "
- "[-all|-keepkvno oldest_kvno_to_keep] principal\n"));
+ error(_("usage: purgekeys [-all|-keepkvno oldest_kvno_to_keep] "
+ "principal\n"));
return;
}
@@ -1867,9 +1896,9 @@ kadmin_purgekeys(int argc, char *argv[])
}
if (keepkvno == KRB5_INT32_MAX)
- printf(_("All keys for principal \"%s\" removed.\n"), canon);
+ info(_("All keys for principal \"%s\" removed.\n"), canon);
else
- printf(_("Old keys for principal \"%s\" purged.\n"), canon);
+ info(_("Old keys for principal \"%s\" purged.\n"), canon);
cleanup:
krb5_free_principal(context, princ);
free(canon);
@@ -1886,7 +1915,7 @@ kadmin_getstrings(int argc, char *argv[])
int count, i;
if (argc != 2) {
- fprintf(stderr, _("usage: get_strings principal\n"));
+ error(_("usage: get_strings principal\n"));
return;
}
pname = argv[1];
@@ -1930,7 +1959,7 @@ kadmin_setstring(int argc, char *argv[])
krb5_principal princ = NULL;
if (argc != 4) {
- fprintf(stderr, _("usage: set_string principal key value\n"));
+ error(_("usage: set_string principal key value\n"));
return;
}
pname = argv[1];
@@ -1956,7 +1985,7 @@ kadmin_setstring(int argc, char *argv[])
goto cleanup;
}
- printf(_("Attribute set for principal \"%s\".\n"), canon);
+ info(_("Attribute set for principal \"%s\".\n"), canon);
cleanup:
krb5_free_principal(context, princ);
free(canon);
@@ -1971,7 +2000,7 @@ kadmin_delstring(int argc, char *argv[])
krb5_principal princ = NULL;
if (argc != 3) {
- fprintf(stderr, _("usage: del_string principal key\n"));
+ error(_("usage: del_string principal key\n"));
return;
}
pname = argv[1];
@@ -1996,7 +2025,7 @@ kadmin_delstring(int argc, char *argv[])
goto cleanup;
}
- printf(_("Attribute removed from principal \"%s\".\n"), canon);
+ info(_("Attribute removed from principal \"%s\".\n"), canon);
cleanup:
krb5_free_principal(context, princ);
free(canon);
diff --git a/src/kadmin/cli/kadmin.h b/src/kadmin/cli/kadmin.h
index 9cff390..72bda93 100644
--- a/src/kadmin/cli/kadmin.h
+++ b/src/kadmin/cli/kadmin.h
@@ -33,7 +33,8 @@
#define __KADMIN_H__
/* It would be nice if ss produced a header file we could reference */
-extern char *kadmin_startup(int argc, char *argv[]);
+extern void kadmin_startup(int argc, char *argv[], char **request_out,
+ char ***args_out);
extern int quit (void);
extern void kadmin_lock(int argc, char *argv[]);
extern void kadmin_unlock(int argc, char *argv[]);
diff --git a/src/kadmin/cli/ss_wrapper.c b/src/kadmin/cli/ss_wrapper.c
index bd368a8..d9a1d8f 100644
--- a/src/kadmin/cli/ss_wrapper.c
+++ b/src/kadmin/cli/ss_wrapper.c
@@ -36,26 +36,30 @@ extern char *whoami;
int
main(int argc, char *argv[])
{
- char *request;
+ char *request, **args;
krb5_error_code retval;
int sci_idx, code = 0;
setlocale(LC_ALL, "");
whoami = ((whoami = strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
- request = kadmin_startup(argc, argv);
+ kadmin_startup(argc, argv, &request, &args);
sci_idx = ss_create_invocation(whoami, "5.0", NULL, &kadmin_cmds, &retval);
if (retval) {
ss_perror(sci_idx, retval, _("creating invocation"));
exit(1);
}
- if (request) {
- code = ss_execute_line(sci_idx, request);
+ if (request == NULL && *args == NULL) {
+ (void)ss_listen(sci_idx);
+ } else {
+ if (request != NULL)
+ code = ss_execute_line(sci_idx, request);
+ else
+ code = ss_execute_command(sci_idx, args);
if (code != 0) {
ss_perror(sci_idx, code, request);
- exit_status++;
+ exit_status = 1;
}
- } else
- retval = ss_listen(sci_idx);
+ }
return quit() ? 1 : exit_status;
}
More information about the cvs-krb5
mailing list