155682Smarkm/* 2178825Sdfr * Copyright (c) 1997 - 2004 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "kadmin_locl.h" 35178825Sdfr#include "kadmin-commands.h" 3655682Smarkm#include <sl.h> 3755682Smarkm 38178825SdfrRCSID("$Id: kadmin.c 22253 2007-12-09 06:00:00Z lha $"); 3955682Smarkm 4055682Smarkmstatic char *config_file; 4155682Smarkmstatic char *keyfile; 42178825Sdfrint local_flag; 43178825Sdfrstatic int ad_flag; 4455682Smarkmstatic int help_flag; 4555682Smarkmstatic int version_flag; 4655682Smarkmstatic char *realm; 4755682Smarkmstatic char *admin_server; 4855682Smarkmstatic int server_port = 0; 4955682Smarkmstatic char *client_name; 5078527Sassarstatic char *keytab; 51178825Sdfrstatic char *check_library = NULL; 52178825Sdfrstatic char *check_function = NULL; 53178825Sdfrstatic getarg_strings policy_libraries = { 0, NULL }; 5455682Smarkm 5555682Smarkmstatic struct getargs args[] = { 5655682Smarkm { "principal", 'p', arg_string, &client_name, 5755682Smarkm "principal to authenticate as" }, 5878527Sassar { "keytab", 'K', arg_string, &keytab, 59120945Snectar "keytab for authentication principal" }, 6055682Smarkm { 6155682Smarkm "config-file", 'c', arg_string, &config_file, 6255682Smarkm "location of config file", "file" 6355682Smarkm }, 6455682Smarkm { 6555682Smarkm "key-file", 'k', arg_string, &keyfile, 6655682Smarkm "location of master key file", "file" 6755682Smarkm }, 6855682Smarkm { 6955682Smarkm "realm", 'r', arg_string, &realm, 7055682Smarkm "realm to use", "realm" 7155682Smarkm }, 7255682Smarkm { 7355682Smarkm "admin-server", 'a', arg_string, &admin_server, 7455682Smarkm "server to contact", "host" 7555682Smarkm }, 7655682Smarkm { 7755682Smarkm "server-port", 's', arg_integer, &server_port, 7857416Smarkm "port to use", "port number" 7955682Smarkm }, 80178825Sdfr { "ad", 0, arg_flag, &ad_flag, "active directory admin mode" }, 81178825Sdfr#ifdef HAVE_DLOPEN 82178825Sdfr { "check-library", 0, arg_string, &check_library, 83178825Sdfr "library to load password check function from", "library" }, 84178825Sdfr { "check-function", 0, arg_string, &check_function, 85178825Sdfr "password check function to load", "function" }, 86178825Sdfr { "policy-libraries", 0, arg_strings, &policy_libraries, 87178825Sdfr "password check function to load", "function" }, 88178825Sdfr#endif 8955682Smarkm { "local", 'l', arg_flag, &local_flag, "local admin mode" }, 9055682Smarkm { "help", 'h', arg_flag, &help_flag }, 9155682Smarkm { "version", 'v', arg_flag, &version_flag } 9255682Smarkm}; 9355682Smarkm 9455682Smarkmstatic int num_args = sizeof(args) / sizeof(args[0]); 9555682Smarkm 9655682Smarkm 9755682Smarkmkrb5_context context; 9855682Smarkmvoid *kadm_handle; 9955682Smarkm 10055682Smarkmint 101178825Sdfrhelp(void *opt, int argc, char **argv) 10255682Smarkm{ 103178825Sdfr sl_slc_help(commands, argc, argv); 10455682Smarkm return 0; 10555682Smarkm} 10655682Smarkm 107178825Sdfrstatic int exit_seen = 0; 108178825Sdfr 10955682Smarkmint 110178825Sdfrexit_kadmin (void *opt, int argc, char **argv) 11155682Smarkm{ 112178825Sdfr exit_seen = 1; 113178825Sdfr return 0; 11455682Smarkm} 11555682Smarkm 11655682Smarkmstatic void 11755682Smarkmusage(int ret) 11855682Smarkm{ 11955682Smarkm arg_printusage (args, num_args, NULL, "[command]"); 12055682Smarkm exit (ret); 12155682Smarkm} 12255682Smarkm 12355682Smarkmint 124178825Sdfrget_privs(void *opt, int argc, char **argv) 12555682Smarkm{ 126178825Sdfr uint32_t privs; 12755682Smarkm char str[128]; 12855682Smarkm kadm5_ret_t ret; 12955682Smarkm 13055682Smarkm ret = kadm5_get_privs(kadm_handle, &privs); 13155682Smarkm if(ret) 13255682Smarkm krb5_warn(context, ret, "kadm5_get_privs"); 13355682Smarkm else{ 13455682Smarkm ret =_kadm5_privs_to_string(privs, str, sizeof(str)); 13555682Smarkm printf("%s\n", str); 13655682Smarkm } 13755682Smarkm return 0; 13855682Smarkm} 13955682Smarkm 14055682Smarkmint 14155682Smarkmmain(int argc, char **argv) 14255682Smarkm{ 14355682Smarkm krb5_error_code ret; 144178825Sdfr char **files; 14555682Smarkm kadm5_config_params conf; 146178825Sdfr int optidx = 0; 147178825Sdfr int exit_status = 0; 14855682Smarkm 14978527Sassar setprogname(argv[0]); 15055682Smarkm 15172445Sassar ret = krb5_init_context(&context); 15272445Sassar if (ret) 15372445Sassar errx (1, "krb5_init_context failed: %d", ret); 15490926Snectar 155178825Sdfr if(getarg(args, num_args, argc, argv, &optidx)) 15690926Snectar usage(1); 15755682Smarkm 15855682Smarkm if (help_flag) 15955682Smarkm usage (0); 16055682Smarkm 16155682Smarkm if (version_flag) { 16255682Smarkm print_version(NULL); 16355682Smarkm exit(0); 16455682Smarkm } 16555682Smarkm 166178825Sdfr argc -= optidx; 167178825Sdfr argv += optidx; 16855682Smarkm 169178825Sdfr if (config_file == NULL) { 170178825Sdfr asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); 171178825Sdfr if (config_file == NULL) 172178825Sdfr errx(1, "out of memory"); 17355682Smarkm } 17455682Smarkm 175178825Sdfr ret = krb5_prepend_config_files_default(config_file, &files); 176178825Sdfr if (ret) 177178825Sdfr krb5_err(context, 1, ret, "getting configuration files"); 178178825Sdfr 179178825Sdfr ret = krb5_set_config_files(context, files); 180178825Sdfr krb5_free_config_files(files); 181178825Sdfr if(ret) 182178825Sdfr krb5_err(context, 1, ret, "reading configuration files"); 183178825Sdfr 18455682Smarkm memset(&conf, 0, sizeof(conf)); 18555682Smarkm if(realm) { 18655682Smarkm krb5_set_default_realm(context, realm); /* XXX should be fixed 18755682Smarkm some other way */ 18855682Smarkm conf.realm = realm; 18955682Smarkm conf.mask |= KADM5_CONFIG_REALM; 19055682Smarkm } 19155682Smarkm 19255682Smarkm if (admin_server) { 19355682Smarkm conf.admin_server = admin_server; 19455682Smarkm conf.mask |= KADM5_CONFIG_ADMIN_SERVER; 19555682Smarkm } 19655682Smarkm 19755682Smarkm if (server_port) { 19855682Smarkm conf.kadmind_port = htons(server_port); 19955682Smarkm conf.mask |= KADM5_CONFIG_KADMIND_PORT; 20055682Smarkm } 20155682Smarkm 202178825Sdfr if (keyfile) { 203178825Sdfr conf.stash_file = keyfile; 204178825Sdfr conf.mask |= KADM5_CONFIG_STASH_FILE; 205178825Sdfr } 206178825Sdfr 207178825Sdfr if(local_flag) { 208178825Sdfr int i; 209178825Sdfr 210178825Sdfr kadm5_setup_passwd_quality_check (context, 211178825Sdfr check_library, check_function); 212178825Sdfr 213178825Sdfr for (i = 0; i < policy_libraries.num_strings; i++) { 214178825Sdfr ret = kadm5_add_passwd_quality_verifier(context, 215178825Sdfr policy_libraries.strings[i]); 216178825Sdfr if (ret) 217178825Sdfr krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); 218178825Sdfr } 219178825Sdfr ret = kadm5_add_passwd_quality_verifier(context, NULL); 220178825Sdfr if (ret) 221178825Sdfr krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); 222178825Sdfr 22355682Smarkm ret = kadm5_s_init_with_password_ctx(context, 22455682Smarkm KADM5_ADMIN_SERVICE, 22555682Smarkm NULL, 22655682Smarkm KADM5_ADMIN_SERVICE, 22755682Smarkm &conf, 0, 0, 22855682Smarkm &kadm_handle); 229178825Sdfr } else if (ad_flag) { 230178825Sdfr if (client_name == NULL) 231178825Sdfr krb5_errx(context, 1, "keytab mode require principal name"); 232178825Sdfr ret = kadm5_ad_init_with_password_ctx(context, 233178825Sdfr client_name, 234178825Sdfr NULL, 235178825Sdfr KADM5_ADMIN_SERVICE, 236178825Sdfr &conf, 0, 0, 237178825Sdfr &kadm_handle); 23878527Sassar } else if (keytab) { 239178825Sdfr if (client_name == NULL) 240178825Sdfr krb5_errx(context, 1, "keytab mode require principal name"); 24178527Sassar ret = kadm5_c_init_with_skey_ctx(context, 24278527Sassar client_name, 24378527Sassar keytab, 24478527Sassar KADM5_ADMIN_SERVICE, 24578527Sassar &conf, 0, 0, 24678527Sassar &kadm_handle); 247178825Sdfr } else 24855682Smarkm ret = kadm5_c_init_with_password_ctx(context, 24955682Smarkm client_name, 25055682Smarkm NULL, 25155682Smarkm KADM5_ADMIN_SERVICE, 25255682Smarkm &conf, 0, 0, 25355682Smarkm &kadm_handle); 25455682Smarkm 25555682Smarkm if(ret) 25655682Smarkm krb5_err(context, 1, ret, "kadm5_init_with_password"); 25772445Sassar 25872445Sassar signal(SIGINT, SIG_IGN); /* ignore signals for now, the sl command 25972445Sassar parser will handle SIGINT its own way; 26072445Sassar we should really take care of this in 26172445Sassar each function, f.i `get' might be 26272445Sassar interruptable, but not `create' */ 26355682Smarkm if (argc != 0) { 264178825Sdfr ret = sl_command (commands, argc, argv); 26555682Smarkm if(ret == -1) 26655682Smarkm krb5_warnx (context, "unrecognized command: %s", argv[0]); 267178825Sdfr else if (ret == -2) 268178825Sdfr ret = 0; 269178825Sdfr if(ret != 0) 270178825Sdfr exit_status = 1; 271178825Sdfr } else { 272178825Sdfr while(!exit_seen) { 273178825Sdfr ret = sl_command_loop(commands, "kadmin> ", NULL); 274178825Sdfr if (ret == -2) 275178825Sdfr exit_seen = 1; 276178825Sdfr else if (ret != 0) 277178825Sdfr exit_status = 1; 278178825Sdfr } 279178825Sdfr } 28055682Smarkm 28155682Smarkm kadm5_destroy(kadm_handle); 28255682Smarkm krb5_free_context(context); 283178825Sdfr return exit_status; 28455682Smarkm} 285