155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2004 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "kadmin_locl.h" 35178825Sdfr#include "kadmin-commands.h" 3655682Smarkm#include <sl.h> 3755682Smarkm 3855682Smarkmstatic char *config_file; 3955682Smarkmstatic char *keyfile; 40178825Sdfrint local_flag; 41178825Sdfrstatic int ad_flag; 4255682Smarkmstatic int help_flag; 4355682Smarkmstatic int version_flag; 4455682Smarkmstatic char *realm; 4555682Smarkmstatic char *admin_server; 4655682Smarkmstatic int server_port = 0; 4755682Smarkmstatic char *client_name; 4878527Sassarstatic char *keytab; 49178825Sdfrstatic char *check_library = NULL; 50178825Sdfrstatic char *check_function = NULL; 51178825Sdfrstatic getarg_strings policy_libraries = { 0, NULL }; 5255682Smarkm 5355682Smarkmstatic struct getargs args[] = { 5455682Smarkm { "principal", 'p', arg_string, &client_name, 55233294Sstas "principal to authenticate as", NULL }, 5678527Sassar { "keytab", 'K', arg_string, &keytab, 57233294Sstas "keytab for authentication principal", NULL }, 58233294Sstas { 59233294Sstas "config-file", 'c', arg_string, &config_file, 60233294Sstas "location of config file", "file" 6155682Smarkm }, 6255682Smarkm { 63233294Sstas "key-file", 'k', arg_string, &keyfile, 6455682Smarkm "location of master key file", "file" 6555682Smarkm }, 66233294Sstas { 67233294Sstas "realm", 'r', arg_string, &realm, 68233294Sstas "realm to use", "realm" 6955682Smarkm }, 70233294Sstas { 71233294Sstas "admin-server", 'a', arg_string, &admin_server, 72233294Sstas "server to contact", "host" 7355682Smarkm }, 74233294Sstas { 75233294Sstas "server-port", 's', arg_integer, &server_port, 76233294Sstas "port to use", "port number" 7755682Smarkm }, 78233294Sstas { "ad", 0, arg_flag, &ad_flag, "active directory admin mode", 79233294Sstas NULL }, 80178825Sdfr#ifdef HAVE_DLOPEN 81233294Sstas { "check-library", 0, arg_string, &check_library, 82178825Sdfr "library to load password check function from", "library" }, 83178825Sdfr { "check-function", 0, arg_string, &check_function, 84178825Sdfr "password check function to load", "function" }, 85178825Sdfr { "policy-libraries", 0, arg_strings, &policy_libraries, 86178825Sdfr "password check function to load", "function" }, 87178825Sdfr#endif 88233294Sstas { "local", 'l', arg_flag, &local_flag, "local admin mode", NULL }, 89233294Sstas { "help", 'h', arg_flag, &help_flag, NULL, NULL }, 90233294Sstas { "version", 'v', arg_flag, &version_flag, NULL, NULL } 9155682Smarkm}; 9255682Smarkm 9355682Smarkmstatic int num_args = sizeof(args) / sizeof(args[0]); 9455682Smarkm 9555682Smarkm 9655682Smarkmkrb5_context context; 9755682Smarkmvoid *kadm_handle; 9855682Smarkm 9955682Smarkmint 100178825Sdfrhelp(void *opt, int argc, char **argv) 10155682Smarkm{ 102178825Sdfr sl_slc_help(commands, argc, argv); 10355682Smarkm return 0; 10455682Smarkm} 10555682Smarkm 106178825Sdfrstatic int exit_seen = 0; 107178825Sdfr 10855682Smarkmint 109178825Sdfrexit_kadmin (void *opt, int argc, char **argv) 11055682Smarkm{ 111178825Sdfr exit_seen = 1; 112178825Sdfr return 0; 11355682Smarkm} 11455682Smarkm 11555682Smarkmstatic void 11655682Smarkmusage(int ret) 11755682Smarkm{ 11855682Smarkm arg_printusage (args, num_args, NULL, "[command]"); 11955682Smarkm exit (ret); 12055682Smarkm} 12155682Smarkm 12255682Smarkmint 123178825Sdfrget_privs(void *opt, int argc, char **argv) 12455682Smarkm{ 125178825Sdfr uint32_t privs; 12655682Smarkm char str[128]; 12755682Smarkm kadm5_ret_t ret; 128233294Sstas 12955682Smarkm ret = kadm5_get_privs(kadm_handle, &privs); 13055682Smarkm if(ret) 13155682Smarkm krb5_warn(context, ret, "kadm5_get_privs"); 13255682Smarkm else{ 13355682Smarkm ret =_kadm5_privs_to_string(privs, str, sizeof(str)); 134233294Sstas if (ret == 0) 135233294Sstas printf("%s\n", str); 136233294Sstas else 137233294Sstas printf("privs: 0x%x\n", (unsigned int)privs); 13855682Smarkm } 13955682Smarkm return 0; 14055682Smarkm} 14155682Smarkm 14255682Smarkmint 14355682Smarkmmain(int argc, char **argv) 14455682Smarkm{ 14555682Smarkm krb5_error_code ret; 146178825Sdfr char **files; 14755682Smarkm kadm5_config_params conf; 148178825Sdfr int optidx = 0; 149178825Sdfr int exit_status = 0; 15055682Smarkm 15178527Sassar setprogname(argv[0]); 15255682Smarkm 15372445Sassar ret = krb5_init_context(&context); 15472445Sassar if (ret) 15572445Sassar errx (1, "krb5_init_context failed: %d", ret); 156233294Sstas 157178825Sdfr if(getarg(args, num_args, argc, argv, &optidx)) 15890926Snectar usage(1); 15955682Smarkm 16055682Smarkm if (help_flag) 16155682Smarkm usage (0); 16255682Smarkm 16355682Smarkm if (version_flag) { 16455682Smarkm print_version(NULL); 16555682Smarkm exit(0); 16655682Smarkm } 16755682Smarkm 168178825Sdfr argc -= optidx; 169178825Sdfr argv += optidx; 17055682Smarkm 171178825Sdfr if (config_file == NULL) { 172178825Sdfr asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); 173178825Sdfr if (config_file == NULL) 174178825Sdfr errx(1, "out of memory"); 17555682Smarkm } 17655682Smarkm 177178825Sdfr ret = krb5_prepend_config_files_default(config_file, &files); 178178825Sdfr if (ret) 179178825Sdfr krb5_err(context, 1, ret, "getting configuration files"); 180233294Sstas 181178825Sdfr ret = krb5_set_config_files(context, files); 182178825Sdfr krb5_free_config_files(files); 183233294Sstas if(ret) 184178825Sdfr krb5_err(context, 1, ret, "reading configuration files"); 185233294Sstas 18655682Smarkm memset(&conf, 0, sizeof(conf)); 18755682Smarkm if(realm) { 18855682Smarkm krb5_set_default_realm(context, realm); /* XXX should be fixed 18955682Smarkm some other way */ 19055682Smarkm conf.realm = realm; 19155682Smarkm conf.mask |= KADM5_CONFIG_REALM; 19255682Smarkm } 19355682Smarkm 19455682Smarkm if (admin_server) { 19555682Smarkm conf.admin_server = admin_server; 19655682Smarkm conf.mask |= KADM5_CONFIG_ADMIN_SERVER; 19755682Smarkm } 19855682Smarkm 19955682Smarkm if (server_port) { 20055682Smarkm conf.kadmind_port = htons(server_port); 20155682Smarkm conf.mask |= KADM5_CONFIG_KADMIND_PORT; 20255682Smarkm } 20355682Smarkm 204178825Sdfr if (keyfile) { 205178825Sdfr conf.stash_file = keyfile; 206178825Sdfr conf.mask |= KADM5_CONFIG_STASH_FILE; 207178825Sdfr } 208178825Sdfr 209178825Sdfr if(local_flag) { 210178825Sdfr int i; 211178825Sdfr 212233294Sstas kadm5_setup_passwd_quality_check (context, 213178825Sdfr check_library, check_function); 214233294Sstas 215178825Sdfr for (i = 0; i < policy_libraries.num_strings; i++) { 216233294Sstas ret = kadm5_add_passwd_quality_verifier(context, 217178825Sdfr policy_libraries.strings[i]); 218178825Sdfr if (ret) 219178825Sdfr krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); 220178825Sdfr } 221178825Sdfr ret = kadm5_add_passwd_quality_verifier(context, NULL); 222178825Sdfr if (ret) 223178825Sdfr krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); 224233294Sstas 225233294Sstas ret = kadm5_s_init_with_password_ctx(context, 22655682Smarkm KADM5_ADMIN_SERVICE, 22755682Smarkm NULL, 22855682Smarkm KADM5_ADMIN_SERVICE, 229233294Sstas &conf, 0, 0, 23055682Smarkm &kadm_handle); 231178825Sdfr } else if (ad_flag) { 232178825Sdfr if (client_name == NULL) 233178825Sdfr krb5_errx(context, 1, "keytab mode require principal name"); 234178825Sdfr ret = kadm5_ad_init_with_password_ctx(context, 235178825Sdfr client_name, 236178825Sdfr NULL, 237178825Sdfr KADM5_ADMIN_SERVICE, 238178825Sdfr &conf, 0, 0, 239178825Sdfr &kadm_handle); 24078527Sassar } else if (keytab) { 241178825Sdfr if (client_name == NULL) 242178825Sdfr krb5_errx(context, 1, "keytab mode require principal name"); 24378527Sassar ret = kadm5_c_init_with_skey_ctx(context, 24478527Sassar client_name, 24578527Sassar keytab, 24678527Sassar KADM5_ADMIN_SERVICE, 24778527Sassar &conf, 0, 0, 24878527Sassar &kadm_handle); 249178825Sdfr } else 250233294Sstas ret = kadm5_c_init_with_password_ctx(context, 25155682Smarkm client_name, 25255682Smarkm NULL, 25355682Smarkm KADM5_ADMIN_SERVICE, 254233294Sstas &conf, 0, 0, 25555682Smarkm &kadm_handle); 256233294Sstas 25755682Smarkm if(ret) 25855682Smarkm krb5_err(context, 1, ret, "kadm5_init_with_password"); 25972445Sassar 26072445Sassar signal(SIGINT, SIG_IGN); /* ignore signals for now, the sl command 26172445Sassar parser will handle SIGINT its own way; 26272445Sassar we should really take care of this in 26372445Sassar each function, f.i `get' might be 26472445Sassar interruptable, but not `create' */ 26555682Smarkm if (argc != 0) { 266178825Sdfr ret = sl_command (commands, argc, argv); 26755682Smarkm if(ret == -1) 26855682Smarkm krb5_warnx (context, "unrecognized command: %s", argv[0]); 269178825Sdfr else if (ret == -2) 270178825Sdfr ret = 0; 271178825Sdfr if(ret != 0) 272178825Sdfr exit_status = 1; 273178825Sdfr } else { 274178825Sdfr while(!exit_seen) { 275178825Sdfr ret = sl_command_loop(commands, "kadmin> ", NULL); 276178825Sdfr if (ret == -2) 277178825Sdfr exit_seen = 1; 278178825Sdfr else if (ret != 0) 279178825Sdfr exit_status = 1; 280178825Sdfr } 281178825Sdfr } 28255682Smarkm 28355682Smarkm kadm5_destroy(kadm_handle); 28455682Smarkm krb5_free_context(context); 285178825Sdfr return exit_status; 28655682Smarkm} 287