diff options
Diffstat (limited to 'crypto/heimdal/lib/kadm5')
66 files changed, 6833 insertions, 1604 deletions
diff --git a/crypto/heimdal/lib/kadm5/ChangeLog b/crypto/heimdal/lib/kadm5/ChangeLog index 51b559b..9b1235c 100644 --- a/crypto/heimdal/lib/kadm5/ChangeLog +++ b/crypto/heimdal/lib/kadm5/ChangeLog @@ -1,35 +1,756 @@ -2003-12-30 Love Hörnquist Åstrand <lha@it.su.se> +2008-01-21 Love Hörnquist Åstrand <lha@it.su.se> - * chpass_s.c: from 1.14->1.15: - (change): fix same-password-again by decrypting keys and setting - an error code. From: Buck Huppmann <buckh@pobox.com> + * default_keys.c: Use hdb_free_keys(). + +2008-01-11 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: add check-cracklib.pl, flush.c, + sample_passwd_check.c + +2007-12-07 Love Hörnquist Åstrand <lha@it.su.se> + + * use hdb_db_dir() and hdb_default_db() + +2007-10-18 Love <lha@stacken.kth.se> + + * init_c.c: We are getting default_client, not client. this way + the user can override the result. + +2007-09-29 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop.8: fix spelling, From Antoine Jacoutt. + +2007-08-16 Love Hörnquist Åstrand <lha@it.su.se> + + * version-script.map: export _kadm5_unmarshal_params, + _kadm5_acl_check_permission + + * version-script.map: export kadm5_log_ symbols. + + * log.c: Unexport the specific log replay operations. + +2007-08-10 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: build sample_passwd_check.la as part of noinst. + + * sample_passwd_check.c: Add missing prototype for check_length(). + +2007-08-07 Love Hörnquist Åstrand <lha@it.su.se> + + * log.c: Sprinkle krb5_set_error_string(). + + * ipropd_slave.c: Provide better error why kadm5_log_replay + failed. + +2007-08-06 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_master.c: - don't push whole database to the new client + every time. - make slaves get the whole new database if they have + a newer log the the master (and thus have them go back in time). + +2007-08-03 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c: make more sane. + + * ipropd_slave.c: more paranoid check that the log entires are + self consistant + + * log.c (kadm5_log_foreach): check that the postamble contains the + right data. + + * ipropd_master.c: Sprinkle more info about what versions the + master thinks about the client versions. + + * ipropd_master.c: Start the server at the current version, not 0. + +2007-08-02 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_master.c: Add more logging, to figure out what is + happening in the master. + +2007-08-01 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: add version-script for libkadm5srv.la + + * version-script.map: version script fro kadm5 server libary. + + * log.c: only free the orignal entries extentions if there was + any. Bug reported by Peter Meinecke. + + * add configuration for signal file and acl file, let user select + hostname, catch signals and print why we are quiting, make nop + cause one new version, not two + +2007-07-30 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_master.c (send_diffs): make current slave's version + uptodate when diff have been sent. + +2007-07-27 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c: More comments and some more error checking. + +2007-07-26 Love Hörnquist Åstrand <lha@it.su.se> + + * init_c.c (get_cache_principal): make sure id is reset if we + fail. From Benjamin Bennet. + +2007-07-10 Love Hörnquist Åstrand <lha@it.su.se> + + * context_s.c (find_db_spec): match realm-less as the default + realm. + + * Makefile.am: New library version. + +2007-07-05 Love Hörnquist Åstrand <lha@it.su.se> + + * context_s.c: Use hdb_get_dbinfo to pick up configuration. + ctx->config.realm can be NULL, check for that, from Bjorn S. + +2007-07-04 Love Hörnquist Åstrand <lha@it.su.se> + + * init_c.c: Try harder to use the right principal. + +2007-06-20 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c: Catch return value from krb5_program_setup. From + Steven Luo. + +2007-05-08 Love Hörnquist Åstrand <lha@it.su.se> + + * delete_s.c: Write log entry after store is successful, rename + out goto statments. + + * randkey_s.c: Write log entry after store is successful. + + * modify_s.c: Write log entry after store is successful. + + * rename_s.c: indent. + + * chpass_s.c: Write log entry after store is successful. + + * create_s.c: Write log entry after store is successful. + +2007-05-07 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop-commands.in: Add default values to make this working + again. + + * iprop-log.c (iprop_replay): create the database with more + liberal mode. + + * log.c: make it slightly more working. + + * iprop-log.8: Document last-version. + + * iprop-log.c: (last_version): print last version of the log. + + * iprop-commands.in: new command last-version: print last version + of the log. + + * log.c (kadm5_log_previous): document assumptions and make less + broken. Bug report from Ronny Blomme. + +2007-02-17 Love Hörnquist Åstrand <lha@it.su.se> + + * admin.h: add support to get aliases + + * get_s.c: add support to get aliases + +2007-02-11 David Love <fx@gnu.org> + + * iprop-log.8: Small fixes, from David Love. + +2006-12-15 Love Hörnquist Åstrand <lha@it.su.se> + + * init_c.c: if the user have a kadmin/admin initial ticket, don't + ask for password, just use the credential instead. + +2006-12-06 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_master.c: Use strcspn to remove \n from string returned + by fgets. From Björn Sandell + +2006-11-30 Love Hörnquist Åstrand <lha@it.su.se> + + * init_c.c (kadm_connect): clear error string before trying to + print a errno, this way we don't pick up a random failure code + +2006-11-20 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c: Make krb5_get_init_creds_opt_free take a context + argument. + + * init_c.c: Make krb5_get_init_creds_opt_free take a context + argument. + +2006-10-22 Love Hörnquist Åstrand <lha@it.su.se> + + * ent_setup.c: Try to not leak memory. + +2006-10-07 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: split build files into dist_ and noinst_ SOURCES + +2006-08-24 Love Hörnquist Åstrand <lha@it.su.se> + + * get_s.c: Add KRB5_KDB_ALLOW_DIGEST + + * ent_setup.c: Add KRB5_KDB_ALLOW_DIGEST + + * admin.h: Add KRB5_KDB_ALLOW_DIGEST + +2006-06-16 Love Hörnquist Åstrand <lha@it.su.se> + + * check-cracklib.pl: Add password reuse checking. From Harald + Barth. + +2006-06-14 Love Hörnquist Åstrand <lha@it.su.se> + + * ent_setup.c (attr_to_flags): Add KRB5_KDB_ALLOW_KERBEROS4 + + * get_s.c (kadm5_s_get_principal): Add KRB5_KDB_ALLOW_KERBEROS4 + + * admin.h: Add KRB5_KDB_ALLOW_KERBEROS4 + +2006-06-06 Love Hörnquist Åstrand <lha@it.su.se> + + * ent_setup.c (attr_to_flags): Add KRB5_KDB_TRUSTED_FOR_DELEGATION + +2006-05-30 Love Hörnquist Åstrand <lha@it.su.se> + + * password_quality.c (kadm5_check_password_quality): set error + message in context. + +2006-05-13 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop-log.c: Avoid shadowing. + + * rename_s.c: Avoid shadowing. + +2006-05-08 Love Hörnquist Åstrand <lha@it.su.se> + + * privs_c.c (kadm5_c_get_privs): privs is a uint32_t, let copy it + that way. + +2006-05-05 Love Hörnquist Åstrand <lha@it.su.se> + + * Rename u_intXX_t to uintXX_t + +2006-04-27 Love Hörnquist Åstrand <lha@it.su.se> + + * chpass_s.c,delete_s.c,get_s.c,log.c,modify_s.c,randkey_s.c,rename_s.c: + Pass in HDB_F_GET_ANY to all ->hdb fetch to hint what entries we are looking for + + * send_recv.c: set and clear error string + + * rename_s.c: Break out the that we request from principal from + the entry and pass it in as a separate argument. + + * randkey_s.c: Break out the that we request from principal from + the entry and pass it in as a separate argument. + + * modify_s.c: Break out the that we request from principal from + the entry and pass it in as a separate argument. + + * log.c: Break out the that we request from principal from the + entry and pass it in as a separate argument. + + * get_s.c: Break out the that we request from principal from the + entry and pass it in as a separate argument. + + * delete_s.c: Break out the that we request from principal from + the entry and pass it in as a separate argument. + + * chpass_s.c: Break out the that we request from principal from + the entry and pass it in as a separate argument. + +2006-04-25 Love Hörnquist Åstrand <lha@it.su.se> + + * create_s.c (create_principal*): If client doesn't send kvno, + make sure to set it to 1. + +2006-04-10 Love Hörnquist Åstrand <lha@it.su.se> + + * log.c: (kadm5_log_rename): handle errors better + Fixes Coverity, NetBSD CID#628 + + * log.c (kadm5_log_delete): add error handling Coverity, NetBSD + CID#626 + (kadm5_log_modify): add error handling Coverity, NetBSD CID#627 + + * init_c.c (_kadm5_c_get_cred_cache): handle ccache case better in + case no client name was passed in. Coverity, NetBSD CID#919 + + * init_c.c (_kadm5_c_get_cred_cache): Free client principal in + case of error. Coverity NetBSD CID#1908 + +2006-02-02 Love Hörnquist Åstrand <lha@it.su.se> + + * kadm5_err.et: (PASS_REUSE): Spelling, + from Václav H?la <ax@natur.cuni.cz> + +2006-01-25 Love Hörnquist Åstrand <lha@it.su.se> + + * send_recv.c: Clear error-string when introducing new errors. + + * *_c.c: Clear error-string when introducing new errors. + +2006-01-15 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am (libkadm5clnt.la) doesn't depend on libhdb, remove + dependency + +2005-12-13 Love Hörnquist Åstrand <lha@it.su.se> + + * memset hdb_entry_ex before use + +2005-12-12 Love Hörnquist Åstrand <lha@it.su.se> + + * Wrap hdb_entry with hdb_entry_ex, patch originally + from Andrew Bartlet + +2005-11-30 Love Hörnquist Åstrand <lha@it.su.se> + + * context_s.c (set_field): try another way to calculate the path + to the database/logfile/signal-socket + + * log.c (kadm5_log_init): set error string on failures + +2005-09-08 Love Hörnquist Åstrand <lha@it.su.se> + + * Constify password. + + * admin.h: Add KRB5_TL_PKINIT_ACL. + + * marshall.c (_kadm5_unmarshal_params): avoid signed-ness warnings + + * get_s.c (kadm5_s_get_principal): clear error string + +2005-08-25 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop-log.8: More text about iprop-log. + +2005-08-24 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop.8: SEE ALSO iprop-log. + + * Makefile.am: man_MANS += iprop-log.8 + + * iprop-log.8: Basic for documentation of iprop-log. + + * remove replay_log.c, dump_log.c, and truncate_log.c, folded into + iprop-log. + + * log.c (kadm5_log_foreach): add a context variable and pass it + down to `func´. + + * iprop-commands.in: Move truncate_log and replay_log into + iprop-log. + + * iprop-log.c: Move truncate_log and replay_log into iprop-log. + + * Makefile.am: Move truncate_log and replay_log into iprop-log. + + * Makefile.am: Make this work with a clean directory. + + * ipropd_master.c: Make compile. + + * ipropd_master.c: Update to new signature of kadm5_log_previous. + + * log.c (kadm5_log_previous): catch errors instead of asserting + and set error string. + + * iprop-commands.in: New program iprop-log that incorperates + dump_log as a subcommand, truncate_log and replay_log soon to come + after. + + * iprop-log.c: New program iprop-log that incorperates dump_log as + a subcommand, truncate_log and replay_log soon to come after. + + * Makefile.am: New program iprop-log that incorperates dump_log as + a subcommand, truncate_log and replay_log soon to come after. + +2005-08-11 Love Hörnquist Åstrand <lha@it.su.se> + + * get_s.c: Implement KADM5_LAST_PWD_CHANGE. + + * set_keys.c: Set and clear password where appropriate. + + * randkey_s.c: Operation modifies tl_data. + + * log.c (kadm5_log_replay_modify): Check return values of + malloc(), replace all extensions. + + * kadm5_err.et: Make BAD_TL_TYPE error more helpful. + + * get_s.c: Expose KADM5_TL_DATA options to the client. + + * ent_setup.c: Merge in KADM5_TL_DATA in the database. + + * chpass_s.c: Operations modify extensions, mark that with + TL_DATA. + + * admin.h: Add more TL types (password and extension). + +2005-06-17 Love Hörnquist Åstrand <lha@it.su.se> + + * constify + + * ipropd_slave.c: avoid shadowing + + * ipropd_master.c: rename local variable slave to s, optind -> + optidx + + * get_princs_c.c: rename variable exp to expression + + * ad.c: rename variable exp to expression + + * log.c: rename shadowing len to num + + * get_princs_s.c: rename variable exp to expression + + * context_s.c: const poison + + * common_glue.c: rename variable exp to expression + +2005-05-30 Love Hörnquist Åstrand <lha@it.su.se> + + * ent_setup.c (attr_to_flags): check for KRB5_KDB_OK_AS_DELEGATE + + * get_s.c (kadm5_s_get_principal): set KRB5_KDB_OK_AS_DELEGATE + + * admin.h: add KRB5_KDB_OK_AS_DELEGATE, sync KRB5_TL_ flags + +2005-05-25 Love Hörnquist Åstrand <lha@it.su.se> + + * kadm5_pwcheck.3: please mdoclint + +2005-05-25 Dave Love <fx@gnu.org> + + * kadm5_pwcheck.3: document kadm5_add_passwd_quality_verifier, + improve text + +2005-05-24 Dave Love <fx@gnu.org> + + * iprop.8: Added some info about defaults, fixed some markup. + +2005-05-23 Dave Love <fx@gnu.org> + + * ipropd_slave.c: Don't test HAVE_DAEMON since roken supplies it. + + * ipropd_master.c: Don't test HAVE_DAEMON since roken supplies it. + +2005-05-13 Love Hörnquist Åstrand <lha@it.su.se> + + * init_c.c (_kadm5_c_init_context): fix memory leak in case of + failure + +2005-05-09 Dave Love <fx@gnu.org> + + * password_quality.c (find_func): Fix off-by-one and logic error. + (external_passwd_quality): Improve messages. + + * test_pw_quality.c (main): Call kadm5_setup_passwd_quality_check + and kadm5_add_passwd_quality_verifier. + +2005-04-30 Love Hörnquist Åstrand <lha@it.su.se> + + * default_keys.c: #include <err.h>, only print salt it its longer + then 0, use krb5_err instead of errx where appropriate + +2005-04-25 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c: add the documented option --port + + * ipropd_master.c: add the documented option --port + + * dump_log.c: use the newly generated units function + +2005-04-24 Love Hörnquist Åstrand <lha@it.su.se> + + * dump_log.c: use strlcpy + + * password_quality.c: don't use sizeof(pointer) + +2005-04-15 Love Hörnquist Åstrand <lha@it.su.se> + + * check-cracklib.pl: external password verifier sample + + * password_quality.c (kadm5_add_passwd_quality_verifier): if NULL + is passed in, load defaults + +2005-04-14 Love Hörnquist Åstrand <lha@it.su.se> + + * password_quality.c: add an end tag to the external password + quality check protocol + +2005-04-13 Love Hörnquist Åstrand <lha@it.su.se> + + * password_quality.c: add external passsword quality check builtin + module + + [password_quality] + policies = external-check + external-program = /bin/false + + To approve password a, make the test program return APPROVED on + stderr and fail with exit code 0. + +2004-10-12 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: bump version to 7:7:0 and 6:5:2 + + * default_keys.c (parse_file): use hdb_generate_key_set + + * keys.c,set_keys.c: Move keyset parsing and password based keyset + generation into hdb. Requested by Andrew Bartlett <abartlet@samba.org> + for hdb-ldb backend. -2003-12-21 Love Hörnquist Åstrand <lha@it.su.se> +2004-09-23 Johan Danielsson <joda@pdc.kth.se> - * init_c.c: 1.47->1.48: (_kadm5_c_init_context): catch errors from - strdup and other krb5_ functions + * ipropd_master.c: add help strings to some options -2003-08-15 Love Hörnquist Åstrand <lha@it.su.se> +2004-09-12 Love Hörnquist Åstrand <lha@it.su.se> - * ipropd_slave.c: 1.27->1.28: (receive_everything): switch close - and rename From: Alf Wachsmann <alfw@SLAC.Stanford.EDU> + * chpass_s.c: deal with changed prototype for _kadm5_free_keys -2003-04-16 Love Hörnquist Åstrand <lha@it.su.se> + * keys.c (_kadm5_free_keys): change prototype, make it use + krb5_context instead of a kadm5_server_context + + * set_keys.c (parse_key_set): do way with static returning + (function) static variable and returned allocated memory + (_kadm5_generate_key_set): free enctypes returned by parse_key_set + +2004-09-06 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c: Fix memory leak, don't return stack variables From + Andrew Bartlett + + * set_keys.c: make all_etypes const and move outside function to + avoid returning data on stack + +2004-08-26 Love Hörnquist Åstrand <lha@it.su.se> + + * acl.c (fetch_acl): use " \t\n" instead of just "\n" for the + delim of the third element, this is so we can match + "foo@REALM<SPC>all<SPC><SPC>*@REALM", before it just matched + "foo@REALM<SPC>all<SPC>*@REALM", but that is kind of lucky since + what really happen was that the last <SPC> was stamped out, and + the it never strtok_r never needed to parse over it. + +2004-08-25 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c (_kadm5_generate_key_set): since arcfour-hmac-md5 is + without salting, some people tries to add the string + "arcfour-hmac-md5" when they really should have used + "arcfour-hmac-md5:pw-salt", help them and add glue for that + +2004-08-18 Johan Danielsson <joda@pdc.kth.se> + + * ipropd_slave.c: add --detach + +2004-07-06 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: use new tsasl interface remove debug printf add upn to + computer-accounts + +2004-06-28 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: implement kadm5_ad_init_with_password_ctx set more error + strings + +2004-06-21 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: man_MANS = kadm5_pwcheck.3 + + * kadm5_pwcheck.3: document new password quality api + + * password_quality.c: new password check interface (old still + supported) + + * kadm5-pwcheck.h: new password check interface + +2004-06-08 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_master.c (main): process all slaves, not just up to the + last slave sending data + (bug report from Björn Sandell <biorn@dce.chalmers.se>) + (*): only send one ARE_YOU_THERE + +2004-06-02 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: use krb5_set_password_using_ccache + +2004-06-01 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: try handle spn's better + +2004-05-31 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: add expiration time + + * ad.c: add modify operations + + * ad.c: handle create and delete + +2004-05-27 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: more code for get, handle attributes + + * ad.c: more code for get, handle time stamps and bad password + counter + + * ad.c: more code for get, only fetches kvno for now + +2004-05-26 Love Hörnquist Åstrand <lha@it.su.se> + + * ad.c: add support for tsasl + + * private.h: add kadm5_ad_context + + * ipropd_master.c (prop_one): store the opcode in the begining of + the blob, not the end + + * ad.c: try all ldap servers in dns, generate a random password, + base64(random_block(64)), XXX must make it support other then + ARCFOUR + + * ad.c: framework for windows AD backend + +2004-03-07 Love Hörnquist Åstrand <lha@it.su.se> + + * create_s.c (kadm5_s_create_principal): remove old XXX command + and related code, _kadm5_set_keys will do all this now + +2004-02-29 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c (_kadm5_set_keys_randomly): make sure enctype to copy + enctype for des keys From: Andrew Bartlett <abartlet@samba.org> + + * create_s.c (kadm5_s_create_principal_with_key): don't call + _kadm5_set_keys2, create_principal will do that for us. Set kvno + to 1. + + * chpass_s.c (change): bump kvno + (kadm5_s_chpass_principal_with_key): bump kvno + + * randkey_s.c (kadm5_s_randkey_principal): bump kvno + + * set_keys.c (_kadm5_set_*): don't change the kvno, let the callee + to that + +2003-12-30 Love Hörnquist Åstrand <lha@it.su.se> + + * chpass_s.c (change): fix same-password-again by decrypting keys + and setting an error code From: Buck Huppmann <buckh@pobox.com> + +2003-12-21 Love Hörnquist Åstrand <lha@it.su.se> + + * init_c.c (_kadm5_c_init_context): catch errors from strdup and + other krb5_ functions + +2003-12-08 Love Hörnquist Åstrand <lha@it.su.se> + + * rename_s.c (kadm5_s_rename_principal): allow principal to change + realm From Panasas Inc + +2003-12-07 Love Hörnquist Åstrand <lha@it.su.se> + + * destroy_c.c (kadm5_c_destroy): fix memory leaks, From Panasas, + Inc + +2003-11-23 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop.h: don't include <krb5-private.h> + + * ipropd_slave.c: stop using krb5 lib private byte-frobbing + functions and replace them with with krb5_storage + + * ipropd_master.c: stop using krb5 lib private byte-frobbing + functions and replace them with with krb5_storage + +2003-11-19 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c (receive_loop): when seeking over the entries we + already have, skip over the trailer. From: Jeffrey Hutzelman + <jhutz@cmu.edu> + + * dump_log.c,ipropd_master.c,ipropd_slave.c, + replay_log.c,truncate_log.c: parse kdc.conf + From: Jeffrey Hutzelman <jhutz@cmu.edu> + +2003-10-10 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: += test_pw_quality + + * test_pw_quality.c: test program for verifying password quality + function + +2003-09-03 Love Hörnquist Åstrand <lha@it.su.se> + + * Makefile.am: add and enable check program default_keys + + * default_keys.c: test program for _kadm5_generate_key_set + + * init_c.c: use + krb5_get_init_creds_opt_alloc/krb5_get_init_creds_opt_free + +2003-08-17 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c (_kadm5_set_keys_randomly): remove dup return + + * ipropd_master.c (main): make sure current_version is initialized + +2003-08-15 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c: use default_keys for the both random keys and + password derived keys if its defined + +2003-07-24 Love Hörnquist Åstrand <lha@it.su.se> + + * ipropd_slave.c (receive_everything): switch close and rename + From: Alf Wachsmann <alfw@SLAC.Stanford.EDU> + +2003-07-03 Love Hörnquist Åstrand <lha@it.su.se> + + * iprop.h, ipropd_master.c, ipropd_slave.c: + Add probing from the server that the client is still there, also + make the client check that the server is probing. + +2003-07-02 Love Hörnquist Åstrand <lha@it.su.se> + + * truncate_log.c (main): add missing ``if (ret)'' + +2003-06-26 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c (make_keys): add AES support + + * set_keys.c: fix off by one in the aes case, pointed out by Ken + Raeburn + +2003-04-30 Love Hörnquist Åstrand <lha@it.su.se> + + * set_keys.c (_kadm5_set_keys_randomly): add + ETYPE_AES256_CTS_HMAC_SHA1_96 key when configuried with aes + support + +2003-04-16 Love Hörnquist Åstrand <lha@it.su.se> * send_recv.c: check return values from krb5_data_alloc * log.c: check return values from krb5_data_alloc -2003-04-16 Love Hörnquist Åstrand <lha@it.su.se> +2003-04-16 Love Hörnquist Åstrand <lha@it.su.se> * dump_log.c (print_entry): check return values from krb5_data_alloc -2003-04-01 Love Hörnquist Åstrand <lha@it.su.se> +2003-04-01 Love Hörnquist Åstrand <lha@it.su.se> * init_c.c (kadm_connect): if a context realm was passed in, use that to form the kadmin/admin principal -2003-03-19 Love Hörnquist Åstrand <lha@it.su.se> +2003-03-19 Love Hörnquist Åstrand <lha@it.su.se> * ipropd_master.c (main): make sure we don't consider dead slave for select processing diff --git a/crypto/heimdal/lib/kadm5/Makefile.am b/crypto/heimdal/lib/kadm5/Makefile.am index 9b0c49d..66ffd37 100644 --- a/crypto/heimdal/lib/kadm5/Makefile.am +++ b/crypto/heimdal/lib/kadm5/Makefile.am @@ -1,25 +1,44 @@ -# $Id: Makefile.am,v 1.51.6.1 2003/05/12 15:20:46 joda Exp $ +# $Id: Makefile.am 22403 2008-01-11 14:37:26Z lha $ include $(top_srcdir)/Makefile.am.common +SLC = $(top_builddir)/lib/sl/slc + lib_LTLIBRARIES = libkadm5srv.la libkadm5clnt.la -libkadm5srv_la_LDFLAGS = -version-info 7:6:0 -libkadm5clnt_la_LDFLAGS = -version-info 6:4:2 -sbin_PROGRAMS = dump_log replay_log truncate_log +libkadm5srv_la_LDFLAGS = -version-info 8:1:0 +libkadm5clnt_la_LDFLAGS = -version-info 7:1:0 + +if versionscript +libkadm5srv_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map +endif + +sbin_PROGRAMS = iprop-log +check_PROGRAMS = default_keys +noinst_PROGRAMS = test_pw_quality + +noinst_LTLIBRARIES = sample_passwd_check.la -libkadm5srv_la_LIBADD = ../krb5/libkrb5.la ../hdb/libhdb.la ../roken/libroken.la -libkadm5clnt_la_LIBADD = ../krb5/libkrb5.la ../hdb/libhdb.la ../roken/libroken.la +sample_passwd_check_la_SOURCES = sample_passwd_check.c +sample_passwd_check_la_LDFLAGS = -module + +libkadm5srv_la_LIBADD = \ + $(LIB_com_err) ../krb5/libkrb5.la \ + ../hdb/libhdb.la $(LIBADD_roken) +libkadm5clnt_la_LIBADD = \ + $(LIB_com_err) ../krb5/libkrb5.la $(LIBADD_roken) libexec_PROGRAMS = ipropd-master ipropd-slave +default_keys_SOURCES = default_keys.c + kadm5includedir = $(includedir)/kadm5 buildkadm5include = $(buildinclude)/kadm5 -kadm5include_HEADERS = kadm5_err.h admin.h private.h \ - kadm5-protos.h kadm5-private.h +dist_kadm5include_HEADERS = admin.h private.h kadm5-protos.h kadm5-private.h +nodist_kadm5include_HEADERS = kadm5_err.h -install-build-headers:: $(kadm5include_HEADERS) - @foo='$(kadm5include_HEADERS)'; \ +install-build-headers:: $(dist_kadm5include_HEADERS) $(nodist_kadm5include_HEADERS) + @foo='$(dist_kadm5include_HEADERS) $(nodist_kadm5include_HEADERS)'; \ for f in $$foo; do \ f=`basename $$f`; \ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ @@ -31,9 +50,10 @@ install-build-headers:: $(kadm5include_HEADERS) fi ; \ done -SOURCES_client = \ - admin.h \ +dist_libkadm5clnt_la_SOURCES = \ + ad.c \ chpass_c.c \ + client_glue.c \ common_glue.c \ create_c.c \ delete_c.c \ @@ -43,7 +63,6 @@ SOURCES_client = \ get_c.c \ get_princs_c.c \ init_c.c \ - kadm5_err.c \ kadm5_locl.h \ marshall.c \ modify_c.c \ @@ -51,9 +70,15 @@ SOURCES_client = \ privs_c.c \ randkey_c.c \ rename_c.c \ - send_recv.c + send_recv.c \ + kadm5-pwcheck.h \ + admin.h + +nodist_libkadm5clnt_la_SOURCES = \ + kadm5_err.c \ + kadm5_err.h -SOURCES_server = \ +dist_libkadm5srv_la_SOURCES = \ acl.c \ admin.h \ bump_pw_expire.c \ @@ -70,32 +95,34 @@ SOURCES_server = \ get_princs_s.c \ get_s.c \ init_s.c \ - kadm5_err.c \ kadm5_locl.h \ keys.c \ log.c \ marshall.c \ modify_s.c \ + password_quality.c \ private.h \ privs_s.c \ randkey_s.c \ rename_s.c \ + server_glue.c \ set_keys.c \ set_modifier.c \ - password_quality.c - -libkadm5srv_la_SOURCES = $(SOURCES_server) server_glue.c -libkadm5clnt_la_SOURCES = $(SOURCES_client) client_glue.c + kadm5-pwcheck.h \ + admin.h -dump_log_SOURCES = dump_log.c kadm5_locl.h +nodist_libkadm5srv_la_SOURCES = \ + kadm5_err.c \ + kadm5_err.h -replay_log_SOURCES = replay_log.c kadm5_locl.h +dist_iprop_log_SOURCES = iprop-log.c +nodist_iprop_log_SOURCES = iprop-commands.c -ipropd_master_SOURCES = ipropd_master.c iprop.h kadm5_locl.h +ipropd_master_SOURCES = ipropd_master.c ipropd_common.c iprop.h kadm5_locl.h -ipropd_slave_SOURCES = ipropd_slave.c iprop.h kadm5_locl.h +ipropd_slave_SOURCES = ipropd_slave.c ipropd_common.c iprop.h kadm5_locl.h -truncate_log_SOURCES = truncate_log.c +man_MANS = kadm5_pwcheck.3 iprop.8 iprop-log.8 LDADD = \ libkadm5srv.la \ @@ -103,18 +130,37 @@ LDADD = \ $(LIB_openldap) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(top_builddir)/lib/asn1/libasn1.la \ - $(LIB_des) \ + $(LIB_hcrypto) \ + $(LIB_roken) \ + $(DBLIB) \ + $(LIB_dlopen) \ + $(LIB_pidfile) + +iprop_log_LDADD = \ + libkadm5srv.la \ + $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_hcrypto) \ + $(top_builddir)/lib/sl/libsl.la \ + $(LIB_readline) \ $(LIB_roken) \ $(DBLIB) \ $(LIB_dlopen) \ $(LIB_pidfile) -CLEANFILES = kadm5_err.c kadm5_err.h + +iprop-commands.c iprop-commands.h: iprop-commands.in + $(SLC) $(srcdir)/iprop-commands.in $(libkadm5srv_la_OBJECTS): kadm5_err.h +$(iprop_log_OBJECTS): iprop-commands.h client_glue.lo server_glue.lo: $(srcdir)/common_glue.c +CLEANFILES = kadm5_err.c kadm5_err.h iprop-commands.h iprop-commands.c + # to help stupid solaris make kadm5_err.h: kadm5_err.et @@ -125,11 +171,22 @@ proto_opts = -q -R '^(_|kadm5_c_|kadm5_s_|kadm5_log)' -P comment $(srcdir)/kadm5-protos.h: cd $(srcdir); perl ../../cf/make-proto.pl $(proto_opts) \ -o kadm5-protos.h \ - $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) \ + $(dist_libkadm5clnt_la_SOURCES) \ + $(dist_libkadm5srv_la_SOURCES) \ || rm -f kadm5-protos.h $(srcdir)/kadm5-private.h: cd $(srcdir); perl ../../cf/make-proto.pl $(proto_opts) \ -p kadm5-private.h \ - $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) \ + $(dist_libkadm5clnt_la_SOURCES) \ + $(dist_libkadm5srv_la_SOURCES) \ || rm -f kadm5-private.h + +EXTRA_DIST = \ + kadm5_err.et \ + iprop-commands.in \ + $(man_MANS) \ + check-cracklib.pl \ + flush.c \ + sample_passwd_check.c \ + version-script.map diff --git a/crypto/heimdal/lib/kadm5/Makefile.in b/crypto/heimdal/lib/kadm5/Makefile.in index 8695002..81f1ced 100644 --- a/crypto/heimdal/lib/kadm5/Makefile.in +++ b/crypto/heimdal/lib/kadm5/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.8.3 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,25 +14,19 @@ @SET_MAKE@ -# $Id: Makefile.am,v 1.51.6.1 2003/05/12 15:20:46 joda Exp $ +# $Id: Makefile.am 22403 2008-01-11 14:37:26Z lha $ -# $Id: Makefile.am.common,v 1.5 2002/05/19 18:35:37 joda Exp $ +# $Id: Makefile.am.common 10998 2002-05-19 18:35:37Z joda $ -# $Id: Makefile.am.common,v 1.37.2.2 2003/10/13 13:15:39 joda Exp $ +# $Id: Makefile.am.common 22488 2008-01-21 11:47:22Z lha $ -SOURCES = $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) $(dump_log_SOURCES) $(ipropd_master_SOURCES) $(ipropd_slave_SOURCES) $(replay_log_SOURCES) $(truncate_log_SOURCES) - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c @@ -44,26 +38,27 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : +build_triplet = @build@ host_triplet = @host@ -DIST_COMMON = $(kadm5include_HEADERS) $(srcdir)/Makefile.am \ +DIST_COMMON = $(dist_kadm5include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/Makefile.am.common \ $(top_srcdir)/cf/Makefile.am.common ChangeLog -sbin_PROGRAMS = dump_log$(EXEEXT) replay_log$(EXEEXT) \ - truncate_log$(EXEEXT) +@versionscript_TRUE@am__append_1 = $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map +sbin_PROGRAMS = iprop-log$(EXEEXT) +check_PROGRAMS = default_keys$(EXEEXT) +noinst_PROGRAMS = test_pw_quality$(EXEEXT) libexec_PROGRAMS = ipropd-master$(EXEEXT) ipropd-slave$(EXEEXT) subdir = lib/kadm5 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ - $(top_srcdir)/cf/auth-modules.m4 \ + $(top_srcdir)/cf/auth-modules.m4 $(top_srcdir)/cf/autobuild.m4 \ $(top_srcdir)/cf/broken-getaddrinfo.m4 \ - $(top_srcdir)/cf/broken-getnameinfo.m4 \ $(top_srcdir)/cf/broken-glob.m4 \ $(top_srcdir)/cf/broken-realloc.m4 \ $(top_srcdir)/cf/broken-snprintf.m4 $(top_srcdir)/cf/broken.m4 \ $(top_srcdir)/cf/broken2.m4 $(top_srcdir)/cf/c-attribute.m4 \ $(top_srcdir)/cf/capabilities.m4 \ $(top_srcdir)/cf/check-compile-et.m4 \ - $(top_srcdir)/cf/check-declaration.m4 \ $(top_srcdir)/cf/check-getpwnam_r-posix.m4 \ $(top_srcdir)/cf/check-man.m4 \ $(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \ @@ -76,6 +71,7 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ $(top_srcdir)/cf/find-func-no-libs2.m4 \ $(top_srcdir)/cf/find-func.m4 \ $(top_srcdir)/cf/find-if-not-broken.m4 \ + $(top_srcdir)/cf/framework-security.m4 \ $(top_srcdir)/cf/have-struct-field.m4 \ $(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/irix.m4 \ $(top_srcdir)/cf/krb-bigendian.m4 \ @@ -84,53 +80,92 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ $(top_srcdir)/cf/krb-readline.m4 \ $(top_srcdir)/cf/krb-struct-spwd.m4 \ $(top_srcdir)/cf/krb-struct-winsize.m4 \ - $(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \ - $(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \ - $(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/proto-compat.m4 \ - $(top_srcdir)/cf/retsigtype.m4 $(top_srcdir)/cf/roken-frag.m4 \ - $(top_srcdir)/cf/sunos.m4 $(top_srcdir)/cf/telnet.m4 \ - $(top_srcdir)/cf/test-package.m4 $(top_srcdir)/cf/wflags.m4 \ - $(top_srcdir)/cf/with-all.m4 $(top_srcdir)/configure.in + $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/mips-abi.m4 \ + $(top_srcdir)/cf/misc.m4 $(top_srcdir)/cf/need-proto.m4 \ + $(top_srcdir)/cf/osfc2.m4 $(top_srcdir)/cf/otp.m4 \ + $(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \ + $(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \ + $(top_srcdir)/cf/roken-frag.m4 \ + $(top_srcdir)/cf/socket-wrapper.m4 $(top_srcdir)/cf/sunos.m4 \ + $(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \ + $(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \ + $(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(kadm5includedir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" \ + "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(kadm5includedir)" \ + "$(DESTDIR)$(kadm5includedir)" libLTLIBRARIES_INSTALL = $(INSTALL) -LTLIBRARIES = $(lib_LTLIBRARIES) -libkadm5clnt_la_DEPENDENCIES = ../krb5/libkrb5.la ../hdb/libhdb.la \ - ../roken/libroken.la -am__objects_1 = chpass_c.lo common_glue.lo create_c.lo delete_c.lo \ - destroy_c.lo flush_c.lo free.lo get_c.lo get_princs_c.lo \ - init_c.lo kadm5_err.lo marshall.lo modify_c.lo privs_c.lo \ - randkey_c.lo rename_c.lo send_recv.lo -am_libkadm5clnt_la_OBJECTS = $(am__objects_1) client_glue.lo -libkadm5clnt_la_OBJECTS = $(am_libkadm5clnt_la_OBJECTS) -libkadm5srv_la_DEPENDENCIES = ../krb5/libkrb5.la ../hdb/libhdb.la \ - ../roken/libroken.la -am__objects_2 = acl.lo bump_pw_expire.lo chpass_s.lo common_glue.lo \ - context_s.lo create_s.lo delete_s.lo destroy_s.lo ent_setup.lo \ - error.lo flush_s.lo free.lo get_princs_s.lo get_s.lo init_s.lo \ - kadm5_err.lo keys.lo log.lo marshall.lo modify_s.lo privs_s.lo \ - randkey_s.lo rename_s.lo set_keys.lo set_modifier.lo \ - password_quality.lo -am_libkadm5srv_la_OBJECTS = $(am__objects_2) server_glue.lo -libkadm5srv_la_OBJECTS = $(am_libkadm5srv_la_OBJECTS) +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libkadm5clnt_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + ../krb5/libkrb5.la $(am__DEPENDENCIES_1) +dist_libkadm5clnt_la_OBJECTS = ad.lo chpass_c.lo client_glue.lo \ + common_glue.lo create_c.lo delete_c.lo destroy_c.lo flush_c.lo \ + free.lo get_c.lo get_princs_c.lo init_c.lo marshall.lo \ + modify_c.lo privs_c.lo randkey_c.lo rename_c.lo send_recv.lo +nodist_libkadm5clnt_la_OBJECTS = kadm5_err.lo +libkadm5clnt_la_OBJECTS = $(dist_libkadm5clnt_la_OBJECTS) \ + $(nodist_libkadm5clnt_la_OBJECTS) +libkadm5clnt_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libkadm5clnt_la_LDFLAGS) $(LDFLAGS) -o $@ +libkadm5srv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) ../krb5/libkrb5.la \ + ../hdb/libhdb.la $(am__DEPENDENCIES_1) +dist_libkadm5srv_la_OBJECTS = acl.lo bump_pw_expire.lo chpass_s.lo \ + common_glue.lo context_s.lo create_s.lo delete_s.lo \ + destroy_s.lo ent_setup.lo error.lo flush_s.lo free.lo \ + get_princs_s.lo get_s.lo init_s.lo keys.lo log.lo marshall.lo \ + modify_s.lo password_quality.lo privs_s.lo randkey_s.lo \ + rename_s.lo server_glue.lo set_keys.lo set_modifier.lo +nodist_libkadm5srv_la_OBJECTS = kadm5_err.lo +libkadm5srv_la_OBJECTS = $(dist_libkadm5srv_la_OBJECTS) \ + $(nodist_libkadm5srv_la_OBJECTS) +libkadm5srv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libkadm5srv_la_LDFLAGS) $(LDFLAGS) -o $@ +sample_passwd_check_la_LIBADD = +am_sample_passwd_check_la_OBJECTS = sample_passwd_check.lo +sample_passwd_check_la_OBJECTS = $(am_sample_passwd_check_la_OBJECTS) +sample_passwd_check_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(sample_passwd_check_la_LDFLAGS) $(LDFLAGS) -o $@ libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS) -am_dump_log_OBJECTS = dump_log.$(OBJEXT) -dump_log_OBJECTS = $(am_dump_log_OBJECTS) -dump_log_LDADD = $(LDADD) -am__DEPENDENCIES_1 = -dump_log_DEPENDENCIES = libkadm5srv.la \ +PROGRAMS = $(libexec_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) +am_default_keys_OBJECTS = default_keys.$(OBJEXT) +default_keys_OBJECTS = $(am_default_keys_OBJECTS) +default_keys_LDADD = $(LDADD) +default_keys_DEPENDENCIES = libkadm5srv.la \ + $(top_builddir)/lib/hdb/libhdb.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +dist_iprop_log_OBJECTS = iprop-log.$(OBJEXT) +nodist_iprop_log_OBJECTS = iprop-commands.$(OBJEXT) +iprop_log_OBJECTS = $(dist_iprop_log_OBJECTS) \ + $(nodist_iprop_log_OBJECTS) +iprop_log_DEPENDENCIES = libkadm5srv.la \ $(top_builddir)/lib/hdb/libhdb.la $(am__DEPENDENCIES_1) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/lib/sl/libsl.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_ipropd_master_OBJECTS = ipropd_master.$(OBJEXT) +am_ipropd_master_OBJECTS = ipropd_master.$(OBJEXT) \ + ipropd_common.$(OBJEXT) ipropd_master_OBJECTS = $(am_ipropd_master_OBJECTS) ipropd_master_LDADD = $(LDADD) ipropd_master_DEPENDENCIES = libkadm5srv.la \ @@ -139,7 +174,8 @@ ipropd_master_DEPENDENCIES = libkadm5srv.la \ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_ipropd_slave_OBJECTS = ipropd_slave.$(OBJEXT) +am_ipropd_slave_OBJECTS = ipropd_slave.$(OBJEXT) \ + ipropd_common.$(OBJEXT) ipropd_slave_OBJECTS = $(am_ipropd_slave_OBJECTS) ipropd_slave_LDADD = $(LDADD) ipropd_slave_DEPENDENCIES = libkadm5srv.la \ @@ -148,56 +184,51 @@ ipropd_slave_DEPENDENCIES = libkadm5srv.la \ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_replay_log_OBJECTS = replay_log.$(OBJEXT) -replay_log_OBJECTS = $(am_replay_log_OBJECTS) -replay_log_LDADD = $(LDADD) -replay_log_DEPENDENCIES = libkadm5srv.la \ +test_pw_quality_SOURCES = test_pw_quality.c +test_pw_quality_OBJECTS = test_pw_quality.$(OBJEXT) +test_pw_quality_LDADD = $(LDADD) +test_pw_quality_DEPENDENCIES = libkadm5srv.la \ $(top_builddir)/lib/hdb/libhdb.la $(am__DEPENDENCIES_1) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_truncate_log_OBJECTS = truncate_log.$(OBJEXT) -truncate_log_OBJECTS = $(am_truncate_log_OBJECTS) -truncate_log_LDADD = $(LDADD) -truncate_log_DEPENDENCIES = libkadm5srv.la \ - $(top_builddir)/lib/hdb/libhdb.la $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/krb5/libkrb5.la \ - $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include +DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@ depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) \ - $(dump_log_SOURCES) $(ipropd_master_SOURCES) \ - $(ipropd_slave_SOURCES) $(replay_log_SOURCES) \ - $(truncate_log_SOURCES) -DIST_SOURCES = $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) \ - $(dump_log_SOURCES) $(ipropd_master_SOURCES) \ - $(ipropd_slave_SOURCES) $(replay_log_SOURCES) \ - $(truncate_log_SOURCES) -kadm5includeHEADERS_INSTALL = $(INSTALL_HEADER) -HEADERS = $(kadm5include_HEADERS) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(dist_libkadm5clnt_la_SOURCES) \ + $(nodist_libkadm5clnt_la_SOURCES) \ + $(dist_libkadm5srv_la_SOURCES) \ + $(nodist_libkadm5srv_la_SOURCES) \ + $(sample_passwd_check_la_SOURCES) $(default_keys_SOURCES) \ + $(dist_iprop_log_SOURCES) $(nodist_iprop_log_SOURCES) \ + $(ipropd_master_SOURCES) $(ipropd_slave_SOURCES) \ + test_pw_quality.c +DIST_SOURCES = $(dist_libkadm5clnt_la_SOURCES) \ + $(dist_libkadm5srv_la_SOURCES) \ + $(sample_passwd_check_la_SOURCES) $(default_keys_SOURCES) \ + $(dist_iprop_log_SOURCES) $(ipropd_master_SOURCES) \ + $(ipropd_slave_SOURCES) test_pw_quality.c +man3dir = $(mandir)/man3 +man8dir = $(mandir)/man8 +MANS = $(man_MANS) +dist_kadm5includeHEADERS_INSTALL = $(INSTALL_HEADER) +nodist_kadm5includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(dist_kadm5include_HEADERS) $(nodist_kadm5include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ -AIX4_FALSE = @AIX4_FALSE@ -AIX4_TRUE = @AIX4_TRUE@ -AIX_DYNAMIC_AFS_FALSE = @AIX_DYNAMIC_AFS_FALSE@ -AIX_DYNAMIC_AFS_TRUE = @AIX_DYNAMIC_AFS_TRUE@ AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@ -AIX_FALSE = @AIX_FALSE@ -AIX_TRUE = @AIX_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ @@ -207,8 +238,6 @@ AWK = @AWK@ CANONICAL_HOST = @CANONICAL_HOST@ CATMAN = @CATMAN@ CATMANEXT = @CATMANEXT@ -CATMAN_FALSE = @CATMAN_FALSE@ -CATMAN_TRUE = @CATMAN_TRUE@ CC = @CC@ CFLAGS = @CFLAGS@ COMPILE_ET = @COMPILE_ET@ @@ -219,11 +248,10 @@ CXXCPP = @CXXCPP@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DBLIB = @DBLIB@ -DCE_FALSE = @DCE_FALSE@ -DCE_TRUE = @DCE_TRUE@ DEFS = @DEFS@ DIR_com_err = @DIR_com_err@ -DIR_des = @DIR_des@ +DIR_hcrypto = @DIR_hcrypto@ +DIR_hdbdir = @DIR_hdbdir@ DIR_roken = @DIR_roken@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ @@ -231,42 +259,27 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -EXTRA_LIB45 = @EXTRA_LIB45@ F77 = @F77@ FFLAGS = @FFLAGS@ +GREP = @GREP@ GROFF = @GROFF@ -HAVE_DB1_FALSE = @HAVE_DB1_FALSE@ -HAVE_DB1_TRUE = @HAVE_DB1_TRUE@ -HAVE_DB3_FALSE = @HAVE_DB3_FALSE@ -HAVE_DB3_TRUE = @HAVE_DB3_TRUE@ -HAVE_DLOPEN_FALSE = @HAVE_DLOPEN_FALSE@ -HAVE_DLOPEN_TRUE = @HAVE_DLOPEN_TRUE@ -HAVE_NDBM_FALSE = @HAVE_NDBM_FALSE@ -HAVE_NDBM_TRUE = @HAVE_NDBM_TRUE@ -HAVE_OPENSSL_FALSE = @HAVE_OPENSSL_FALSE@ -HAVE_OPENSSL_TRUE = @HAVE_OPENSSL_TRUE@ -HAVE_X_FALSE = @HAVE_X_FALSE@ -HAVE_X_TRUE = @HAVE_X_TRUE@ INCLUDES_roken = @INCLUDES_roken@ -INCLUDE_des = @INCLUDE_des@ +INCLUDE_hcrypto = @INCLUDE_hcrypto@ INCLUDE_hesiod = @INCLUDE_hesiod@ INCLUDE_krb4 = @INCLUDE_krb4@ INCLUDE_openldap = @INCLUDE_openldap@ INCLUDE_readline = @INCLUDE_readline@ +INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IRIX_FALSE = @IRIX_FALSE@ -IRIX_TRUE = @IRIX_TRUE@ -KRB4_FALSE = @KRB4_FALSE@ -KRB4_TRUE = @KRB4_TRUE@ -KRB5_FALSE = @KRB5_FALSE@ -KRB5_TRUE = @KRB5_TRUE@ LDFLAGS = @LDFLAGS@ +LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_roken = @LIBADD_roken@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -284,12 +297,9 @@ LIB_crypt = @LIB_crypt@ LIB_db_create = @LIB_db_create@ LIB_dbm_firstkey = @LIB_dbm_firstkey@ LIB_dbopen = @LIB_dbopen@ -LIB_des = @LIB_des@ -LIB_des_a = @LIB_des_a@ -LIB_des_appl = @LIB_des_appl@ -LIB_des_so = @LIB_des_so@ LIB_dlopen = @LIB_dlopen@ LIB_dn_expand = @LIB_dn_expand@ +LIB_door_create = @LIB_door_create@ LIB_el_init = @LIB_el_init@ LIB_freeaddrinfo = @LIB_freeaddrinfo@ LIB_gai_strerror = @LIB_gai_strerror@ @@ -299,15 +309,14 @@ LIB_gethostbyname2 = @LIB_gethostbyname2@ LIB_getnameinfo = @LIB_getnameinfo@ LIB_getpwnam_r = @LIB_getpwnam_r@ LIB_getsockopt = @LIB_getsockopt@ +LIB_hcrypto = @LIB_hcrypto@ +LIB_hcrypto_a = @LIB_hcrypto_a@ +LIB_hcrypto_appl = @LIB_hcrypto_appl@ +LIB_hcrypto_so = @LIB_hcrypto_so@ LIB_hesiod = @LIB_hesiod@ LIB_hstrerror = @LIB_hstrerror@ LIB_kdb = @LIB_kdb@ LIB_krb4 = @LIB_krb4@ -LIB_krb_disable_debug = @LIB_krb_disable_debug@ -LIB_krb_enable_debug = @LIB_krb_enable_debug@ -LIB_krb_get_kdc_time_diff = @LIB_krb_get_kdc_time_diff@ -LIB_krb_get_our_ip_for_realm = @LIB_krb_get_our_ip_for_realm@ -LIB_krb_kdctimeofday = @LIB_krb_kdctimeofday@ LIB_loadquery = @LIB_loadquery@ LIB_logout = @LIB_logout@ LIB_logwtmp = @LIB_logwtmp@ @@ -316,6 +325,7 @@ LIB_openpty = @LIB_openpty@ LIB_otp = @LIB_otp@ LIB_pidfile = @LIB_pidfile@ LIB_readline = @LIB_readline@ +LIB_res_ndestroy = @LIB_res_ndestroy@ LIB_res_nsearch = @LIB_res_nsearch@ LIB_res_search = @LIB_res_search@ LIB_roken = @LIB_roken@ @@ -327,15 +337,10 @@ LIB_tgetent = @LIB_tgetent@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ -MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ -MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ -NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@ -NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@ +MKDIR_P = @MKDIR_P@ NROFF = @NROFF@ OBJEXT = @OBJEXT@ -OTP_FALSE = @OTP_FALSE@ -OTP_TRUE = @OTP_TRUE@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -343,74 +348,79 @@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +VERSIONING = @VERSIONING@ VOID_RETSIGTYPE = @VOID_RETSIGTYPE@ WFLAGS = @WFLAGS@ WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@ WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@ +XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ YACC = @YACC@ -ac_ct_AR = @ac_ct_AR@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ +builddir = @builddir@ datadir = @datadir@ -do_roken_rename_FALSE = @do_roken_rename_FALSE@ -do_roken_rename_TRUE = @do_roken_rename_TRUE@ +datarootdir = @datarootdir@ +docdir = @docdir@ dpagaix_cflags = @dpagaix_cflags@ dpagaix_ldadd = @dpagaix_ldadd@ dpagaix_ldflags = @dpagaix_ldflags@ -el_compat_FALSE = @el_compat_FALSE@ -el_compat_TRUE = @el_compat_TRUE@ +dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_err_h_FALSE = @have_err_h_FALSE@ -have_err_h_TRUE = @have_err_h_TRUE@ -have_fnmatch_h_FALSE = @have_fnmatch_h_FALSE@ -have_fnmatch_h_TRUE = @have_fnmatch_h_TRUE@ -have_glob_h_FALSE = @have_glob_h_FALSE@ -have_glob_h_TRUE = @have_glob_h_TRUE@ -have_ifaddrs_h_FALSE = @have_ifaddrs_h_FALSE@ -have_ifaddrs_h_TRUE = @have_ifaddrs_h_TRUE@ -have_vis_h_FALSE = @have_vis_h_FALSE@ -have_vis_h_TRUE = @have_vis_h_TRUE@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ +htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ +psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -SUFFIXES = .et .h .x .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 -INCLUDES = -I$(top_builddir)/include $(INCLUDES_roken) +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUFFIXES = .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 +AM_CPPFLAGS = -I$(top_builddir)/include $(INCLUDES_roken) @do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME AM_CFLAGS = $(WFLAGS) CP = cp @@ -427,20 +437,31 @@ LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) @KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la @KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la +@KRB5_TRUE@LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la @DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la +SLC = $(top_builddir)/lib/sl/slc lib_LTLIBRARIES = libkadm5srv.la libkadm5clnt.la -libkadm5srv_la_LDFLAGS = -version-info 7:6:0 -libkadm5clnt_la_LDFLAGS = -version-info 6:4:2 -libkadm5srv_la_LIBADD = ../krb5/libkrb5.la ../hdb/libhdb.la ../roken/libroken.la -libkadm5clnt_la_LIBADD = ../krb5/libkrb5.la ../hdb/libhdb.la ../roken/libroken.la +libkadm5srv_la_LDFLAGS = -version-info 8:1:0 $(am__append_1) +libkadm5clnt_la_LDFLAGS = -version-info 7:1:0 +noinst_LTLIBRARIES = sample_passwd_check.la +sample_passwd_check_la_SOURCES = sample_passwd_check.c +sample_passwd_check_la_LDFLAGS = -module +libkadm5srv_la_LIBADD = \ + $(LIB_com_err) ../krb5/libkrb5.la \ + ../hdb/libhdb.la $(LIBADD_roken) + +libkadm5clnt_la_LIBADD = \ + $(LIB_com_err) ../krb5/libkrb5.la $(LIBADD_roken) + +default_keys_SOURCES = default_keys.c kadm5includedir = $(includedir)/kadm5 buildkadm5include = $(buildinclude)/kadm5 -kadm5include_HEADERS = kadm5_err.h admin.h private.h \ - kadm5-protos.h kadm5-private.h - -SOURCES_client = \ - admin.h \ +dist_kadm5include_HEADERS = admin.h private.h kadm5-protos.h kadm5-private.h +nodist_kadm5include_HEADERS = kadm5_err.h +dist_libkadm5clnt_la_SOURCES = \ + ad.c \ chpass_c.c \ + client_glue.c \ common_glue.c \ create_c.c \ delete_c.c \ @@ -450,7 +471,6 @@ SOURCES_client = \ get_c.c \ get_princs_c.c \ init_c.c \ - kadm5_err.c \ kadm5_locl.h \ marshall.c \ modify_c.c \ @@ -458,9 +478,15 @@ SOURCES_client = \ privs_c.c \ randkey_c.c \ rename_c.c \ - send_recv.c + send_recv.c \ + kadm5-pwcheck.h \ + admin.h + +nodist_libkadm5clnt_la_SOURCES = \ + kadm5_err.c \ + kadm5_err.h -SOURCES_server = \ +dist_libkadm5srv_la_SOURCES = \ acl.c \ admin.h \ bump_pw_expire.c \ @@ -477,45 +503,72 @@ SOURCES_server = \ get_princs_s.c \ get_s.c \ init_s.c \ - kadm5_err.c \ kadm5_locl.h \ keys.c \ log.c \ marshall.c \ modify_s.c \ + password_quality.c \ private.h \ privs_s.c \ randkey_s.c \ rename_s.c \ + server_glue.c \ set_keys.c \ set_modifier.c \ - password_quality.c - -libkadm5srv_la_SOURCES = $(SOURCES_server) server_glue.c -libkadm5clnt_la_SOURCES = $(SOURCES_client) client_glue.c -dump_log_SOURCES = dump_log.c kadm5_locl.h -replay_log_SOURCES = replay_log.c kadm5_locl.h -ipropd_master_SOURCES = ipropd_master.c iprop.h kadm5_locl.h -ipropd_slave_SOURCES = ipropd_slave.c iprop.h kadm5_locl.h -truncate_log_SOURCES = truncate_log.c + kadm5-pwcheck.h \ + admin.h + +nodist_libkadm5srv_la_SOURCES = \ + kadm5_err.c \ + kadm5_err.h + +dist_iprop_log_SOURCES = iprop-log.c +nodist_iprop_log_SOURCES = iprop-commands.c +ipropd_master_SOURCES = ipropd_master.c ipropd_common.c iprop.h kadm5_locl.h +ipropd_slave_SOURCES = ipropd_slave.c ipropd_common.c iprop.h kadm5_locl.h +man_MANS = kadm5_pwcheck.3 iprop.8 iprop-log.8 LDADD = \ libkadm5srv.la \ $(top_builddir)/lib/hdb/libhdb.la \ $(LIB_openldap) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(top_builddir)/lib/asn1/libasn1.la \ - $(LIB_des) \ + $(LIB_hcrypto) \ $(LIB_roken) \ $(DBLIB) \ $(LIB_dlopen) \ $(LIB_pidfile) -CLEANFILES = kadm5_err.c kadm5_err.h +iprop_log_LDADD = \ + libkadm5srv.la \ + $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_hcrypto) \ + $(top_builddir)/lib/sl/libsl.la \ + $(LIB_readline) \ + $(LIB_roken) \ + $(DBLIB) \ + $(LIB_dlopen) \ + $(LIB_pidfile) + +CLEANFILES = kadm5_err.c kadm5_err.h iprop-commands.h iprop-commands.c proto_opts = -q -R '^(_|kadm5_c_|kadm5_s_|kadm5_log)' -P comment +EXTRA_DIST = \ + kadm5_err.et \ + iprop-commands.in \ + $(man_MANS) \ + check-cracklib.pl \ + flush.c \ + sample_passwd_check.c \ + version-script.map + all: all-am .SUFFIXES: -.SUFFIXES: .et .h .x .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj +.SUFFIXES: .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -547,10 +600,10 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ + f=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ @@ -559,7 +612,7 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p="`echo $$p | sed -e 's|^.*/||'`"; \ + p=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done @@ -568,17 +621,35 @@ clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" = "$$p" && dir=.; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libkadm5clnt.la: $(libkadm5clnt_la_OBJECTS) $(libkadm5clnt_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libkadm5clnt_la_LDFLAGS) $(libkadm5clnt_la_OBJECTS) $(libkadm5clnt_la_LIBADD) $(LIBS) + $(libkadm5clnt_la_LINK) -rpath $(libdir) $(libkadm5clnt_la_OBJECTS) $(libkadm5clnt_la_LIBADD) $(LIBS) libkadm5srv.la: $(libkadm5srv_la_OBJECTS) $(libkadm5srv_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libkadm5srv_la_LDFLAGS) $(libkadm5srv_la_OBJECTS) $(libkadm5srv_la_LIBADD) $(LIBS) + $(libkadm5srv_la_LINK) -rpath $(libdir) $(libkadm5srv_la_OBJECTS) $(libkadm5srv_la_LIBADD) $(LIBS) +sample_passwd_check.la: $(sample_passwd_check_la_OBJECTS) $(sample_passwd_check_la_DEPENDENCIES) + $(sample_passwd_check_la_LINK) $(sample_passwd_check_la_OBJECTS) $(sample_passwd_check_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done install-libexecPROGRAMS: $(libexec_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(libexecdir)" || $(mkdir_p) "$(DESTDIR)$(libexecdir)" + test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)" @list='$(libexec_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ @@ -604,9 +675,16 @@ clean-libexecPROGRAMS: echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)" + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ @@ -632,21 +710,21 @@ clean-sbinPROGRAMS: echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done -dump_log$(EXEEXT): $(dump_log_OBJECTS) $(dump_log_DEPENDENCIES) - @rm -f dump_log$(EXEEXT) - $(LINK) $(dump_log_LDFLAGS) $(dump_log_OBJECTS) $(dump_log_LDADD) $(LIBS) +default_keys$(EXEEXT): $(default_keys_OBJECTS) $(default_keys_DEPENDENCIES) + @rm -f default_keys$(EXEEXT) + $(LINK) $(default_keys_OBJECTS) $(default_keys_LDADD) $(LIBS) +iprop-log$(EXEEXT): $(iprop_log_OBJECTS) $(iprop_log_DEPENDENCIES) + @rm -f iprop-log$(EXEEXT) + $(LINK) $(iprop_log_OBJECTS) $(iprop_log_LDADD) $(LIBS) ipropd-master$(EXEEXT): $(ipropd_master_OBJECTS) $(ipropd_master_DEPENDENCIES) @rm -f ipropd-master$(EXEEXT) - $(LINK) $(ipropd_master_LDFLAGS) $(ipropd_master_OBJECTS) $(ipropd_master_LDADD) $(LIBS) + $(LINK) $(ipropd_master_OBJECTS) $(ipropd_master_LDADD) $(LIBS) ipropd-slave$(EXEEXT): $(ipropd_slave_OBJECTS) $(ipropd_slave_DEPENDENCIES) @rm -f ipropd-slave$(EXEEXT) - $(LINK) $(ipropd_slave_LDFLAGS) $(ipropd_slave_OBJECTS) $(ipropd_slave_LDADD) $(LIBS) -replay_log$(EXEEXT): $(replay_log_OBJECTS) $(replay_log_DEPENDENCIES) - @rm -f replay_log$(EXEEXT) - $(LINK) $(replay_log_LDFLAGS) $(replay_log_OBJECTS) $(replay_log_LDADD) $(LIBS) -truncate_log$(EXEEXT): $(truncate_log_OBJECTS) $(truncate_log_DEPENDENCIES) - @rm -f truncate_log$(EXEEXT) - $(LINK) $(truncate_log_LDFLAGS) $(truncate_log_OBJECTS) $(truncate_log_LDADD) $(LIBS) + $(LINK) $(ipropd_slave_OBJECTS) $(ipropd_slave_LDADD) $(LIBS) +test_pw_quality$(EXEEXT): $(test_pw_quality_OBJECTS) $(test_pw_quality_DEPENDENCIES) + @rm -f test_pw_quality$(EXEEXT) + $(LINK) $(test_pw_quality_OBJECTS) $(test_pw_quality_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -668,24 +746,127 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-man3: $(man3_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \ + done +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man3dir)/$$inst"; \ + done +install-man8: $(man8_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 8*) ;; \ + *) ext='8' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \ + done +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 8*) ;; \ + *) ext='8' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man8dir)/$$inst"; \ + done +install-dist_kadm5includeHEADERS: $(dist_kadm5include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(kadm5includedir)" || $(MKDIR_P) "$(DESTDIR)$(kadm5includedir)" + @list='$(dist_kadm5include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(dist_kadm5includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(kadm5includedir)/$$f'"; \ + $(dist_kadm5includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(kadm5includedir)/$$f"; \ + done -distclean-libtool: - -rm -f libtool -uninstall-info-am: -install-kadm5includeHEADERS: $(kadm5include_HEADERS) +uninstall-dist_kadm5includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(dist_kadm5include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(kadm5includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(kadm5includedir)/$$f"; \ + done +install-nodist_kadm5includeHEADERS: $(nodist_kadm5include_HEADERS) @$(NORMAL_INSTALL) - test -z "$(kadm5includedir)" || $(mkdir_p) "$(DESTDIR)$(kadm5includedir)" - @list='$(kadm5include_HEADERS)'; for p in $$list; do \ + test -z "$(kadm5includedir)" || $(MKDIR_P) "$(DESTDIR)$(kadm5includedir)" + @list='$(nodist_kadm5include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(kadm5includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(kadm5includedir)/$$f'"; \ - $(kadm5includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(kadm5includedir)/$$f"; \ + f=$(am__strip_dir) \ + echo " $(nodist_kadm5includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(kadm5includedir)/$$f'"; \ + $(nodist_kadm5includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(kadm5includedir)/$$f"; \ done -uninstall-kadm5includeHEADERS: +uninstall-nodist_kadm5includeHEADERS: @$(NORMAL_UNINSTALL) - @list='$(kadm5include_HEADERS)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ + @list='$(nodist_kadm5include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(kadm5includedir)/$$f'"; \ rm -f "$(DESTDIR)$(kadm5includedir)/$$f"; \ done @@ -710,9 +891,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) @@ -737,23 +920,21 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) - $(mkdir_p) $(distdir)/../.. $(distdir)/../../cf - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ @@ -768,12 +949,14 @@ distdir: $(DISTFILES) top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) \ + all-local installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(kadm5includedir)"; do \ - test -z "$$dir" || $(mkdir_p) "$$dir"; \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(kadm5includedir)" "$(DESTDIR)$(kadm5includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am @@ -795,20 +978,21 @@ clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \ - clean-libtool clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libexecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \ + clean-noinstPROGRAMS clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags + distclean-tags dvi: dvi-am @@ -820,18 +1004,27 @@ info: info-am info-am: -install-data-am: install-kadm5includeHEADERS +install-data-am: install-dist_kadm5includeHEADERS install-man \ + install-nodist_kadm5includeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS \ install-sbinPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + install-info: install-info-am -install-man: +install-man: install-man3 install-man8 + +install-pdf: install-pdf-am + +install-ps: install-ps-am installcheck-am: @@ -852,25 +1045,40 @@ ps: ps-am ps-am: -uninstall-am: uninstall-info-am uninstall-kadm5includeHEADERS \ +uninstall-am: uninstall-dist_kadm5includeHEADERS \ uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \ + uninstall-man uninstall-nodist_kadm5includeHEADERS \ uninstall-sbinPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook + +uninstall-man: uninstall-man3 uninstall-man8 + +.MAKE: install-am install-data-am install-exec-am install-strip \ + uninstall-am .PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \ - clean clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \ - clean-libtool clean-sbinPROGRAMS ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-exec \ - install-exec-am install-info install-info-am \ - install-kadm5includeHEADERS install-libLTLIBRARIES \ - install-libexecPROGRAMS install-man install-sbinPROGRAMS \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-info-am uninstall-kadm5includeHEADERS \ - uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \ + clean clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libexecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \ + clean-noinstPROGRAMS clean-sbinPROGRAMS ctags dist-hook \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-data-hook \ + install-dist_kadm5includeHEADERS install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-hook install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-libexecPROGRAMS install-man \ + install-man3 install-man8 install-nodist_kadm5includeHEADERS \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-dist_kadm5includeHEADERS \ + uninstall-hook uninstall-libLTLIBRARIES \ + uninstall-libexecPROGRAMS uninstall-man uninstall-man3 \ + uninstall-man8 uninstall-nodist_kadm5includeHEADERS \ uninstall-sbinPROGRAMS @@ -886,8 +1094,8 @@ install-suid-programs: install-exec-hook: install-suid-programs -install-build-headers:: $(include_HEADERS) $(build_HEADERZ) - @foo='$(include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \ +install-build-headers:: $(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS) + @foo='$(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \ for f in $$foo; do \ f=`basename $$f`; \ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ @@ -897,19 +1105,31 @@ install-build-headers:: $(include_HEADERS) $(build_HEADERZ) echo " $(CP) $$file $(buildinclude)/$$f"; \ $(CP) $$file $(buildinclude)/$$f; \ fi ; \ + done ; \ + foo='$(nobase_include_HEADERS)'; \ + for f in $$foo; do \ + if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ + else file="$$f"; fi; \ + $(mkdir_p) $(buildinclude)/`dirname $$f` ; \ + if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \ + : ; else \ + echo " $(CP) $$file $(buildinclude)/$$f"; \ + $(CP) $$file $(buildinclude)/$$f; \ + fi ; \ done all-local: install-build-headers check-local:: - @if test '$(CHECK_LOCAL)'; then \ + @if test '$(CHECK_LOCAL)' = "no-check-local"; then \ + foo=''; elif test '$(CHECK_LOCAL)'; then \ foo='$(CHECK_LOCAL)'; else \ foo='$(PROGRAMS)'; fi; \ if test "$$foo"; then \ failed=0; all=0; \ for i in $$foo; do \ all=`expr $$all + 1`; \ - if ./$$i --version > /dev/null 2>&1; then \ + if (./$$i --version && ./$$i --help) > /dev/null 2>&1; then \ echo "PASS: $$i"; \ else \ echo "FAIL: $$i"; \ @@ -925,7 +1145,7 @@ check-local:: echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes"; \ - test "$$failed" -eq 0; \ + test "$$failed" -eq 0 || exit 1; \ fi .x.c: @@ -995,17 +1215,42 @@ dist-cat8-mans: dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans install-cat-mans: - $(SHELL) $(top_srcdir)/cf/install-catman.sh "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + $(SHELL) $(top_srcdir)/cf/install-catman.sh install "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + +uninstall-cat-mans: + $(SHELL) $(top_srcdir)/cf/install-catman.sh uninstall "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) install-data-hook: install-cat-mans +uninstall-hook: uninstall-cat-mans .et.h: $(COMPILE_ET) $< .et.c: $(COMPILE_ET) $< -install-build-headers:: $(kadm5include_HEADERS) - @foo='$(kadm5include_HEADERS)'; \ +# +# Useful target for debugging +# + +check-valgrind: + tobjdir=`cd $(top_builddir) && pwd` ; \ + tsrcdir=`cd $(top_srcdir) && pwd` ; \ + env TESTS_ENVIRONMENT="$${tobjdir}/libtool --mode execute valgrind --leak-check=full --trace-children=yes --quiet -q --num-callers=30 --suppressions=$${tsrcdir}/cf/valgrind-suppressions" make check + +# +# Target to please samba build farm, builds distfiles in-tree. +# Will break when automake changes... +# + +distdir-in-tree: $(DISTFILES) $(INFO_DEPS) + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" != .; then \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) distdir-in-tree) ; \ + fi ; \ + done + +install-build-headers:: $(dist_kadm5include_HEADERS) $(nodist_kadm5include_HEADERS) + @foo='$(dist_kadm5include_HEADERS) $(nodist_kadm5include_HEADERS)'; \ for f in $$foo; do \ f=`basename $$f`; \ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ @@ -1017,7 +1262,11 @@ install-build-headers:: $(kadm5include_HEADERS) fi ; \ done +iprop-commands.c iprop-commands.h: iprop-commands.in + $(SLC) $(srcdir)/iprop-commands.in + $(libkadm5srv_la_OBJECTS): kadm5_err.h +$(iprop_log_OBJECTS): iprop-commands.h client_glue.lo server_glue.lo: $(srcdir)/common_glue.c @@ -1029,13 +1278,15 @@ $(libkadm5clnt_la_OBJECTS) $(libkadm5srv_la_OBJECTS): $(srcdir)/kadm5-protos.h $ $(srcdir)/kadm5-protos.h: cd $(srcdir); perl ../../cf/make-proto.pl $(proto_opts) \ -o kadm5-protos.h \ - $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) \ + $(dist_libkadm5clnt_la_SOURCES) \ + $(dist_libkadm5srv_la_SOURCES) \ || rm -f kadm5-protos.h $(srcdir)/kadm5-private.h: cd $(srcdir); perl ../../cf/make-proto.pl $(proto_opts) \ -p kadm5-private.h \ - $(libkadm5clnt_la_SOURCES) $(libkadm5srv_la_SOURCES) \ + $(dist_libkadm5clnt_la_SOURCES) \ + $(dist_libkadm5srv_la_SOURCES) \ || rm -f kadm5-private.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/crypto/heimdal/lib/kadm5/acl.c b/crypto/heimdal/lib/kadm5/acl.c index 6240588..9a2f75b 100644 --- a/crypto/heimdal/lib/kadm5/acl.c +++ b/crypto/heimdal/lib/kadm5/acl.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: acl.c,v 1.13 2001/08/24 04:01:42 assar Exp $"); +RCSID("$Id: acl.c 17445 2006-05-05 10:37:46Z lha $"); static struct units acl_units[] = { { "all", KADM5_PRIV_ALL }, @@ -48,7 +48,7 @@ static struct units acl_units[] = { }; kadm5_ret_t -_kadm5_string_to_privs(const char *s, u_int32_t* privs) +_kadm5_string_to_privs(const char *s, uint32_t* privs) { int flags; flags = parse_flags(s, acl_units, 0); @@ -59,7 +59,7 @@ _kadm5_string_to_privs(const char *s, u_int32_t* privs) } kadm5_ret_t -_kadm5_privs_to_string(u_int32_t privs, char *string, size_t len) +_kadm5_privs_to_string(uint32_t privs, char *string, size_t len) { if(privs == 0) strlcpy(string, "none", len); @@ -115,7 +115,7 @@ fetch_acl (kadm5_server_context *context, ret = _kadm5_string_to_privs(p, &flags); if (ret) break; - p = strtok_r(NULL, "\n", &foo); + p = strtok_r(NULL, " \t\n", &foo); if (p == NULL) { *ret_flags = flags; break; diff --git a/crypto/heimdal/lib/kadm5/ad.c b/crypto/heimdal/lib/kadm5/ad.c new file mode 100644 index 0000000..72288d9 --- /dev/null +++ b/crypto/heimdal/lib/kadm5/ad.c @@ -0,0 +1,1449 @@ +/* + * Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define HAVE_TSASL 1 + +#include "kadm5_locl.h" +#if 1 +#undef OPENLDAP +#undef HAVE_TSASL +#endif +#ifdef OPENLDAP +#include <ldap.h> +#ifdef HAVE_TSASL +#include <tsasl.h> +#endif +#include <resolve.h> +#include <base64.h> +#endif + +RCSID("$Id: ad.c 17445 2006-05-05 10:37:46Z lha $"); + +#ifdef OPENLDAP + +#define CTX2LP(context) ((LDAP *)((context)->ldap_conn)) +#define CTX2BASE(context) ((context)->base_dn) + +/* + * userAccountControl + */ + +#define UF_SCRIPT 0x00000001 +#define UF_ACCOUNTDISABLE 0x00000002 +#define UF_UNUSED_0 0x00000004 +#define UF_HOMEDIR_REQUIRED 0x00000008 +#define UF_LOCKOUT 0x00000010 +#define UF_PASSWD_NOTREQD 0x00000020 +#define UF_PASSWD_CANT_CHANGE 0x00000040 +#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 +#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 +#define UF_NORMAL_ACCOUNT 0x00000200 +#define UF_UNUSED_1 0x00000400 +#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 +#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 +#define UF_SERVER_TRUST_ACCOUNT 0x00002000 +#define UF_UNUSED_2 0x00004000 +#define UF_UNUSED_3 0x00008000 +#define UF_PASSWD_NOT_EXPIRE 0x00010000 +#define UF_MNS_LOGON_ACCOUNT 0x00020000 +#define UF_SMARTCARD_REQUIRED 0x00040000 +#define UF_TRUSTED_FOR_DELEGATION 0x00080000 +#define UF_NOT_DELEGATED 0x00100000 +#define UF_USE_DES_KEY_ONLY 0x00200000 +#define UF_DONT_REQUIRE_PREAUTH 0x00400000 +#define UF_UNUSED_4 0x00800000 +#define UF_UNUSED_5 0x01000000 +#define UF_UNUSED_6 0x02000000 +#define UF_UNUSED_7 0x04000000 +#define UF_UNUSED_8 0x08000000 +#define UF_UNUSED_9 0x10000000 +#define UF_UNUSED_10 0x20000000 +#define UF_UNUSED_11 0x40000000 +#define UF_UNUSED_12 0x80000000 + +/* + * + */ + +#ifndef HAVE_TSASL +static int +sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *interact) +{ + return LDAP_SUCCESS; +} +#endif + +#if 0 +static Sockbuf_IO ldap_tsasl_io = { + NULL, /* sbi_setup */ + NULL, /* sbi_remove */ + NULL, /* sbi_ctrl */ + NULL, /* sbi_read */ + NULL, /* sbi_write */ + NULL /* sbi_close */ +}; +#endif + +#ifdef HAVE_TSASL +static int +ldap_tsasl_bind_s(LDAP *ld, + LDAP_CONST char *dn, + LDAPControl **serverControls, + LDAPControl **clientControls, + const char *host) +{ + char *attrs[] = { "supportedSASLMechanisms", NULL }; + struct tsasl_peer *peer = NULL; + struct tsasl_buffer in, out; + struct berval ccred, *scred; + LDAPMessage *m, *m0; + const char *mech; + char **vals; + int ret, rc; + + ret = tsasl_peer_init(TSASL_FLAGS_INITIATOR | TSASL_FLAGS_CLEAR, + "ldap", host, &peer); + if (ret != TSASL_DONE) { + rc = LDAP_LOCAL_ERROR; + goto out; + } + + rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE, NULL, attrs, 0, &m0); + if (rc != LDAP_SUCCESS) + goto out; + + m = ldap_first_entry(ld, m0); + if (m == NULL) { + ldap_msgfree(m0); + goto out; + } + + vals = ldap_get_values(ld, m, "supportedSASLMechanisms"); + if (vals == NULL) { + ldap_msgfree(m0); + goto out; + } + + ret = tsasl_find_best_mech(peer, vals, &mech); + if (ret) { + ldap_msgfree(m0); + goto out; + } + + ldap_msgfree(m0); + + ret = tsasl_select_mech(peer, mech); + if (ret != TSASL_DONE) { + rc = LDAP_LOCAL_ERROR; + goto out; + } + + in.tb_data = NULL; + in.tb_size = 0; + + do { + ret = tsasl_request(peer, &in, &out); + if (in.tb_size != 0) { + free(in.tb_data); + in.tb_data = NULL; + in.tb_size = 0; + } + if (ret != TSASL_DONE && ret != TSASL_CONTINUE) { + rc = LDAP_AUTH_UNKNOWN; + goto out; + } + + ccred.bv_val = out.tb_data; + ccred.bv_len = out.tb_size; + + rc = ldap_sasl_bind_s(ld, dn, mech, &ccred, + serverControls, clientControls, &scred); + tsasl_buffer_free(&out); + + if (rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS) { + if(scred && scred->bv_len) + ber_bvfree(scred); + goto out; + } + + in.tb_data = malloc(scred->bv_len); + if (in.tb_data == NULL) { + rc = LDAP_LOCAL_ERROR; + goto out; + } + memcpy(in.tb_data, scred->bv_val, scred->bv_len); + in.tb_size = scred->bv_len; + ber_bvfree(scred); + + } while (rc == LDAP_SASL_BIND_IN_PROGRESS); + + out: + if (rc == LDAP_SUCCESS) { +#if 0 + ber_sockbuf_add_io(ld->ld_conns->lconn_sb, &ldap_tsasl_io, + LBER_SBIOD_LEVEL_APPLICATION, peer); + +#endif + } else if (peer != NULL) + tsasl_peer_free(peer); + + return rc; +} +#endif /* HAVE_TSASL */ + + +static int +check_ldap(kadm5_ad_context *context, int ret) +{ + switch (ret) { + case LDAP_SUCCESS: + return 0; + case LDAP_SERVER_DOWN: { + LDAP *lp = CTX2LP(context); + ldap_unbind(lp); + context->ldap_conn = NULL; + free(context->base_dn); + context->base_dn = NULL; + return 1; + } + default: + return 1; + } +} + +/* + * + */ + +static void +laddattr(char ***al, int *attrlen, char *attr) +{ + char **a; + a = realloc(*al, (*attrlen + 2) * sizeof(**al)); + if (a == NULL) + return; + a[*attrlen] = attr; + a[*attrlen + 1] = NULL; + (*attrlen)++; + *al = a; +} + +static kadm5_ret_t +_kadm5_ad_connect(void *server_handle) +{ + kadm5_ad_context *context = server_handle; + struct { + char *server; + int port; + } *s, *servers = NULL; + int i, num_servers = 0; + + if (context->ldap_conn) + return 0; + + { + struct dns_reply *r; + struct resource_record *rr; + char *domain; + + asprintf(&domain, "_ldap._tcp.%s", context->realm); + if (domain == NULL) { + krb5_set_error_string(context->context, "malloc"); + return KADM5_NO_SRV; + } + + r = dns_lookup(domain, "SRV"); + free(domain); + if (r == NULL) { + krb5_set_error_string(context->context, "Didn't find ldap dns"); + return KADM5_NO_SRV; + } + + for (rr = r->head ; rr != NULL; rr = rr->next) { + if (rr->type != T_SRV) + continue; + s = realloc(servers, sizeof(*servers) * (num_servers + 1)); + if (s == NULL) { + krb5_set_error_string(context->context, "malloc"); + dns_free_data(r); + goto fail; + } + servers = s; + num_servers++; + servers[num_servers - 1].port = rr->u.srv->port; + servers[num_servers - 1].server = strdup(rr->u.srv->target); + } + dns_free_data(r); + } + + if (num_servers == 0) { + krb5_set_error_string(context->context, "No AD server found in DNS"); + return KADM5_NO_SRV; + } + + for (i = 0; i < num_servers; i++) { + int lret, version = LDAP_VERSION3; + LDAP *lp; + + lp = ldap_init(servers[i].server, servers[i].port); + if (lp == NULL) + continue; + + if (ldap_set_option(lp, LDAP_OPT_PROTOCOL_VERSION, &version)) { + ldap_unbind(lp); + continue; + } + + if (ldap_set_option(lp, LDAP_OPT_REFERRALS, LDAP_OPT_OFF)) { + ldap_unbind(lp); + continue; + } + +#ifdef HAVE_TSASL + lret = ldap_tsasl_bind_s(lp, NULL, NULL, NULL, servers[i].server); + +#else + lret = ldap_sasl_interactive_bind_s(lp, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, + sasl_interact, NULL); +#endif + if (lret != LDAP_SUCCESS) { + krb5_set_error_string(context->context, + "Couldn't contact any AD servers: %s", + ldap_err2string(lret)); + ldap_unbind(lp); + continue; + } + + context->ldap_conn = lp; + break; + } + if (i >= num_servers) { + goto fail; + } + + { + LDAPMessage *m, *m0; + char **attr = NULL; + int attrlen = 0; + char **vals; + int ret; + + laddattr(&attr, &attrlen, "defaultNamingContext"); + + ret = ldap_search_s(CTX2LP(context), "", LDAP_SCOPE_BASE, + "objectclass=*", attr, 0, &m); + free(attr); + if (check_ldap(context, ret)) + goto fail; + + if (ldap_count_entries(CTX2LP(context), m) > 0) { + m0 = ldap_first_entry(CTX2LP(context), m); + if (m0 == NULL) { + krb5_set_error_string(context->context, + "Error in AD ldap responce"); + ldap_msgfree(m); + goto fail; + } + vals = ldap_get_values(CTX2LP(context), + m0, "defaultNamingContext"); + if (vals == NULL) { + krb5_set_error_string(context->context, + "No naming context found"); + goto fail; + } + context->base_dn = strdup(vals[0]); + } else + goto fail; + ldap_msgfree(m); + } + + for (i = 0; i < num_servers; i++) + free(servers[i].server); + free(servers); + + return 0; + + fail: + for (i = 0; i < num_servers; i++) + free(servers[i].server); + free(servers); + + if (context->ldap_conn) { + ldap_unbind(CTX2LP(context)); + context->ldap_conn = NULL; + } + return KADM5_RPC_ERROR; +} + +#define NTTIME_EPOCH 0x019DB1DED53E8000LL + +static time_t +nt2unixtime(const char *str) +{ + unsigned long long t; + t = strtoll(str, NULL, 10); + t = ((t - NTTIME_EPOCH) / (long long)10000000); + if (t > (((time_t)(~(long long)0)) >> 1)) + return 0; + return (time_t)t; +} + +static long long +unix2nttime(time_t unix_time) +{ + long long wt; + wt = unix_time * (long long)10000000 + (long long)NTTIME_EPOCH; + return wt; +} + +/* XXX create filter in a better way */ + +static int +ad_find_entry(kadm5_ad_context *context, + const char *fqdn, + const char *pn, + char **name) +{ + LDAPMessage *m, *m0; + char *attr[] = { "distinguishedName", NULL }; + char *filter; + int ret; + + if (name) + *name = NULL; + + if (fqdn) + asprintf(&filter, + "(&(objectClass=computer)(|(dNSHostName=%s)(servicePrincipalName=%s)))", + fqdn, pn); + else if(pn) + asprintf(&filter, "(&(objectClass=account)(userPrincipalName=%s))", pn); + else + return KADM5_RPC_ERROR; + + ret = ldap_search_s(CTX2LP(context), CTX2BASE(context), + LDAP_SCOPE_SUBTREE, + filter, attr, 0, &m); + free(filter); + if (check_ldap(context, ret)) + return KADM5_RPC_ERROR; + + if (ldap_count_entries(CTX2LP(context), m) > 0) { + char **vals; + m0 = ldap_first_entry(CTX2LP(context), m); + vals = ldap_get_values(CTX2LP(context), m0, "distinguishedName"); + if (vals == NULL || vals[0] == NULL) { + ldap_msgfree(m); + return KADM5_RPC_ERROR; + } + if (name) + *name = strdup(vals[0]); + ldap_msgfree(m); + } else + return KADM5_UNK_PRINC; + + return 0; +} + +#endif /* OPENLDAP */ + +static kadm5_ret_t +ad_get_cred(kadm5_ad_context *context, const char *password) +{ + kadm5_ret_t ret; + krb5_ccache cc; + char *service; + + if (context->ccache) + return 0; + + asprintf(&service, "%s/%s@%s", KRB5_TGS_NAME, + context->realm, context->realm); + if (service == NULL) + return ENOMEM; + + ret = _kadm5_c_get_cred_cache(context->context, + context->client_name, + service, + password, krb5_prompter_posix, + NULL, NULL, &cc); + free(service); + if(ret) + return ret; /* XXX */ + context->ccache = cc; + return 0; +} + +static kadm5_ret_t +kadm5_ad_chpass_principal(void *server_handle, + krb5_principal principal, + const char *password) +{ + kadm5_ad_context *context = server_handle; + krb5_data result_code_string, result_string; + int result_code; + kadm5_ret_t ret; + + ret = ad_get_cred(context, NULL); + if (ret) + return ret; + + krb5_data_zero (&result_code_string); + krb5_data_zero (&result_string); + + ret = krb5_set_password_using_ccache (context->context, + context->ccache, + password, + principal, + &result_code, + &result_code_string, + &result_string); + + krb5_data_free (&result_code_string); + krb5_data_free (&result_string); + + /* XXX do mapping here on error codes */ + + return ret; +} + +#ifdef OPENLDAP +static const char * +get_fqdn(krb5_context context, const krb5_principal p) +{ + const char *s, *hosttypes[] = { "host", "ldap", "gc", "cifs", "dns" }; + int i; + + s = krb5_principal_get_comp_string(context, p, 0); + if (p == NULL) + return NULL; + + for (i = 0; i < sizeof(hosttypes)/sizeof(hosttypes[0]); i++) { + if (strcasecmp(s, hosttypes[i]) == 0) + return krb5_principal_get_comp_string(context, p, 1); + } + return 0; +} +#endif + + +static kadm5_ret_t +kadm5_ad_create_principal(void *server_handle, + kadm5_principal_ent_t entry, + uint32_t mask, + const char *password) +{ + kadm5_ad_context *context = server_handle; + + /* + * KADM5_PRINC_EXPIRE_TIME + * + * return 0 || KADM5_DUP; + */ + +#ifdef OPENLDAP + LDAPMod *attrs[8], rattrs[7], *a; + char *useraccvals[2] = { NULL, NULL }, + *samvals[2], *dnsvals[2], *spnvals[5], *upnvals[2], *tv[2]; + char *ocvals_spn[] = { "top", "person", "organizationalPerson", + "user", "computer", NULL}; + char *p, *realmless_p, *p_msrealm = NULL, *dn = NULL; + const char *fqdn; + char *s, *samname = NULL, *short_spn = NULL; + int ret, i; + int32_t uf_flags = 0; + + if ((mask & KADM5_PRINCIPAL) == 0) + return KADM5_BAD_MASK; + + for (i = 0; i < sizeof(rattrs)/sizeof(rattrs[0]); i++) + attrs[i] = &rattrs[i]; + attrs[i] = NULL; + + ret = ad_get_cred(context, NULL); + if (ret) + return ret; + + ret = _kadm5_ad_connect(server_handle); + if (ret) + return ret; + + fqdn = get_fqdn(context->context, entry->principal); + + ret = krb5_unparse_name(context->context, entry->principal, &p); + if (ret) + return ret; + + if (ad_find_entry(context, fqdn, p, NULL) == 0) { + free(p); + return KADM5_DUP; + } + + if (mask & KADM5_ATTRIBUTES) { + if (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX) + uf_flags |= UF_ACCOUNTDISABLE|UF_LOCKOUT; + if ((entry->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) == 0) + uf_flags |= UF_DONT_REQUIRE_PREAUTH; + if (entry->attributes & KRB5_KDB_REQUIRES_HW_AUTH) + uf_flags |= UF_SMARTCARD_REQUIRED; + } + + realmless_p = strdup(p); + if (realmless_p == NULL) { + ret = ENOMEM; + goto out; + } + s = strrchr(realmless_p, '@'); + if (s) + *s = '\0'; + + if (fqdn) { + /* create computer account */ + asprintf(&samname, "%s$", fqdn); + if (samname == NULL) { + ret = ENOMEM; + goto out; + } + s = strchr(samname, '.'); + if (s) { + s[0] = '$'; + s[1] = '\0'; + } + + short_spn = strdup(p); + if (short_spn == NULL) { + errno = ENOMEM; + goto out; + } + s = strchr(short_spn, '.'); + if (s) { + *s = '\0'; + } else { + free(short_spn); + short_spn = NULL; + } + + p_msrealm = strdup(p); + if (p_msrealm == NULL) { + errno = ENOMEM; + goto out; + } + s = strrchr(p_msrealm, '@'); + if (s) { + *s = '/'; + } else { + free(p_msrealm); + p_msrealm = NULL; + } + + asprintf(&dn, "cn=%s, cn=Computers, %s", fqdn, CTX2BASE(context)); + if (dn == NULL) { + ret = ENOMEM; + goto out; + } + + a = &rattrs[0]; + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "objectClass"; + a->mod_values = ocvals_spn; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "userAccountControl"; + a->mod_values = useraccvals; + asprintf(&useraccvals[0], "%d", + uf_flags | + UF_PASSWD_NOT_EXPIRE | + UF_WORKSTATION_TRUST_ACCOUNT); + useraccvals[1] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "sAMAccountName"; + a->mod_values = samvals; + samvals[0] = samname; + samvals[1] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "dNSHostName"; + a->mod_values = dnsvals; + dnsvals[0] = (char *)fqdn; + dnsvals[1] = NULL; + a++; + + /* XXX add even more spn's */ + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "servicePrincipalName"; + a->mod_values = spnvals; + i = 0; + spnvals[i++] = p; + spnvals[i++] = realmless_p; + if (short_spn) + spnvals[i++] = short_spn; + if (p_msrealm) + spnvals[i++] = p_msrealm; + spnvals[i++] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "userPrincipalName"; + a->mod_values = upnvals; + upnvals[0] = p; + upnvals[1] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "accountExpires"; + a->mod_values = tv; + tv[0] = "9223372036854775807"; /* "never" */ + tv[1] = NULL; + a++; + + } else { + /* create user account */ + + a = &rattrs[0]; + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "userAccountControl"; + a->mod_values = useraccvals; + asprintf(&useraccvals[0], "%d", + uf_flags | + UF_PASSWD_NOT_EXPIRE); + useraccvals[1] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "sAMAccountName"; + a->mod_values = samvals; + samvals[0] = realmless_p; + samvals[1] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "userPrincipalName"; + a->mod_values = upnvals; + upnvals[0] = p; + upnvals[1] = NULL; + a++; + + a->mod_op = LDAP_MOD_ADD; + a->mod_type = "accountExpires"; + a->mod_values = tv; + tv[0] = "9223372036854775807"; /* "never" */ + tv[1] = NULL; + a++; + } + + attrs[a - &rattrs[0]] = NULL; + + ret = ldap_add_s(CTX2LP(context), dn, attrs); + + out: + if (useraccvals[0]) + free(useraccvals[0]); + if (realmless_p) + free(realmless_p); + if (samname) + free(samname); + if (short_spn) + free(short_spn); + if (p_msrealm) + free(p_msrealm); + free(p); + + if (check_ldap(context, ret)) + return KADM5_RPC_ERROR; + + return 0; +#else + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_delete_principal(void *server_handle, krb5_principal principal) +{ + kadm5_ad_context *context = server_handle; +#ifdef OPENLDAP + char *p, *dn = NULL; + const char *fqdn; + int ret; + + ret = ad_get_cred(context, NULL); + if (ret) + return ret; + + ret = _kadm5_ad_connect(server_handle); + if (ret) + return ret; + + fqdn = get_fqdn(context->context, principal); + + ret = krb5_unparse_name(context->context, principal, &p); + if (ret) + return ret; + + if (ad_find_entry(context, fqdn, p, &dn) != 0) { + free(p); + return KADM5_UNK_PRINC; + } + + ret = ldap_delete_s(CTX2LP(context), dn); + + free(dn); + free(p); + + if (check_ldap(context, ret)) + return KADM5_RPC_ERROR; + return 0; +#else + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_destroy(void *server_handle) +{ + kadm5_ad_context *context = server_handle; + + if (context->ccache) + krb5_cc_destroy(context->context, context->ccache); + +#ifdef OPENLDAP + { + LDAP *lp = CTX2LP(context); + if (lp) + ldap_unbind(lp); + if (context->base_dn) + free(context->base_dn); + } +#endif + free(context->realm); + free(context->client_name); + krb5_free_principal(context->context, context->caller); + if(context->my_context) + krb5_free_context(context->context); + return 0; +} + +static kadm5_ret_t +kadm5_ad_flush(void *server_handle) +{ + kadm5_ad_context *context = server_handle; +#ifdef OPENLDAP + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#else + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_get_principal(void *server_handle, + krb5_principal principal, + kadm5_principal_ent_t entry, + uint32_t mask) +{ + kadm5_ad_context *context = server_handle; +#ifdef OPENLDAP + LDAPMessage *m, *m0; + char **attr = NULL; + int attrlen = 0; + char *filter, *p, *q, *u; + int ret; + + /* + * principal + * KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES + */ + + /* + * return 0 || KADM5_DUP; + */ + + memset(entry, 0, sizeof(*entry)); + + if (mask & KADM5_KVNO) + laddattr(&attr, &attrlen, "msDS-KeyVersionNumber"); + + if (mask & KADM5_PRINCIPAL) { + laddattr(&attr, &attrlen, "userPrincipalName"); + laddattr(&attr, &attrlen, "servicePrincipalName"); + } + laddattr(&attr, &attrlen, "objectClass"); + laddattr(&attr, &attrlen, "lastLogon"); + laddattr(&attr, &attrlen, "badPwdCount"); + laddattr(&attr, &attrlen, "badPasswordTime"); + laddattr(&attr, &attrlen, "pwdLastSet"); + laddattr(&attr, &attrlen, "accountExpires"); + laddattr(&attr, &attrlen, "userAccountControl"); + + krb5_unparse_name_short(context->context, principal, &p); + krb5_unparse_name(context->context, principal, &u); + + /* replace @ in domain part with a / */ + q = strrchr(p, '@'); + if (q && (p != q && *(q - 1) != '\\')) + *q = '/'; + + asprintf(&filter, + "(|(userPrincipalName=%s)(servicePrincipalName=%s)(servicePrincipalName=%s))", + u, p, u); + free(p); + free(u); + + ret = ldap_search_s(CTX2LP(context), CTX2BASE(context), + LDAP_SCOPE_SUBTREE, + filter, attr, 0, &m); + free(attr); + if (check_ldap(context, ret)) + return KADM5_RPC_ERROR; + + if (ldap_count_entries(CTX2LP(context), m) > 0) { + char **vals; + m0 = ldap_first_entry(CTX2LP(context), m); + if (m0 == NULL) { + ldap_msgfree(m); + goto fail; + } +#if 0 + vals = ldap_get_values(CTX2LP(context), m0, "servicePrincipalName"); + if (vals) + printf("servicePrincipalName %s\n", vals[0]); + vals = ldap_get_values(CTX2LP(context), m0, "userPrincipalName"); + if (vals) + printf("userPrincipalName %s\n", vals[0]); + vals = ldap_get_values(CTX2LP(context), m0, "userAccountControl"); + if (vals) + printf("userAccountControl %s\n", vals[0]); +#endif + entry->princ_expire_time = 0; + if (mask & KADM5_PRINC_EXPIRE_TIME) { + vals = ldap_get_values(CTX2LP(context), m0, "accountExpires"); + if (vals) + entry->princ_expire_time = nt2unixtime(vals[0]); + } + entry->last_success = 0; + if (mask & KADM5_LAST_SUCCESS) { + vals = ldap_get_values(CTX2LP(context), m0, "lastLogon"); + if (vals) + entry->last_success = nt2unixtime(vals[0]); + } + if (mask & KADM5_LAST_FAILED) { + vals = ldap_get_values(CTX2LP(context), m0, "badPasswordTime"); + if (vals) + entry->last_failed = nt2unixtime(vals[0]); + } + if (mask & KADM5_LAST_PWD_CHANGE) { + vals = ldap_get_values(CTX2LP(context), m0, "pwdLastSet"); + if (vals) + entry->last_pwd_change = nt2unixtime(vals[0]); + } + if (mask & KADM5_FAIL_AUTH_COUNT) { + vals = ldap_get_values(CTX2LP(context), m0, "badPwdCount"); + if (vals) + entry->fail_auth_count = atoi(vals[0]); + } + if (mask & KADM5_ATTRIBUTES) { + vals = ldap_get_values(CTX2LP(context), m0, "userAccountControl"); + if (vals) { + uint32_t i; + i = atoi(vals[0]); + if (i & (UF_ACCOUNTDISABLE|UF_LOCKOUT)) + entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; + if ((i & UF_DONT_REQUIRE_PREAUTH) == 0) + entry->attributes |= KRB5_KDB_REQUIRES_PRE_AUTH; + if (i & UF_SMARTCARD_REQUIRED) + entry->attributes |= KRB5_KDB_REQUIRES_HW_AUTH; + if ((i & UF_WORKSTATION_TRUST_ACCOUNT) == 0) + entry->attributes |= KRB5_KDB_DISALLOW_SVR; + } + } + if (mask & KADM5_KVNO) { + vals = ldap_get_values(CTX2LP(context), m0, + "msDS-KeyVersionNumber"); + if (vals) + entry->kvno = atoi(vals[0]); + else + entry->kvno = 0; + } + ldap_msgfree(m); + } else { + return KADM5_UNK_PRINC; + } + + if (mask & KADM5_PRINCIPAL) + krb5_copy_principal(context->context, principal, &entry->principal); + + return 0; + fail: + return KADM5_RPC_ERROR; +#else + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_get_principals(void *server_handle, + const char *expression, + char ***principals, + int *count) +{ + kadm5_ad_context *context = server_handle; + + /* + * KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES + */ + +#ifdef OPENLDAP + kadm5_ret_t ret; + + ret = ad_get_cred(context, NULL); + if (ret) + return ret; + + ret = _kadm5_ad_connect(server_handle); + if (ret) + return ret; + + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#else + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_get_privs(void *server_handle, uint32_t*privs) +{ + kadm5_ad_context *context = server_handle; + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +} + +static kadm5_ret_t +kadm5_ad_modify_principal(void *server_handle, + kadm5_principal_ent_t entry, + uint32_t mask) +{ + kadm5_ad_context *context = server_handle; + + /* + * KADM5_ATTRIBUTES + * KRB5_KDB_DISALLOW_ALL_TIX (| KADM5_KVNO) + */ + +#ifdef OPENLDAP + LDAPMessage *m = NULL, *m0; + kadm5_ret_t ret; + char **attr = NULL; + int attrlen = 0; + char *p = NULL, *s = NULL, *q; + char **vals; + LDAPMod *attrs[4], rattrs[3], *a; + char *uaf[2] = { NULL, NULL }; + char *kvno[2] = { NULL, NULL }; + char *tv[2] = { NULL, NULL }; + char *filter, *dn; + int i; + + for (i = 0; i < sizeof(rattrs)/sizeof(rattrs[0]); i++) + attrs[i] = &rattrs[i]; + attrs[i] = NULL; + a = &rattrs[0]; + + ret = _kadm5_ad_connect(server_handle); + if (ret) + return ret; + + if (mask & KADM5_KVNO) + laddattr(&attr, &attrlen, "msDS-KeyVersionNumber"); + if (mask & KADM5_PRINC_EXPIRE_TIME) + laddattr(&attr, &attrlen, "accountExpires"); + if (mask & KADM5_ATTRIBUTES) + laddattr(&attr, &attrlen, "userAccountControl"); + laddattr(&attr, &attrlen, "distinguishedName"); + + krb5_unparse_name(context->context, entry->principal, &p); + + s = strdup(p); + + q = strrchr(s, '@'); + if (q && (p != q && *(q - 1) != '\\')) + *q = '\0'; + + asprintf(&filter, + "(|(userPrincipalName=%s)(servicePrincipalName=%s))", + s, s); + free(p); + free(s); + + ret = ldap_search_s(CTX2LP(context), CTX2BASE(context), + LDAP_SCOPE_SUBTREE, + filter, attr, 0, &m); + free(attr); + free(filter); + if (check_ldap(context, ret)) + return KADM5_RPC_ERROR; + + if (ldap_count_entries(CTX2LP(context), m) <= 0) { + ret = KADM5_RPC_ERROR; + goto out; + } + + m0 = ldap_first_entry(CTX2LP(context), m); + + if (mask & KADM5_ATTRIBUTES) { + int32_t i; + + vals = ldap_get_values(CTX2LP(context), m0, "userAccountControl"); + if (vals == NULL) { + ret = KADM5_RPC_ERROR; + goto out; + } + + i = atoi(vals[0]); + if (i == 0) + return KADM5_RPC_ERROR; + + if (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX) + i |= (UF_ACCOUNTDISABLE|UF_LOCKOUT); + else + i &= ~(UF_ACCOUNTDISABLE|UF_LOCKOUT); + if (entry->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) + i &= ~UF_DONT_REQUIRE_PREAUTH; + else + i |= UF_DONT_REQUIRE_PREAUTH; + if (entry->attributes & KRB5_KDB_REQUIRES_HW_AUTH) + i |= UF_SMARTCARD_REQUIRED; + else + i &= UF_SMARTCARD_REQUIRED; + if (entry->attributes & KRB5_KDB_DISALLOW_SVR) + i &= ~UF_WORKSTATION_TRUST_ACCOUNT; + else + i |= UF_WORKSTATION_TRUST_ACCOUNT; + + asprintf(&uaf[0], "%d", i); + + a->mod_op = LDAP_MOD_REPLACE; + a->mod_type = "userAccountControl"; + a->mod_values = uaf; + a++; + } + + if (mask & KADM5_KVNO) { + vals = ldap_get_values(CTX2LP(context), m0, "msDS-KeyVersionNumber"); + if (vals == NULL) { + entry->kvno = 0; + } else { + asprintf(&kvno[0], "%d", entry->kvno); + + a->mod_op = LDAP_MOD_REPLACE; + a->mod_type = "msDS-KeyVersionNumber"; + a->mod_values = kvno; + a++; + } + } + + if (mask & KADM5_PRINC_EXPIRE_TIME) { + long long wt; + vals = ldap_get_values(CTX2LP(context), m0, "accountExpires"); + if (vals == NULL) { + ret = KADM5_RPC_ERROR; + goto out; + } + + wt = unix2nttime(entry->princ_expire_time); + + asprintf(&tv[0], "%llu", wt); + + a->mod_op = LDAP_MOD_REPLACE; + a->mod_type = "accountExpires"; + a->mod_values = tv; + a++; + } + + vals = ldap_get_values(CTX2LP(context), m0, "distinguishedName"); + if (vals == NULL) { + ret = KADM5_RPC_ERROR; + goto out; + } + dn = vals[0]; + + attrs[a - &rattrs[0]] = NULL; + + ret = ldap_modify_s(CTX2LP(context), dn, attrs); + if (check_ldap(context, ret)) + return KADM5_RPC_ERROR; + + out: + if (m) + ldap_msgfree(m); + if (uaf[0]) + free(uaf[0]); + if (kvno[0]) + free(kvno[0]); + if (tv[0]) + free(tv[0]); + return ret; +#else + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_randkey_principal(void *server_handle, + krb5_principal principal, + krb5_keyblock **keys, + int *n_keys) +{ + kadm5_ad_context *context = server_handle; + + /* + * random key + */ + +#ifdef OPENLDAP + krb5_data result_code_string, result_string; + int result_code, plen; + kadm5_ret_t ret; + char *password; + + *keys = NULL; + *n_keys = 0; + + { + char p[64]; + krb5_generate_random_block(p, sizeof(p)); + plen = base64_encode(p, sizeof(p), &password); + if (plen < 0) + return ENOMEM; + } + + ret = ad_get_cred(context, NULL); + if (ret) { + free(password); + return ret; + } + + krb5_data_zero (&result_code_string); + krb5_data_zero (&result_string); + + ret = krb5_set_password_using_ccache (context->context, + context->ccache, + password, + principal, + &result_code, + &result_code_string, + &result_string); + + krb5_data_free (&result_code_string); + krb5_data_free (&result_string); + + if (ret == 0) { + + *keys = malloc(sizeof(**keys) * 1); + if (*keys == NULL) { + ret = ENOMEM; + goto out; + } + *n_keys = 1; + + ret = krb5_string_to_key(context->context, + ENCTYPE_ARCFOUR_HMAC_MD5, + password, + principal, + &(*keys)[0]); + memset(password, 0, sizeof(password)); + if (ret) { + free(*keys); + *keys = NULL; + *n_keys = 0; + goto out; + } + } + memset(password, 0, plen); + free(password); + out: + return ret; +#else + *keys = NULL; + *n_keys = 0; + + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t +kadm5_ad_rename_principal(void *server_handle, + krb5_principal from, + krb5_principal to) +{ + kadm5_ad_context *context = server_handle; + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +} + +static kadm5_ret_t +kadm5_ad_chpass_principal_with_key(void *server_handle, + krb5_principal princ, + int n_key_data, + krb5_key_data *key_data) +{ + kadm5_ad_context *context = server_handle; + krb5_set_error_string(context->context, "Function not implemented"); + return KADM5_RPC_ERROR; +} + +static void +set_funcs(kadm5_ad_context *c) +{ +#define SET(C, F) (C)->funcs.F = kadm5_ad_ ## F + SET(c, chpass_principal); + SET(c, chpass_principal_with_key); + SET(c, create_principal); + SET(c, delete_principal); + SET(c, destroy); + SET(c, flush); + SET(c, get_principal); + SET(c, get_principals); + SET(c, get_privs); + SET(c, modify_principal); + SET(c, randkey_principal); + SET(c, rename_principal); +} + +kadm5_ret_t +kadm5_ad_init_with_password_ctx(krb5_context context, + const char *client_name, + const char *password, + const char *service_name, + kadm5_config_params *realm_params, + unsigned long struct_version, + unsigned long api_version, + void **server_handle) +{ + kadm5_ret_t ret; + kadm5_ad_context *ctx; + + ctx = malloc(sizeof(*ctx)); + if(ctx == NULL) + return ENOMEM; + memset(ctx, 0, sizeof(*ctx)); + set_funcs(ctx); + + ctx->context = context; + krb5_add_et_list (context, initialize_kadm5_error_table_r); + + ret = krb5_parse_name(ctx->context, client_name, &ctx->caller); + if(ret) { + free(ctx); + return ret; + } + + if(realm_params->mask & KADM5_CONFIG_REALM) { + ret = 0; + ctx->realm = strdup(realm_params->realm); + if (ctx->realm == NULL) + ret = ENOMEM; + } else + ret = krb5_get_default_realm(ctx->context, &ctx->realm); + if (ret) { + free(ctx); + return ret; + } + + ctx->client_name = strdup(client_name); + + if(password != NULL && *password != '\0') + ret = ad_get_cred(ctx, password); + else + ret = ad_get_cred(ctx, NULL); + if(ret) { + kadm5_ad_destroy(ctx); + return ret; + } + +#ifdef OPENLDAP + ret = _kadm5_ad_connect(ctx); + if (ret) { + kadm5_ad_destroy(ctx); + return ret; + } +#endif + + *server_handle = ctx; + return 0; +} + +kadm5_ret_t +kadm5_ad_init_with_password(const char *client_name, + const char *password, + const char *service_name, + kadm5_config_params *realm_params, + unsigned long struct_version, + unsigned long api_version, + void **server_handle) +{ + krb5_context context; + kadm5_ret_t ret; + kadm5_ad_context *ctx; + + ret = krb5_init_context(&context); + if (ret) + return ret; + ret = kadm5_ad_init_with_password_ctx(context, + client_name, + password, + service_name, + realm_params, + struct_version, + api_version, + server_handle); + if(ret) { + krb5_free_context(context); + return ret; + } + ctx = *server_handle; + ctx->my_context = 1; + return 0; +} diff --git a/crypto/heimdal/lib/kadm5/admin.h b/crypto/heimdal/lib/kadm5/admin.h index d9bd85f..30d68d8 100644 --- a/crypto/heimdal/lib/kadm5/admin.h +++ b/crypto/heimdal/lib/kadm5/admin.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* $Id: admin.h,v 1.18 2000/08/04 11:26:21 joda Exp $ */ +/* $Id: admin.h 20237 2007-02-16 23:54:34Z lha $ */ #ifndef __KADM5_ADMIN_H__ #define __KADM5_ADMIN_H__ @@ -64,6 +64,10 @@ #define KRB5_KDB_PWCHANGE_SERVICE 0x00002000 #define KRB5_KDB_SUPPORT_DESMD5 0x00004000 #define KRB5_KDB_NEW_PRINC 0x00008000 +#define KRB5_KDB_OK_AS_DELEGATE 0x00010000 +#define KRB5_KDB_TRUSTED_FOR_DELEGATION 0x00020000 +#define KRB5_KDB_ALLOW_KERBEROS4 0x00040000 +#define KRB5_KDB_ALLOW_DIGEST 0x00080000 #define KADM5_PRINCIPAL 0x000001 #define KADM5_PRINC_EXPIRE_TIME 0x000002 @@ -115,6 +119,17 @@ typedef struct _krb5_tl_data { void* tl_data_contents; } krb5_tl_data; +#define KRB5_TL_LAST_PWD_CHANGE 0x0001 +#define KRB5_TL_MOD_PRINC 0x0002 +#define KRB5_TL_KADM_DATA 0x0003 +#define KRB5_TL_KADM5_E_DATA 0x0004 +#define KRB5_TL_RB1_CHALLENGE 0x0005 +#define KRB5_TL_SECURID_STATE 0x0006 +#define KRB5_TL_PASSWORD 0x0007 +#define KRB5_TL_EXTENSION 0x0008 +#define KRB5_TL_PKINIT_ACL 0x0009 +#define KRB5_TL_ALIASES 0x000a + typedef struct _kadm5_principal_ent_t { krb5_principal principal; @@ -129,7 +144,7 @@ typedef struct _kadm5_principal_ent_t { krb5_kvno mkvno; char * policy; - u_int32_t aux_attributes; + uint32_t aux_attributes; krb5_deltat max_renewable_life; krb5_timestamp last_success; @@ -144,12 +159,12 @@ typedef struct _kadm5_principal_ent_t { typedef struct _kadm5_policy_ent_t { char *policy; - u_int32_t pw_min_life; - u_int32_t pw_max_life; - u_int32_t pw_min_length; - u_int32_t pw_min_classes; - u_int32_t pw_history_num; - u_int32_t policy_refcnt; + uint32_t pw_min_life; + uint32_t pw_max_life; + uint32_t pw_min_length; + uint32_t pw_min_classes; + uint32_t pw_history_num; + uint32_t policy_refcnt; } kadm5_policy_ent_rec, *kadm5_policy_ent_t; #define KADM5_CONFIG_REALM (1 << 0) @@ -185,7 +200,7 @@ typedef struct { }krb5_key_salt_tuple; typedef struct _kadm5_config_params { - u_int32_t mask; + uint32_t mask; /* Client and server fields */ char *realm; @@ -217,7 +232,7 @@ kadm5_decrypt_key(void *server_handle, kadm5_ret_t kadm5_create_policy(void *server_handle, - kadm5_policy_ent_t policy, u_int32_t mask); + kadm5_policy_ent_t policy, uint32_t mask); kadm5_ret_t kadm5_delete_policy(void *server_handle, char *policy); @@ -226,7 +241,7 @@ kadm5_delete_policy(void *server_handle, char *policy); kadm5_ret_t kadm5_modify_policy(void *server_handle, kadm5_policy_ent_t policy, - u_int32_t mask); + uint32_t mask); kadm5_ret_t kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t ent); diff --git a/crypto/heimdal/lib/kadm5/bump_pw_expire.c b/crypto/heimdal/lib/kadm5/bump_pw_expire.c index a185c20..17bd5e1 100644 --- a/crypto/heimdal/lib/kadm5/bump_pw_expire.c +++ b/crypto/heimdal/lib/kadm5/bump_pw_expire.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: bump_pw_expire.c,v 1.1 2000/07/24 03:47:54 assar Exp $"); +RCSID("$Id: bump_pw_expire.c 8797 2000-07-24 03:47:54Z assar $"); /* * extend password_expiration if it's defined diff --git a/crypto/heimdal/lib/kadm5/check-cracklib.pl b/crypto/heimdal/lib/kadm5/check-cracklib.pl new file mode 100755 index 0000000..229cc7f --- /dev/null +++ b/crypto/heimdal/lib/kadm5/check-cracklib.pl @@ -0,0 +1,106 @@ +#!/usr/pkg/bin/perl +# +# Sample password verifier for Heimdals external password +# verifier, see the chapter "Password changing" in the the info +# documentation for more information about the protocol used. +# +# Three checks +# 1. Check that password is not the principal name +# 2. Check that the password passes cracklib +# 3. Check that password isn't repeated for this principal +# +# The repeat check must be last because some clients ask +# twice when getting "no" back and thus the error message +# would be wrong. +# +# Prereqs (example versions): +# +# * perl (5.8.5) http://www.perl.org/ +# * cracklib (2.8.5) http://sourceforge.net/projects/cracklib +# * Crypt-Cracklib perlmodule (0.01) http://search.cpan.org/~daniel/ +# +# Sample dictionaries: +# cracklib-words (1.1) http://sourceforge.net/projects/cracklib +# miscfiles (1.4.2) http://directory.fsf.org/miscfiles.html +# +# Configuration for krb5.conf or kdc.conf +# +# [password_quality] +# policies = builtin:external-check +# external_program = <your-path>/check-cracklib.pl +# +# $Id: check-cracklib.pl 20578 2007-05-07 22:21:51Z lha $ + +use strict; +use Crypt::Cracklib; +use Digest::MD5; + +# NEED TO CHANGE THESE TO MATCH YOUR SYSTEM +my $database = '/usr/lib/cracklib_dict'; +my $historydb = '/var/heimdal/historydb'; +# NEED TO CHANGE THESE TO MATCH YOUR SYSTEM + +my %params; + +sub check_basic +{ + my $principal = shift; + my $passwd = shift; + + if ($principal eq $passwd) { + return "Principal name as password is not allowed"; + } + return "ok"; +} + +sub check_repeat +{ + my $principal = shift; + my $passwd = shift; + my $result = 'Do not reuse passwords'; + my %DB; + my $md5context = new Digest::MD5; + + $md5context->reset(); + $md5context->add($principal, ":", $passwd); + + my $key=$md5context->hexdigest(); + + dbmopen(%DB,$historydb,0600) or die "Internal: Could not open $historydb"; + $result = "ok" if (!$DB{$key}); + $DB{$key}=scalar(time()); + dbmclose(%DB) or die "Internal: Could not close $historydb"; + return $result; +} + +sub badpassword +{ + my $reason = shift; + print "$reason\n"; + exit 0 +} + +while (<>) { + last if /^end$/; + if (!/^([^:]+): (.+)$/) { + die "key value pair not correct: $_"; + } + $params{$1} = $2; +} + +die "missing principal" if (!defined $params{'principal'}); +die "missing password" if (!defined $params{'new-password'}); + +my $reason; + +$reason = check_basic($params{'principal'}, $params{'new-password'}); +badpassword($reason) if ($reason ne "ok"); + +$reason = fascist_check($params{'new-password'}, $database); +badpassword($reason) if ($reason ne "ok"); + +$reason = check_repeat($params{'principal'}, $params{'new-password'}); +badpassword($reason) if ($reason ne "ok"); + +print "APPROVED\n"; +exit 0 diff --git a/crypto/heimdal/lib/kadm5/chpass_c.c b/crypto/heimdal/lib/kadm5/chpass_c.c index b06b8cd..5319ce9 100644 --- a/crypto/heimdal/lib/kadm5/chpass_c.c +++ b/crypto/heimdal/lib/kadm5/chpass_c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2000, 2005-2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,12 +33,12 @@ #include "kadm5_locl.h" -RCSID("$Id: chpass_c.c,v 1.5 2000/07/11 15:59:14 joda Exp $"); +RCSID("$Id: chpass_c.c 16661 2006-01-25 12:50:10Z lha $"); kadm5_ret_t kadm5_c_chpass_principal(void *server_handle, krb5_principal princ, - char *password) + const char *password) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; @@ -52,8 +52,10 @@ kadm5_c_chpass_principal(void *server_handle, return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_chpass); krb5_store_principal(sp, princ); krb5_store_string(sp, password); @@ -64,10 +66,12 @@ kadm5_c_chpass_principal(void *server_handle, return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); + krb5_clear_error_string(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; @@ -92,8 +96,10 @@ kadm5_c_chpass_principal_with_key(void *server_handle, return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_chpass_with_key); krb5_store_principal(sp, princ); krb5_store_int32(sp, n_key_data); @@ -106,10 +112,12 @@ kadm5_c_chpass_principal_with_key(void *server_handle, return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); + krb5_clear_error_string(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; diff --git a/crypto/heimdal/lib/kadm5/chpass_s.c b/crypto/heimdal/lib/kadm5/chpass_s.c index a1a4b43..abef28c 100644 --- a/crypto/heimdal/lib/kadm5/chpass_s.c +++ b/crypto/heimdal/lib/kadm5/chpass_s.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,74 +33,80 @@ #include "kadm5_locl.h" -RCSID("$Id: chpass_s.c,v 1.13.8.1 2003/12/30 15:59:58 lha Exp $"); +RCSID("$Id: chpass_s.c 20608 2007-05-08 07:11:48Z lha $"); static kadm5_ret_t change(void *server_handle, krb5_principal princ, - char *password, + const char *password, int cond) { kadm5_server_context *context = server_handle; - hdb_entry ent; + hdb_entry_ex ent; kadm5_ret_t ret; Key *keys; size_t num_keys; int cmp = 1; - ent.principal = princ; - ret = context->db->open(context->context, context->db, O_RDWR, 0); + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; - ret = context->db->fetch(context->context, context->db, - HDB_F_DECRYPT, &ent); + ret = context->db->hdb_fetch(context->context, context->db, princ, + HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); if(ret == HDB_ERR_NOENTRY) goto out; - num_keys = ent.keys.len; - keys = ent.keys.val; + num_keys = ent.entry.keys.len; + keys = ent.entry.keys.val; - ent.keys.len = 0; - ent.keys.val = NULL; + ent.entry.keys.len = 0; + ent.entry.keys.val = NULL; - ret = _kadm5_set_keys(context, &ent, password); + ret = _kadm5_set_keys(context, &ent.entry, password); if(ret) { - _kadm5_free_keys (server_handle, num_keys, keys); + _kadm5_free_keys (context->context, num_keys, keys); goto out2; } + ent.entry.kvno++; if (cond) - cmp = _kadm5_cmp_keys (ent.keys.val, ent.keys.len, + cmp = _kadm5_cmp_keys (ent.entry.keys.val, ent.entry.keys.len, keys, num_keys); - _kadm5_free_keys (server_handle, num_keys, keys); + _kadm5_free_keys (context->context, num_keys, keys); if (cmp == 0) { krb5_set_error_string(context->context, "Password reuse forbidden"); ret = KADM5_PASS_REUSE; - goto out2; + goto out2; } - ret = _kadm5_set_modifier(context, &ent); + + ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out2; - ret = _kadm5_bump_pw_expire(context, &ent); + ret = _kadm5_bump_pw_expire(context, &ent.entry); + if (ret) + goto out2; + + ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) goto out2; - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = context->db->hdb_store(context->context, context->db, + HDB_F_REPLACE, &ent); if (ret) goto out2; kadm5_log_modify (context, - &ent, + &ent.entry, KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | - KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION); - - ret = context->db->store(context->context, context->db, - HDB_F_REPLACE, &ent); + KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | + KADM5_TL_DATA); + out2: hdb_free_entry(context->context, &ent); out: - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); } @@ -113,7 +119,7 @@ out: kadm5_ret_t kadm5_s_chpass_principal_cond(void *server_handle, krb5_principal princ, - char *password) + const char *password) { return change (server_handle, princ, password, 1); } @@ -125,7 +131,7 @@ kadm5_s_chpass_principal_cond(void *server_handle, kadm5_ret_t kadm5_s_chpass_principal(void *server_handle, krb5_principal princ, - char *password) + const char *password) { return change (server_handle, princ, password, 0); } @@ -141,39 +147,46 @@ kadm5_s_chpass_principal_with_key(void *server_handle, krb5_key_data *key_data) { kadm5_server_context *context = server_handle; - hdb_entry ent; + hdb_entry_ex ent; kadm5_ret_t ret; - ent.principal = princ; - ret = context->db->open(context->context, context->db, O_RDWR, 0); + + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; - ret = context->db->fetch(context->context, context->db, 0, &ent); + ret = context->db->hdb_fetch(context->context, context->db, princ, + HDB_F_GET_ANY, &ent); if(ret == HDB_ERR_NOENTRY) goto out; - ret = _kadm5_set_keys2(context, &ent, n_key_data, key_data); + ret = _kadm5_set_keys2(context, &ent.entry, n_key_data, key_data); if(ret) goto out2; - ret = _kadm5_set_modifier(context, &ent); + ent.entry.kvno++; + ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out2; - ret = _kadm5_bump_pw_expire(context, &ent); + ret = _kadm5_bump_pw_expire(context, &ent.entry); if (ret) goto out2; - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = hdb_seal_keys(context->context, context->db, &ent.entry); + if (ret) + goto out2; + + ret = context->db->hdb_store(context->context, context->db, + HDB_F_REPLACE, &ent); if (ret) goto out2; kadm5_log_modify (context, - &ent, + &ent.entry, KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | - KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION); - - ret = context->db->store(context->context, context->db, - HDB_F_REPLACE, &ent); + KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | + KADM5_TL_DATA); + out2: hdb_free_entry(context->context, &ent); out: - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); } diff --git a/crypto/heimdal/lib/kadm5/client_glue.c b/crypto/heimdal/lib/kadm5/client_glue.c index 395577d..24d91b3 100644 --- a/crypto/heimdal/lib/kadm5/client_glue.c +++ b/crypto/heimdal/lib/kadm5/client_glue.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: client_glue.c,v 1.5 1999/12/02 17:05:05 joda Exp $"); +RCSID("$Id: client_glue.c 7464 1999-12-02 17:05:13Z joda $"); kadm5_ret_t kadm5_init_with_password(const char *client_name, diff --git a/crypto/heimdal/lib/kadm5/common_glue.c b/crypto/heimdal/lib/kadm5/common_glue.c index b508282..48d9d84 100644 --- a/crypto/heimdal/lib/kadm5/common_glue.c +++ b/crypto/heimdal/lib/kadm5/common_glue.c @@ -33,14 +33,14 @@ #include "kadm5_locl.h" -RCSID("$Id: common_glue.c,v 1.5 2000/03/23 22:58:26 assar Exp $"); +RCSID("$Id: common_glue.c 17445 2006-05-05 10:37:46Z lha $"); #define __CALL(F, P) (*((kadm5_common_context*)server_handle)->funcs.F)P; kadm5_ret_t kadm5_chpass_principal(void *server_handle, krb5_principal princ, - char *password) + const char *password) { return __CALL(chpass_principal, (server_handle, princ, password)); } @@ -58,8 +58,8 @@ kadm5_chpass_principal_with_key(void *server_handle, kadm5_ret_t kadm5_create_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask, - char *password) + uint32_t mask, + const char *password) { return __CALL(create_principal, (server_handle, princ, mask, password)); } @@ -87,7 +87,7 @@ kadm5_ret_t kadm5_get_principal(void *server_handle, krb5_principal princ, kadm5_principal_ent_t out, - u_int32_t mask) + uint32_t mask) { return __CALL(get_principal, (server_handle, princ, out, mask)); } @@ -95,7 +95,7 @@ kadm5_get_principal(void *server_handle, kadm5_ret_t kadm5_modify_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { return __CALL(modify_principal, (server_handle, princ, mask)); } @@ -119,16 +119,16 @@ kadm5_rename_principal(void *server_handle, kadm5_ret_t kadm5_get_principals(void *server_handle, - const char *exp, + const char *expression, char ***princs, int *count) { - return __CALL(get_principals, (server_handle, exp, princs, count)); + return __CALL(get_principals, (server_handle, expression, princs, count)); } kadm5_ret_t kadm5_get_privs(void *server_handle, - u_int32_t *privs) + uint32_t *privs) { return __CALL(get_privs, (server_handle, privs)); } diff --git a/crypto/heimdal/lib/kadm5/context_s.c b/crypto/heimdal/lib/kadm5/context_s.c index a5a78e6..6ac7a9c 100644 --- a/crypto/heimdal/lib/kadm5/context_s.c +++ b/crypto/heimdal/lib/kadm5/context_s.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: context_s.c,v 1.17 2002/08/26 13:28:36 assar Exp $"); +RCSID("$Id: context_s.c 22211 2007-12-07 19:27:27Z lha $"); static void set_funcs(kadm5_server_context *c) @@ -53,121 +53,70 @@ set_funcs(kadm5_server_context *c) SET(c, rename_principal); } -struct database_spec { - char *dbpath; - char *logfile; - char *mkeyfile; - char *aclfile; -}; - static void -set_field(krb5_context context, krb5_config_binding *binding, - const char *dbname, const char *name, const char *ext, - char **variable) +set_socket_name(krb5_context context, struct sockaddr_un *un) { - const char *p; - - if (*variable != NULL) - free (*variable); - - p = krb5_config_get_string(context, binding, name, NULL); - if(p) - *variable = strdup(p); - else { - p = strrchr(dbname, '.'); - if(p == NULL) - asprintf(variable, "%s.%s", dbname, ext); - else - asprintf(variable, "%.*s.%s", (int)(p - dbname), dbname, ext); - } -} + const char *fn = kadm5_log_signal_socket(context); -static void -set_socket_name(const char *dbname, struct sockaddr_un *un) -{ - const char *p; memset(un, 0, sizeof(*un)); un->sun_family = AF_UNIX; - p = strrchr(dbname, '.'); - if(p == NULL) - snprintf(un->sun_path, sizeof(un->sun_path), "%s.signal", - dbname); - else - snprintf(un->sun_path, sizeof(un->sun_path), "%.*s.signal", - (int)(p - dbname), dbname); -} - -static void -set_config(kadm5_server_context *ctx, - krb5_config_binding *binding) -{ - const char *p; - if(ctx->config.dbname == NULL) { - p = krb5_config_get_string(ctx->context, binding, "dbname", NULL); - if(p) - ctx->config.dbname = strdup(p); - else - ctx->config.dbname = strdup(HDB_DEFAULT_DB); - } - if(ctx->log_context.log_file == NULL) - set_field(ctx->context, binding, ctx->config.dbname, - "log_file", "log", &ctx->log_context.log_file); - set_socket_name(ctx->config.dbname, &ctx->log_context.socket_name); - if(ctx->config.acl_file == NULL) - set_field(ctx->context, binding, ctx->config.dbname, - "acl_file", "acl", &ctx->config.acl_file); - if(ctx->config.stash_file == NULL) - set_field(ctx->context, binding, ctx->config.dbname, - "mkey_file", "mkey", &ctx->config.stash_file); + strlcpy (un->sun_path, fn, sizeof(un->sun_path)); } static kadm5_ret_t find_db_spec(kadm5_server_context *ctx) { - const krb5_config_binding *top_binding = NULL; - krb5_config_binding *db_binding; - krb5_config_binding *default_binding = NULL; krb5_context context = ctx->context; + struct hdb_dbinfo *info, *d; + krb5_error_code ret; - while((db_binding = (krb5_config_binding *) - krb5_config_get_next(context, - NULL, - &top_binding, - krb5_config_list, - "kdc", - "database", - NULL))) { - const char *p; - p = krb5_config_get_string(context, db_binding, "realm", NULL); - if(p == NULL) { - if(default_binding) { - krb5_warnx(context, "WARNING: more than one realm-less " - "database specification"); - krb5_warnx(context, "WARNING: using the first encountered"); - } else - default_binding = db_binding; - continue; - } - if(strcmp(ctx->config.realm, p) != 0) - continue; + if (ctx->config.realm) { + /* fetch the databases */ + ret = hdb_get_dbinfo(context, &info); + if (ret) + return ret; - set_config(ctx, db_binding); - return 0; - } - if(default_binding) - set_config(ctx, default_binding); - else { - ctx->config.dbname = strdup(HDB_DEFAULT_DB); - ctx->config.acl_file = strdup(HDB_DB_DIR "/kadmind.acl"); - ctx->config.stash_file = strdup(HDB_DB_DIR "/m-key"); - ctx->log_context.log_file = strdup(HDB_DB_DIR "/log"); - memset(&ctx->log_context.socket_name, 0, - sizeof(ctx->log_context.socket_name)); - ctx->log_context.socket_name.sun_family = AF_UNIX; - strlcpy(ctx->log_context.socket_name.sun_path, - KADM5_LOG_SIGNAL, - sizeof(ctx->log_context.socket_name.sun_path)); + d = NULL; + while ((d = hdb_dbinfo_get_next(info, d)) != NULL) { + const char *p = hdb_dbinfo_get_realm(context, d); + + /* match default (realm-less) */ + if(p != NULL && strcmp(ctx->config.realm, p) != 0) + continue; + + p = hdb_dbinfo_get_dbname(context, d); + if (p) + ctx->config.dbname = strdup(p); + + p = hdb_dbinfo_get_acl_file(context, d); + if (p) + ctx->config.acl_file = strdup(p); + + p = hdb_dbinfo_get_mkey_file(context, d); + if (p) + ctx->config.stash_file = strdup(p); + + p = hdb_dbinfo_get_log_file(context, d); + if (p) + ctx->log_context.log_file = strdup(p); + break; + } + hdb_free_dbinfo(context, &info); } + + /* If any of the values was unset, pick up the default value */ + + if (ctx->config.dbname == NULL) + ctx->config.dbname = strdup(hdb_default_db(context)); + if (ctx->config.acl_file == NULL) + asprintf(&ctx->config.acl_file, "%s/kadmind.acl", hdb_db_dir(context)); + if (ctx->config.stash_file == NULL) + asprintf(&ctx->config.stash_file, "%s/m-key", hdb_db_dir(context)); + if (ctx->log_context.log_file == NULL) + asprintf(&ctx->log_context.log_file, "%s/log", hdb_db_dir(context)); + + set_socket_name(context, &ctx->log_context.socket_name); + return 0; } diff --git a/crypto/heimdal/lib/kadm5/create_c.c b/crypto/heimdal/lib/kadm5/create_c.c index 8d81cb3..903a06a 100644 --- a/crypto/heimdal/lib/kadm5/create_c.c +++ b/crypto/heimdal/lib/kadm5/create_c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2000, 2005-2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,13 +33,13 @@ #include "kadm5_locl.h" -RCSID("$Id: create_c.c,v 1.4 2000/07/11 15:59:21 joda Exp $"); +RCSID("$Id: create_c.c 17445 2006-05-05 10:37:46Z lha $"); kadm5_ret_t kadm5_c_create_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask, - char *password) + uint32_t mask, + const char *password) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; @@ -53,8 +53,10 @@ kadm5_c_create_principal(void *server_handle, return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_create); kadm5_store_principal_ent(sp, princ); krb5_store_int32(sp, mask); @@ -66,10 +68,12 @@ kadm5_c_create_principal(void *server_handle, return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); + krb5_clear_error_string(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; diff --git a/crypto/heimdal/lib/kadm5/create_s.c b/crypto/heimdal/lib/kadm5/create_s.c index 287211b..9465310 100644 --- a/crypto/heimdal/lib/kadm5/create_s.c +++ b/crypto/heimdal/lib/kadm5/create_s.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: create_s.c,v 1.19 2001/01/30 01:24:28 assar Exp $"); +RCSID("$Id: create_s.c 20607 2007-05-08 07:11:11Z lha $"); static kadm5_ret_t get_default(kadm5_server_context *context, krb5_principal princ, @@ -56,14 +56,14 @@ get_default(kadm5_server_context *context, krb5_principal princ, static kadm5_ret_t create_principal(kadm5_server_context *context, kadm5_principal_ent_t princ, - u_int32_t mask, - hdb_entry *ent, - u_int32_t required_mask, - u_int32_t forbidden_mask) + uint32_t mask, + hdb_entry_ex *ent, + uint32_t required_mask, + uint32_t forbidden_mask) { kadm5_ret_t ret; kadm5_principal_ent_rec defrec, *defent; - u_int32_t def_mask; + uint32_t def_mask; if((mask & required_mask) != required_mask) return KADM5_BAD_MASK; @@ -74,7 +74,7 @@ create_principal(kadm5_server_context *context, return KADM5_UNK_POLICY; memset(ent, 0, sizeof(*ent)); ret = krb5_copy_principal(context->context, princ->principal, - &ent->principal); + &ent->entry.principal); if(ret) return ret; @@ -94,9 +94,9 @@ create_principal(kadm5_server_context *context, if(defent) kadm5_free_principal_ent(context, defent); - ent->created_by.time = time(NULL); + ent->entry.created_by.time = time(NULL); ret = krb5_copy_principal(context->context, context->caller, - &ent->created_by.principal); + &ent->entry.created_by.principal); return ret; } @@ -104,10 +104,10 @@ create_principal(kadm5_server_context *context, kadm5_ret_t kadm5_s_create_principal_with_key(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { kadm5_ret_t ret; - hdb_entry ent; + hdb_entry_ex ent; kadm5_server_context *context = server_handle; ret = create_principal(context, princ, mask, &ent, @@ -120,21 +120,22 @@ kadm5_s_create_principal_with_key(void *server_handle, if(ret) goto out; - ret = _kadm5_set_keys2(context, &ent, princ->n_key_data, princ->key_data); - if(ret) - goto out; - - ret = hdb_seal_keys(context->context, context->db, &ent); + if ((mask & KADM5_KVNO) == 0) + ent.entry.kvno = 1; + + ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) goto out; - kadm5_log_create (context, &ent); - - ret = context->db->open(context->context, context->db, O_RDWR, 0); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) goto out; - ret = context->db->store(context->context, context->db, 0, &ent); - context->db->close(context->context, context->db); + ret = context->db->hdb_store(context->context, context->db, 0, &ent); + context->db->hdb_close(context->context, context->db); + if (ret) + goto out; + kadm5_log_create (context, &ent.entry); + out: hdb_free_entry(context->context, &ent); return _kadm5_error_code(ret); @@ -144,11 +145,11 @@ out: kadm5_ret_t kadm5_s_create_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask, - char *password) + uint32_t mask, + const char *password) { kadm5_ret_t ret; - hdb_entry ent; + hdb_entry_ex ent; kadm5_server_context *context = server_handle; ret = create_principal(context, princ, mask, &ent, @@ -161,37 +162,31 @@ kadm5_s_create_principal(void *server_handle, if(ret) goto out; - /* XXX this should be fixed */ - ent.keys.len = 4; - ent.keys.val = calloc(ent.keys.len, sizeof(*ent.keys.val)); - ent.keys.val[0].key.keytype = ETYPE_DES_CBC_CRC; - /* flag as version 4 compatible salt; ignored by _kadm5_set_keys - if we don't want to be compatible */ - ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt)); - ent.keys.val[0].salt->type = hdb_pw_salt; - ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4; - ent.keys.val[1].salt = calloc(1, sizeof(*ent.keys.val[1].salt)); - ent.keys.val[1].salt->type = hdb_pw_salt; - ent.keys.val[2].key.keytype = ETYPE_DES_CBC_MD5; - ent.keys.val[2].salt = calloc(1, sizeof(*ent.keys.val[2].salt)); - ent.keys.val[2].salt->type = hdb_pw_salt; - ent.keys.val[3].key.keytype = ETYPE_DES3_CBC_SHA1; - ret = _kadm5_set_keys(context, &ent, password); + if ((mask & KADM5_KVNO) == 0) + ent.entry.kvno = 1; + + ent.entry.keys.len = 0; + ent.entry.keys.val = NULL; + + ret = _kadm5_set_keys(context, &ent.entry, password); if (ret) goto out; - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) goto out; - kadm5_log_create (context, &ent); - - ret = context->db->open(context->context, context->db, O_RDWR, 0); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) goto out; - ret = context->db->store(context->context, context->db, 0, &ent); - context->db->close(context->context, context->db); -out: + ret = context->db->hdb_store(context->context, context->db, 0, &ent); + context->db->hdb_close(context->context, context->db); + if (ret) + goto out; + + kadm5_log_create (context, &ent.entry); + + out: hdb_free_entry(context->context, &ent); return _kadm5_error_code(ret); } diff --git a/crypto/heimdal/lib/kadm5/default_keys.c b/crypto/heimdal/lib/kadm5/default_keys.c new file mode 100644 index 0000000..2a851cd --- /dev/null +++ b/crypto/heimdal/lib/kadm5/default_keys.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kadm5_locl.h" +#include <err.h> + +RCSID("$Id: default_keys.c 22494 2008-01-21 11:56:44Z lha $"); + +static void +print_keys(krb5_context context, Key *keys, size_t nkeys) +{ + krb5_error_code ret; + char *str; + int i; + + printf("keys:\n"); + + for (i = 0; i < nkeys; i++) { + + ret = krb5_enctype_to_string(context, keys[i].key.keytype, &str); + if (ret) + krb5_err(context, ret, 1, "krb5_enctype_to_string: %d\n", + (int)keys[i].key.keytype); + + printf("\tenctype %s", str); + free(str); + + if (keys[i].salt) { + printf(" salt: "); + + switch (keys[i].salt->type) { + case KRB5_PW_SALT: + printf("pw-salt:"); + break; + case KRB5_AFS3_SALT: + printf("afs3-salt:"); + break; + default: + printf("unknown salt: %d", keys[i].salt->type); + break; + } + if (keys[i].salt->salt.length) + printf("%.*s", (int)keys[i].salt->salt.length, + (char *)keys[i].salt->salt.data); + } + printf("\n"); + } + printf("end keys:\n"); +} + +static void +parse_file(krb5_context context, krb5_principal principal, int no_salt) +{ + krb5_error_code ret; + size_t nkeys; + Key *keys; + + ret = hdb_generate_key_set(context, principal, &keys, &nkeys, no_salt); + if (ret) + krb5_err(context, 1, ret, "hdb_generate_key_set"); + + print_keys(context, keys, nkeys); + + hdb_free_keys(context, nkeys, keys); +} + +int +main(int argc, char **argv) +{ + krb5_error_code ret; + krb5_context context; + krb5_principal principal; + + ret = krb5_init_context(&context); + if (ret) + errx(1, "krb5_init_context"); + + ret = krb5_parse_name(context, "lha@SU.SE", &principal); + if (ret) + krb5_err(context, ret, 1, "krb5_parse_name"); + + parse_file(context, principal, 0); + parse_file(context, principal, 1); + + krb5_free_principal(context, principal); + + krb5_free_context(context); + + return 0; +} diff --git a/crypto/heimdal/lib/kadm5/delete_c.c b/crypto/heimdal/lib/kadm5/delete_c.c index 7575c5e..5018fd6 100644 --- a/crypto/heimdal/lib/kadm5/delete_c.c +++ b/crypto/heimdal/lib/kadm5/delete_c.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: delete_c.c,v 1.4 2000/07/11 15:59:29 joda Exp $"); +RCSID("$Id: delete_c.c 16661 2006-01-25 12:50:10Z lha $"); kadm5_ret_t kadm5_c_delete_principal(void *server_handle, krb5_principal princ) @@ -50,8 +50,10 @@ kadm5_c_delete_principal(void *server_handle, krb5_principal princ) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_delete); krb5_store_principal(sp, princ); ret = _kadm5_client_send(context, sp); @@ -63,10 +65,12 @@ kadm5_c_delete_principal(void *server_handle, krb5_principal princ) return ret; sp = krb5_storage_from_data (&reply); if(sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); + krb5_clear_error_string(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; diff --git a/crypto/heimdal/lib/kadm5/delete_s.c b/crypto/heimdal/lib/kadm5/delete_s.c index 2f2bf88..b4e5a37 100644 --- a/crypto/heimdal/lib/kadm5/delete_s.c +++ b/crypto/heimdal/lib/kadm5/delete_s.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003, 2005 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,40 +33,43 @@ #include "kadm5_locl.h" -RCSID("$Id: delete_s.c,v 1.9 2001/01/30 01:24:28 assar Exp $"); +RCSID("$Id: delete_s.c 20612 2007-05-08 07:13:45Z lha $"); kadm5_ret_t kadm5_s_delete_principal(void *server_handle, krb5_principal princ) { kadm5_server_context *context = server_handle; kadm5_ret_t ret; - hdb_entry ent; + hdb_entry_ex ent; - ent.principal = princ; - ret = context->db->open(context->context, context->db, O_RDWR, 0); + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) { krb5_warn(context->context, ret, "opening database"); return ret; } - ret = context->db->fetch(context->context, context->db, - HDB_F_DECRYPT, &ent); + ret = context->db->hdb_fetch(context->context, context->db, princ, + HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); if(ret == HDB_ERR_NOENTRY) - goto out2; - if(ent.flags.immutable) { - ret = KADM5_PROTECT_PRINCIPAL; goto out; + if(ent.entry.flags.immutable) { + ret = KADM5_PROTECT_PRINCIPAL; + goto out2; } - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) - goto out; + goto out2; + + ret = context->db->hdb_remove(context->context, context->db, princ); + if (ret) + goto out2; kadm5_log_delete (context, princ); - - ret = context->db->remove(context->context, context->db, &ent); -out: - hdb_free_entry(context->context, &ent); + out2: - context->db->close(context->context, context->db); + hdb_free_entry(context->context, &ent); +out: + context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); } diff --git a/crypto/heimdal/lib/kadm5/destroy_c.c b/crypto/heimdal/lib/kadm5/destroy_c.c index b42c84c..9ae2e9d 100644 --- a/crypto/heimdal/lib/kadm5/destroy_c.c +++ b/crypto/heimdal/lib/kadm5/destroy_c.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: destroy_c.c,v 1.3 1999/12/02 17:05:05 joda Exp $"); +RCSID("$Id: destroy_c.c 13198 2003-12-07 19:01:39Z lha $"); kadm5_ret_t kadm5_c_destroy(void *server_handle) @@ -43,6 +43,10 @@ kadm5_c_destroy(void *server_handle) free(context->realm); free(context->admin_server); close(context->sock); + if (context->client_name) + free(context->client_name); + if (context->service_name) + free(context->service_name); if (context->ac != NULL) krb5_auth_con_free(context->context, context->ac); if(context->my_context) diff --git a/crypto/heimdal/lib/kadm5/destroy_s.c b/crypto/heimdal/lib/kadm5/destroy_s.c index a8ad328..edfc6b5 100644 --- a/crypto/heimdal/lib/kadm5/destroy_s.c +++ b/crypto/heimdal/lib/kadm5/destroy_s.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: destroy_s.c,v 1.6 2000/05/12 15:23:13 assar Exp $"); +RCSID("$Id: destroy_s.c 12880 2003-09-19 00:25:35Z lha $"); /* * dealloc a `kadm5_config_params' @@ -70,7 +70,7 @@ kadm5_s_destroy(void *server_handle) kadm5_server_context *context = server_handle; krb5_context kcontext = context->context; - ret = context->db->destroy(kcontext, context->db); + ret = context->db->hdb_destroy(kcontext, context->db); destroy_kadm5_log_context (&context->log_context); destroy_config (&context->config); krb5_free_principal (kcontext, context->caller); diff --git a/crypto/heimdal/lib/kadm5/ent_setup.c b/crypto/heimdal/lib/kadm5/ent_setup.c index 29fab74..dfc4a9b 100644 --- a/crypto/heimdal/lib/kadm5/ent_setup.c +++ b/crypto/heimdal/lib/kadm5/ent_setup.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: ent_setup.c,v 1.12 2000/03/23 23:02:35 assar Exp $"); +RCSID("$Id: ent_setup.c 18823 2006-10-22 10:15:53Z lha $"); #define set_value(X, V) do { if((X) == NULL) (X) = malloc(sizeof(*(X))); *(X) = V; } while(0) #define set_null(X) do { if((X) != NULL) free((X)); (X) = NULL; } while (0) @@ -53,9 +53,65 @@ attr_to_flags(unsigned attr, HDBFlags *flags) flags->server = !(attr & KRB5_KDB_DISALLOW_SVR); flags->change_pw = !!(attr & KRB5_KDB_PWCHANGE_SERVICE); flags->client = 1; /* XXX */ + flags->ok_as_delegate = !!(attr & KRB5_KDB_OK_AS_DELEGATE); + flags->trusted_for_delegation = !!(attr & KRB5_KDB_TRUSTED_FOR_DELEGATION); + flags->allow_kerberos4 = !!(attr & KRB5_KDB_ALLOW_KERBEROS4); + flags->allow_digest = !!(attr & KRB5_KDB_ALLOW_DIGEST); } /* + * Modify the `ent' according to `tl_data'. + */ + +static kadm5_ret_t +perform_tl_data(krb5_context context, + HDB *db, + hdb_entry_ex *ent, + const krb5_tl_data *tl_data) +{ + kadm5_ret_t ret = 0; + + if (tl_data->tl_data_type == KRB5_TL_PASSWORD) { + heim_utf8_string pw = tl_data->tl_data_contents; + + if (pw[tl_data->tl_data_length] != '\0') + return KADM5_BAD_TL_TYPE; + + ret = hdb_entry_set_password(context, db, &ent->entry, pw); + + } else if (tl_data->tl_data_type == KRB5_TL_LAST_PWD_CHANGE) { + unsigned char *s; + time_t t; + + if (tl_data->tl_data_length != 4) + return KADM5_BAD_TL_TYPE; + + s = tl_data->tl_data_contents; + + t = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); + + ret = hdb_entry_set_pw_change_time(context, &ent->entry, t); + + } else if (tl_data->tl_data_type == KRB5_TL_EXTENSION) { + HDB_extension ext; + + ret = decode_HDB_extension(tl_data->tl_data_contents, + tl_data->tl_data_length, + &ext, + NULL); + if (ret) + return KADM5_BAD_TL_TYPE; + + ret = hdb_replace_extension(context, &ent->entry, &ext); + free_HDB_extension(&ext); + } else { + return KADM5_BAD_TL_TYPE; + } + return ret; +} + + +/* * Create the hdb entry `ent' based on data from `princ' with * `princ_mask' specifying what fields to be gotten from there and * `mask' specifying what fields we want filled in. @@ -63,77 +119,85 @@ attr_to_flags(unsigned attr, HDBFlags *flags) kadm5_ret_t _kadm5_setup_entry(kadm5_server_context *context, - hdb_entry *ent, - u_int32_t mask, + hdb_entry_ex *ent, + uint32_t mask, kadm5_principal_ent_t princ, - u_int32_t princ_mask, + uint32_t princ_mask, kadm5_principal_ent_t def, - u_int32_t def_mask) + uint32_t def_mask) { if(mask & KADM5_PRINC_EXPIRE_TIME && princ_mask & KADM5_PRINC_EXPIRE_TIME) { if (princ->princ_expire_time) - set_value(ent->valid_end, princ->princ_expire_time); + set_value(ent->entry.valid_end, princ->princ_expire_time); else - set_null(ent->valid_end); + set_null(ent->entry.valid_end); } if(mask & KADM5_PW_EXPIRATION && princ_mask & KADM5_PW_EXPIRATION) { if (princ->pw_expiration) - set_value(ent->pw_end, princ->pw_expiration); + set_value(ent->entry.pw_end, princ->pw_expiration); else - set_null(ent->pw_end); + set_null(ent->entry.pw_end); } if(mask & KADM5_ATTRIBUTES) { if (princ_mask & KADM5_ATTRIBUTES) { - attr_to_flags(princ->attributes, &ent->flags); + attr_to_flags(princ->attributes, &ent->entry.flags); } else if(def_mask & KADM5_ATTRIBUTES) { - attr_to_flags(def->attributes, &ent->flags); - ent->flags.invalid = 0; + attr_to_flags(def->attributes, &ent->entry.flags); + ent->entry.flags.invalid = 0; } else { - ent->flags.client = 1; - ent->flags.server = 1; - ent->flags.forwardable = 1; - ent->flags.proxiable = 1; - ent->flags.renewable = 1; - ent->flags.postdate = 1; + ent->entry.flags.client = 1; + ent->entry.flags.server = 1; + ent->entry.flags.forwardable = 1; + ent->entry.flags.proxiable = 1; + ent->entry.flags.renewable = 1; + ent->entry.flags.postdate = 1; } } if(mask & KADM5_MAX_LIFE) { if(princ_mask & KADM5_MAX_LIFE) { if(princ->max_life) - set_value(ent->max_life, princ->max_life); + set_value(ent->entry.max_life, princ->max_life); else - set_null(ent->max_life); + set_null(ent->entry.max_life); } else if(def_mask & KADM5_MAX_LIFE) { if(def->max_life) - set_value(ent->max_life, def->max_life); + set_value(ent->entry.max_life, def->max_life); else - set_null(ent->max_life); + set_null(ent->entry.max_life); } } if(mask & KADM5_KVNO && princ_mask & KADM5_KVNO) - ent->kvno = princ->kvno; + ent->entry.kvno = princ->kvno; if(mask & KADM5_MAX_RLIFE) { if(princ_mask & KADM5_MAX_RLIFE) { if(princ->max_renewable_life) - set_value(ent->max_renew, princ->max_renewable_life); + set_value(ent->entry.max_renew, princ->max_renewable_life); else - set_null(ent->max_renew); + set_null(ent->entry.max_renew); } else if(def_mask & KADM5_MAX_RLIFE) { if(def->max_renewable_life) - set_value(ent->max_renew, def->max_renewable_life); + set_value(ent->entry.max_renew, def->max_renewable_life); else - set_null(ent->max_renew); + set_null(ent->entry.max_renew); } } if(mask & KADM5_KEY_DATA && princ_mask & KADM5_KEY_DATA) { - _kadm5_set_keys2(context, ent, princ->n_key_data, princ->key_data); + _kadm5_set_keys2(context, &ent->entry, + princ->n_key_data, princ->key_data); } if(mask & KADM5_TL_DATA) { - /* XXX */ + krb5_tl_data *tl; + + for (tl = princ->tl_data; tl != NULL; tl = tl->tl_data_next) { + kadm5_ret_t ret; + ret = perform_tl_data(context->context, context->db, ent, tl); + if (ret) + return ret; + } } if(mask & KADM5_FAIL_AUTH_COUNT) { /* XXX */ diff --git a/crypto/heimdal/lib/kadm5/error.c b/crypto/heimdal/lib/kadm5/error.c index 11b1ded..46211d2 100644 --- a/crypto/heimdal/lib/kadm5/error.c +++ b/crypto/heimdal/lib/kadm5/error.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: error.c,v 1.3 1999/12/02 17:05:06 joda Exp $"); +RCSID("$Id: error.c 7464 1999-12-02 17:05:13Z joda $"); kadm5_ret_t _kadm5_error_code(kadm5_ret_t code) diff --git a/crypto/heimdal/lib/kadm5/flush.c b/crypto/heimdal/lib/kadm5/flush.c index 4808259..ad1574f 100644 --- a/crypto/heimdal/lib/kadm5/flush.c +++ b/crypto/heimdal/lib/kadm5/flush.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: flush.c,v 1.2 1999/12/02 17:05:06 joda Exp $"); +RCSID("$Id: flush.c 7464 1999-12-02 17:05:13Z joda $"); kadm5_ret_t kadm5_s_flush(void *server_handle) diff --git a/crypto/heimdal/lib/kadm5/flush_c.c b/crypto/heimdal/lib/kadm5/flush_c.c index 01cdcf7..748a49a 100644 --- a/crypto/heimdal/lib/kadm5/flush_c.c +++ b/crypto/heimdal/lib/kadm5/flush_c.c @@ -32,7 +32,7 @@ #include "kadm5_locl.h" -RCSID("$Id: flush_c.c,v 1.1 1999/03/23 18:23:36 joda Exp $"); +RCSID("$Id: flush_c.c 5723 1999-03-23 18:23:37Z joda $"); kadm5_ret_t kadm5_c_flush(void *server_handle) diff --git a/crypto/heimdal/lib/kadm5/flush_s.c b/crypto/heimdal/lib/kadm5/flush_s.c index dffbe2f..9bed0c6 100644 --- a/crypto/heimdal/lib/kadm5/flush_s.c +++ b/crypto/heimdal/lib/kadm5/flush_s.c @@ -32,7 +32,7 @@ #include "kadm5_locl.h" -RCSID("$Id: flush_s.c,v 1.1 1999/03/23 18:23:37 joda Exp $"); +RCSID("$Id: flush_s.c 5723 1999-03-23 18:23:37Z joda $"); kadm5_ret_t kadm5_s_flush(void *server_handle) diff --git a/crypto/heimdal/lib/kadm5/free.c b/crypto/heimdal/lib/kadm5/free.c index fcc1e70..1f1740d 100644 --- a/crypto/heimdal/lib/kadm5/free.c +++ b/crypto/heimdal/lib/kadm5/free.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: free.c,v 1.4 1999/12/02 17:05:06 joda Exp $"); +RCSID("$Id: free.c 7464 1999-12-02 17:05:13Z joda $"); void kadm5_free_key_data(void *server_handle, diff --git a/crypto/heimdal/lib/kadm5/get_c.c b/crypto/heimdal/lib/kadm5/get_c.c index 279a77a..5f9724f 100644 --- a/crypto/heimdal/lib/kadm5/get_c.c +++ b/crypto/heimdal/lib/kadm5/get_c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2000, 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,13 +33,13 @@ #include "kadm5_locl.h" -RCSID("$Id: get_c.c,v 1.6 2000/07/11 15:59:36 joda Exp $"); +RCSID("$Id: get_c.c 17445 2006-05-05 10:37:46Z lha $"); kadm5_ret_t kadm5_c_get_principal(void *server_handle, krb5_principal princ, kadm5_principal_ent_t out, - u_int32_t mask) + uint32_t mask) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; @@ -53,8 +53,10 @@ kadm5_c_get_principal(void *server_handle, return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_get); krb5_store_principal(sp, princ); krb5_store_int32(sp, mask); @@ -67,11 +69,13 @@ kadm5_c_get_principal(void *server_handle, return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); ret = tmp; + krb5_clear_error_string(context->context); if(ret == 0) kadm5_ret_principal_ent(sp, out); krb5_storage_free(sp); diff --git a/crypto/heimdal/lib/kadm5/get_princs_c.c b/crypto/heimdal/lib/kadm5/get_princs_c.c index 3536cdf..81a3cfd 100644 --- a/crypto/heimdal/lib/kadm5/get_princs_c.c +++ b/crypto/heimdal/lib/kadm5/get_princs_c.c @@ -33,11 +33,11 @@ #include "kadm5_locl.h" -RCSID("$Id: get_princs_c.c,v 1.4 2000/07/11 16:00:19 joda Exp $"); +RCSID("$Id: get_princs_c.c 15484 2005-06-17 05:21:07Z lha $"); kadm5_ret_t kadm5_c_get_principals(void *server_handle, - const char *exp, + const char *expression, char ***princs, int *count) { @@ -56,9 +56,9 @@ kadm5_c_get_principals(void *server_handle, if (sp == NULL) return ENOMEM; krb5_store_int32(sp, kadm_get_princs); - krb5_store_int32(sp, exp != NULL); - if(exp) - krb5_store_string(sp, exp); + krb5_store_int32(sp, expression != NULL); + if(expression) + krb5_store_string(sp, expression); ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); ret = _kadm5_client_recv(context, &reply); diff --git a/crypto/heimdal/lib/kadm5/get_princs_s.c b/crypto/heimdal/lib/kadm5/get_princs_s.c index 2702bae..cab6ef7 100644 --- a/crypto/heimdal/lib/kadm5/get_princs_s.c +++ b/crypto/heimdal/lib/kadm5/get_princs_s.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: get_princs_s.c,v 1.5 1999/12/02 17:05:06 joda Exp $"); +RCSID("$Id: get_princs_s.c 16378 2005-12-12 12:40:12Z lha $"); struct foreach_data { const char *exp; @@ -55,12 +55,12 @@ add_princ(struct foreach_data *d, char *princ) } static krb5_error_code -foreach(krb5_context context, HDB *db, hdb_entry *ent, void *data) +foreach(krb5_context context, HDB *db, hdb_entry_ex *ent, void *data) { struct foreach_data *d = data; char *princ; krb5_error_code ret; - ret = krb5_unparse_name(context, ent->principal, &princ); + ret = krb5_unparse_name(context, ent->entry.principal, &princ); if(ret) return ret; if(d->exp){ @@ -78,29 +78,29 @@ foreach(krb5_context context, HDB *db, hdb_entry *ent, void *data) kadm5_ret_t kadm5_s_get_principals(void *server_handle, - const char *exp, + const char *expression, char ***princs, int *count) { struct foreach_data d; kadm5_server_context *context = server_handle; kadm5_ret_t ret; - ret = context->db->open(context->context, context->db, O_RDWR, 0); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) { krb5_warn(context->context, ret, "opening database"); return ret; } - d.exp = exp; + d.exp = expression; { krb5_realm r; krb5_get_default_realm(context->context, &r); - asprintf(&d.exp2, "%s@%s", exp, r); + asprintf(&d.exp2, "%s@%s", expression, r); free(r); } d.princs = NULL; d.count = 0; ret = hdb_foreach(context->context, context->db, 0, foreach, &d); - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); if(ret == 0) ret = add_princ(&d, NULL); if(ret == 0){ diff --git a/crypto/heimdal/lib/kadm5/get_s.c b/crypto/heimdal/lib/kadm5/get_s.c index 0851900..5d0db9b 100644 --- a/crypto/heimdal/lib/kadm5/get_s.c +++ b/crypto/heimdal/lib/kadm5/get_s.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,72 +33,105 @@ #include "kadm5_locl.h" -RCSID("$Id: get_s.c,v 1.13 2000/06/19 16:11:31 joda Exp $"); +RCSID("$Id: get_s.c 21745 2007-07-31 16:11:25Z lha $"); + +static kadm5_ret_t +add_tl_data(kadm5_principal_ent_t ent, int16_t type, + const void *data, size_t size) +{ + krb5_tl_data *tl; + + tl = calloc(1, sizeof(*tl)); + if (tl == NULL) + return _kadm5_error_code(ENOMEM); + + tl->tl_data_type = type; + tl->tl_data_length = size; + tl->tl_data_contents = malloc(size); + if (tl->tl_data_contents == NULL) { + free(tl); + return _kadm5_error_code(ENOMEM); + } + memcpy(tl->tl_data_contents, data, size); + + tl->tl_data_next = ent->tl_data; + ent->tl_data = tl; + ent->n_tl_data++; + + return 0; +} + +krb5_ssize_t KRB5_LIB_FUNCTION +_krb5_put_int(void *buffer, unsigned long value, size_t size); /* XXX */ kadm5_ret_t kadm5_s_get_principal(void *server_handle, krb5_principal princ, kadm5_principal_ent_t out, - u_int32_t mask) + uint32_t mask) { kadm5_server_context *context = server_handle; kadm5_ret_t ret; - hdb_entry ent; + hdb_entry_ex ent; - ent.principal = princ; - ret = context->db->open(context->context, context->db, O_RDONLY, 0); + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_open(context->context, context->db, O_RDONLY, 0); if(ret) return ret; - ret = context->db->fetch(context->context, context->db, - HDB_F_DECRYPT, &ent); - context->db->close(context->context, context->db); + ret = context->db->hdb_fetch(context->context, context->db, princ, + HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); + context->db->hdb_close(context->context, context->db); if(ret) return _kadm5_error_code(ret); memset(out, 0, sizeof(*out)); if(mask & KADM5_PRINCIPAL) - ret = krb5_copy_principal(context->context, ent.principal, + ret = krb5_copy_principal(context->context, ent.entry.principal, &out->principal); if(ret) goto out; - if(mask & KADM5_PRINC_EXPIRE_TIME && ent.valid_end) - out->princ_expire_time = *ent.valid_end; - if(mask & KADM5_PW_EXPIRATION && ent.pw_end) - out->pw_expiration = *ent.pw_end; + if(mask & KADM5_PRINC_EXPIRE_TIME && ent.entry.valid_end) + out->princ_expire_time = *ent.entry.valid_end; + if(mask & KADM5_PW_EXPIRATION && ent.entry.pw_end) + out->pw_expiration = *ent.entry.pw_end; if(mask & KADM5_LAST_PWD_CHANGE) - /* XXX implement */; + hdb_entry_get_pw_change_time(&ent.entry, &out->last_pwd_change); if(mask & KADM5_ATTRIBUTES){ - out->attributes |= ent.flags.postdate ? 0 : KRB5_KDB_DISALLOW_POSTDATED; - out->attributes |= ent.flags.forwardable ? 0 : KRB5_KDB_DISALLOW_FORWARDABLE; - out->attributes |= ent.flags.initial ? KRB5_KDB_DISALLOW_TGT_BASED : 0; - out->attributes |= ent.flags.renewable ? 0 : KRB5_KDB_DISALLOW_RENEWABLE; - out->attributes |= ent.flags.proxiable ? 0 : KRB5_KDB_DISALLOW_PROXIABLE; - out->attributes |= ent.flags.invalid ? KRB5_KDB_DISALLOW_ALL_TIX : 0; - out->attributes |= ent.flags.require_preauth ? KRB5_KDB_REQUIRES_PRE_AUTH : 0; - out->attributes |= ent.flags.server ? 0 : KRB5_KDB_DISALLOW_SVR; - out->attributes |= ent.flags.change_pw ? KRB5_KDB_PWCHANGE_SERVICE : 0; + out->attributes |= ent.entry.flags.postdate ? 0 : KRB5_KDB_DISALLOW_POSTDATED; + out->attributes |= ent.entry.flags.forwardable ? 0 : KRB5_KDB_DISALLOW_FORWARDABLE; + out->attributes |= ent.entry.flags.initial ? KRB5_KDB_DISALLOW_TGT_BASED : 0; + out->attributes |= ent.entry.flags.renewable ? 0 : KRB5_KDB_DISALLOW_RENEWABLE; + out->attributes |= ent.entry.flags.proxiable ? 0 : KRB5_KDB_DISALLOW_PROXIABLE; + out->attributes |= ent.entry.flags.invalid ? KRB5_KDB_DISALLOW_ALL_TIX : 0; + out->attributes |= ent.entry.flags.require_preauth ? KRB5_KDB_REQUIRES_PRE_AUTH : 0; + out->attributes |= ent.entry.flags.server ? 0 : KRB5_KDB_DISALLOW_SVR; + out->attributes |= ent.entry.flags.change_pw ? KRB5_KDB_PWCHANGE_SERVICE : 0; + out->attributes |= ent.entry.flags.ok_as_delegate ? KRB5_KDB_OK_AS_DELEGATE : 0; + out->attributes |= ent.entry.flags.trusted_for_delegation ? KRB5_KDB_TRUSTED_FOR_DELEGATION : 0; + out->attributes |= ent.entry.flags.allow_kerberos4 ? KRB5_KDB_ALLOW_KERBEROS4 : 0; + out->attributes |= ent.entry.flags.allow_digest ? KRB5_KDB_ALLOW_DIGEST : 0; } if(mask & KADM5_MAX_LIFE) { - if(ent.max_life) - out->max_life = *ent.max_life; + if(ent.entry.max_life) + out->max_life = *ent.entry.max_life; else out->max_life = INT_MAX; } if(mask & KADM5_MOD_TIME) { - if(ent.modified_by) - out->mod_date = ent.modified_by->time; + if(ent.entry.modified_by) + out->mod_date = ent.entry.modified_by->time; else - out->mod_date = ent.created_by.time; + out->mod_date = ent.entry.created_by.time; } if(mask & KADM5_MOD_NAME) { - if(ent.modified_by) { - if (ent.modified_by->principal != NULL) + if(ent.entry.modified_by) { + if (ent.entry.modified_by->principal != NULL) ret = krb5_copy_principal(context->context, - ent.modified_by->principal, + ent.entry.modified_by->principal, &out->mod_name); - } else if(ent.created_by.principal != NULL) + } else if(ent.entry.created_by.principal != NULL) ret = krb5_copy_principal(context->context, - ent.created_by.principal, + ent.entry.created_by.principal, &out->mod_name); else out->mod_name = NULL; @@ -107,13 +140,13 @@ kadm5_s_get_principal(void *server_handle, goto out; if(mask & KADM5_KVNO) - out->kvno = ent.kvno; + out->kvno = ent.entry.kvno; if(mask & KADM5_MKVNO) { int n; out->mkvno = 0; /* XXX */ - for(n = 0; n < ent.keys.len; n++) - if(ent.keys.val[n].mkvno) { - out->mkvno = *ent.keys.val[n].mkvno; /* XXX this isn't right */ + for(n = 0; n < ent.entry.keys.len; n++) + if(ent.entry.keys.val[n].mkvno) { + out->mkvno = *ent.entry.keys.val[n].mkvno; /* XXX this isn't right */ break; } } @@ -122,8 +155,8 @@ kadm5_s_get_principal(void *server_handle, if(mask & KADM5_POLICY) out->policy = NULL; if(mask & KADM5_MAX_RLIFE) { - if(ent.max_renew) - out->max_renewable_life = *ent.max_renew; + if(ent.entry.max_renew) + out->max_renewable_life = *ent.entry.max_renew; else out->max_renewable_life = INT_MAX; } @@ -139,13 +172,17 @@ kadm5_s_get_principal(void *server_handle, krb5_key_data *kd; krb5_salt salt; krb5_data *sp; - krb5_get_pw_salt(context->context, ent.principal, &salt); - out->key_data = malloc(ent.keys.len * sizeof(*out->key_data)); - for(i = 0; i < ent.keys.len; i++){ - key = &ent.keys.val[i]; + krb5_get_pw_salt(context->context, ent.entry.principal, &salt); + out->key_data = malloc(ent.entry.keys.len * sizeof(*out->key_data)); + if (out->key_data == NULL) { + ret = ENOMEM; + goto out; + } + for(i = 0; i < ent.entry.keys.len; i++){ + key = &ent.entry.keys.val[i]; kd = &out->key_data[i]; kd->key_data_ver = 2; - kd->key_data_kvno = ent.kvno; + kd->key_data_kvno = ent.entry.kvno; kd->key_data_type[0] = key->key.keytype; if(key->salt) kd->key_data_type[1] = key->salt->type; @@ -182,8 +219,64 @@ kadm5_s_get_principal(void *server_handle, kadm5_free_principal_ent(context, out); goto out; } - if(mask & KADM5_TL_DATA) - /* XXX implement */; + if(mask & KADM5_TL_DATA) { + time_t last_pw_expire; + const HDB_Ext_Aliases *aliases; + + ret = hdb_entry_get_pw_change_time(&ent.entry, &last_pw_expire); + if (ret == 0 && last_pw_expire) { + unsigned char buf[4]; + _krb5_put_int(buf, last_pw_expire, sizeof(buf)); + ret = add_tl_data(out, KRB5_TL_LAST_PWD_CHANGE, buf, sizeof(buf)); + } + if(ret){ + kadm5_free_principal_ent(context, out); + goto out; + } + /* + * If the client was allowed to get key data, let it have the + * password too. + */ + if(mask & KADM5_KEY_DATA) { + heim_utf8_string pw; + + ret = hdb_entry_get_password(context->context, + context->db, &ent.entry, &pw); + if (ret == 0) { + ret = add_tl_data(out, KRB5_TL_PASSWORD, pw, strlen(pw) + 1); + free(pw); + } + krb5_clear_error_string(context->context); + ret = 0; + } + + ret = hdb_entry_get_aliases(&ent.entry, &aliases); + if (ret == 0 && aliases) { + krb5_data buf; + size_t len; + + ASN1_MALLOC_ENCODE(HDB_Ext_Aliases, buf.data, buf.length, + aliases, &len, ret); + if (ret) { + kadm5_free_principal_ent(context, out); + goto out; + } + if (len != buf.length) + krb5_abortx(context->context, + "internal ASN.1 encoder error"); + ret = add_tl_data(out, KRB5_TL_ALIASES, buf.data, buf.length); + free(buf.data); + if (ret) { + kadm5_free_principal_ent(context, out); + goto out; + } + } + if(ret){ + kadm5_free_principal_ent(context, out); + goto out; + } + + } out: hdb_free_entry(context->context, &ent); diff --git a/crypto/heimdal/lib/kadm5/init_c.c b/crypto/heimdal/lib/kadm5/init_c.c index 05b7adb..be53992 100644 --- a/crypto/heimdal/lib/kadm5/init_c.c +++ b/crypto/heimdal/lib/kadm5/init_c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ #include <netinet/in.h> #include <netdb.h> -RCSID("$Id: init_c.c,v 1.45.2.1 2003/12/21 22:48:13 lha Exp $"); +RCSID("$Id: init_c.c 21972 2007-10-18 19:11:15Z lha $"); static void set_funcs(kadm5_client_context *c) @@ -99,9 +99,9 @@ _kadm5_c_init_context(kadm5_client_context **ctx, } if ((*ctx)->admin_server == NULL) { - return ENOMEM; free((*ctx)->realm); free(*ctx); + return ENOMEM; } colon = strchr ((*ctx)->admin_server, ':'); if (colon != NULL) @@ -154,19 +154,21 @@ get_new_cache(krb5_context context, { krb5_error_code ret; krb5_creds cred; - krb5_get_init_creds_opt opt; + krb5_get_init_creds_opt *opt; krb5_ccache id; - krb5_get_init_creds_opt_init (&opt); + ret = krb5_get_init_creds_opt_alloc (context, &opt); + if (ret) + return ret; krb5_get_init_creds_opt_set_default_flags(context, "kadmin", krb5_principal_get_realm(context, client), - &opt); + opt); - krb5_get_init_creds_opt_set_forwardable (&opt, FALSE); - krb5_get_init_creds_opt_set_proxiable (&opt, FALSE); + krb5_get_init_creds_opt_set_forwardable (opt, FALSE); + krb5_get_init_creds_opt_set_proxiable (opt, FALSE); if(password == NULL && prompter == NULL) { krb5_keytab kt; @@ -174,15 +176,17 @@ get_new_cache(krb5_context context, ret = krb5_kt_default(context, &kt); else ret = krb5_kt_resolve(context, keytab, &kt); - if(ret) + if(ret) { + krb5_get_init_creds_opt_free(context, opt); return ret; + } ret = krb5_get_init_creds_keytab (context, &cred, client, kt, 0, server_name, - &opt); + opt); krb5_kt_close(context, kt); } else { ret = krb5_get_init_creds_password (context, @@ -193,8 +197,9 @@ get_new_cache(krb5_context context, NULL, 0, server_name, - &opt); + opt); } + krb5_get_init_creds_opt_free(context, opt); switch(ret){ case 0: break; @@ -214,20 +219,102 @@ get_new_cache(krb5_context context, ret = krb5_cc_store_cred (context, id, &cred); if (ret) return ret; - krb5_free_creds_contents (context, &cred); + krb5_free_cred_contents (context, &cred); *ret_cache = id; return 0; } +/* + * Check the credential cache `id´ to figure out what principal to use + * when talking to the kadmind. If there is a initial kadmin/admin@ + * credential in the cache, use that client principal. Otherwise, use + * the client principals first component and add /admin to the + * principal. + */ + static krb5_error_code -get_cred_cache(krb5_context context, - const char *client_name, - const char *server_name, - const char *password, - krb5_prompter_fct prompter, - const char *keytab, - krb5_ccache ccache, - krb5_ccache *ret_cache) +get_cache_principal(krb5_context context, + krb5_ccache *id, + krb5_principal *client) +{ + krb5_error_code ret; + const char *name, *inst; + krb5_principal p1, p2; + + ret = krb5_cc_default(context, id); + if(ret) { + *id = NULL; + return ret; + } + + ret = krb5_cc_get_principal(context, *id, &p1); + if(ret) { + krb5_cc_close(context, *id); + *id = NULL; + return ret; + } + + ret = krb5_make_principal(context, &p2, NULL, + "kadmin", "admin", NULL); + if (ret) { + krb5_cc_close(context, *id); + *id = NULL; + krb5_free_principal(context, p1); + return ret; + } + + { + krb5_creds in, *out; + krb5_kdc_flags flags; + + flags.i = 0; + memset(&in, 0, sizeof(in)); + + in.client = p1; + in.server = p2; + + /* check for initial ticket kadmin/admin */ + ret = krb5_get_credentials_with_flags(context, KRB5_GC_CACHED, flags, + *id, &in, &out); + krb5_free_principal(context, p2); + if (ret == 0) { + if (out->flags.b.initial) { + *client = p1; + krb5_free_creds(context, out); + return 0; + } + krb5_free_creds(context, out); + } + } + krb5_cc_close(context, *id); + *id = NULL; + + name = krb5_principal_get_comp_string(context, p1, 0); + inst = krb5_principal_get_comp_string(context, p1, 1); + if(inst == NULL || strcmp(inst, "admin") != 0) { + ret = krb5_make_principal(context, &p2, NULL, name, "admin", NULL); + krb5_free_principal(context, p1); + if(ret != 0) + return ret; + + *client = p2; + return 0; + } + + *client = p1; + + return 0; +} + +krb5_error_code +_kadm5_c_get_cred_cache(krb5_context context, + const char *client_name, + const char *server_name, + const char *password, + krb5_prompter_fct prompter, + const char *keytab, + krb5_ccache ccache, + krb5_ccache *ret_cache) { krb5_error_code ret; krb5_ccache id = NULL; @@ -245,70 +332,43 @@ get_cred_cache(krb5_context context, return ret; } - if(password != NULL || prompter != NULL) { + if(ccache != NULL) { + id = ccache; + ret = krb5_cc_get_principal(context, id, &client); + if(ret) + return ret; + } else { /* get principal from default cache, ok if this doesn't work */ - ret = krb5_cc_default(context, &id); - if(ret == 0) { - ret = krb5_cc_get_principal(context, id, &default_client); - if(ret) { - krb5_cc_close(context, id); - id = NULL; - } else { - const char *name, *inst; - krb5_principal tmp; - name = krb5_principal_get_comp_string(context, - default_client, 0); - inst = krb5_principal_get_comp_string(context, - default_client, 1); - if(inst == NULL || strcmp(inst, "admin") != 0) { - ret = krb5_make_principal(context, &tmp, NULL, - name, "admin", NULL); - if(ret != 0) { - krb5_free_principal(context, default_client); - krb5_cc_close(context, id); - return ret; - } - krb5_free_principal(context, default_client); - default_client = tmp; - krb5_cc_close(context, id); - id = NULL; - } - } - } - if (client != NULL) { - /* A client was specified by the caller. */ - if (default_client != NULL) { - krb5_free_principal(context, default_client); - default_client = NULL; - } - } - else if (default_client != NULL) - /* No client was specified by the caller, but we have a - * client from the default credentials cache. - */ - client = default_client; - else { - /* No client was specified by the caller and we cannot determine - * the client from a credentials cache. + ret = get_cache_principal(context, &id, &default_client); + if (ret) { + /* + * No client was specified by the caller and we cannot + * determine the client from a credentials cache. */ const char *user; user = get_default_username (); - if(user == NULL) + if(user == NULL) { + krb5_set_error_string(context, "Unable to find local user name"); return KADM5_FAILURE; - ret = krb5_make_principal(context, &client, + } + ret = krb5_make_principal(context, &default_client, NULL, user, "admin", NULL); if(ret) return ret; - if (id != NULL) { - krb5_cc_close(context, id); - id = NULL; - } } - } else if(ccache != NULL) - id = ccache; + } + + + /* + * No client was specified by the caller, but we have a client + * from the default credentials cache. + */ + if (client == NULL && default_client != NULL) + client = default_client; + if(id && (default_client == NULL || krb5_principal_compare(context, client, default_client))) { @@ -325,7 +385,7 @@ get_cred_cache(krb5_context context, return -1; } /* get creds via AS request */ - if(id) + if(id && (id != ccache)) krb5_cc_close(context, id); if (client != default_client) krb5_free_principal(context, default_client); @@ -363,14 +423,17 @@ kadm_connect(kadm5_client_context *ctx) hostname = slash + 1; error = getaddrinfo (hostname, portstr, &hints, &ai); - if (error) + if (error) { + krb5_clear_error_string(context); return KADM5_BAD_SERVER_NAME; + } for (a = ai; a != NULL; a = a->ai_next) { s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (s < 0) continue; if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { + krb5_clear_error_string(context); krb5_warn (context, errno, "connect(%s)", hostname); close (s); continue; @@ -379,12 +442,15 @@ kadm_connect(kadm5_client_context *ctx) } if (a == NULL) { freeaddrinfo (ai); + krb5_clear_error_string(context); krb5_warnx (context, "failed to contact %s", hostname); return KADM5_FAILURE; } - ret = get_cred_cache(context, ctx->client_name, ctx->service_name, - NULL, ctx->prompter, ctx->keytab, - ctx->ccache, &cc); + ret = _kadm5_c_get_cred_cache(context, + ctx->client_name, + ctx->service_name, + NULL, ctx->prompter, ctx->keytab, + ctx->ccache, &cc); if(ret) { freeaddrinfo (ai); @@ -400,6 +466,7 @@ kadm_connect(kadm5_client_context *ctx) if (service_name == NULL) { freeaddrinfo (ai); close(s); + krb5_clear_error_string(context); return ENOMEM; } @@ -443,11 +510,13 @@ kadm_connect(kadm5_client_context *ctx) s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (s < 0) { freeaddrinfo (ai); + krb5_clear_error_string(context); return errno; } if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { close (s); freeaddrinfo (ai); + krb5_clear_error_string(context); return errno; } ret = krb5_sendauth(context, &ctx->ac, &s, @@ -464,10 +533,6 @@ kadm_connect(kadm5_client_context *ctx) krb5_free_principal(context, server); if(ctx->ccache == NULL) krb5_cc_close(context, cc); - if(ret) { - close(s); - return ret; - } ctx->sock = s; return 0; @@ -504,8 +569,10 @@ kadm5_c_init_with_context(krb5_context context, return ret; if(password != NULL && *password != '\0') { - ret = get_cred_cache(context, client_name, service_name, - password, prompter, keytab, ccache, &cc); + ret = _kadm5_c_get_cred_cache(context, + client_name, + service_name, + password, prompter, keytab, ccache, &cc); if(ret) return ret; /* XXX */ ccache = cc; diff --git a/crypto/heimdal/lib/kadm5/init_s.c b/crypto/heimdal/lib/kadm5/init_s.c index bf5d036..dee464b 100644 --- a/crypto/heimdal/lib/kadm5/init_s.c +++ b/crypto/heimdal/lib/kadm5/init_s.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: init_s.c,v 1.10 2000/12/31 08:01:16 assar Exp $"); +RCSID("$Id: init_s.c 9441 2000-12-31 08:01:16Z assar $"); static kadm5_ret_t diff --git a/crypto/heimdal/lib/kadm5/iprop-commands.in b/crypto/heimdal/lib/kadm5/iprop-commands.in new file mode 100644 index 0000000..438594e --- /dev/null +++ b/crypto/heimdal/lib/kadm5/iprop-commands.in @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $Id: iprop-commands.in 20602 2007-05-08 03:08:35Z lha $ */ + +command = { + name = "dump" + option = { + long = "config-file" + short = "c" + type = "string" + help = "configuration file" + argument = "file" + } + option = { + long = "realm" + short = "r" + type = "string" + help = "realm" + } + function = "iprop_dump" + help = "Prints the iprop transaction log in text." + max_args = "0" +} +command = { + name = "truncate" + option = { + long = "config-file" + short = "c" + type = "string" + help = "configuration file" + argument = "file" + } + option = { + long = "realm" + short = "r" + type = "string" + help = "realm" + } + function = "iprop_truncate" + help = "Truncate the log, preserve the version number." + max_args = "0" +} +command = { + name = "replay" + option = { + long = "start-version" + type = "integer" + help = "start replay with this version" + argument = "version-number" + default = "-1" + } + option = { + long = "end-version" + type = "integer" + help = "end replay with this version" + argument = "version-number" + default = "-1" + } + option = { + long = "config-file" + short = "c" + type = "string" + help = "configuration file" + argument = "file" + } + option = { + long = "realm" + short = "r" + type = "string" + help = "realm" + } + function = "iprop_replay" + help = "Replay the log on the database." + max_args = "0" +} +command = { + name = "last-version" + option = { + long = "config-file" + short = "c" + type = "string" + help = "configuration file" + argument = "file" + } + option = { + long = "realm" + short = "r" + type = "string" + help = "realm" + } + function = "last_version" + help = "Print the last version of the log-file." + max_args = "0" +} +command = { + name = "help" + argument = "command" + max_args = "1" + function = "help" +} diff --git a/crypto/heimdal/lib/kadm5/iprop-log.8 b/crypto/heimdal/lib/kadm5/iprop-log.8 new file mode 100644 index 0000000..599046b --- /dev/null +++ b/crypto/heimdal/lib/kadm5/iprop-log.8 @@ -0,0 +1,170 @@ +.\" $Id: iprop-log.8 21713 2007-07-27 14:38:49Z lha $ +.\" +.\" Copyright (c) 2005 - 2007 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: iprop-log.8 21713 2007-07-27 14:38:49Z lha $ +.\" +.Dd February 18, 2007 +.Dt IPROP-LOG 8 +.Os Heimdal +.Sh NAME +.Nm iprop-log +.Nd +maintain the iprop log file +.Sh SYNOPSIS +.Nm +.Op Fl -version +.Op Fl h | Fl -help +.Ar command +.Pp +.Nm iprop-log truncate +.Oo Fl c Ar file \*(Ba Xo +.Fl -config-file= Ns Ar file +.Xc +.Oc +.Oo Fl r Ar string \*(Ba Xo +.Fl -realm= Ns Ar string +.Xc +.Oc +.Op Fl h | Fl -help +.Pp +.Nm iprop-log dump +.Oo Fl c Ar file \*(Ba Xo +.Fl -config-file= Ns Ar file +.Xc +.Oc +.Oo Fl r Ar string \*(Ba Xo +.Fl -realm= Ns Ar string +.Xc +.Oc +.Op Fl h | Fl -help +.Pp +.Nm iprop-log replay +.Op Fl -start-version= Ns Ar version-number +.Op Fl -end-version= Ns Ar version-number +.Oo Fl c Ar file \*(Ba Xo +.Fl -config-file= Ns Ar file +.Xc +.Oc +.Oo Fl r Ar string \*(Ba Xo +.Fl -realm= Ns Ar string +.Xc +.Oc +.Op Fl h | Fl -help +.Sh DESCRIPTION +Supported options: +.Bl -tag -width Ds +.It Xo +.Fl -version +.Xc +.It Xo +.Fl h , +.Fl -help +.Xc +.El +.Pp +command can be one of the following: +.Bl -tag -width truncate +.It truncate +.Bl -tag -width Ds +.It Xo +.Fl c Ar file , +.Fl -config-file= Ns Ar file +.Xc +configuration file +.It Xo +.Fl r Ar string , +.Fl -realm= Ns Ar string +.Xc +realm +.El +.Pp +Truncates the log. Sets the new logs version number for the to the +last entry of the old log. If the log is truncted by emptying the +file, the log will start over at the first version (0). +.It dump +.Bl -tag -width Ds +.It Xo +.Fl c Ar file , +.Fl -config-file= Ns Ar file +.Xc +configuration file +.It Xo +.Fl r Ar string , +.Fl -realm= Ns Ar string +.Xc +realm +.El +.Pp +Print out all entires in the log to standard output. +.It replay +.Bl -tag -width Ds +.It Xo +.Fl -start-version= Ns Ar version-number +.Xc +start replay with this version +.It Xo +.Fl -end-version= Ns Ar version-number +.Xc +end replay with this version +.It Xo +.Fl c Ar file , +.Fl -config-file= Ns Ar file +.Xc +configuration file +.It Xo +.Fl r Ar string , +.Fl -realm= Ns Ar string +.Xc +realm +.El +.Pp +Replay the changes from specified entries (or all if none is +specified) in the transaction log to the database. +.It last-version +.Bl -tag -width Ds +.It Xo +.Fl c Ar file , +.Fl -config-file= Ns Ar file +.Xc +configuration file +.It Xo +.Fl r Ar string , +.Fl -realm= Ns Ar string +.Xc +realm +.El +.Pp +prints the version of the last log entry. +.El +.Sh SEE ALSO +.Xr iprop 8 diff --git a/crypto/heimdal/lib/kadm5/iprop-log.c b/crypto/heimdal/lib/kadm5/iprop-log.c new file mode 100644 index 0000000..7b43076 --- /dev/null +++ b/crypto/heimdal/lib/kadm5/iprop-log.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "iprop.h" +#include <sl.h> +#include <parse_time.h> +#include "iprop-commands.h" + +RCSID("$Id: iprop-log.c 22211 2007-12-07 19:27:27Z lha $"); + +static krb5_context context; + +static kadm5_server_context * +get_kadmin_context(const char *config_file, char *realm) +{ + kadm5_config_params conf; + krb5_error_code ret; + void *kadm_handle; + char **files; + + if (config_file == NULL) { + char *file; + asprintf(&file, "%s/kdc.conf", hdb_db_dir(context)); + if (file == NULL) + errx(1, "out of memory"); + config_file = file; + } + + ret = krb5_prepend_config_files_default(config_file, &files); + if (ret) + krb5_err(context, 1, ret, "getting configuration files"); + + ret = krb5_set_config_files(context, files); + krb5_free_config_files(files); + if (ret) + krb5_err(context, 1, ret, "reading configuration files"); + + memset(&conf, 0, sizeof(conf)); + if(realm) { + conf.mask |= KADM5_CONFIG_REALM; + conf.realm = realm; + } + + ret = kadm5_init_with_password_ctx (context, + KADM5_ADMIN_SERVICE, + NULL, + KADM5_ADMIN_SERVICE, + &conf, 0, 0, + &kadm_handle); + if (ret) + krb5_err (context, 1, ret, "kadm5_init_with_password_ctx"); + + return (kadm5_server_context *)kadm_handle; +} + +/* + * dump log + */ + +static const char *op_names[] = { + "get", + "delete", + "create", + "rename", + "chpass", + "modify", + "randkey", + "get_privs", + "get_princs", + "chpass_with_key", + "nop" +}; + +static void +print_entry(kadm5_server_context *server_context, + uint32_t ver, + time_t timestamp, + enum kadm_ops op, + uint32_t len, + krb5_storage *sp, + void *ctx) +{ + char t[256]; + int32_t mask; + hdb_entry ent; + krb5_principal source; + char *name1, *name2; + krb5_data data; + krb5_context scontext = server_context->context; + + off_t end = krb5_storage_seek(sp, 0, SEEK_CUR) + len; + + krb5_error_code ret; + + strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); + + if(op < kadm_get || op > kadm_nop) { + printf("unknown op: %d\n", op); + krb5_storage_seek(sp, end, SEEK_SET); + return; + } + + printf ("%s: ver = %u, timestamp = %s, len = %u\n", + op_names[op], ver, t, len); + switch(op) { + case kadm_delete: + krb5_ret_principal(sp, &source); + krb5_unparse_name(scontext, source, &name1); + printf(" %s\n", name1); + free(name1); + krb5_free_principal(scontext, source); + break; + case kadm_rename: + ret = krb5_data_alloc(&data, len); + if (ret) + krb5_err (scontext, 1, ret, "kadm_rename: data alloc: %d", len); + krb5_ret_principal(sp, &source); + krb5_storage_read(sp, data.data, data.length); + hdb_value2entry(scontext, &data, &ent); + krb5_unparse_name(scontext, source, &name1); + krb5_unparse_name(scontext, ent.principal, &name2); + printf(" %s -> %s\n", name1, name2); + free(name1); + free(name2); + krb5_free_principal(scontext, source); + free_hdb_entry(&ent); + break; + case kadm_create: + ret = krb5_data_alloc(&data, len); + if (ret) + krb5_err (scontext, 1, ret, "kadm_create: data alloc: %d", len); + krb5_storage_read(sp, data.data, data.length); + ret = hdb_value2entry(scontext, &data, &ent); + if(ret) + abort(); + mask = ~0; + goto foo; + case kadm_modify: + ret = krb5_data_alloc(&data, len); + if (ret) + krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len); + krb5_ret_int32(sp, &mask); + krb5_storage_read(sp, data.data, data.length); + ret = hdb_value2entry(scontext, &data, &ent); + if(ret) + abort(); + foo: + if(ent.principal /* mask & KADM5_PRINCIPAL */) { + krb5_unparse_name(scontext, ent.principal, &name1); + printf(" principal = %s\n", name1); + free(name1); + } + if(mask & KADM5_PRINC_EXPIRE_TIME) { + if(ent.valid_end == NULL) { + strlcpy(t, "never", sizeof(t)); + } else { + strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", + localtime(ent.valid_end)); + } + printf(" expires = %s\n", t); + } + if(mask & KADM5_PW_EXPIRATION) { + if(ent.pw_end == NULL) { + strlcpy(t, "never", sizeof(t)); + } else { + strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", + localtime(ent.pw_end)); + } + printf(" password exp = %s\n", t); + } + if(mask & KADM5_LAST_PWD_CHANGE) { + } + if(mask & KADM5_ATTRIBUTES) { + unparse_flags(HDBFlags2int(ent.flags), + asn1_HDBFlags_units(), t, sizeof(t)); + printf(" attributes = %s\n", t); + } + if(mask & KADM5_MAX_LIFE) { + if(ent.max_life == NULL) + strlcpy(t, "for ever", sizeof(t)); + else + unparse_time(*ent.max_life, t, sizeof(t)); + printf(" max life = %s\n", t); + } + if(mask & KADM5_MAX_RLIFE) { + if(ent.max_renew == NULL) + strlcpy(t, "for ever", sizeof(t)); + else + unparse_time(*ent.max_renew, t, sizeof(t)); + printf(" max rlife = %s\n", t); + } + if(mask & KADM5_MOD_TIME) { + printf(" mod time\n"); + } + if(mask & KADM5_MOD_NAME) { + printf(" mod name\n"); + } + if(mask & KADM5_KVNO) { + printf(" kvno = %d\n", ent.kvno); + } + if(mask & KADM5_MKVNO) { + printf(" mkvno\n"); + } + if(mask & KADM5_AUX_ATTRIBUTES) { + printf(" aux attributes\n"); + } + if(mask & KADM5_POLICY) { + printf(" policy\n"); + } + if(mask & KADM5_POLICY_CLR) { + printf(" mod time\n"); + } + if(mask & KADM5_LAST_SUCCESS) { + printf(" last success\n"); + } + if(mask & KADM5_LAST_FAILED) { + printf(" last failed\n"); + } + if(mask & KADM5_FAIL_AUTH_COUNT) { + printf(" fail auth count\n"); + } + if(mask & KADM5_KEY_DATA) { + printf(" key data\n"); + } + if(mask & KADM5_TL_DATA) { + printf(" tl data\n"); + } + free_hdb_entry(&ent); + break; + case kadm_nop : + break; + default: + abort(); + } + krb5_storage_seek(sp, end, SEEK_SET); +} + +int +iprop_dump(struct dump_options *opt, int argc, char **argv) +{ + kadm5_server_context *server_context; + krb5_error_code ret; + + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); + + ret = kadm5_log_init (server_context); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_init"); + + ret = kadm5_log_foreach (server_context, print_entry, NULL); + if(ret) + krb5_warn(context, ret, "kadm5_log_foreach"); + + ret = kadm5_log_end (server_context); + if (ret) + krb5_warn(context, ret, "kadm5_log_end"); + return 0; +} + +int +iprop_truncate(struct truncate_options *opt, int argc, char **argv) +{ + kadm5_server_context *server_context; + krb5_error_code ret; + + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); + + ret = kadm5_log_truncate (server_context); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_truncate"); + + return 0; +} + +int +last_version(struct last_version_options *opt, int argc, char **argv) +{ + kadm5_server_context *server_context; + krb5_error_code ret; + uint32_t version; + + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); + + ret = kadm5_log_init (server_context); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_init"); + + ret = kadm5_log_get_version (server_context, &version); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_get_version"); + + ret = kadm5_log_end (server_context); + if (ret) + krb5_warn(context, ret, "kadm5_log_end"); + + printf("version: %lu\n", (unsigned long)version); + + return 0; +} + +/* + * Replay log + */ + +int start_version = -1; +int end_version = -1; + +static void +apply_entry(kadm5_server_context *server_context, + uint32_t ver, + time_t timestamp, + enum kadm_ops op, + uint32_t len, + krb5_storage *sp, + void *ctx) +{ + struct replay_options *opt = ctx; + krb5_error_code ret; + + if((opt->start_version_integer != -1 && ver < opt->start_version_integer) || + (opt->end_version_integer != -1 && ver > opt->end_version_integer)) { + /* XXX skip this entry */ + krb5_storage_seek(sp, len, SEEK_CUR); + return; + } + printf ("ver %u... ", ver); + fflush (stdout); + + ret = kadm5_log_replay (server_context, + op, ver, len, sp); + if (ret) + krb5_warn (server_context->context, ret, "kadm5_log_replay"); + + printf ("done\n"); +} + +int +iprop_replay(struct replay_options *opt, int argc, char **argv) +{ + kadm5_server_context *server_context; + krb5_error_code ret; + + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); + + ret = server_context->db->hdb_open(context, + server_context->db, + O_RDWR | O_CREAT, 0600); + if (ret) + krb5_err (context, 1, ret, "db->open"); + + ret = kadm5_log_init (server_context); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_init"); + + ret = kadm5_log_foreach (server_context, apply_entry, opt); + if(ret) + krb5_warn(context, ret, "kadm5_log_foreach"); + ret = kadm5_log_end (server_context); + if (ret) + krb5_warn(context, ret, "kadm5_log_end"); + ret = server_context->db->hdb_close (context, server_context->db); + if (ret) + krb5_err (context, 1, ret, "db->close"); + + return 0; +} + +static int help_flag; +static int version_flag; + +static struct getargs args[] = { + { "version", 0, arg_flag, &version_flag, + NULL, NULL + }, + { "help", 'h', arg_flag, &help_flag, + NULL, NULL + } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +int +help(void *opt, int argc, char **argv) +{ + if(argc == 0) { + sl_help(commands, 1, argv - 1 /* XXX */); + } else { + SL_cmd *c = sl_match (commands, argv[0], 0); + if(c == NULL) { + fprintf (stderr, "No such command: %s. " + "Try \"help\" for a list of commands\n", + argv[0]); + } else { + if(c->func) { + char *fake[] = { NULL, "--help", NULL }; + fake[0] = argv[0]; + (*c->func)(2, fake); + fprintf(stderr, "\n"); + } + if(c->help && *c->help) + fprintf (stderr, "%s\n", c->help); + if((++c)->name && c->func == NULL) { + int f = 0; + fprintf (stderr, "Synonyms:"); + while (c->name && c->func == NULL) { + fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name); + f = 1; + } + fprintf (stderr, "\n"); + } + } + } + return 0; +} + +static void +usage(int status) +{ + arg_printusage(args, num_args, NULL, "command"); + exit(status); +} + +int +main(int argc, char **argv) +{ + int optidx = 0; + krb5_error_code ret; + + setprogname(argv[0]); + + if(getarg(args, num_args, argc, argv, &optidx)) + usage(1); + if(help_flag) + usage(0); + if(version_flag) { + print_version(NULL); + exit(0); + } + argc -= optidx; + argv += optidx; + if(argc == 0) + usage(1); + + ret = krb5_init_context(&context); + if (ret) + errx(1, "krb5_init_context failed with: %d\n", ret); + + ret = sl_command(commands, argc, argv); + if(ret == -1) + warnx ("unrecognized command: %s", argv[0]); + return ret; +} diff --git a/crypto/heimdal/lib/kadm5/iprop.8 b/crypto/heimdal/lib/kadm5/iprop.8 new file mode 100644 index 0000000..d1e55cc --- /dev/null +++ b/crypto/heimdal/lib/kadm5/iprop.8 @@ -0,0 +1,223 @@ +.\" $Id: iprop.8 21940 2007-09-28 22:28:09Z lha $ +.\" +.\" Copyright (c) 2005 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 24, 2005 +.Dt IPROP 8 +.Os Heimdal +.Sh NAME +.Nm iprop , +.Nm ipropd-master , +.Nm ipropd-slave +.Nd +propagate changes to a Heimdal Kerberos master KDC to slave KDCs +.Sh SYNOPSIS +.Nm ipropd-master +.Oo Fl c Ar string \*(Ba Xo +.Fl -config-file= Ns Ar string +.Xc +.Oc +.Oo Fl r Ar string \*(Ba Xo +.Fl -realm= Ns Ar string +.Xc +.Oc +.Oo Fl k Ar kspec \*(Ba Xo +.Fl -keytab= Ns Ar kspec +.Xc +.Oc +.Oo Fl d Ar file \*(Ba Xo +.Fl -database= Ns Ar file +.Xc +.Oc +.Op Fl -slave-stats-file= Ns Ar file +.Op Fl -time-missing= Ns Ar time +.Op Fl -time-gone= Ns Ar time +.Op Fl -detach +.Op Fl -version +.Op Fl -help +.Nm ipropd-slave +.Oo Fl c Ar string \*(Ba Xo +.Fl -config-file= Ns Ar string +.Xc +.Oc +.Oo Fl r Ar string \*(Ba Xo +.Fl -realm= Ns Ar string +.Xc +.Oc +.Oo Fl k Ar kspec \*(Ba Xo +.Fl -keytab= Ns Ar kspec +.Xc +.Oc +.Op Fl -time-lost= Ns Ar time +.Op Fl -detach +.Op Fl -version +.Op Fl -help +.Ar master +.Pp +.Sh DESCRIPTION +.Nm ipropd-master +is used to propagate changes to a Heimdal Kerberos database from the +master Kerberos server on which it runs to slave Kerberos servers +running +.Nm ipropd-slave . +.Pp +The slaves are specified by the contents of the +.Pa slaves +file in the KDC's database directory, e.g.\& +.Pa /var/heimdal/slaves . +This has principals one per-line of the form +.Dl iprop/ Ns Ar slave Ns @ Ns Ar REALM +where +.Ar slave +is the hostname of the slave server in the given +.Ar REALM , +e.g.\& +.Dl iprop/kerberos-1.example.com@EXAMPLE.COM +On a slave, the argument +.Fa master +specifies the hostname of the master server from which to receive updates. +.Pp +In contrast to +.Xr hprop 8 , +which sends the whole database to the slaves regularly, +.Nm +normally sends only the changes as they happen on the master. The +master keeps track of all the changes by assigning a version number to +every change to the database. The slaves know which was the latest +version they saw, and in this way it can be determined if they are in +sync or not. A log of all the changes is kept on the master. When a +slave is at an older version than the oldest one in the log, the whole +database has to be sent. +.Pp +The changes are propagated over a secure channel (on port 2121 by +default). This should normally be defined as +.Dq iprop/tcp +in +.Pa /etc/services +or another source of the services database. The master and slaves +must each have access to a keytab with keys for the +.Nm iprop +service principal on the local host. +.Pp +There is a keep-alive feature logged in the master's +.Pa slave-stats +file (e.g.\& +.Pa /var/heimdal/slave-stats ) . +.Pp +Supported options for +.Nm ipropd-master : +.Bl -tag -width Ds +.It Xo +.Fl c Ar string , +.Fl -config-file= Ns Ar string +.Xc +.It Xo +.Fl r Ar string , +.Fl -realm= Ns Ar string +.Xc +.It Xo +.Fl k Ar kspec , +.Fl -keytab= Ns Ar kspec +.Xc +keytab to get authentication from +.It Xo +.Fl d Ar file , +.Fl -database= Ns Ar file +.Xc +Database (default per KDC) +.It Xo +.Fl -slave-stats-file= Ns Ar file +.Xc +file for slave status information +.It Xo +.Fl -time-missing= Ns Ar time +.Xc +time before slave is polled for presence (default 2 min) +.It Xo +.Fl -time-gone= Ns Ar time +.Xc +time of inactivity after which a slave is considered gone (default 5 min) +.It Xo +.Fl -detach +.Xc +detach from console +.It Xo +.Fl -version +.Xc +.It Xo +.Fl -help +.Xc +.El +.Pp +Supported options for +.Nm ipropd-slave : +.Bl -tag -width Ds +.It Xo +.Fl c Ar string , +.Fl -config-file= Ns Ar string +.Xc +.It Xo +.Fl r Ar string , +.Fl -realm= Ns Ar string +.Xc +.It Xo +.Fl k Ar kspec , +.Fl -keytab= Ns Ar kspec +.Xc +keytab to get authentication from +.It Xo +.Fl -time-lost= Ns Ar time +.Xc +time before server is considered lost (default 5 min) +.It Xo +.Fl -detach +.Xc +detach from console +.It Xo +.Fl -version +.Xc +.It Xo +.Fl -help +.Xc +.El +Time arguments for the relevant options above may be specified in forms +like 5 min, 300 s, or simply a number of seconds. +.Sh FILES +.Pa slaves , +.Pa slave-stats +in the database directory. +.Sh SEE ALSO +.Xr hpropd 8 , +.Xr hprop 8 , +.Xr krb5.conf 8 , +.Xr kdc 8 , +.Xr iprop-log 8 . diff --git a/crypto/heimdal/lib/kadm5/iprop.h b/crypto/heimdal/lib/kadm5/iprop.h index e02a9d6..beb5414 100644 --- a/crypto/heimdal/lib/kadm5/iprop.h +++ b/crypto/heimdal/lib/kadm5/iprop.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Kungliga Tekniska Högskolan + * Copyright (c) 1998-2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,13 +31,12 @@ * SUCH DAMAGE. */ -/* $Id: iprop.h,v 1.7 2002/07/04 14:39:19 joda Exp $ */ +/* $Id: iprop.h 22211 2007-12-07 19:27:27Z lha $ */ #ifndef __IPROP_H__ #define __IPROP_H__ #include "kadm5_locl.h" -#include <krb5-private.h> /* _krb5_{get,put}_int */ #include <getarg.h> #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> @@ -46,11 +45,9 @@ #include <util.h> #endif -#define IPROP_VERSION "iprop-0.0" - -#define KADM5_SLAVE_ACL HDB_DB_DIR "/slaves" +#include <parse_time.h> -#define KADM5_SLAVE_STATS HDB_DB_DIR "/slaves-stats" +#define IPROP_VERSION "iprop-0.0" #define IPROP_NAME "iprop" @@ -62,7 +59,12 @@ enum iprop_cmd { I_HAVE = 1, FOR_YOU = 2, TELL_YOU_EVERYTHING = 3, ONE_PRINC = 4, - NOW_YOU_HAVE = 5 + NOW_YOU_HAVE = 5, + ARE_YOU_THERE = 6, + I_AM_HERE = 7 }; +extern sig_atomic_t exit_flag; +void setup_signal(void); + #endif /* __IPROP_H__ */ diff --git a/crypto/heimdal/lib/kadm5/ipropd_common.c b/crypto/heimdal/lib/kadm5/ipropd_common.c new file mode 100644 index 0000000..e656159 --- /dev/null +++ b/crypto/heimdal/lib/kadm5/ipropd_common.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "iprop.h" +RCSID("$Id$"); + +sig_atomic_t exit_flag; + +static RETSIGTYPE +sigterm(int sig) +{ + exit_flag = sig; +} + +void +setup_signal(void) +{ +#ifdef HAVE_SIGACTION + { + struct sigaction sa; + + sa.sa_flags = 0; + sa.sa_handler = sigterm; + sigemptyset(&sa.sa_mask); + + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGXCPU, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &sa, NULL); + } +#else + signal(SIGINT, sigterm); + signal(SIGTERM, sigterm); + signal(SIGXCPU, sigterm); + signal(SIGPIPE, SIG_IGN); +#endif +} diff --git a/crypto/heimdal/lib/kadm5/ipropd_master.c b/crypto/heimdal/lib/kadm5/ipropd_master.c index 537d403..bd8f71f 100644 --- a/crypto/heimdal/lib/kadm5/ipropd_master.c +++ b/crypto/heimdal/lib/kadm5/ipropd_master.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -34,24 +34,34 @@ #include "iprop.h" #include <rtbl.h> -RCSID("$Id: ipropd_master.c,v 1.29 2003/03/19 11:56:38 lha Exp $"); +RCSID("$Id: ipropd_master.c 22211 2007-12-07 19:27:27Z lha $"); static krb5_log_facility *log_facility; -const char *slave_stats_file = KADM5_SLAVE_STATS; +const char *slave_stats_file; +const char *slave_time_missing = "2 min"; +const char *slave_time_gone = "5 min"; + +static int time_before_missing; +static int time_before_gone; + +const char *master_hostname; static int make_signal_socket (krb5_context context) { struct sockaddr_un addr; + const char *fn; int fd; + fn = kadm5_log_signal_socket(context); + fd = socket (AF_UNIX, SOCK_DGRAM, 0); if (fd < 0) krb5_err (context, 1, errno, "socket AF_UNIX"); memset (&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy (addr.sun_path, KADM5_LOG_SIGNAL, sizeof(addr.sun_path)); + strlcpy (addr.sun_path, fn, sizeof(addr.sun_path)); unlink (addr.sun_path); if (bind (fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) krb5_err (context, 1, errno, "bind %s", addr.sun_path); @@ -59,7 +69,7 @@ make_signal_socket (krb5_context context) } static int -make_listen_socket (krb5_context context) +make_listen_socket (krb5_context context, const char *port_str) { int fd; int one = 1; @@ -71,8 +81,24 @@ make_listen_socket (krb5_context context) setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); memset (&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = krb5_getportbyname (context, - IPROP_SERVICE, "tcp", IPROP_PORT); + + if (port_str) { + addr.sin_port = krb5_getportbyname (context, + port_str, "tcp", + 0); + if (addr.sin_port == 0) { + char *ptr; + long port; + + port = strtol (port_str, &ptr, 10); + if (port == 0 && ptr == port_str) + krb5_errx (context, 1, "bad port `%s'", port_str); + addr.sin_port = htons(port); + } + } else { + addr.sin_port = krb5_getportbyname (context, IPROP_SERVICE, + "tcp", IPROP_PORT); + } if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) krb5_err (context, 1, errno, "bind"); if (listen(fd, SOMAXCONN) < 0) @@ -85,10 +111,11 @@ struct slave { struct sockaddr_in addr; char *name; krb5_auth_context ac; - u_int32_t version; + uint32_t version; time_t seen; unsigned long flags; #define SLAVE_F_DEAD 0x1 +#define SLAVE_F_AYT 0x2 struct slave *next; }; @@ -97,16 +124,27 @@ typedef struct slave slave; static int check_acl (krb5_context context, const char *name) { + const char *fn; FILE *fp; char buf[256]; int ret = 1; + char *slavefile; + + asprintf(&slavefile, "%s/slaves", hdb_db_dir(context)); - fp = fopen (KADM5_SLAVE_ACL, "r"); + fn = krb5_config_get_string_default(context, + NULL, + slavefile, + "kdc", + "iprop-acl", + NULL); + + fp = fopen (fn, "r"); + free(slavefile); if (fp == NULL) return 1; while (fgets(buf, sizeof(buf), fp) != NULL) { - if (buf[strlen(buf) - 1 ] == '\n') - buf[strlen(buf) - 1 ] = '\0'; + buf[strcspn(buf, "\r\n")] = '\0'; if (strcmp (buf, name) == 0) { ret = 0; break; @@ -119,12 +157,31 @@ check_acl (krb5_context context, const char *name) static void slave_seen(slave *s) { + s->flags &= ~SLAVE_F_AYT; s->seen = time(NULL); } +static int +slave_missing_p (slave *s) +{ + if (time(NULL) > s->seen + time_before_missing) + return 1; + return 0; +} + +static int +slave_gone_p (slave *s) +{ + if (time(NULL) > s->seen + time_before_gone) + return 1; + return 0; +} + static void -slave_dead(slave *s) +slave_dead(krb5_context context, slave *s) { + krb5_warnx(context, "slave %s dead", s->name); + if (s->fd >= 0) { close (s->fd); s->fd = -1; @@ -177,7 +234,11 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root, int fd) krb5_warn (context, errno, "accept"); goto error; } - gethostname(hostname, sizeof(hostname)); + if (master_hostname) + strlcpy(hostname, master_hostname, sizeof(hostname)); + else + gethostname(hostname, sizeof(hostname)); + ret = krb5_sname_to_principal (context, hostname, IPROP_NAME, KRB5_NT_SRV_HST, &server); if (ret) { @@ -240,13 +301,14 @@ struct prop_context { }; static int -prop_one (krb5_context context, HDB *db, hdb_entry *entry, void *v) +prop_one (krb5_context context, HDB *db, hdb_entry_ex *entry, void *v) { krb5_error_code ret; + krb5_storage *sp; krb5_data data; - struct slave *slave = (struct slave *)v; + struct slave *s = (struct slave *)v; - ret = hdb_entry2value (context, entry, &data); + ret = hdb_entry2value (context, &entry->entry, &data); if (ret) return ret; ret = krb5_data_realloc (&data, data.length + 4); @@ -255,18 +317,25 @@ prop_one (krb5_context context, HDB *db, hdb_entry *entry, void *v) return ret; } memmove ((char *)data.data + 4, data.data, data.length - 4); - _krb5_put_int (data.data, ONE_PRINC, 4); + sp = krb5_storage_from_data(&data); + if (sp == NULL) { + krb5_data_free (&data); + return ENOMEM; + } + krb5_store_int32(sp, ONE_PRINC); + krb5_storage_free(sp); - ret = krb5_write_priv_message (context, slave->ac, &slave->fd, &data); + ret = krb5_write_priv_message (context, s->ac, &s->fd, &data); krb5_data_free (&data); return ret; } static int send_complete (krb5_context context, slave *s, - const char *database, u_int32_t current_version) + const char *database, uint32_t current_version) { krb5_error_code ret; + krb5_storage *sp; HDB *db; krb5_data data; char buf[8]; @@ -274,11 +343,15 @@ send_complete (krb5_context context, slave *s, ret = hdb_create (context, &db, database); if (ret) krb5_err (context, 1, ret, "hdb_create: %s", database); - ret = db->open (context, db, O_RDONLY, 0); + ret = db->hdb_open (context, db, O_RDONLY, 0); if (ret) krb5_err (context, 1, ret, "db->open"); - _krb5_put_int(buf, TELL_YOU_EVERYTHING, 4); + sp = krb5_storage_from_mem (buf, 4); + if (sp == NULL) + krb5_errx (context, 1, "krb5_storage_from_mem"); + krb5_store_int32 (sp, TELL_YOU_EVERYTHING); + krb5_storage_free (sp); data.data = buf; data.length = 4; @@ -287,26 +360,34 @@ send_complete (krb5_context context, slave *s, if (ret) { krb5_warn (context, ret, "krb5_write_priv_message"); - slave_dead(s); + slave_dead(context, s); return ret; } ret = hdb_foreach (context, db, 0, prop_one, s); if (ret) { krb5_warn (context, ret, "hdb_foreach"); - slave_dead(s); + slave_dead(context, s); return ret; } - _krb5_put_int (buf, NOW_YOU_HAVE, 4); - _krb5_put_int (buf + 4, current_version, 4); + (*db->hdb_close)(context, db); + (*db->hdb_destroy)(context, db); + + sp = krb5_storage_from_mem (buf, 8); + if (sp == NULL) + krb5_errx (context, 1, "krb5_storage_from_mem"); + krb5_store_int32 (sp, NOW_YOU_HAVE); + krb5_store_int32 (sp, current_version); + krb5_storage_free (sp); + data.length = 8; s->version = current_version; ret = krb5_write_priv_message(context, s->ac, &s->fd, &data); if (ret) { - slave_dead(s); + slave_dead(context, s); krb5_warn (context, ret, "krb5_write_priv_message"); return ret; } @@ -317,59 +398,132 @@ send_complete (krb5_context context, slave *s, } static int +send_are_you_there (krb5_context context, slave *s) +{ + krb5_storage *sp; + krb5_data data; + char buf[4]; + int ret; + + if (s->flags & (SLAVE_F_DEAD|SLAVE_F_AYT)) + return 0; + + s->flags |= SLAVE_F_AYT; + + data.data = buf; + data.length = 4; + + sp = krb5_storage_from_mem (buf, 4); + if (sp == NULL) { + krb5_warnx (context, "are_you_there: krb5_data_alloc"); + slave_dead(context, s); + return 1; + } + krb5_store_int32 (sp, ARE_YOU_THERE); + krb5_storage_free (sp); + + ret = krb5_write_priv_message(context, s->ac, &s->fd, &data); + + if (ret) { + krb5_warn (context, ret, "are_you_there: krb5_write_priv_message"); + slave_dead(context, s); + return 1; + } + + return 0; +} + +static int send_diffs (krb5_context context, slave *s, int log_fd, - const char *database, u_int32_t current_version) + const char *database, uint32_t current_version) { krb5_storage *sp; - u_int32_t ver; + uint32_t ver; time_t timestamp; enum kadm_ops op; - u_int32_t len; + uint32_t len; off_t right, left; krb5_data data; int ret = 0; - if (s->version == current_version) + if (s->version == current_version) { + krb5_warnx(context, "slave %s in sync already at version %ld", + s->name, (long)s->version); return 0; + } if (s->flags & SLAVE_F_DEAD) return 0; + /* if slave is a fresh client, starting over */ + if (s->version == 0) { + krb5_warnx(context, "sending complete log to fresh slave %s", + s->name); + return send_complete (context, s, database, current_version); + } + sp = kadm5_log_goto_end (log_fd); right = krb5_storage_seek(sp, 0, SEEK_CUR); for (;;) { - if (kadm5_log_previous (sp, &ver, ×tamp, &op, &len)) - abort (); + ret = kadm5_log_previous (context, sp, &ver, ×tamp, &op, &len); + if (ret) + krb5_err(context, 1, ret, + "send_diffs: failed to find previous entry"); left = krb5_storage_seek(sp, -16, SEEK_CUR); if (ver == s->version) return 0; if (ver == s->version + 1) break; - if (left == 0) + if (left == 0) { + krb5_warnx(context, + "slave %s (version %lu) out of sync with master " + "(first version in log %lu), sending complete database", + s->name, (unsigned long)s->version, (unsigned long)ver); return send_complete (context, s, database, current_version); + } + } + + krb5_warnx(context, + "syncing slave %s from version %lu to version %lu", + s->name, (unsigned long)s->version, + (unsigned long)current_version); + + ret = krb5_data_alloc (&data, right - left + 4); + if (ret) { + krb5_warn (context, ret, "send_diffs: krb5_data_alloc"); + slave_dead(context, s); + return 1; } - krb5_data_alloc (&data, right - left + 4); krb5_storage_read (sp, (char *)data.data + 4, data.length - 4); krb5_storage_free(sp); - _krb5_put_int(data.data, FOR_YOU, 4); + sp = krb5_storage_from_data (&data); + if (sp == NULL) { + krb5_warnx (context, "send_diffs: krb5_storage_from_data"); + slave_dead(context, s); + return 1; + } + krb5_store_int32 (sp, FOR_YOU); + krb5_storage_free(sp); ret = krb5_write_priv_message(context, s->ac, &s->fd, &data); krb5_data_free(&data); if (ret) { - krb5_warn (context, ret, "krb5_write_priv_message"); - slave_dead(s); + krb5_warn (context, ret, "send_diffs: krb5_write_priv_message"); + slave_dead(context, s); return 1; } slave_seen(s); + s->version = current_version; + return 0; } static int process_msg (krb5_context context, slave *s, int log_fd, - const char *database, u_int32_t current_version) + const char *database, uint32_t current_version) { int ret = 0; krb5_data out; @@ -383,13 +537,42 @@ process_msg (krb5_context context, slave *s, int log_fd, } sp = krb5_storage_from_mem (out.data, out.length); - krb5_ret_int32 (sp, &tmp); + if (sp == NULL) { + krb5_warnx (context, "process_msg: no memory"); + krb5_data_free (&out); + return 1; + } + if (krb5_ret_int32 (sp, &tmp) != 0) { + krb5_warnx (context, "process_msg: client send too short command"); + krb5_data_free (&out); + return 1; + } switch (tmp) { case I_HAVE : - krb5_ret_int32 (sp, &tmp); - s->version = tmp; - ret = send_diffs (context, s, log_fd, database, current_version); + ret = krb5_ret_int32 (sp, &tmp); + if (ret != 0) { + krb5_warnx (context, "process_msg: client send too I_HAVE data"); + break; + } + /* new started slave that have old log */ + if (s->version == 0 && tmp != 0) { + if (s->version < tmp) { + krb5_warnx (context, "Slave %s have later version the master " + "OUT OF SYNC", s->name); + } else { + s->version = tmp; + } + } + if (tmp < s->version) { + krb5_warnx (context, "Slave claims to not have " + "version we already sent to it"); + } else { + ret = send_diffs (context, s, log_fd, database, current_version); + } + break; + case I_AM_HERE : break; + case ARE_YOU_THERE: case FOR_YOU : default : krb5_warnx (context, "Ignoring command %d", tmp); @@ -409,20 +592,60 @@ process_msg (krb5_context context, slave *s, int log_fd, #define SLAVE_STATUS "Status" #define SLAVE_SEEN "Last Seen" +static FILE * +open_stats(krb5_context context) +{ + char *statfile = NULL; + const char *fn; + FILE *f; + + if (slave_stats_file) + fn = slave_stats_file; + else { + asprintf(&statfile, "%s/slaves-stats", hdb_db_dir(context)); + fn = krb5_config_get_string_default(context, + NULL, + statfile, + "kdc", + "iprop-stats", + NULL); + } + f = fopen(fn, "w"); + if (statfile) + free(statfile); + + return f; +} + +static void +write_master_down(krb5_context context) +{ + char str[100]; + time_t t = time(NULL); + FILE *fp; + + fp = open_stats(context); + if (fp == NULL) + return; + krb5_format_time(context, t, str, sizeof(str), TRUE); + fprintf(fp, "master down at %s\n", str); + + fclose(fp); +} + static void -write_stats(krb5_context context, slave *slaves, u_int32_t current_version) +write_stats(krb5_context context, slave *slaves, uint32_t current_version) { char str[100]; rtbl_t tbl; time_t t = time(NULL); FILE *fp; - fp = fopen(slave_stats_file, "w"); + fp = open_stats(context); if (fp == NULL) return; - strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", - localtime(&t)); + krb5_format_time(context, t, str, sizeof(str), TRUE); fprintf(fp, "Status for slaves, last updated: %s\n\n", str); fprintf(fp, "Master version: %lu\n\n", (unsigned long)current_version); @@ -463,9 +686,7 @@ write_stats(krb5_context context, slave *slaves, u_int32_t current_version) else rtbl_add_column_entry(tbl, SLAVE_STATUS, "Up"); - if (strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", - localtime(&slaves->seen)) == 0) - strlcpy(str, "Unknown time", sizeof(str)); + ret = krb5_format_time(context, slaves->seen, str, sizeof(str), TRUE); rtbl_add_column_entry(tbl, SLAVE_SEEN, str); slaves = slaves->next; @@ -483,13 +704,28 @@ static int version_flag; static int help_flag; static char *keytab_str = "HDB:"; static char *database; +static char *config_file; +static char *port_str; +static int detach_from_console = 0; static struct getargs args[] = { + { "config-file", 'c', arg_string, &config_file }, { "realm", 'r', arg_string, &realm }, { "keytab", 'k', arg_string, &keytab_str, "keytab to get authentication from", "kspec" }, { "database", 'd', arg_string, &database, "database", "file"}, - { "slave-stats-file", 0, arg_string, &slave_stats_file, "file"}, + { "slave-stats-file", 0, arg_string, &slave_stats_file, + "file for slave status information", "file"}, + { "time-missing", 0, arg_string, &slave_time_missing, + "time before slave is polled for presence", "time"}, + { "time-gone", 0, arg_string, &slave_time_gone, + "time of inactivity after which a slave is considered gone", "time"}, + { "port", 0, arg_string, &port_str, + "port ipropd will listen to", "port"}, + { "detach", 0, arg_flag, &detach_from_console, + "detach from console" }, + { "hostname", 0, arg_string, &master_hostname, + "hostname of master (if not same as hostname)", "hostname" }, { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; @@ -506,11 +742,12 @@ main(int argc, char **argv) int signal_fd, listen_fd; int log_fd; slave *slaves = NULL; - u_int32_t current_version, old_version = 0; + uint32_t current_version = 0, old_version = 0; krb5_keytab keytab; - int optind; + int optidx; + char **files; - optind = krb5_program_setup(&context, argc, argv, args, num_args, NULL); + optidx = krb5_program_setup(&context, argc, argv, args, num_args, NULL); if(help_flag) krb5_std_usage(0, args, num_args); @@ -519,6 +756,32 @@ main(int argc, char **argv) exit(0); } + setup_signal(); + + if (config_file == NULL) { + asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); + if (config_file == NULL) + errx(1, "out of memory"); + } + + ret = krb5_prepend_config_files_default(config_file, &files); + if (ret) + krb5_err(context, 1, ret, "getting configuration files"); + + ret = krb5_set_config_files(context, files); + krb5_free_config_files(files); + if (ret) + krb5_err(context, 1, ret, "reading configuration files"); + + time_before_gone = parse_time (slave_time_gone, "s"); + if (time_before_gone < 0) + krb5_errx (context, 1, "couldn't parse time: %s", slave_time_gone); + time_before_missing = parse_time (slave_time_missing, "s"); + if (time_before_missing < 0) + krb5_errx (context, 1, "couldn't parse time: %s", slave_time_missing); + + if (detach_from_console) + daemon(0, 0); pidfile (NULL); krb5_openlog (context, "ipropd-master", &log_facility); krb5_set_warn_dest(context, log_facility); @@ -553,16 +816,19 @@ main(int argc, char **argv) server_context->log_context.log_file); signal_fd = make_signal_socket (context); - listen_fd = make_listen_socket (context); + listen_fd = make_listen_socket (context, port_str); - signal (SIGPIPE, SIG_IGN); + kadm5_log_get_version_fd (log_fd, ¤t_version); - for (;;) { + krb5_warnx(context, "ipropd-master started at version: %lu", + (unsigned long)current_version); + + while(exit_flag == 0){ slave *p; fd_set readset; int max_fd = 0; struct timeval to = {30, 0}; - u_int32_t vers; + uint32_t vers; if (signal_fd >= FD_SETSIZE || listen_fd >= FD_SETSIZE) krb5_errx (context, 1, "fd too large"); @@ -593,12 +859,17 @@ main(int argc, char **argv) old_version = current_version; kadm5_log_get_version_fd (log_fd, ¤t_version); - if (current_version > old_version) + if (current_version > old_version) { + krb5_warnx(context, + "Missed a signal, updating slaves %lu to %lu", + (unsigned long)old_version, + (unsigned long)current_version); for (p = slaves; p != NULL; p = p->next) { if (p->flags & SLAVE_F_DEAD) continue; send_diffs (context, p, log_fd, database, current_version); } + } } if (ret && FD_ISSET(signal_fd, &readset)) { @@ -611,28 +882,56 @@ main(int argc, char **argv) continue; } --ret; + assert(ret >= 0); old_version = current_version; kadm5_log_get_version_fd (log_fd, ¤t_version); - for (p = slaves; p != NULL; p = p->next) - send_diffs (context, p, log_fd, database, current_version); - } + if (current_version > old_version) { + krb5_warnx(context, + "Got a signal, updating slaves %lu to %lu", + (unsigned long)old_version, + (unsigned long)current_version); + for (p = slaves; p != NULL; p = p->next) + send_diffs (context, p, log_fd, database, current_version); + } else { + krb5_warnx(context, + "Got a signal, but no update in log version %lu", + (unsigned long)current_version); + } + } - for(p = slaves; ret && p != NULL; p = p->next) { + for(p = slaves; p != NULL; p = p->next) { if (p->flags & SLAVE_F_DEAD) - continue; - if (FD_ISSET(p->fd, &readset)) { + continue; + if (ret && FD_ISSET(p->fd, &readset)) { --ret; + assert(ret >= 0); if(process_msg (context, p, log_fd, database, current_version)) - slave_dead(p); + slave_dead(context, p); + } else if (slave_gone_p (p)) + slave_dead(context, p); + else if (slave_missing_p (p)) { + krb5_warnx(context, "slave %s missing, sending AYT", p->name); + send_are_you_there (context, p); } } if (ret && FD_ISSET(listen_fd, &readset)) { add_slave (context, keytab, &slaves, listen_fd); --ret; + assert(ret >= 0); } write_stats(context, slaves, current_version); } + if(exit_flag == SIGXCPU) + krb5_warnx(context, "%s CPU time limit exceeded", getprogname()); + else if(exit_flag == SIGINT || exit_flag == SIGTERM) + krb5_warnx(context, "%s terminated", getprogname()); + else + krb5_warnx(context, "%s unexpected exit reason: %d", + getprogname(), exit_flag); + + write_master_down(context); + return 0; } diff --git a/crypto/heimdal/lib/kadm5/ipropd_slave.c b/crypto/heimdal/lib/kadm5/ipropd_slave.c index abeb29d..482a3f7 100644 --- a/crypto/heimdal/lib/kadm5/ipropd_slave.c +++ b/crypto/heimdal/lib/kadm5/ipropd_slave.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,12 +33,16 @@ #include "iprop.h" -RCSID("$Id: ipropd_slave.c,v 1.27.2.1 2003/08/15 16:45:15 lha Exp $"); +RCSID("$Id: ipropd_slave.c 22211 2007-12-07 19:27:27Z lha $"); static krb5_log_facility *log_facility; +static char *server_time_lost = "5 min"; +static int time_before_lost; +const char *slave_str = NULL; static int -connect_to_master (krb5_context context, const char *master) +connect_to_master (krb5_context context, const char *master, + const char *port_str) { int fd; struct sockaddr_in addr; @@ -49,8 +53,23 @@ connect_to_master (krb5_context context, const char *master) krb5_err (context, 1, errno, "socket AF_INET"); memset (&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = krb5_getportbyname (context, - IPROP_SERVICE, "tcp", IPROP_PORT); + if (port_str) { + addr.sin_port = krb5_getportbyname (context, + port_str, "tcp", + 0); + if (addr.sin_port == 0) { + char *ptr; + long port; + + port = strtol (port_str, &ptr, 10); + if (port == 0 && ptr == port_str) + krb5_errx (context, 1, "bad port `%s'", port_str); + addr.sin_port = htons(port); + } + } else { + addr.sin_port = krb5_getportbyname (context, IPROP_SERVICE, + "tcp", IPROP_PORT); + } he = roken_gethostbyname (master); if (he == NULL) krb5_errx (context, 1, "gethostbyname: %s", hstrerror(h_errno)); @@ -62,12 +81,12 @@ connect_to_master (krb5_context context, const char *master) static void get_creds(krb5_context context, const char *keytab_str, - krb5_ccache *cache, const char *host) + krb5_ccache *cache, const char *serverhost) { krb5_keytab keytab; krb5_principal client; krb5_error_code ret; - krb5_get_init_creds_opt init_opts; + krb5_get_init_creds_opt *init_opts; krb5_creds creds; char *server; char keytab_buf[256]; @@ -83,19 +102,22 @@ get_creds(krb5_context context, const char *keytab_str, if(ret) krb5_err(context, 1, ret, "%s", keytab_str); - ret = krb5_sname_to_principal (context, NULL, IPROP_NAME, + + ret = krb5_sname_to_principal (context, slave_str, IPROP_NAME, KRB5_NT_SRV_HST, &client); if (ret) krb5_err(context, 1, ret, "krb5_sname_to_principal"); - krb5_get_init_creds_opt_init(&init_opts); + ret = krb5_get_init_creds_opt_alloc(context, &init_opts); + if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); - asprintf (&server, "%s/%s", IPROP_NAME, host); + asprintf (&server, "%s/%s", IPROP_NAME, serverhost); if (server == NULL) krb5_errx (context, 1, "malloc: no memory"); ret = krb5_get_init_creds_keytab(context, &creds, client, keytab, - 0, server, &init_opts); + 0, server, init_opts); free (server); + krb5_get_init_creds_opt_free(context, init_opts); if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds"); ret = krb5_kt_close(context, keytab); @@ -113,12 +135,12 @@ get_creds(krb5_context context, const char *keytab_str, static void ihave (krb5_context context, krb5_auth_context auth_context, - int fd, u_int32_t version) + int fd, uint32_t version) { int ret; u_char buf[8]; krb5_storage *sp; - krb5_data data, priv_data; + krb5_data data; sp = krb5_storage_from_mem (buf, 8); krb5_store_int32 (sp, I_HAVE); @@ -127,15 +149,9 @@ ihave (krb5_context context, krb5_auth_context auth_context, data.length = 8; data.data = buf; - ret = krb5_mk_priv (context, auth_context, &data, &priv_data, NULL); + ret = krb5_write_priv_message(context, auth_context, &fd, &data); if (ret) - krb5_err (context, 1, ret, "krb_mk_priv"); - - ret = krb5_write_message (context, &fd, &priv_data); - if (ret) - krb5_err (context, 1, ret, "krb5_write_message"); - - krb5_data_free (&priv_data); + krb5_err (context, 1, ret, "krb5_write_priv_message"); } static void @@ -146,8 +162,12 @@ receive_loop (krb5_context context, int ret; off_t left, right; void *buf; - int32_t vers; + int32_t vers, vers2; + ssize_t sret; + /* + * Seek to the current version of the local database. + */ do { int32_t len, timestamp, tmp; enum kadm_ops op; @@ -159,43 +179,98 @@ receive_loop (krb5_context context, op = tmp; krb5_ret_int32 (sp, &len); if (vers <= server_context->log_context.version) - krb5_storage_seek(sp, len, SEEK_CUR); + krb5_storage_seek(sp, len + 8, SEEK_CUR); } while(vers <= server_context->log_context.version); + /* + * Read up rest of the entires into the memory... + */ left = krb5_storage_seek (sp, -16, SEEK_CUR); right = krb5_storage_seek (sp, 0, SEEK_END); buf = malloc (right - left); - if (buf == NULL && (right - left) != 0) { - krb5_warnx (context, "malloc: no memory"); - return; - } + if (buf == NULL && (right - left) != 0) + krb5_errx (context, 1, "malloc: no memory"); + + /* + * ...and then write them out to the on-disk log. + */ krb5_storage_seek (sp, left, SEEK_SET); krb5_storage_read (sp, buf, right - left); - write (server_context->log_context.log_fd, buf, right-left); - fsync (server_context->log_context.log_fd); + sret = write (server_context->log_context.log_fd, buf, right-left); + if (sret != right - left) + krb5_err(context, 1, errno, "Failed to write log to disk"); + ret = fsync (server_context->log_context.log_fd); + if (ret) + krb5_err(context, 1, errno, "Failed to sync log to disk"); free (buf); + /* + * Go back to the startpoint and start to commit the entires to + * the database. + */ krb5_storage_seek (sp, left, SEEK_SET); for(;;) { - int32_t len, timestamp, tmp; + int32_t len, len2, timestamp, tmp; + off_t cur, cur2; enum kadm_ops op; if(krb5_ret_int32 (sp, &vers) != 0) break; - krb5_ret_int32 (sp, ×tamp); - krb5_ret_int32 (sp, &tmp); + ret = krb5_ret_int32 (sp, ×tamp); + if (ret) krb5_errx(context, 1, "entry %ld: too short", (long)vers); + ret = krb5_ret_int32 (sp, &tmp); + if (ret) krb5_errx(context, 1, "entry %ld: too short", (long)vers); op = tmp; - krb5_ret_int32 (sp, &len); + ret = krb5_ret_int32 (sp, &len); + if (ret) krb5_errx(context, 1, "entry %ld: too short", (long)vers); + if (len < 0) + krb5_errx(context, 1, "log is corrupted, " + "negative length of entry version %ld: %ld", + (long)vers, (long)len); + cur = krb5_storage_seek(sp, 0, SEEK_CUR); + + krb5_warnx (context, "replaying entry %d", (int)vers); ret = kadm5_log_replay (server_context, op, vers, len, sp); - if (ret) - krb5_warn (context, ret, "kadm5_log_replay"); - else - server_context->log_context.version = vers; - krb5_storage_seek (sp, 8, SEEK_CUR); + if (ret) { + char *s = krb5_get_error_message(server_context->context, ret); + krb5_warnx (context, + "kadm5_log_replay: %ld. Lost entry entry, " + "Database out of sync ?: %s (%d)", + (long)vers, s ? s : "unknown error", ret); + krb5_xfree(s); + } + + { + /* + * Make sure the krb5_log_replay does the right thing wrt + * reading out data from the sp. + */ + cur2 = krb5_storage_seek(sp, 0, SEEK_CUR); + if (cur + len != cur2) + krb5_errx(context, 1, + "kadm5_log_reply version: %ld didn't read the whole entry", + (long)vers); + } + + if (krb5_ret_int32 (sp, &len2) != 0) + krb5_errx(context, 1, "entry %ld: postamble too short", (long)vers); + if(krb5_ret_int32 (sp, &vers2) != 0) + krb5_errx(context, 1, "entry %ld: postamble too short", (long)vers); + + if (len != len2) + krb5_errx(context, 1, "entry %ld: len != len2", (long)vers); + if (vers != vers2) + krb5_errx(context, 1, "entry %ld: vers != vers2", (long)vers); } + + /* + * Update version + */ + + server_context->log_context.version = vers; } static void @@ -205,20 +280,45 @@ receive (krb5_context context, { int ret; - ret = server_context->db->open(context, - server_context->db, - O_RDWR | O_CREAT, 0600); + ret = server_context->db->hdb_open(context, + server_context->db, + O_RDWR | O_CREAT, 0600); if (ret) krb5_err (context, 1, ret, "db->open"); receive_loop (context, sp, server_context); - ret = server_context->db->close (context, server_context->db); + ret = server_context->db->hdb_close (context, server_context->db); if (ret) krb5_err (context, 1, ret, "db->close"); } static void +send_im_here (krb5_context context, int fd, + krb5_auth_context auth_context) +{ + krb5_storage *sp; + krb5_data data; + int ret; + + ret = krb5_data_alloc (&data, 4); + if (ret) + krb5_err (context, 1, ret, "send_im_here"); + + sp = krb5_storage_from_data (&data); + if (sp == NULL) + krb5_errx (context, 1, "krb5_storage_from_data"); + krb5_store_int32(sp, I_AM_HERE); + krb5_storage_free(sp); + + ret = krb5_write_priv_message(context, auth_context, &fd, &data); + krb5_data_free(&data); + + if (ret) + krb5_err (context, 1, ret, "krb5_write_priv_message"); +} + +static void receive_everything (krb5_context context, int fd, kadm5_server_context *server_context, krb5_auth_context auth_context) @@ -227,12 +327,14 @@ receive_everything (krb5_context context, int fd, krb5_data data; int32_t vno; int32_t opcode; - unsigned long tmp; + krb5_storage *sp; char *dbname; HDB *mydb; - asprintf(&dbname, "%s-NEW", server_context->db->name); + krb5_warnx(context, "receive complete database"); + + asprintf(&dbname, "%s-NEW", server_context->db->hdb_name); ret = hdb_create(context, &mydb, dbname); if(ret) krb5_err(context,1, ret, "hdb_create"); @@ -245,47 +347,54 @@ receive_everything (krb5_context context, int fd, /* I really want to use O_EXCL here, but given that I can't easily clean up on error, I won't */ - ret = mydb->open(context, mydb, O_RDWR | O_CREAT | O_TRUNC, 0600); - + ret = mydb->hdb_open(context, mydb, O_RDWR | O_CREAT | O_TRUNC, 0600); if (ret) krb5_err (context, 1, ret, "db->open"); + sp = NULL; do { - krb5_storage *sp; - ret = krb5_read_priv_message(context, auth_context, &fd, &data); if (ret) krb5_err (context, 1, ret, "krb5_read_priv_message"); sp = krb5_storage_from_data (&data); + if (sp == NULL) + krb5_errx (context, 1, "krb5_storage_from_data"); krb5_ret_int32 (sp, &opcode); if (opcode == ONE_PRINC) { krb5_data fake_data; - hdb_entry entry; + hdb_entry_ex entry; + + krb5_storage_free(sp); fake_data.data = (char *)data.data + 4; fake_data.length = data.length - 4; - ret = hdb_value2entry (context, &fake_data, &entry); + memset(&entry, 0, sizeof(entry)); + + ret = hdb_value2entry (context, &fake_data, &entry.entry); if (ret) krb5_err (context, 1, ret, "hdb_value2entry"); - ret = mydb->store(server_context->context, - mydb, - 0, &entry); + ret = mydb->hdb_store(server_context->context, + mydb, + 0, &entry); if (ret) krb5_err (context, 1, ret, "hdb_store"); hdb_free_entry (context, &entry); krb5_data_free (&data); - } + } else if (opcode == NOW_YOU_HAVE) + ; + else + krb5_errx (context, 1, "strange opcode %d", opcode); } while (opcode == ONE_PRINC); if (opcode != NOW_YOU_HAVE) krb5_errx (context, 1, "receive_everything: strange %d", opcode); - _krb5_get_int ((char *)data.data + 4, &tmp, 4); - vno = tmp; + krb5_ret_int32 (sp, &vno); + krb5_storage_free(sp); ret = kadm5_log_reinit (server_context); if (ret) @@ -301,41 +410,48 @@ receive_everything (krb5_context context, int fd, krb5_data_free (&data); - ret = mydb->rename (context, mydb, server_context->db->name); + ret = mydb->hdb_rename (context, mydb, server_context->db->hdb_name); if (ret) krb5_err (context, 1, ret, "db->rename"); - ret = mydb->close (context, mydb); + ret = mydb->hdb_close (context, mydb); if (ret) krb5_err (context, 1, ret, "db->close"); - ret = mydb->destroy (context, mydb); + ret = mydb->hdb_destroy (context, mydb); if (ret) krb5_err (context, 1, ret, "db->destroy"); + + krb5_warnx(context, "receive complete database, version %ld", (long)vno); } +static char *config_file; static char *realm; static int version_flag; static int help_flag; static char *keytab_str; +static char *port_str; +static int detach_from_console = 0; static struct getargs args[] = { + { "config-file", 'c', arg_string, &config_file }, { "realm", 'r', arg_string, &realm }, { "keytab", 'k', arg_string, &keytab_str, "keytab to get authentication from", "kspec" }, + { "time-lost", 0, arg_string, &server_time_lost, + "time before server is considered lost", "time" }, + { "port", 0, arg_string, &port_str, + "port ipropd-slave will connect to", "port"}, + { "detach", 0, arg_flag, &detach_from_console, + "detach from console" }, + { "hostname", 0, arg_string, &slave_str, + "hostname of slave (if not same as hostname)", "hostname" }, { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; static int num_args = sizeof(args) / sizeof(args[0]); -static void -usage (int code, struct getargs *args, int num_args) -{ - arg_printusage (args, num_args, NULL, "master"); - exit (code); -} - int main(int argc, char **argv) { @@ -348,27 +464,47 @@ main(int argc, char **argv) int master_fd; krb5_ccache ccache; krb5_principal server; + char **files; + int optidx; - int optind; const char *master; - optind = krb5_program_setup(&context, argc, argv, args, num_args, usage); + optidx = krb5_program_setup(&context, argc, argv, args, num_args, NULL); if(help_flag) - usage (0, args, num_args); + krb5_std_usage(0, args, num_args); if(version_flag) { print_version(NULL); exit(0); } - argc -= optind; - argv += optind; + setup_signal(); + + if (config_file == NULL) { + asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); + if (config_file == NULL) + errx(1, "out of memory"); + } + + ret = krb5_prepend_config_files_default(config_file, &files); + if (ret) + krb5_err(context, 1, ret, "getting configuration files"); + + ret = krb5_set_config_files(context, files); + krb5_free_config_files(files); + if (ret) + krb5_err(context, 1, ret, "reading configuration files"); + + argc -= optidx; + argv += optidx; if (argc != 1) - usage (1, args, num_args); + krb5_std_usage(1, args, num_args); master = argv[0]; + if (detach_from_console) + daemon(0, 0); pidfile (NULL); krb5_openlog (context, "ipropd-slave", &log_facility); krb5_set_warn_dest(context, log_facility); @@ -377,6 +513,10 @@ main(int argc, char **argv) if(ret) krb5_err(context, 1, ret, "krb5_kt_register"); + time_before_lost = parse_time (server_time_lost, "s"); + if (time_before_lost < 0) + krb5_errx (context, 1, "couldn't parse time: %s", server_time_lost); + memset(&conf, 0, sizeof(conf)); if(realm) { conf.mask |= KADM5_CONFIG_REALM; @@ -399,7 +539,7 @@ main(int argc, char **argv) get_creds(context, keytab_str, &ccache, master); - master_fd = connect_to_master (context, master); + master_fd = connect_to_master (context, master, port_str); ret = krb5_sname_to_principal (context, master, IPROP_NAME, KRB5_NT_SRV_HST, &server); @@ -414,14 +554,39 @@ main(int argc, char **argv) if (ret) krb5_err (context, 1, ret, "krb5_sendauth"); + krb5_warnx(context, "ipropd-slave started at version: %ld", + (long)server_context->log_context.version); + ihave (context, auth_context, master_fd, server_context->log_context.version); - for (;;) { - int ret; + while (exit_flag == 0) { krb5_data out; krb5_storage *sp; int32_t tmp; + fd_set readset; + struct timeval to; + + if (master_fd >= FD_SETSIZE) + krb5_errx (context, 1, "fd too large"); + + FD_ZERO(&readset); + FD_SET(master_fd, &readset); + + to.tv_sec = time_before_lost; + to.tv_usec = 0; + + ret = select (master_fd + 1, + &readset, NULL, NULL, &to); + if (ret < 0) { + if (errno == EINTR) + continue; + else + krb5_err (context, 1, errno, "select"); + } + if (ret == 0) + krb5_errx (context, 1, "server didn't send a message " + "in %d seconds", time_before_lost); ret = krb5_read_priv_message(context, auth_context, &master_fd, &out); @@ -440,9 +605,13 @@ main(int argc, char **argv) receive_everything (context, master_fd, server_context, auth_context); break; + case ARE_YOU_THERE : + send_im_here (context, master_fd, auth_context); + break; case NOW_YOU_HAVE : case I_HAVE : case ONE_PRINC : + case I_AM_HERE : default : krb5_warnx (context, "Ignoring command %d", tmp); break; @@ -451,5 +620,13 @@ main(int argc, char **argv) krb5_data_free (&out); } + if(exit_flag == SIGXCPU) + krb5_warnx(context, "%s CPU time limit exceeded", getprogname()); + else if(exit_flag == SIGINT || exit_flag == SIGTERM) + krb5_warnx(context, "%s terminated", getprogname()); + else + krb5_warnx(context, "%s unexpected exit reason: %d", + getprogname(), exit_flag); + return 0; } diff --git a/crypto/heimdal/lib/kadm5/kadm5-private.h b/crypto/heimdal/lib/kadm5/kadm5-private.h index 63e579f..56b2b32 100644 --- a/crypto/heimdal/lib/kadm5/kadm5-private.h +++ b/crypto/heimdal/lib/kadm5/kadm5-private.h @@ -18,6 +18,17 @@ _kadm5_bump_pw_expire ( kadm5_server_context */*context*/, hdb_entry */*ent*/); +krb5_error_code +_kadm5_c_get_cred_cache ( + krb5_context /*context*/, + const char */*client_name*/, + const char */*server_name*/, + const char */*password*/, + krb5_prompter_fct /*prompter*/, + const char */*keytab*/, + krb5_ccache /*ccache*/, + krb5_ccache */*ret_cache*/); + kadm5_ret_t _kadm5_c_init_context ( kadm5_client_context **/*ctx*/, @@ -49,7 +60,7 @@ _kadm5_error_code (kadm5_ret_t /*code*/); void _kadm5_free_keys ( - kadm5_server_context */*context*/, + krb5_context /*context*/, int /*len*/, Key */*keys*/); @@ -66,7 +77,7 @@ _kadm5_marshal_params ( kadm5_ret_t _kadm5_privs_to_string ( - u_int32_t /*privs*/, + uint32_t /*privs*/, char */*string*/, size_t /*len*/); @@ -114,17 +125,17 @@ _kadm5_set_modifier ( kadm5_ret_t _kadm5_setup_entry ( kadm5_server_context */*context*/, - hdb_entry */*ent*/, - u_int32_t /*mask*/, + hdb_entry_ex */*ent*/, + uint32_t /*mask*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*princ_mask*/, + uint32_t /*princ_mask*/, kadm5_principal_ent_t /*def*/, - u_int32_t /*def_mask*/); + uint32_t /*def_mask*/); kadm5_ret_t _kadm5_string_to_privs ( const char */*s*/, - u_int32_t* /*privs*/); + uint32_t* /*privs*/); kadm5_ret_t _kadm5_unmarshal_params ( @@ -136,7 +147,7 @@ kadm5_ret_t kadm5_c_chpass_principal ( void */*server_handle*/, krb5_principal /*princ*/, - char */*password*/); + const char */*password*/); kadm5_ret_t kadm5_c_chpass_principal_with_key ( @@ -149,8 +160,8 @@ kadm5_ret_t kadm5_c_create_principal ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/, - char */*password*/); + uint32_t /*mask*/, + const char */*password*/); kadm5_ret_t kadm5_c_delete_principal ( @@ -168,19 +179,19 @@ kadm5_c_get_principal ( void */*server_handle*/, krb5_principal /*princ*/, kadm5_principal_ent_t /*out*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_c_get_principals ( void */*server_handle*/, - const char */*exp*/, + const char */*expression*/, char ***/*princs*/, int */*count*/); kadm5_ret_t kadm5_c_get_privs ( void */*server_handle*/, - u_int32_t */*privs*/); + uint32_t */*privs*/); kadm5_ret_t kadm5_c_init_with_creds ( @@ -249,7 +260,7 @@ kadm5_ret_t kadm5_c_modify_principal ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_c_randkey_principal ( @@ -280,17 +291,18 @@ kadm5_log_end (kadm5_server_context */*context*/); kadm5_ret_t kadm5_log_foreach ( kadm5_server_context */*context*/, - void (*/*func*/)(kadm5_server_context *server_context, u_int32_t ver, time_t timestamp, enum kadm_ops op, u_int32_t len, krb5_storage *sp)); + void (*/*func*/)(kadm5_server_context *server_context, uint32_t ver, time_t timestamp, enum kadm_ops op, uint32_t len, krb5_storage *, void *), + void */*ctx*/); kadm5_ret_t kadm5_log_get_version ( kadm5_server_context */*context*/, - u_int32_t */*ver*/); + uint32_t */*ver*/); kadm5_ret_t kadm5_log_get_version_fd ( int /*fd*/, - u_int32_t */*ver*/); + uint32_t */*ver*/); krb5_storage * kadm5_log_goto_end (int /*fd*/); @@ -302,18 +314,19 @@ kadm5_ret_t kadm5_log_modify ( kadm5_server_context */*context*/, hdb_entry */*ent*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_log_nop (kadm5_server_context */*context*/); kadm5_ret_t kadm5_log_previous ( + krb5_context /*context*/, krb5_storage */*sp*/, - u_int32_t */*ver*/, + uint32_t */*ver*/, time_t */*timestamp*/, enum kadm_ops */*op*/, - u_int32_t */*len*/); + uint32_t */*len*/); kadm5_ret_t kadm5_log_reinit (kadm5_server_context */*context*/); @@ -328,49 +341,17 @@ kadm5_ret_t kadm5_log_replay ( kadm5_server_context */*context*/, enum kadm_ops /*op*/, - u_int32_t /*ver*/, - u_int32_t /*len*/, - krb5_storage */*sp*/); - -kadm5_ret_t -kadm5_log_replay_create ( - kadm5_server_context */*context*/, - u_int32_t /*ver*/, - u_int32_t /*len*/, - krb5_storage */*sp*/); - -kadm5_ret_t -kadm5_log_replay_delete ( - kadm5_server_context */*context*/, - u_int32_t /*ver*/, - u_int32_t /*len*/, - krb5_storage */*sp*/); - -kadm5_ret_t -kadm5_log_replay_modify ( - kadm5_server_context */*context*/, - u_int32_t /*ver*/, - u_int32_t /*len*/, - krb5_storage */*sp*/); - -kadm5_ret_t -kadm5_log_replay_nop ( - kadm5_server_context */*context*/, - u_int32_t /*ver*/, - u_int32_t /*len*/, - krb5_storage */*sp*/); - -kadm5_ret_t -kadm5_log_replay_rename ( - kadm5_server_context */*context*/, - u_int32_t /*ver*/, - u_int32_t /*len*/, + uint32_t /*ver*/, + uint32_t /*len*/, krb5_storage */*sp*/); kadm5_ret_t kadm5_log_set_version ( kadm5_server_context */*context*/, - u_int32_t /*vno*/); + uint32_t /*vno*/); + +const char * +kadm5_log_signal_socket (krb5_context /*context*/); kadm5_ret_t kadm5_log_truncate (kadm5_server_context */*server_context*/); @@ -379,13 +360,13 @@ kadm5_ret_t kadm5_s_chpass_principal ( void */*server_handle*/, krb5_principal /*princ*/, - char */*password*/); + const char */*password*/); kadm5_ret_t kadm5_s_chpass_principal_cond ( void */*server_handle*/, krb5_principal /*princ*/, - char */*password*/); + const char */*password*/); kadm5_ret_t kadm5_s_chpass_principal_with_key ( @@ -398,14 +379,14 @@ kadm5_ret_t kadm5_s_create_principal ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/, - char */*password*/); + uint32_t /*mask*/, + const char */*password*/); kadm5_ret_t kadm5_s_create_principal_with_key ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_s_delete_principal ( @@ -423,19 +404,19 @@ kadm5_s_get_principal ( void */*server_handle*/, krb5_principal /*princ*/, kadm5_principal_ent_t /*out*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_s_get_principals ( void */*server_handle*/, - const char */*exp*/, + const char */*expression*/, char ***/*princs*/, int */*count*/); kadm5_ret_t kadm5_s_get_privs ( void */*server_handle*/, - u_int32_t */*privs*/); + uint32_t */*privs*/); kadm5_ret_t kadm5_s_init_with_creds ( @@ -504,7 +485,7 @@ kadm5_ret_t kadm5_s_modify_principal ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_s_randkey_principal ( diff --git a/crypto/heimdal/lib/kadm5/kadm5-protos.h b/crypto/heimdal/lib/kadm5/kadm5-protos.h index c0a0cce..eebae95 100644 --- a/crypto/heimdal/lib/kadm5/kadm5-protos.h +++ b/crypto/heimdal/lib/kadm5/kadm5-protos.h @@ -4,6 +4,36 @@ #include <stdarg.h> +#ifdef __cplusplus +extern "C" { +#endif + +kadm5_ret_t +kadm5_ad_init_with_password ( + const char */*client_name*/, + const char */*password*/, + const char */*service_name*/, + kadm5_config_params */*realm_params*/, + unsigned long /*struct_version*/, + unsigned long /*api_version*/, + void **/*server_handle*/); + +kadm5_ret_t +kadm5_ad_init_with_password_ctx ( + krb5_context /*context*/, + const char */*client_name*/, + const char */*password*/, + const char */*service_name*/, + kadm5_config_params */*realm_params*/, + unsigned long /*struct_version*/, + unsigned long /*api_version*/, + void **/*server_handle*/); + +krb5_error_code +kadm5_add_passwd_quality_verifier ( + krb5_context /*context*/, + const char */*check_library*/); + const char * kadm5_check_password_quality ( krb5_context /*context*/, @@ -14,7 +44,7 @@ kadm5_ret_t kadm5_chpass_principal ( void */*server_handle*/, krb5_principal /*princ*/, - char */*password*/); + const char */*password*/); kadm5_ret_t kadm5_chpass_principal_with_key ( @@ -27,8 +57,8 @@ kadm5_ret_t kadm5_create_principal ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/, - char */*password*/); + uint32_t /*mask*/, + const char */*password*/); kadm5_ret_t kadm5_delete_principal ( @@ -63,19 +93,19 @@ kadm5_get_principal ( void */*server_handle*/, krb5_principal /*princ*/, kadm5_principal_ent_t /*out*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_get_principals ( void */*server_handle*/, - const char */*exp*/, + const char */*expression*/, char ***/*princs*/, int */*count*/); kadm5_ret_t kadm5_get_privs ( void */*server_handle*/, - u_int32_t */*privs*/); + uint32_t */*privs*/); kadm5_ret_t kadm5_init_with_creds ( @@ -144,7 +174,7 @@ kadm5_ret_t kadm5_modify_principal ( void */*server_handle*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_randkey_principal ( @@ -173,7 +203,7 @@ kadm5_ret_t kadm5_ret_principal_ent_mask ( krb5_storage */*sp*/, kadm5_principal_ent_t /*princ*/, - u_int32_t */*mask*/); + uint32_t */*mask*/); kadm5_ret_t kadm5_ret_tl_data ( @@ -200,11 +230,15 @@ kadm5_ret_t kadm5_store_principal_ent_mask ( krb5_storage */*sp*/, kadm5_principal_ent_t /*princ*/, - u_int32_t /*mask*/); + uint32_t /*mask*/); kadm5_ret_t kadm5_store_tl_data ( krb5_storage */*sp*/, krb5_tl_data */*tl*/); +#ifdef __cplusplus +} +#endif + #endif /* __kadm5_protos_h__ */ diff --git a/crypto/heimdal/lib/kadm5/kadm5-pwcheck.h b/crypto/heimdal/lib/kadm5/kadm5-pwcheck.h new file mode 100644 index 0000000..96f3f18 --- /dev/null +++ b/crypto/heimdal/lib/kadm5/kadm5-pwcheck.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: kadm5-pwcheck.h 15489 2005-06-17 06:45:52Z lha $ */ + +#ifndef KADM5_PWCHECK_H +#define KADM5_PWCHECK_H 1 + + +#define KADM5_PASSWD_VERSION_V0 0 +#define KADM5_PASSWD_VERSION_V1 1 + +typedef const char* (*kadm5_passwd_quality_check_func_v0)(krb5_context, + krb5_principal, + krb5_data*); + +/* + * The 4th argument, is a tuning parameter for the quality check + * function, the lib/caller will providing it for the password quality + * module. + */ + +typedef int +(*kadm5_passwd_quality_check_func)(krb5_context context, + krb5_principal principal, + krb5_data *password, + const char *tuning, + char *message, + size_t length); + +struct kadm5_pw_policy_check_func { + const char *name; + kadm5_passwd_quality_check_func func; +}; + +struct kadm5_pw_policy_verifier { + const char *name; + int version; + const char *vendor; + const struct kadm5_pw_policy_check_func *funcs; +}; + +#endif /* KADM5_PWCHECK_H */ diff --git a/crypto/heimdal/lib/kadm5/kadm5_err.et b/crypto/heimdal/lib/kadm5/kadm5_err.et index 674fbe7..1ac624a 100644 --- a/crypto/heimdal/lib/kadm5/kadm5_err.et +++ b/crypto/heimdal/lib/kadm5/kadm5_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: kadm5_err.et,v 1.5 2001/12/06 17:02:55 assar Exp $" +id "$Id: kadm5_err.et 16683 2006-02-02 13:11:47Z lha $" error_table ovk kadm5 @@ -33,7 +33,7 @@ error_code BAD_MIN_PASS_LIFE, "Password minimum life is greater than password ma error_code PASS_Q_TOOSHORT, "Password is too short" error_code PASS_Q_CLASS, "Password does not contain enough character classes" error_code PASS_Q_DICT, "Password is in the password dictionary" -error_code PASS_REUSE, "Can't resuse password" +error_code PASS_REUSE, "Can't reuse password" error_code PASS_TOOSOON, "Current password's minimum life has not expired" error_code POLICY_REF, "Policy is in use" error_code INIT, "Connection to server already initialized" @@ -54,6 +54,6 @@ error_code BAD_CLIENT_PARAMS, "Invalid configuration parameter for remote KADM5 error_code BAD_SERVER_PARAMS, "Invalid configuration parameter for local KADM5 client." error_code AUTH_LIST, "Operation requires `list' privilege" error_code AUTH_CHANGEPW, "Operation requires `change-password' privilege" -error_code BAD_TL_TYPE, "Programmer error! Invalid tagged data list element type" +error_code BAD_TL_TYPE, "Invalid tagged data list element type" error_code MISSING_CONF_PARAMS, "Required parameters in kdc.conf missing" error_code BAD_SERVER_NAME, "Bad krb5 admin server hostname" diff --git a/crypto/heimdal/lib/kadm5/kadm5_locl.h b/crypto/heimdal/lib/kadm5/kadm5_locl.h index 6f634ed..c79e644 100644 --- a/crypto/heimdal/lib/kadm5/kadm5_locl.h +++ b/crypto/heimdal/lib/kadm5/kadm5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: kadm5_locl.h,v 1.23 2000/07/08 11:57:40 assar Exp $ */ +/* $Id: kadm5_locl.h 8579 2000-07-08 11:57:40Z assar $ */ #ifndef __KADM5_LOCL_H__ #define __KADM5_LOCL_H__ diff --git a/crypto/heimdal/lib/kadm5/kadm5_pwcheck.3 b/crypto/heimdal/lib/kadm5/kadm5_pwcheck.3 new file mode 100644 index 0000000..ee045c9 --- /dev/null +++ b/crypto/heimdal/lib/kadm5/kadm5_pwcheck.3 @@ -0,0 +1,146 @@ +.\" Copyright (c) 2003 - 2004 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: kadm5_pwcheck.3 15237 2005-05-25 13:16:27Z lha $ +.\" +.Dd February 29, 2004 +.Dt KADM5_PWCHECK 3 +.Os HEIMDAL +.Sh NAME +.Nm krb5_pwcheck , +.Nm kadm5_setup_passwd_quality_check , +.Nm kadm5_add_passwd_quality_verifier , +.Nm kadm5_check_password_quality +.Nd Heimdal warning and error functions +.Sh LIBRARY +Kerberos 5 Library (libkadm5srv, -lkadm5srv) +.Sh SYNOPSIS +.In kadm5-protos.h +.In kadm5-pwcheck.h +.Ft void +.Fo kadm5_setup_passwd_quality_check +.Fa "krb5_context context" +.Fa "const char *check_library" +.Fa "const char *check_function" +.Fc +.Ft "krb5_error_code" +.Fo kadm5_add_passwd_quality_verifier +.Fa "krb5_context context" +.Fa "const char *check_library" +.Fc +.Ft "const char *" +.Fo kadm5_check_password_quality +.Fa "krb5_context context" +.Fa "krb5_principal principal" +.Fa "krb5_data *pwd_data" +.Fc +.Ft int +.Fo "(*kadm5_passwd_quality_check_func)" +.Fa "krb5_context context" +.Fa "krb5_principal principal" +.Fa "krb5_data *password" +.Fa "const char *tuning" +.Fa "char *message" +.Fa "size_t length" +.Fc +.Sh DESCRIPTION +These functions perform the quality check for the heimdal database +library. +.Pp +There are two versions of the shared object API; the old version (0) +is deprecated, but still supported. The new version (1) supports +multiple password quality checking modules in the same shared object. +See below for details. +.Pp +The password quality checker will run over all tests that are +configured by the user. +.Pp +Module names are of the form +.Ql vendor:test-name +or, if the the test name is unique enough, just +.Ql test-name . +.Sh IMPLEMENTING A PASSWORD QUALITY CHECKING SHARED OBJECT +(This refers to the version 1 API only.) +.Pp +Module shared objects may conveniently be compiled and linked with +.Xr libtool 1 . +An object needs to export a symbol called +.Ql kadm5_password_verifier +of the type +.Ft "struct kadm5_pw_policy_verifier" . +.Pp +Its +.Ft name +and +.Ft vendor +fields should be contain the obvious information and +.Ft version +should be +.Dv KADM5_PASSWD_VERSION_V1 . +.Ft funcs +contains an array of +.Ft "struct kadm5_pw_policy_check_func" +structures that is terminated with an entry whose +.Ft name +component is +.Dv NULL . +The +.Ft func +Fields of the array elements are functions that are exported by the +module to be called to check the password. They get the following +arguments: the Kerberos context, principal, password, a tuning parameter, and +a pointer to a message buffer and its length. The tuning parameter +for the quality check function is currently always +.Dv NULL . +If the password is acceptable, the function returns zero. Otherwise +it returns non-zero and fills in the message buffer with an +appropriate explanation. +.Sh RUNNING THE CHECKS +.Nm kadm5_setup_passwd_quality_check +sets up type 0 checks. It sets up all type 0 checks defined in +.Xr krb5.conf 5 +if called with the last two arguments null. +.Pp +.Nm kadm5_add_passwd_quality_verifier +sets up type 1 checks. It sets up all type 1 tests defined in +.Xr krb5.conf 5 +if called with a null second argument. +.Nm kadm5_check_password_quality +runs the checks in the order in which they are defined in +.Xr krb5.conf 5 +and the order in which they occur in a +module's +.Ft funcs +array until one returns non-zero. +.Sh SEE ALSO +.Xr libtool 1 , +.Xr krb5 3 , +.Xr krb5.conf 5 diff --git a/crypto/heimdal/lib/kadm5/keys.c b/crypto/heimdal/lib/kadm5/keys.c index 3ae21ab..2521fae 100644 --- a/crypto/heimdal/lib/kadm5/keys.c +++ b/crypto/heimdal/lib/kadm5/keys.c @@ -33,29 +33,17 @@ #include "kadm5_locl.h" -RCSID("$Id: keys.c,v 1.1 2000/07/22 05:53:02 assar Exp $"); +RCSID("$Id: keys.c 14297 2004-10-11 23:50:25Z lha $"); /* * free all the memory used by (len, keys) */ void -_kadm5_free_keys (kadm5_server_context *context, +_kadm5_free_keys (krb5_context context, int len, Key *keys) { - int i; - - for (i = 0; i < len; ++i) { - free (keys[i].mkvno); - keys[i].mkvno = NULL; - if (keys[i].salt != NULL) { - free_Salt(keys[i].salt); - free(keys[i].salt); - keys[i].salt = NULL; - } - krb5_free_keyblock_contents(context->context, &keys[i].key); - } - free (keys); + hdb_free_keys(context, len, keys); } /* diff --git a/crypto/heimdal/lib/kadm5/log.c b/crypto/heimdal/lib/kadm5/log.c index 8ea3ca9..5c4aaef 100644 --- a/crypto/heimdal/lib/kadm5/log.c +++ b/crypto/heimdal/lib/kadm5/log.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,8 +32,9 @@ */ #include "kadm5_locl.h" +#include "heim_threads.h" -RCSID("$Id: log.c,v 1.20 2003/04/16 17:56:55 lha Exp $"); +RCSID("$Id: log.c 22211 2007-12-07 19:27:27Z lha $"); /* * A log record consists of: @@ -50,7 +51,7 @@ RCSID("$Id: log.c,v 1.20 2003/04/16 17:56:55 lha Exp $"); kadm5_ret_t kadm5_log_get_version_fd (int fd, - u_int32_t *ver) + uint32_t *ver) { int ret; krb5_storage *sp; @@ -73,13 +74,13 @@ kadm5_log_get_version_fd (int fd, } kadm5_ret_t -kadm5_log_get_version (kadm5_server_context *context, u_int32_t *ver) +kadm5_log_get_version (kadm5_server_context *context, uint32_t *ver) { return kadm5_log_get_version_fd (context->log_context.log_fd, ver); } kadm5_ret_t -kadm5_log_set_version (kadm5_server_context *context, u_int32_t vno) +kadm5_log_set_version (kadm5_server_context *context, uint32_t vno) { kadm5_log_context *log_context = &context->log_context; @@ -97,9 +98,14 @@ kadm5_log_init (kadm5_server_context *context) if (log_context->log_fd != -1) return 0; fd = open (log_context->log_file, O_RDWR | O_CREAT, 0600); - if (fd < 0) + if (fd < 0) { + krb5_set_error_string(context->context, "kadm5_log_init: open %s", + log_context->log_file); return errno; + } if (flock (fd, LOCK_EX) < 0) { + krb5_set_error_string(context->context, "kadm5_log_init: flock %s", + log_context->log_file); close (fd); return errno; } @@ -119,6 +125,7 @@ kadm5_log_reinit (kadm5_server_context *context) kadm5_log_context *log_context = &context->log_context; if (log_context->log_fd != -1) { + flock (log_context->log_fd, LOCK_UN); close (log_context->log_fd); log_context->log_fd = -1; } @@ -258,25 +265,32 @@ kadm5_log_create (kadm5_server_context *context, * database. */ -kadm5_ret_t +static kadm5_ret_t kadm5_log_replay_create (kadm5_server_context *context, - u_int32_t ver, - u_int32_t len, + uint32_t ver, + uint32_t len, krb5_storage *sp) { krb5_error_code ret; krb5_data data; - hdb_entry ent; + hdb_entry_ex ent; + + memset(&ent, 0, sizeof(ent)); ret = krb5_data_alloc (&data, len); - if (ret) + if (ret) { + krb5_set_error_string(context->context, "out of memory"); return ret; + } krb5_storage_read (sp, data.data, len); - ret = hdb_value2entry (context->context, &data, &ent); + ret = hdb_value2entry (context->context, &data, &ent.entry); krb5_data_free(&data); - if (ret) + if (ret) { + krb5_set_error_string(context->context, + "Unmarshaling hdb entry failed"); return ret; - ret = context->db->store(context->context, context->db, 0, &ent); + } + ret = context->db->hdb_store(context->context, context->db, 0, &ent); hdb_free_entry (context->context, &ent); return ret; } @@ -296,33 +310,36 @@ kadm5_log_delete (kadm5_server_context *context, kadm5_log_context *log_context = &context->log_context; sp = krb5_storage_emem(); + if (sp == NULL) + return ENOMEM; ret = kadm5_log_preamble (context, sp, kadm_delete); - if (ret) { - krb5_storage_free(sp); - return ret; - } - krb5_store_int32 (sp, 0); + if (ret) + goto out; + ret = krb5_store_int32 (sp, 0); + if (ret) + goto out; off = krb5_storage_seek (sp, 0, SEEK_CUR); - krb5_store_principal (sp, princ); + ret = krb5_store_principal (sp, princ); + if (ret) + goto out; len = krb5_storage_seek (sp, 0, SEEK_CUR) - off; krb5_storage_seek(sp, -(len + 4), SEEK_CUR); - krb5_store_int32 (sp, len); + ret = krb5_store_int32 (sp, len); + if (ret) + goto out; krb5_storage_seek(sp, len, SEEK_CUR); - krb5_store_int32 (sp, len); - if (ret) { - krb5_storage_free (sp); - return ret; - } + ret = krb5_store_int32 (sp, len); + if (ret) + goto out; ret = kadm5_log_postamble (log_context, sp); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto out; ret = kadm5_log_flush (log_context, sp); - krb5_storage_free (sp); if (ret) - return ret; + goto out; ret = kadm5_log_end (context); +out: + krb5_storage_free (sp); return ret; } @@ -330,19 +347,24 @@ kadm5_log_delete (kadm5_server_context *context, * Read a `delete' log operation from `sp' and apply it. */ -kadm5_ret_t +static kadm5_ret_t kadm5_log_replay_delete (kadm5_server_context *context, - u_int32_t ver, - u_int32_t len, + uint32_t ver, + uint32_t len, krb5_storage *sp) { krb5_error_code ret; - hdb_entry ent; + krb5_principal principal; - krb5_ret_principal (sp, &ent.principal); + ret = krb5_ret_principal (sp, &principal); + if (ret) { + krb5_set_error_string(context->context, "Failed to read deleted " + "principal from log version: %ld", (long)ver); + return ret; + } - ret = context->db->remove(context->context, context->db, &ent); - krb5_free_principal (context->context, ent.principal); + ret = context->db->hdb_remove(context->context, context->db, principal); + krb5_free_principal (context->context, principal); return ret; } @@ -362,43 +384,53 @@ kadm5_log_rename (kadm5_server_context *context, krb5_data value; kadm5_log_context *log_context = &context->log_context; + krb5_data_zero(&value); + sp = krb5_storage_emem(); ret = hdb_entry2value (context->context, ent, &value); - if (ret) { - krb5_storage_free(sp); - return ret; - } + if (ret) + goto failed; + ret = kadm5_log_preamble (context, sp, kadm_rename); - if (ret) { - krb5_storage_free(sp); - krb5_data_free (&value); - return ret; - } - krb5_store_int32 (sp, 0); + if (ret) + goto failed; + + ret = krb5_store_int32 (sp, 0); + if (ret) + goto failed; off = krb5_storage_seek (sp, 0, SEEK_CUR); - krb5_store_principal (sp, source); + ret = krb5_store_principal (sp, source); + if (ret) + goto failed; + krb5_storage_write(sp, value.data, value.length); - krb5_data_free (&value); len = krb5_storage_seek (sp, 0, SEEK_CUR) - off; krb5_storage_seek(sp, -(len + 4), SEEK_CUR); - krb5_store_int32 (sp, len); + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; + krb5_storage_seek(sp, len, SEEK_CUR); - krb5_store_int32 (sp, len); - if (ret) { - krb5_storage_free (sp); - return ret; - } + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; + ret = kadm5_log_postamble (log_context, sp); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto failed; + ret = kadm5_log_flush (log_context, sp); - krb5_storage_free (sp); if (ret) - return ret; - ret = kadm5_log_end (context); + goto failed; + krb5_storage_free (sp); + krb5_data_free (&value); + + return kadm5_log_end (context); + +failed: + krb5_data_free(&value); + krb5_storage_free(sp); return ret; } @@ -406,21 +438,28 @@ kadm5_log_rename (kadm5_server_context *context, * Read a `rename' log operation from `sp' and apply it. */ -kadm5_ret_t +static kadm5_ret_t kadm5_log_replay_rename (kadm5_server_context *context, - u_int32_t ver, - u_int32_t len, + uint32_t ver, + uint32_t len, krb5_storage *sp) { krb5_error_code ret; krb5_principal source; - hdb_entry source_ent, target_ent; + hdb_entry_ex target_ent; krb5_data value; off_t off; size_t princ_len, data_len; + memset(&target_ent, 0, sizeof(target_ent)); + off = krb5_storage_seek(sp, 0, SEEK_CUR); - krb5_ret_principal (sp, &source); + ret = krb5_ret_principal (sp, &source); + if (ret) { + krb5_set_error_string(context->context, "Failed to read renamed " + "principal in log, version: %ld", (long)ver); + return ret; + } princ_len = krb5_storage_seek(sp, 0, SEEK_CUR) - off; data_len = len - princ_len; ret = krb5_data_alloc (&value, data_len); @@ -429,20 +468,20 @@ kadm5_log_replay_rename (kadm5_server_context *context, return ret; } krb5_storage_read (sp, value.data, data_len); - ret = hdb_value2entry (context->context, &value, &target_ent); + ret = hdb_value2entry (context->context, &value, &target_ent.entry); krb5_data_free(&value); if (ret) { krb5_free_principal (context->context, source); return ret; } - ret = context->db->store (context->context, context->db, 0, &target_ent); + ret = context->db->hdb_store (context->context, context->db, + 0, &target_ent); hdb_free_entry (context->context, &target_ent); if (ret) { krb5_free_principal (context->context, source); return ret; } - source_ent.principal = source; - ret = context->db->remove (context->context, context->db, &source_ent); + ret = context->db->hdb_remove (context->context, context->db, source); krb5_free_principal (context->context, source); return ret; } @@ -455,46 +494,49 @@ kadm5_log_replay_rename (kadm5_server_context *context, kadm5_ret_t kadm5_log_modify (kadm5_server_context *context, hdb_entry *ent, - u_int32_t mask) + uint32_t mask) { krb5_storage *sp; kadm5_ret_t ret; krb5_data value; - u_int32_t len; + uint32_t len; kadm5_log_context *log_context = &context->log_context; + krb5_data_zero(&value); + sp = krb5_storage_emem(); ret = hdb_entry2value (context->context, ent, &value); - if (ret) { - krb5_storage_free(sp); - return ret; - } + if (ret) + goto failed; + ret = kadm5_log_preamble (context, sp, kadm_modify); - if (ret) { - krb5_data_free (&value); - krb5_storage_free(sp); - return ret; - } + if (ret) + goto failed; + len = value.length + 4; - krb5_store_int32 (sp, len); - krb5_store_int32 (sp, mask); + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; + ret = krb5_store_int32 (sp, mask); + if (ret) + goto failed; krb5_storage_write (sp, value.data, value.length); - krb5_data_free (&value); - krb5_store_int32 (sp, len); - if (ret) { - krb5_storage_free (sp); - return ret; - } + + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; ret = kadm5_log_postamble (log_context, sp); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto failed; ret = kadm5_log_flush (log_context, sp); - krb5_storage_free (sp); if (ret) - return ret; - ret = kadm5_log_end (context); + goto failed; + krb5_data_free(&value); + krb5_storage_free (sp); + return kadm5_log_end (context); +failed: + krb5_data_free(&value); + krb5_storage_free(sp); return ret; } @@ -502,75 +544,107 @@ kadm5_log_modify (kadm5_server_context *context, * Read a `modify' log operation from `sp' and apply it. */ -kadm5_ret_t +static kadm5_ret_t kadm5_log_replay_modify (kadm5_server_context *context, - u_int32_t ver, - u_int32_t len, + uint32_t ver, + uint32_t len, krb5_storage *sp) { krb5_error_code ret; int32_t mask; krb5_data value; - hdb_entry ent, log_ent; + hdb_entry_ex ent, log_ent; + + memset(&log_ent, 0, sizeof(log_ent)); krb5_ret_int32 (sp, &mask); len -= 4; ret = krb5_data_alloc (&value, len); - if (ret) + if (ret) { + krb5_set_error_string(context->context, "out of memory"); return ret; + } krb5_storage_read (sp, value.data, len); - ret = hdb_value2entry (context->context, &value, &log_ent); + ret = hdb_value2entry (context->context, &value, &log_ent.entry); krb5_data_free(&value); if (ret) return ret; - ent.principal = log_ent.principal; - log_ent.principal = NULL; - ret = context->db->fetch(context->context, context->db, - HDB_F_DECRYPT, &ent); + + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_fetch(context->context, context->db, + log_ent.entry.principal, + HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); if (ret) - return ret; + goto out; if (mask & KADM5_PRINC_EXPIRE_TIME) { - if (log_ent.valid_end == NULL) { - ent.valid_end = NULL; + if (log_ent.entry.valid_end == NULL) { + ent.entry.valid_end = NULL; } else { - if (ent.valid_end == NULL) - ent.valid_end = malloc(sizeof(*ent.valid_end)); - *ent.valid_end = *log_ent.valid_end; + if (ent.entry.valid_end == NULL) { + ent.entry.valid_end = malloc(sizeof(*ent.entry.valid_end)); + if (ent.entry.valid_end == NULL) { + krb5_set_error_string(context->context, "out of memory"); + ret = ENOMEM; + goto out; + } + } + *ent.entry.valid_end = *log_ent.entry.valid_end; } } if (mask & KADM5_PW_EXPIRATION) { - if (log_ent.pw_end == NULL) { - ent.pw_end = NULL; + if (log_ent.entry.pw_end == NULL) { + ent.entry.pw_end = NULL; } else { - if (ent.pw_end == NULL) - ent.pw_end = malloc(sizeof(*ent.pw_end)); - *ent.pw_end = *log_ent.pw_end; + if (ent.entry.pw_end == NULL) { + ent.entry.pw_end = malloc(sizeof(*ent.entry.pw_end)); + if (ent.entry.pw_end == NULL) { + krb5_set_error_string(context->context, "out of memory"); + ret = ENOMEM; + goto out; + } + } + *ent.entry.pw_end = *log_ent.entry.pw_end; } } if (mask & KADM5_LAST_PWD_CHANGE) { abort (); /* XXX */ } if (mask & KADM5_ATTRIBUTES) { - ent.flags = log_ent.flags; + ent.entry.flags = log_ent.entry.flags; } if (mask & KADM5_MAX_LIFE) { - if (log_ent.max_life == NULL) { - ent.max_life = NULL; + if (log_ent.entry.max_life == NULL) { + ent.entry.max_life = NULL; } else { - if (ent.max_life == NULL) - ent.max_life = malloc (sizeof(*ent.max_life)); - *ent.max_life = *log_ent.max_life; + if (ent.entry.max_life == NULL) { + ent.entry.max_life = malloc (sizeof(*ent.entry.max_life)); + if (ent.entry.max_life == NULL) { + krb5_set_error_string(context->context, "out of memory"); + ret = ENOMEM; + goto out; + } + } + *ent.entry.max_life = *log_ent.entry.max_life; } } if ((mask & KADM5_MOD_TIME) && (mask & KADM5_MOD_NAME)) { - if (ent.modified_by == NULL) { - ent.modified_by = malloc(sizeof(*ent.modified_by)); + if (ent.entry.modified_by == NULL) { + ent.entry.modified_by = malloc(sizeof(*ent.entry.modified_by)); + if (ent.entry.modified_by == NULL) { + krb5_set_error_string(context->context, "out of memory"); + ret = ENOMEM; + goto out; + } } else - free_Event(ent.modified_by); - copy_Event(log_ent.modified_by, ent.modified_by); + free_Event(ent.entry.modified_by); + ret = copy_Event(log_ent.entry.modified_by, ent.entry.modified_by); + if (ret) { + krb5_set_error_string(context->context, "out of memory"); + goto out; + } } if (mask & KADM5_KVNO) { - ent.kvno = log_ent.kvno; + ent.entry.kvno = log_ent.entry.kvno; } if (mask & KADM5_MKVNO) { abort (); /* XXX */ @@ -585,12 +659,18 @@ kadm5_log_replay_modify (kadm5_server_context *context, abort (); /* XXX */ } if (mask & KADM5_MAX_RLIFE) { - if (log_ent.max_renew == NULL) { - ent.max_renew = NULL; + if (log_ent.entry.max_renew == NULL) { + ent.entry.max_renew = NULL; } else { - if (ent.max_renew == NULL) - ent.max_renew = malloc (sizeof(*ent.max_renew)); - *ent.max_renew = *log_ent.max_renew; + if (ent.entry.max_renew == NULL) { + ent.entry.max_renew = malloc (sizeof(*ent.entry.max_renew)); + if (ent.entry.max_renew == NULL) { + krb5_set_error_string(context->context, "out of memory"); + ret = ENOMEM; + goto out; + } + } + *ent.entry.max_renew = *log_ent.entry.max_renew; } } if (mask & KADM5_LAST_SUCCESS) { @@ -603,30 +683,60 @@ kadm5_log_replay_modify (kadm5_server_context *context, abort (); /* XXX */ } if (mask & KADM5_KEY_DATA) { - size_t len; + size_t num; int i; - for (i = 0; i < ent.keys.len; ++i) - free_Key(&ent.keys.val[i]); - free (ent.keys.val); + for (i = 0; i < ent.entry.keys.len; ++i) + free_Key(&ent.entry.keys.val[i]); + free (ent.entry.keys.val); - len = log_ent.keys.len; + num = log_ent.entry.keys.len; - ent.keys.len = len; - ent.keys.val = malloc(len * sizeof(*ent.keys.val)); - for (i = 0; i < ent.keys.len; ++i) - copy_Key(&log_ent.keys.val[i], - &ent.keys.val[i]); + ent.entry.keys.len = num; + ent.entry.keys.val = malloc(len * sizeof(*ent.entry.keys.val)); + if (ent.entry.keys.val == NULL) { + krb5_set_error_string(context->context, "out of memory"); + return ENOMEM; + } + for (i = 0; i < ent.entry.keys.len; ++i) { + ret = copy_Key(&log_ent.entry.keys.val[i], + &ent.entry.keys.val[i]); + if (ret) { + krb5_set_error_string(context->context, "out of memory"); + goto out; + } + } + } + if ((mask & KADM5_TL_DATA) && log_ent.entry.extensions) { + HDB_extensions *es = ent.entry.extensions; + + ent.entry.extensions = calloc(1, sizeof(*ent.entry.extensions)); + if (ent.entry.extensions == NULL) + goto out; + + ret = copy_HDB_extensions(log_ent.entry.extensions, + ent.entry.extensions); + if (ret) { + krb5_set_error_string(context->context, "out of memory"); + free(ent.entry.extensions); + ent.entry.extensions = es; + goto out; + } + if (es) { + free_HDB_extensions(es); + free(es); + } } - ret = context->db->store(context->context, context->db, - HDB_F_REPLACE, &ent); + ret = context->db->hdb_store(context->context, context->db, + HDB_F_REPLACE, &ent); + out: hdb_free_entry (context->context, &ent); hdb_free_entry (context->context, &log_ent); return ret; } /* - * Add a `nop' operation to the log. + * Add a `nop' operation to the log. Does not close the log. */ kadm5_ret_t @@ -651,9 +761,7 @@ kadm5_log_nop (kadm5_server_context *context) } ret = kadm5_log_flush (log_context, sp); krb5_storage_free (sp); - if (ret) - return ret; - ret = kadm5_log_end (context); + return ret; } @@ -661,10 +769,10 @@ kadm5_log_nop (kadm5_server_context *context) * Read a `nop' log operation from `sp' and apply it. */ -kadm5_ret_t +static kadm5_ret_t kadm5_log_replay_nop (kadm5_server_context *context, - u_int32_t ver, - u_int32_t len, + uint32_t ver, + uint32_t len, krb5_storage *sp) { return 0; @@ -677,11 +785,13 @@ kadm5_log_replay_nop (kadm5_server_context *context, kadm5_ret_t kadm5_log_foreach (kadm5_server_context *context, void (*func)(kadm5_server_context *server_context, - u_int32_t ver, + uint32_t ver, time_t timestamp, enum kadm_ops op, - u_int32_t len, - krb5_storage *sp)) + uint32_t len, + krb5_storage *, + void *), + void *ctx) { int fd = context->log_context.log_fd; krb5_storage *sp; @@ -689,16 +799,22 @@ kadm5_log_foreach (kadm5_server_context *context, lseek (fd, 0, SEEK_SET); sp = krb5_storage_from_fd (fd); for (;;) { - int32_t ver, timestamp, op, len; + int32_t ver, timestamp, op, len, len2, ver2; if(krb5_ret_int32 (sp, &ver) != 0) break; krb5_ret_int32 (sp, ×tamp); krb5_ret_int32 (sp, &op); krb5_ret_int32 (sp, &len); - (*func)(context, ver, timestamp, op, len, sp); - krb5_storage_seek(sp, 8, SEEK_CUR); + (*func)(context, ver, timestamp, op, len, sp, ctx); + krb5_ret_int32 (sp, &len2); + krb5_ret_int32 (sp, &ver2); + if (len != len2) + abort(); + if (ver != ver2) + abort(); } + krb5_storage_free(sp); return 0; } @@ -718,34 +834,66 @@ kadm5_log_goto_end (int fd) /* * Return previous log entry. + * + * The pointer in `sp´ is assumed to be at the top of the entry before + * previous entry. On success, the `sp´ pointer is set to data portion + * of previous entry. In case of error, it's not changed at all. */ kadm5_ret_t -kadm5_log_previous (krb5_storage *sp, - u_int32_t *ver, +kadm5_log_previous (krb5_context context, + krb5_storage *sp, + uint32_t *ver, time_t *timestamp, enum kadm_ops *op, - u_int32_t *len) + uint32_t *len) { - off_t off; + krb5_error_code ret; + off_t off, oldoff; int32_t tmp; + oldoff = krb5_storage_seek(sp, 0, SEEK_CUR); + krb5_storage_seek(sp, -8, SEEK_CUR); - krb5_ret_int32 (sp, &tmp); + ret = krb5_ret_int32 (sp, &tmp); + if (ret) + goto end_of_storage; *len = tmp; - krb5_ret_int32 (sp, &tmp); + ret = krb5_ret_int32 (sp, &tmp); *ver = tmp; off = 24 + *len; krb5_storage_seek(sp, -off, SEEK_CUR); - krb5_ret_int32 (sp, &tmp); - assert(tmp == *ver); - krb5_ret_int32 (sp, &tmp); + ret = krb5_ret_int32 (sp, &tmp); + if (ret) + goto end_of_storage; + if (tmp != *ver) { + krb5_storage_seek(sp, oldoff, SEEK_SET); + krb5_set_error_string(context, "kadm5_log_previous: log entry " + "have consistency failure, version number wrong"); + return KADM5_BAD_DB; + } + ret = krb5_ret_int32 (sp, &tmp); + if (ret) + goto end_of_storage; *timestamp = tmp; - krb5_ret_int32 (sp, &tmp); + ret = krb5_ret_int32 (sp, &tmp); *op = tmp; - krb5_ret_int32 (sp, &tmp); - assert(tmp == *len); + ret = krb5_ret_int32 (sp, &tmp); + if (ret) + goto end_of_storage; + if (tmp != *len) { + krb5_storage_seek(sp, oldoff, SEEK_SET); + krb5_set_error_string(context, "kadm5_log_previous: log entry " + "have consistency failure, length wrong"); + return KADM5_BAD_DB; + } return 0; + + end_of_storage: + krb5_storage_seek(sp, oldoff, SEEK_SET); + krb5_set_error_string(context, "kadm5_log_previous: end of storage " + "reached before end"); + return ret; } /* @@ -755,8 +903,8 @@ kadm5_log_previous (krb5_storage *sp, kadm5_ret_t kadm5_log_replay (kadm5_server_context *context, enum kadm_ops op, - u_int32_t ver, - u_int32_t len, + uint32_t ver, + uint32_t len, krb5_storage *sp) { switch (op) { @@ -771,6 +919,8 @@ kadm5_log_replay (kadm5_server_context *context, case kadm_nop : return kadm5_log_replay_nop (context, ver, len, sp); default : + krb5_set_error_string(context->context, + "Unsupported replay op %d", (int)op); return KADM5_FAILURE; } } @@ -783,7 +933,7 @@ kadm5_ret_t kadm5_log_truncate (kadm5_server_context *server_context) { kadm5_ret_t ret; - u_int32_t vno; + uint32_t vno; ret = kadm5_log_init (server_context); if (ret) @@ -797,7 +947,7 @@ kadm5_log_truncate (kadm5_server_context *server_context) if (ret) return ret; - ret = kadm5_log_set_version (server_context, vno + 1); + ret = kadm5_log_set_version (server_context, vno); if (ret) return ret; @@ -811,3 +961,22 @@ kadm5_log_truncate (kadm5_server_context *server_context) return 0; } + +static char *default_signal = NULL; +static HEIMDAL_MUTEX signal_mutex = HEIMDAL_MUTEX_INITIALIZER; + +const char * +kadm5_log_signal_socket(krb5_context context) +{ + HEIMDAL_MUTEX_lock(&signal_mutex); + if (!default_signal) + asprintf(&default_signal, "%s/signal", hdb_db_dir(context)); + HEIMDAL_MUTEX_unlock(&signal_mutex); + + return krb5_config_get_string_default(context, + NULL, + default_signal, + "kdc", + "signal_socket", + NULL); +} diff --git a/crypto/heimdal/lib/kadm5/marshall.c b/crypto/heimdal/lib/kadm5/marshall.c index 9828837..05ca33f 100644 --- a/crypto/heimdal/lib/kadm5/marshall.c +++ b/crypto/heimdal/lib/kadm5/marshall.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: marshall.c,v 1.6 1999/12/02 17:05:06 joda Exp $"); +RCSID("$Id: marshall.c 21745 2007-07-31 16:11:25Z lha $"); kadm5_ret_t kadm5_store_key_data(krb5_storage *sp, @@ -105,7 +105,7 @@ kadm5_ret_tl_data(krb5_storage *sp, static kadm5_ret_t store_principal_ent(krb5_storage *sp, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { int i; @@ -173,7 +173,7 @@ kadm5_store_principal_ent(krb5_storage *sp, kadm5_ret_t kadm5_store_principal_ent_mask(krb5_storage *sp, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { krb5_store_int32(sp, mask); return store_principal_ent (sp, princ, mask); @@ -182,7 +182,7 @@ kadm5_store_principal_ent_mask(krb5_storage *sp, static kadm5_ret_t ret_principal_ent(krb5_storage *sp, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { int i; int32_t tmp; @@ -260,6 +260,8 @@ ret_principal_ent(krb5_storage *sp, krb5_ret_int32(sp, &tmp); princ->n_key_data = tmp; princ->key_data = malloc(princ->n_key_data * sizeof(*princ->key_data)); + if (princ->key_data == NULL) + return ENOMEM; for(i = 0; i < princ->n_key_data; i++) kadm5_ret_key_data(sp, &princ->key_data[i]); } @@ -269,6 +271,8 @@ ret_principal_ent(krb5_storage *sp, princ->tl_data = NULL; for(i = 0; i < princ->n_tl_data; i++){ krb5_tl_data *tp = malloc(sizeof(*tp)); + if (tp == NULL) + return ENOMEM; kadm5_ret_tl_data(sp, tp); tp->tl_data_next = princ->tl_data; princ->tl_data = tp; @@ -287,7 +291,7 @@ kadm5_ret_principal_ent(krb5_storage *sp, kadm5_ret_t kadm5_ret_principal_ent_mask(krb5_storage *sp, kadm5_principal_ent_t princ, - u_int32_t *mask) + uint32_t *mask) { int32_t tmp; @@ -319,8 +323,10 @@ _kadm5_unmarshal_params(krb5_context context, kadm5_config_params *params) { krb5_storage *sp = krb5_storage_from_data(in); + int32_t mask; - krb5_ret_int32(sp, ¶ms->mask); + krb5_ret_int32(sp, &mask); + params->mask = mask; if(params->mask & KADM5_CONFIG_REALM) krb5_ret_string(sp, ¶ms->realm); diff --git a/crypto/heimdal/lib/kadm5/modify_c.c b/crypto/heimdal/lib/kadm5/modify_c.c index 8d8ca56..ed399b3 100644 --- a/crypto/heimdal/lib/kadm5/modify_c.c +++ b/crypto/heimdal/lib/kadm5/modify_c.c @@ -33,12 +33,12 @@ #include "kadm5_locl.h" -RCSID("$Id: modify_c.c,v 1.4 2000/07/11 15:59:46 joda Exp $"); +RCSID("$Id: modify_c.c 17445 2006-05-05 10:37:46Z lha $"); kadm5_ret_t kadm5_c_modify_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; @@ -52,8 +52,10 @@ kadm5_c_modify_principal(void *server_handle, return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_modify); kadm5_store_principal_ent(sp, princ); krb5_store_int32(sp, mask); @@ -66,10 +68,12 @@ kadm5_c_modify_principal(void *server_handle, return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); + krb5_clear_error_string(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; diff --git a/crypto/heimdal/lib/kadm5/modify_s.c b/crypto/heimdal/lib/kadm5/modify_s.c index 8c595a9..449f619 100644 --- a/crypto/heimdal/lib/kadm5/modify_s.c +++ b/crypto/heimdal/lib/kadm5/modify_s.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001, 2003, 2005-2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,50 +33,54 @@ #include "kadm5_locl.h" -RCSID("$Id: modify_s.c,v 1.12 2001/01/30 01:24:28 assar Exp $"); +RCSID("$Id: modify_s.c 20610 2007-05-08 07:12:37Z lha $"); static kadm5_ret_t modify_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask, - u_int32_t forbidden_mask) + uint32_t mask, + uint32_t forbidden_mask) { kadm5_server_context *context = server_handle; - hdb_entry ent; + hdb_entry_ex ent; kadm5_ret_t ret; if((mask & forbidden_mask)) return KADM5_BAD_MASK; if((mask & KADM5_POLICY) && strcmp(princ->policy, "default")) return KADM5_UNK_POLICY; - ent.principal = princ->principal; - ret = context->db->open(context->context, context->db, O_RDWR, 0); + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; - ret = context->db->fetch(context->context, context->db, 0, &ent); + ret = context->db->hdb_fetch(context->context, context->db, + princ->principal, HDB_F_GET_ANY, &ent); if(ret) goto out; ret = _kadm5_setup_entry(context, &ent, mask, princ, mask, NULL, 0); if(ret) goto out2; - ret = _kadm5_set_modifier(context, &ent); + ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out2; - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = hdb_seal_keys(context->context, context->db, &ent.entry); + if (ret) + goto out2; + + ret = context->db->hdb_store(context->context, context->db, + HDB_F_REPLACE, &ent); if (ret) goto out2; kadm5_log_modify (context, - &ent, + &ent.entry, mask | KADM5_MOD_NAME | KADM5_MOD_TIME); - - ret = context->db->store(context->context, context->db, - HDB_F_REPLACE, &ent); + out2: hdb_free_entry(context->context, &ent); out: - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); } @@ -84,7 +88,7 @@ out: kadm5_ret_t kadm5_s_modify_principal(void *server_handle, kadm5_principal_ent_t princ, - u_int32_t mask) + uint32_t mask) { return modify_principal(server_handle, princ, mask, KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME diff --git a/crypto/heimdal/lib/kadm5/password_quality.c b/crypto/heimdal/lib/kadm5/password_quality.c index bc1463f..2610ce8 100644 --- a/crypto/heimdal/lib/kadm5/password_quality.c +++ b/crypto/heimdal/lib/kadm5/password_quality.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2000, 2003-2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,40 +32,231 @@ */ #include "kadm5_locl.h" +#include "kadm5-pwcheck.h" -RCSID("$Id: password_quality.c,v 1.4 2000/07/05 13:14:45 joda Exp $"); +RCSID("$Id: password_quality.c 17595 2006-05-30 21:51:55Z lha $"); +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif +static int +min_length_passwd_quality (krb5_context context, + krb5_principal principal, + krb5_data *pwd, + const char *opaque, + char *message, + size_t length) +{ + uint32_t min_length = krb5_config_get_int_default(context, NULL, 6, + "password_quality", + "min_length", + NULL); + + if (pwd->length < min_length) { + strlcpy(message, "Password too short", length); + return 1; + } else + return 0; +} + static const char * -simple_passwd_quality (krb5_context context, - krb5_principal principal, - krb5_data *pwd) +min_length_passwd_quality_v0 (krb5_context context, + krb5_principal principal, + krb5_data *pwd) { - if (pwd->length < 6) - return "Password too short"; - else - return NULL; + static char message[1024]; + int ret; + + message[0] = '\0'; + + ret = min_length_passwd_quality(context, principal, pwd, NULL, + message, sizeof(message)); + if (ret) + return message; + return NULL; } -typedef const char* (*passwd_quality_check_func)(krb5_context, - krb5_principal, - krb5_data*); -static passwd_quality_check_func passwd_quality_check = simple_passwd_quality; +static int +char_class_passwd_quality (krb5_context context, + krb5_principal principal, + krb5_data *pwd, + const char *opaque, + char *message, + size_t length) +{ + const char *classes[] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "abcdefghijklmnopqrstuvwxyz", + "1234567890", + "!@#$%^&*()/?<>,.{[]}\\|'~`\" " + }; + int i, counter = 0, req_classes; + size_t len; + char *pw; -#ifdef HAVE_DLOPEN + req_classes = krb5_config_get_int_default(context, NULL, 3, + "password_quality", + "min_classes", + NULL); -#define PASSWD_VERSION 0 + len = pwd->length + 1; + pw = malloc(len); + if (pw == NULL) { + strlcpy(message, "out of memory", length); + return 1; + } + strlcpy(pw, pwd->data, len); + len = strlen(pw); -#endif + for (i = 0; i < sizeof(classes)/sizeof(classes[0]); i++) { + if (strcspn(pw, classes[i]) < len) + counter++; + } + memset(pw, 0, pwd->length + 1); + free(pw); + if (counter < req_classes) { + snprintf(message, length, + "Password doesn't meet complexity requirement.\n" + "Add more characters from the following classes:\n" + "1. English uppercase characters (A through Z)\n" + "2. English lowercase characters (a through z)\n" + "3. Base 10 digits (0 through 9)\n" + "4. Nonalphanumeric characters (e.g., !, $, #, %%)"); + return 1; + } + return 0; +} + +static int +external_passwd_quality (krb5_context context, + krb5_principal principal, + krb5_data *pwd, + const char *opaque, + char *message, + size_t length) +{ + krb5_error_code ret; + const char *program; + char *p; + pid_t child; + int status; + char reply[1024]; + FILE *in = NULL, *out = NULL, *error = NULL; + + if (memchr(pwd->data, pwd->length, '\n') != NULL) { + snprintf(message, length, "password contains newline, " + "not valid for external test"); + return 1; + } + + program = krb5_config_get_string(context, NULL, + "password_quality", + "external_program", + NULL); + if (program == NULL) { + snprintf(message, length, "external password quality " + "program not configured"); + return 1; + } + + ret = krb5_unparse_name(context, principal, &p); + if (ret) { + strlcpy(message, "out of memory", length); + return 1; + } + + child = pipe_execv(&in, &out, &error, program, p, NULL); + if (child < 0) { + snprintf(message, length, "external password quality " + "program failed to execute for principal %s", p); + free(p); + return 1; + } + + fprintf(in, "principal: %s\n" + "new-password: %.*s\n" + "end\n", + p, (int)pwd->length, (char *)pwd->data); + + fclose(in); + + if (fgets(reply, sizeof(reply), out) == NULL) { + + if (fgets(reply, sizeof(reply), error) == NULL) { + snprintf(message, length, "external password quality " + "program failed without error"); + + } else { + reply[strcspn(reply, "\n")] = '\0'; + snprintf(message, length, "External password quality " + "program failed: %s", reply); + } + + fclose(out); + fclose(error); + waitpid(child, &status, 0); + return 1; + } + reply[strcspn(reply, "\n")] = '\0'; + + fclose(out); + fclose(error); + + if (waitpid(child, &status, 0) < 0) { + snprintf(message, length, "external program failed: %s", reply); + free(p); + return 1; + } + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + snprintf(message, length, "external program failed: %s", reply); + free(p); + return 1; + } + + if (strcmp(reply, "APPROVED") != 0) { + snprintf(message, length, "%s", reply); + free(p); + return 1; + } + + free(p); + + return 0; +} + + +static kadm5_passwd_quality_check_func_v0 passwd_quality_check = + min_length_passwd_quality_v0; + +struct kadm5_pw_policy_check_func builtin_funcs[] = { + { "minimum-length", min_length_passwd_quality }, + { "character-class", char_class_passwd_quality }, + { "external-check", external_passwd_quality }, + { NULL } +}; +struct kadm5_pw_policy_verifier builtin_verifier = { + "builtin", + KADM5_PASSWD_VERSION_V1, + "Heimdal builtin", + builtin_funcs +}; + +static struct kadm5_pw_policy_verifier **verifiers; +static int num_verifiers; /* * setup the password quality hook */ +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif + void kadm5_setup_passwd_quality_check(krb5_context context, const char *check_library, @@ -75,15 +266,8 @@ kadm5_setup_passwd_quality_check(krb5_context context, void *handle; void *sym; int *version; - int flags; const char *tmp; -#ifdef RTLD_NOW - flags = RTLD_NOW; -#else - flags = 0; -#endif - if(check_library == NULL) { tmp = krb5_config_get_string(context, NULL, "password_quality", @@ -105,7 +289,7 @@ kadm5_setup_passwd_quality_check(krb5_context context, if(check_library == NULL) return; - handle = dlopen(check_library, flags); + handle = dlopen(check_library, RTLD_NOW); if(handle == NULL) { krb5_warnx(context, "failed to open `%s'", check_library); return; @@ -117,10 +301,10 @@ kadm5_setup_passwd_quality_check(krb5_context context, dlclose(handle); return; } - if(*version != PASSWD_VERSION) { + if(*version != KADM5_PASSWD_VERSION_V0) { krb5_warnx(context, "version of loaded library is %d (expected %d)", - *version, PASSWD_VERSION); + *version, KADM5_PASSWD_VERSION_V0); dlclose(handle); return; } @@ -132,14 +316,197 @@ kadm5_setup_passwd_quality_check(krb5_context context, dlclose(handle); return; } - passwd_quality_check = (passwd_quality_check_func) sym; + passwd_quality_check = (kadm5_passwd_quality_check_func_v0) sym; +#endif /* HAVE_DLOPEN */ +} + +#ifdef HAVE_DLOPEN + +static krb5_error_code +add_verifier(krb5_context context, const char *check_library) +{ + struct kadm5_pw_policy_verifier *v, **tmp; + void *handle; + int i; + + handle = dlopen(check_library, RTLD_NOW); + if(handle == NULL) { + krb5_warnx(context, "failed to open `%s'", check_library); + return ENOENT; + } + v = dlsym(handle, "kadm5_password_verifier"); + if(v == NULL) { + krb5_warnx(context, + "didn't find `kadm5_password_verifier' symbol " + "in `%s'", check_library); + dlclose(handle); + return ENOENT; + } + if(v->version != KADM5_PASSWD_VERSION_V1) { + krb5_warnx(context, + "version of loaded library is %d (expected %d)", + v->version, KADM5_PASSWD_VERSION_V1); + dlclose(handle); + return EINVAL; + } + for (i = 0; i < num_verifiers; i++) { + if (strcmp(v->name, verifiers[i]->name) == 0) + break; + } + if (i < num_verifiers) { + krb5_warnx(context, "password verifier library `%s' is already loaded", + v->name); + dlclose(handle); + return 0; + } + + tmp = realloc(verifiers, (num_verifiers + 1) * sizeof(*verifiers)); + if (tmp == NULL) { + krb5_warnx(context, "out of memory"); + dlclose(handle); + return 0; + } + verifiers = tmp; + verifiers[num_verifiers] = v; + num_verifiers++; + + return 0; +} + +#endif + +krb5_error_code +kadm5_add_passwd_quality_verifier(krb5_context context, + const char *check_library) +{ +#ifdef HAVE_DLOPEN + + if(check_library == NULL) { + krb5_error_code ret; + char **tmp; + + tmp = krb5_config_get_strings(context, NULL, + "password_quality", + "policy_libraries", + NULL); + if(tmp == NULL) + return 0; + + while(tmp) { + ret = add_verifier(context, *tmp); + if (ret) + return ret; + tmp++; + } + } + return add_verifier(context, check_library); +#else + return 0; #endif /* HAVE_DLOPEN */ } +/* + * + */ + +static const struct kadm5_pw_policy_check_func * +find_func(krb5_context context, const char *name) +{ + const struct kadm5_pw_policy_check_func *f; + char *module = NULL; + const char *p, *func; + int i; + + p = strchr(name, ':'); + if (p) { + func = p + 1; + module = strndup(name, p - name); + if (module == NULL) + return NULL; + } else + func = name; + + /* Find module in loaded modules first */ + for (i = 0; i < num_verifiers; i++) { + if (module && strcmp(module, verifiers[i]->name) != 0) + continue; + for (f = verifiers[i]->funcs; f->name ; f++) + if (strcmp(name, f->name) == 0) { + if (module) + free(module); + return f; + } + } + /* Lets try try the builtin modules */ + if (module == NULL || strcmp(module, "builtin") == 0) { + for (f = builtin_verifier.funcs; f->name ; f++) + if (strcmp(func, f->name) == 0) { + if (module) + free(module); + return f; + } + } + if (module) + free(module); + return NULL; +} + const char * kadm5_check_password_quality (krb5_context context, krb5_principal principal, krb5_data *pwd_data) { - return (*passwd_quality_check) (context, principal, pwd_data); + const struct kadm5_pw_policy_check_func *proc; + static char error_msg[1024]; + const char *msg; + char **v, **vp; + int ret; + + /* + * Check if we should use the old version of policy function. + */ + + v = krb5_config_get_strings(context, NULL, + "password_quality", + "policies", + NULL); + if (v == NULL) { + msg = (*passwd_quality_check) (context, principal, pwd_data); + krb5_set_error_string(context, "password policy failed: %s", msg); + return msg; + } + + error_msg[0] = '\0'; + + msg = NULL; + for(vp = v; *vp; vp++) { + proc = find_func(context, *vp); + if (proc == NULL) { + msg = "failed to find password verifier function"; + krb5_set_error_string(context, "Failed to find password policy " + "function: %s", *vp); + break; + } + ret = (proc->func)(context, principal, pwd_data, NULL, + error_msg, sizeof(error_msg)); + if (ret) { + krb5_set_error_string(context, "Password policy " + "%s failed with %s", + proc->name, error_msg); + msg = error_msg; + break; + } + } + krb5_config_free_strings(v); + + /* If the default quality check isn't used, lets check that the + * old quality function the user have set too */ + if (msg == NULL && passwd_quality_check != min_length_passwd_quality_v0) { + msg = (*passwd_quality_check) (context, principal, pwd_data); + if (msg) + krb5_set_error_string(context, "(old) password policy " + "failed with %s", msg); + + } + return msg; } diff --git a/crypto/heimdal/lib/kadm5/private.h b/crypto/heimdal/lib/kadm5/private.h index b09545f..d5e1380 100644 --- a/crypto/heimdal/lib/kadm5/private.h +++ b/crypto/heimdal/lib/kadm5/private.h @@ -31,23 +31,23 @@ * SUCH DAMAGE. */ -/* $Id: private.h,v 1.15 2002/08/16 20:57:44 joda Exp $ */ +/* $Id: private.h 22211 2007-12-07 19:27:27Z lha $ */ #ifndef __kadm5_privatex_h__ #define __kadm5_privatex_h__ struct kadm_func { - kadm5_ret_t (*chpass_principal) (void *, krb5_principal, char*); + kadm5_ret_t (*chpass_principal) (void *, krb5_principal, const char*); kadm5_ret_t (*create_principal) (void*, kadm5_principal_ent_t, - u_int32_t, char*); + uint32_t, const char*); kadm5_ret_t (*delete_principal) (void*, krb5_principal); kadm5_ret_t (*destroy) (void*); kadm5_ret_t (*flush) (void*); kadm5_ret_t (*get_principal) (void*, krb5_principal, - kadm5_principal_ent_t, u_int32_t); + kadm5_principal_ent_t, uint32_t); kadm5_ret_t (*get_principals) (void*, const char*, char***, int*); - kadm5_ret_t (*get_privs) (void*, u_int32_t*); - kadm5_ret_t (*modify_principal) (void*, kadm5_principal_ent_t, u_int32_t); + kadm5_ret_t (*get_privs) (void*, uint32_t*); + kadm5_ret_t (*modify_principal) (void*, kadm5_principal_ent_t, uint32_t); kadm5_ret_t (*randkey_principal) (void*, krb5_principal, krb5_keyblock**, int*); kadm5_ret_t (*rename_principal) (void*, krb5_principal, krb5_principal); @@ -73,7 +73,7 @@ typedef struct kadm5_log_peer { typedef struct kadm5_log_context { char *log_file; int log_fd; - u_int32_t version; + uint32_t version; struct sockaddr_un socket_name; int socket_fd; } kadm5_log_context; @@ -108,6 +108,20 @@ typedef struct kadm5_client_context { kadm5_config_params *realm_params; }kadm5_client_context; +typedef struct kadm5_ad_context { + krb5_context context; + krb5_boolean my_context; + struct kadm_func funcs; + /* */ + kadm5_config_params config; + krb5_principal caller; + krb5_ccache ccache; + char *client_name; + char *realm; + void *ldap_conn; + char *base_dn; +} kadm5_ad_context; + enum kadm_ops { kadm_get, kadm_delete, @@ -125,8 +139,6 @@ enum kadm_ops { #define KADMIN_APPL_VERSION "KADM0.1" #define KADMIN_OLD_APPL_VERSION "KADM0.0" -#define KADM5_LOG_SIGNAL HDB_DB_DIR "/signal" - #include "kadm5-private.h" #endif /* __kadm5_privatex_h__ */ diff --git a/crypto/heimdal/lib/kadm5/privs_c.c b/crypto/heimdal/lib/kadm5/privs_c.c index 83d293c..58e6824 100644 --- a/crypto/heimdal/lib/kadm5/privs_c.c +++ b/crypto/heimdal/lib/kadm5/privs_c.c @@ -33,10 +33,10 @@ #include "kadm5_locl.h" -RCSID("$Id: privs_c.c,v 1.4 2000/07/11 15:59:54 joda Exp $"); +RCSID("$Id: privs_c.c 17512 2006-05-08 13:43:17Z lha $"); kadm5_ret_t -kadm5_c_get_privs(void *server_handle, u_int32_t *privs) +kadm5_c_get_privs(void *server_handle, uint32_t *privs) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; @@ -45,13 +45,17 @@ kadm5_c_get_privs(void *server_handle, u_int32_t *privs) int32_t tmp; krb5_data reply; + *privs = 0; + ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_get_privs); ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); @@ -62,14 +66,15 @@ kadm5_c_get_privs(void *server_handle, u_int32_t *privs) return ret; sp = krb5_storage_from_data(&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); + krb5_clear_error_string(context->context); ret = tmp; if(ret == 0){ - krb5_ret_int32(sp, &tmp); - *privs = tmp; + krb5_ret_uint32(sp, privs); } krb5_storage_free(sp); krb5_data_free (&reply); diff --git a/crypto/heimdal/lib/kadm5/privs_s.c b/crypto/heimdal/lib/kadm5/privs_s.c index 85cd5d5..9c345e3 100644 --- a/crypto/heimdal/lib/kadm5/privs_s.c +++ b/crypto/heimdal/lib/kadm5/privs_s.c @@ -33,10 +33,10 @@ #include "kadm5_locl.h" -RCSID("$Id: privs_s.c,v 1.2 1999/12/02 17:05:07 joda Exp $"); +RCSID("$Id: privs_s.c 17445 2006-05-05 10:37:46Z lha $"); kadm5_ret_t -kadm5_s_get_privs(void *server_handle, u_int32_t *privs) +kadm5_s_get_privs(void *server_handle, uint32_t *privs) { kadm5_server_context *context = server_handle; *privs = context->acl_flags; diff --git a/crypto/heimdal/lib/kadm5/randkey_c.c b/crypto/heimdal/lib/kadm5/randkey_c.c index eedf697..60a3f53 100644 --- a/crypto/heimdal/lib/kadm5/randkey_c.c +++ b/crypto/heimdal/lib/kadm5/randkey_c.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: randkey_c.c,v 1.4 2000/07/11 16:00:02 joda Exp $"); +RCSID("$Id: randkey_c.c 16662 2006-01-25 12:53:09Z lha $"); kadm5_ret_t kadm5_c_randkey_principal(void *server_handle, @@ -53,8 +53,10 @@ kadm5_c_randkey_principal(void *server_handle, return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); - if (sp == NULL) + if (sp == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } krb5_store_int32(sp, kadm_randkey); krb5_store_principal(sp, princ); ret = _kadm5_client_send(context, sp); @@ -66,9 +68,11 @@ kadm5_c_randkey_principal(void *server_handle, return ret; sp = krb5_storage_from_data(&reply); if (sp == NULL) { + krb5_clear_error_string(context->context); krb5_data_free (&reply); return ENOMEM; } + krb5_clear_error_string(context->context); krb5_ret_int32(sp, &tmp); ret = tmp; if(ret == 0){ diff --git a/crypto/heimdal/lib/kadm5/randkey_s.c b/crypto/heimdal/lib/kadm5/randkey_s.c index 9780b11..cb0f0fa 100644 --- a/crypto/heimdal/lib/kadm5/randkey_s.c +++ b/crypto/heimdal/lib/kadm5/randkey_s.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001, 2003-2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: randkey_s.c,v 1.13 2001/01/30 01:24:28 assar Exp $"); +RCSID("$Id: randkey_s.c 20611 2007-05-08 07:13:07Z lha $"); /* * Set the keys of `princ' to random values, returning the random keys @@ -47,42 +47,48 @@ kadm5_s_randkey_principal(void *server_handle, int *n_keys) { kadm5_server_context *context = server_handle; - hdb_entry ent; + hdb_entry_ex ent; kadm5_ret_t ret; - ent.principal = princ; - ret = context->db->open(context->context, context->db, O_RDWR, 0); + memset(&ent, 0, sizeof(ent)); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; - ret = context->db->fetch(context->context, context->db, 0, &ent); + ret = context->db->hdb_fetch(context->context, context->db, princ, + HDB_F_GET_ANY, &ent); if(ret) goto out; ret = _kadm5_set_keys_randomly (context, - &ent, + &ent.entry, new_keys, n_keys); if (ret) goto out2; + ent.entry.kvno++; - ret = _kadm5_set_modifier(context, &ent); + ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out3; - ret = _kadm5_bump_pw_expire(context, &ent); + ret = _kadm5_bump_pw_expire(context, &ent.entry); if (ret) goto out2; - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = hdb_seal_keys(context->context, context->db, &ent.entry); + if (ret) + goto out2; + + ret = context->db->hdb_store(context->context, context->db, + HDB_F_REPLACE, &ent); if (ret) goto out2; kadm5_log_modify (context, - &ent, + &ent.entry, KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | - KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION); + KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | + KADM5_TL_DATA); - ret = context->db->store(context->context, context->db, - HDB_F_REPLACE, &ent); out3: if (ret) { int i; @@ -96,6 +102,6 @@ out3: out2: hdb_free_entry(context->context, &ent); out: - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); } diff --git a/crypto/heimdal/lib/kadm5/rename_c.c b/crypto/heimdal/lib/kadm5/rename_c.c index 95ccf25..cec2fd3 100644 --- a/crypto/heimdal/lib/kadm5/rename_c.c +++ b/crypto/heimdal/lib/kadm5/rename_c.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: rename_c.c,v 1.4 2000/07/11 16:00:08 joda Exp $"); +RCSID("$Id: rename_c.c 8655 2000-07-11 16:00:19Z joda $"); kadm5_ret_t kadm5_c_rename_principal(void *server_handle, diff --git a/crypto/heimdal/lib/kadm5/rename_s.c b/crypto/heimdal/lib/kadm5/rename_s.c index a478e0a..2a19426 100644 --- a/crypto/heimdal/lib/kadm5/rename_s.c +++ b/crypto/heimdal/lib/kadm5/rename_s.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003, 2005 - 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: rename_s.c,v 1.11 2001/01/30 01:24:29 assar Exp $"); +RCSID("$Id: rename_s.c 21745 2007-07-31 16:11:25Z lha $"); kadm5_ret_t kadm5_s_rename_principal(void *server_handle, @@ -42,21 +42,22 @@ kadm5_s_rename_principal(void *server_handle, { kadm5_server_context *context = server_handle; kadm5_ret_t ret; - hdb_entry ent, ent2; - ent.principal = source; + hdb_entry_ex ent; + krb5_principal oldname; + + memset(&ent, 0, sizeof(ent)); if(krb5_principal_compare(context->context, source, target)) return KADM5_DUP; /* XXX is this right? */ - if(!krb5_realm_compare(context->context, source, target)) - return KADM5_FAILURE; /* XXX better code */ - ret = context->db->open(context->context, context->db, O_RDWR, 0); + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); if(ret) return ret; - ret = context->db->fetch(context->context, context->db, 0, &ent); + ret = context->db->hdb_fetch(context->context, context->db, + source, HDB_F_GET_ANY, &ent); if(ret){ - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); goto out; } - ret = _kadm5_set_modifier(context, &ent); + ret = _kadm5_set_modifier(context, &ent.entry); if(ret) goto out2; { @@ -67,10 +68,13 @@ kadm5_s_rename_principal(void *server_handle, krb5_get_pw_salt(context->context, source, &salt2); salt.type = hdb_pw_salt; salt.salt = salt2.saltvalue; - for(i = 0; i < ent.keys.len; i++){ - if(ent.keys.val[i].salt == NULL){ - ent.keys.val[i].salt = malloc(sizeof(*ent.keys.val[i].salt)); - ret = copy_Salt(&salt, ent.keys.val[i].salt); + for(i = 0; i < ent.entry.keys.len; i++){ + if(ent.entry.keys.val[i].salt == NULL){ + ent.entry.keys.val[i].salt = + malloc(sizeof(*ent.entry.keys.val[i].salt)); + if(ent.entry.keys.val[i].salt == NULL) + return ENOMEM; + ret = copy_Salt(&salt, ent.entry.keys.val[i].salt); if(ret) break; } @@ -79,28 +83,26 @@ kadm5_s_rename_principal(void *server_handle, } if(ret) goto out2; - ent2.principal = ent.principal; - ent.principal = target; + oldname = ent.entry.principal; + ent.entry.principal = target; - ret = hdb_seal_keys(context->context, context->db, &ent); + ret = hdb_seal_keys(context->context, context->db, &ent.entry); if (ret) { - ent.principal = ent2.principal; + ent.entry.principal = oldname; goto out2; } - kadm5_log_rename (context, - source, - &ent); + kadm5_log_rename (context, source, &ent.entry); - ret = context->db->store(context->context, context->db, 0, &ent); + ret = context->db->hdb_store(context->context, context->db, 0, &ent); if(ret){ - ent.principal = ent2.principal; + ent.entry.principal = oldname; goto out2; } - ret = context->db->remove(context->context, context->db, &ent2); - ent.principal = ent2.principal; + ret = context->db->hdb_remove(context->context, context->db, oldname); + ent.entry.principal = oldname; out2: - context->db->close(context->context, context->db); + context->db->hdb_close(context->context, context->db); hdb_free_entry(context->context, &ent); out: return _kadm5_error_code(ret); diff --git a/crypto/heimdal/lib/kadm5/sample_passwd_check.c b/crypto/heimdal/lib/kadm5/sample_passwd_check.c index 4ff5122..1a21c10 100644 --- a/crypto/heimdal/lib/kadm5/sample_passwd_check.c +++ b/crypto/heimdal/lib/kadm5/sample_passwd_check.c @@ -30,12 +30,14 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: sample_passwd_check.c,v 1.1 1999/09/10 10:11:03 assar Exp $ */ +/* $Id: sample_passwd_check.c 21901 2007-08-10 06:05:35Z lha $ */ #include <string.h> #include <stdlib.h> #include <krb5.h> +const char* check_length(krb5_context, krb5_principal, krb5_data *); + /* specify the api-version this library conforms to */ int version = 0; diff --git a/crypto/heimdal/lib/kadm5/send_recv.c b/crypto/heimdal/lib/kadm5/send_recv.c index fe44b76..b64bbfe 100644 --- a/crypto/heimdal/lib/kadm5/send_recv.c +++ b/crypto/heimdal/lib/kadm5/send_recv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2003, 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: send_recv.c,v 1.10 2003/04/16 17:58:59 lha Exp $"); +RCSID("$Id: send_recv.c 17311 2006-04-27 11:10:07Z lha $"); kadm5_ret_t _kadm5_client_send(kadm5_client_context *context, krb5_storage *sp) @@ -47,8 +47,10 @@ _kadm5_client_send(kadm5_client_context *context, krb5_storage *sp) len = krb5_storage_seek(sp, 0, SEEK_CUR); ret = krb5_data_alloc(&msg, len); - if (ret) + if (ret) { + krb5_clear_error_string(context->context); return ret; + } krb5_storage_seek(sp, 0, SEEK_SET); krb5_storage_read(sp, msg.data, msg.length); @@ -59,11 +61,14 @@ _kadm5_client_send(kadm5_client_context *context, krb5_storage *sp) sock = krb5_storage_from_fd(context->sock); if(sock == NULL) { + krb5_clear_error_string(context->context); krb5_data_free(&out); return ENOMEM; } ret = krb5_store_data(sock, out); + if (ret) + krb5_clear_error_string(context->context); krb5_storage_free(sock); krb5_data_free(&out); return ret; @@ -77,10 +82,13 @@ _kadm5_client_recv(kadm5_client_context *context, krb5_data *reply) krb5_storage *sock; sock = krb5_storage_from_fd(context->sock); - if(sock == NULL) + if(sock == NULL) { + krb5_clear_error_string(context->context); return ENOMEM; + } ret = krb5_ret_data(sock, &data); krb5_storage_free(sock); + krb5_clear_error_string(context->context); if(ret == KRB5_CC_END) return KADM5_RPC_ERROR; else if(ret) diff --git a/crypto/heimdal/lib/kadm5/server_glue.c b/crypto/heimdal/lib/kadm5/server_glue.c index 21b6077..2862c36 100644 --- a/crypto/heimdal/lib/kadm5/server_glue.c +++ b/crypto/heimdal/lib/kadm5/server_glue.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: server_glue.c,v 1.6 1999/12/02 17:05:07 joda Exp $"); +RCSID("$Id: server_glue.c 7464 1999-12-02 17:05:13Z joda $"); kadm5_ret_t kadm5_init_with_password(const char *client_name, diff --git a/crypto/heimdal/lib/kadm5/set_keys.c b/crypto/heimdal/lib/kadm5/set_keys.c index d69c509..ee4de3b 100644 --- a/crypto/heimdal/lib/kadm5/set_keys.c +++ b/crypto/heimdal/lib/kadm5/set_keys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,258 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: set_keys.c,v 1.25 2001/08/13 15:12:16 joda Exp $"); - -/* - * the known and used DES enctypes - */ - -static krb5_enctype des_types[] = { ETYPE_DES_CBC_CRC, - ETYPE_DES_CBC_MD4, - ETYPE_DES_CBC_MD5 }; -static unsigned n_des_types = sizeof(des_types) / sizeof(des_types[0]); - -static krb5_error_code -make_keys(krb5_context context, krb5_principal principal, const char *password, - Key **keys_ret, size_t *num_keys_ret) -{ - krb5_enctype all_etypes[] = { ETYPE_DES3_CBC_SHA1, - ETYPE_DES_CBC_MD5, - ETYPE_DES_CBC_MD4, - ETYPE_DES_CBC_CRC }; - - - krb5_enctype e; - - krb5_error_code ret = 0; - char **ktypes, **kp; - - Key *keys = NULL, *tmp; - int num_keys = 0; - Key key; - - int i; - char *v4_ktypes[] = {"des3:pw-salt", "v4", NULL}; - - ktypes = krb5_config_get_strings(context, NULL, "kadmin", - "default_keys", NULL); - - /* for each entry in `default_keys' try to parse it as a sequence - of etype:salttype:salt, syntax of this if something like: - [(des|des3|etype):](pw|afs3)[:string], if etype is omitted it - means all etypes, and if string is omitted is means the default - string (for that principal). Additional special values: - v5 == pw-salt, and - v4 == des:pw-salt: - afs or afs3 == des:afs3-salt - */ - - if (ktypes == NULL - && krb5_config_get_bool (context, NULL, "kadmin", - "use_v4_salt", NULL)) - ktypes = v4_ktypes; - - for(kp = ktypes; kp && *kp; kp++) { - krb5_enctype *etypes; - int num_etypes; - krb5_salt salt; - krb5_boolean salt_set; - - const char *p; - char buf[3][256]; - int num_buf = 0; - - p = *kp; - if(strcmp(p, "v5") == 0) - p = "pw-salt"; - else if(strcmp(p, "v4") == 0) - p = "des:pw-salt:"; - else if(strcmp(p, "afs") == 0 || strcmp(p, "afs3") == 0) - p = "des:afs3-salt"; - - /* split p in a list of :-separated strings */ - for(num_buf = 0; num_buf < 3; num_buf++) - if(strsep_copy(&p, ":", buf[num_buf], sizeof(buf[num_buf])) == -1) - break; - - etypes = NULL; - num_etypes = 0; - memset(&salt, 0, sizeof(salt)); - salt_set = FALSE; - - for(i = 0; i < num_buf; i++) { - if(etypes == NULL) { - /* this might be a etype specifier */ - /* XXX there should be a string_to_etypes handling - special cases like `des' and `all' */ - if(strcmp(buf[i], "des") == 0) { - etypes = all_etypes + 1; - num_etypes = 3; - continue; - } else if(strcmp(buf[i], "des3") == 0) { - e = ETYPE_DES3_CBC_SHA1; - etypes = &e; - num_etypes = 1; - continue; - } else { - ret = krb5_string_to_enctype(context, buf[i], &e); - if(ret == 0) { - etypes = &e; - num_etypes = 1; - continue; - } - } - } - if(salt.salttype == 0) { - /* interpret string as a salt specifier, if no etype - is set, this sets default values */ - /* XXX should perhaps use string_to_salttype, but that - interface sucks */ - if(strcmp(buf[i], "pw-salt") == 0) { - if(etypes == NULL) { - etypes = all_etypes; - num_etypes = 4; - } - salt.salttype = KRB5_PW_SALT; - } else if(strcmp(buf[i], "afs3-salt") == 0) { - if(etypes == NULL) { - etypes = all_etypes + 1; - num_etypes = 3; - } - salt.salttype = KRB5_AFS3_SALT; - } - } else { - /* if there is a final string, use it as the string to - salt with, this is mostly useful with null salt for - v4 compat, and a cell name for afs compat */ - salt.saltvalue.data = buf[i]; - salt.saltvalue.length = strlen(buf[i]); - salt_set = TRUE; - } - } - - if(etypes == NULL || salt.salttype == 0) { - krb5_warnx(context, "bad value for default_keys `%s'", *kp); - continue; - } - - if(!salt_set) { - /* make up default salt */ - if(salt.salttype == KRB5_PW_SALT) - ret = krb5_get_pw_salt(context, principal, &salt); - else if(salt.salttype == KRB5_AFS3_SALT) { - krb5_realm *realm = krb5_princ_realm(context, principal); - salt.saltvalue.data = strdup(*realm); - if(salt.saltvalue.data == NULL) { - krb5_set_error_string(context, "out of memory while " - "parsinig salt specifiers"); - ret = ENOMEM; - goto out; - } - strlwr(salt.saltvalue.data); - salt.saltvalue.length = strlen(*realm); - salt_set = 1; - } - } - memset(&key, 0, sizeof(key)); - for(i = 0; i < num_etypes; i++) { - Key *k; - for(k = keys; k < keys + num_keys; k++) { - if(k->key.keytype == etypes[i] && - ((k->salt != NULL && - k->salt->type == salt.salttype && - k->salt->salt.length == salt.saltvalue.length && - memcmp(k->salt->salt.data, salt.saltvalue.data, - salt.saltvalue.length) == 0) || - (k->salt == NULL && - salt.salttype == KRB5_PW_SALT && - !salt_set))) - goto next_etype; - } - - ret = krb5_string_to_key_salt (context, - etypes[i], - password, - salt, - &key.key); - - if(ret) - goto out; - - if (salt.salttype != KRB5_PW_SALT || salt_set) { - key.salt = malloc (sizeof(*key.salt)); - if (key.salt == NULL) { - free_Key(&key); - ret = ENOMEM; - goto out; - } - key.salt->type = salt.salttype; - krb5_data_zero (&key.salt->salt); - - /* is the salt has not been set explicitly, it will be - the default salt, so there's no need to explicitly - copy it */ - if (salt_set) { - ret = krb5_data_copy(&key.salt->salt, - salt.saltvalue.data, - salt.saltvalue.length); - if (ret) { - free_Key(&key); - goto out; - } - } - } - tmp = realloc(keys, (num_keys + 1) * sizeof(*keys)); - if(tmp == NULL) { - free_Key(&key); - ret = ENOMEM; - goto out; - } - keys = tmp; - keys[num_keys++] = key; - next_etype:; - } - } - - if(num_keys == 0) { - /* if we didn't manage to find a single valid key, create a - default set */ - /* XXX only do this is there is no `default_keys'? */ - krb5_salt v5_salt; - tmp = realloc(keys, (num_keys + 4) * sizeof(*keys)); - if(tmp == NULL) { - ret = ENOMEM; - goto out; - } - keys = tmp; - ret = krb5_get_pw_salt(context, principal, &v5_salt); - if(ret) - goto out; - for(i = 0; i < 4; i++) { - memset(&key, 0, sizeof(key)); - ret = krb5_string_to_key_salt(context, all_etypes[i], password, - v5_salt, &key.key); - if(ret) { - krb5_free_salt(context, v5_salt); - goto out; - } - keys[num_keys++] = key; - } - krb5_free_salt(context, v5_salt); - } - - out: - if(ret == 0) { - *keys_ret = keys; - *num_keys_ret = num_keys; - } else { - for(i = 0; i < num_keys; i++) { - free_Key(&keys[i]); - } - free(keys); - } - return ret; -} +RCSID("$Id: set_keys.c 15888 2005-08-11 13:40:35Z lha $"); /* * Set the keys of `ent' to the string-to-key of `password' @@ -295,20 +44,31 @@ _kadm5_set_keys(kadm5_server_context *context, hdb_entry *ent, const char *password) { - kadm5_ret_t ret; Key *keys; size_t num_keys; + kadm5_ret_t ret; - ret = make_keys(context->context, ent->principal, password, - &keys, &num_keys); - - if(ret) + ret = hdb_generate_key_set_password(context->context, + ent->principal, + password, &keys, &num_keys); + if (ret) return ret; - - _kadm5_free_keys (context, ent->keys.len, ent->keys.val); + + _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); ent->keys.val = keys; ent->keys.len = num_keys; - ent->kvno++; + + hdb_entry_set_pw_change_time(context->context, ent, 0); + + if (krb5_config_get_bool_default(context->context, NULL, FALSE, + "kadmin", "save-password", NULL)) + { + ret = hdb_entry_set_password(context->context, context->db, + ent, password); + if (ret) + return ret; + } + return 0; } @@ -358,13 +118,16 @@ _kadm5_set_keys2(kadm5_server_context *context, } else keys[i].salt = NULL; } - _kadm5_free_keys (context, ent->keys.len, ent->keys.val); + _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); ent->keys.len = len; ent->keys.val = keys; - ent->kvno++; + + hdb_entry_set_pw_change_time(context->context, ent, 0); + hdb_entry_clear_password(context->context, ent); + return 0; out: - _kadm5_free_keys (context, len, keys); + _kadm5_free_keys (context->context, len, keys); return ret; } @@ -399,17 +162,33 @@ _kadm5_set_keys3(kadm5_server_context *context, goto out; keys[i].salt = NULL; } - _kadm5_free_keys (context, ent->keys.len, ent->keys.val); + _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); ent->keys.len = len; ent->keys.val = keys; - ent->kvno++; + + hdb_entry_set_pw_change_time(context->context, ent, 0); + hdb_entry_clear_password(context->context, ent); + return 0; out: - _kadm5_free_keys (context, len, keys); + _kadm5_free_keys (context->context, len, keys); return ret; } /* + * + */ + +static int +is_des_key_p(int keytype) +{ + return keytype == ETYPE_DES_CBC_CRC || + keytype == ETYPE_DES_CBC_MD4 || + keytype == ETYPE_DES_CBC_MD5; +} + + +/* * Set the keys of `ent' to random keys and return them in `n_keys' * and `new_keys'. */ @@ -420,80 +199,75 @@ _kadm5_set_keys_randomly (kadm5_server_context *context, krb5_keyblock **new_keys, int *n_keys) { - kadm5_ret_t ret = 0; - int i; - unsigned len; - krb5_keyblock *keys; - Key *hkeys; - - len = n_des_types + 1; - keys = malloc (len * sizeof(*keys)); - if (keys == NULL) - return ENOMEM; - - for (i = 0; i < len; ++i) { - keys[i].keyvalue.length = 0; - keys[i].keyvalue.data = NULL; - } - - hkeys = malloc (len * sizeof(*hkeys)); - if (hkeys == NULL) { - free (keys); - return ENOMEM; - } - - _kadm5_init_keys (hkeys, len); + krb5_keyblock *kblock = NULL; + kadm5_ret_t ret = 0; + int i, des_keyblock; + size_t num_keys; + Key *keys; + + ret = hdb_generate_key_set(context->context, ent->principal, + &keys, &num_keys, 1); + if (ret) + return ret; - ret = krb5_generate_random_keyblock (context->context, - des_types[0], - &keys[0]); - if (ret) - goto out; + kblock = malloc(num_keys * sizeof(kblock[0])); + if (kblock == NULL) { + ret = ENOMEM; + _kadm5_free_keys (context->context, num_keys, keys); + return ret; + } + memset(kblock, 0, num_keys * sizeof(kblock[0])); + + des_keyblock = -1; + for (i = 0; i < num_keys; i++) { + + /* + * To make sure all des keys are the the same we generate only + * the first one and then copy key to all other des keys. + */ + + if (des_keyblock != -1 && is_des_key_p(keys[i].key.keytype)) { + ret = krb5_copy_keyblock_contents (context->context, + &kblock[des_keyblock], + &kblock[i]); + if (ret) + goto out; + kblock[i].keytype = keys[i].key.keytype; + } else { + ret = krb5_generate_random_keyblock (context->context, + keys[i].key.keytype, + &kblock[i]); + if (ret) + goto out; - ret = krb5_copy_keyblock_contents (context->context, - &keys[0], - &hkeys[0].key); - if (ret) - goto out; + if (is_des_key_p(keys[i].key.keytype)) + des_keyblock = i; + } - for (i = 1; i < n_des_types; ++i) { - ret = krb5_copy_keyblock_contents (context->context, - &keys[0], - &keys[i]); - if (ret) - goto out; - keys[i].keytype = des_types[i]; ret = krb5_copy_keyblock_contents (context->context, - &keys[0], - &hkeys[i].key); + &kblock[i], + &keys[i].key); if (ret) goto out; - hkeys[i].key.keytype = des_types[i]; - } - - ret = krb5_generate_random_keyblock (context->context, - ETYPE_DES3_CBC_SHA1, - &keys[n_des_types]); - if (ret) - goto out; + } - ret = krb5_copy_keyblock_contents (context->context, - &keys[n_des_types], - &hkeys[n_des_types].key); - if (ret) - goto out; - - _kadm5_free_keys (context, ent->keys.len, ent->keys.val); - ent->keys.len = len; - ent->keys.val = hkeys; - ent->kvno++; - *new_keys = keys; - *n_keys = len; - return ret; out: - for (i = 0; i < len; ++i) - krb5_free_keyblock_contents (context->context, &keys[i]); - free (keys); - _kadm5_free_keys (context, len, hkeys); - return ret; + if(ret) { + for (i = 0; i < num_keys; ++i) + krb5_free_keyblock_contents (context->context, &kblock[i]); + free(kblock); + _kadm5_free_keys (context->context, num_keys, keys); + return ret; + } + + _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); + ent->keys.val = keys; + ent->keys.len = num_keys; + *new_keys = kblock; + *n_keys = num_keys; + + hdb_entry_set_pw_change_time(context->context, ent, 0); + hdb_entry_clear_password(context->context, ent); + + return 0; } diff --git a/crypto/heimdal/lib/kadm5/set_modifier.c b/crypto/heimdal/lib/kadm5/set_modifier.c index 2b09745..6296519 100644 --- a/crypto/heimdal/lib/kadm5/set_modifier.c +++ b/crypto/heimdal/lib/kadm5/set_modifier.c @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$Id: set_modifier.c,v 1.2 1999/12/02 17:05:07 joda Exp $"); +RCSID("$Id: set_modifier.c 7464 1999-12-02 17:05:13Z joda $"); kadm5_ret_t _kadm5_set_modifier(kadm5_server_context *context, diff --git a/crypto/heimdal/lib/kadm5/test_pw_quality.c b/crypto/heimdal/lib/kadm5/test_pw_quality.c new file mode 100644 index 0000000..745e03e --- /dev/null +++ b/crypto/heimdal/lib/kadm5/test_pw_quality.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2003, 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kadm5_locl.h" +#include <getarg.h> + +RCSID("$Id: test_pw_quality.c 15105 2005-05-09 19:13:29Z lha $"); + +static int version_flag; +static int help_flag; +static char *principal; +static char *password; + +static struct getargs args[] = { + { "principal", 0, arg_string, &principal }, + { "password", 0, arg_string, &password }, + { "version", 0, arg_flag, &version_flag }, + { "help", 0, arg_flag, &help_flag } +}; +int num_args = sizeof(args) / sizeof(args[0]); + +int +main(int argc, char **argv) +{ + krb5_error_code ret; + krb5_context context; + krb5_principal p; + const char *s; + krb5_data pw_data; + + krb5_program_setup(&context, argc, argv, args, num_args, NULL); + + if(help_flag) + krb5_std_usage(0, args, num_args); + if(version_flag) { + print_version(NULL); + exit(0); + } + + if (principal == NULL) + krb5_errx(context, 1, "no principal given"); + if (password == NULL) + krb5_errx(context, 1, "no password given"); + + ret = krb5_parse_name(context, principal, &p); + if (ret) + krb5_errx(context, 1, "krb5_parse_name: %s", principal); + + pw_data.data = password; + pw_data.length = strlen(password); + + kadm5_setup_passwd_quality_check (context, NULL, NULL); + ret = kadm5_add_passwd_quality_verifier(context, NULL); + if (ret) + krb5_errx(context, 1, "kadm5_add_passwd_quality_verifier"); + + s = kadm5_check_password_quality (context, p, &pw_data); + if (s) + krb5_errx(context, 1, "kadm5_check_password_quality:\n%s", s); + + krb5_free_principal(context, p); + krb5_free_context(context); + + return 0; +} diff --git a/crypto/heimdal/lib/kadm5/version-script.map b/crypto/heimdal/lib/kadm5/version-script.map new file mode 100644 index 0000000..90bd6fe --- /dev/null +++ b/crypto/heimdal/lib/kadm5/version-script.map @@ -0,0 +1,66 @@ +# $Id$ + +HEIMDAL_KAMD5_SERVER_1.0 { + global: + kadm5_ad_init_with_password; + kadm5_ad_init_with_password_ctx; + kadm5_add_passwd_quality_verifier; + kadm5_check_password_quality; + kadm5_chpass_principal; + kadm5_chpass_principal_with_key; + kadm5_create_principal; + kadm5_delete_principal; + kadm5_destroy; + kadm5_flush; + kadm5_free_key_data; + kadm5_free_name_list; + kadm5_free_principal_ent; + kadm5_get_principal; + kadm5_get_principals; + kadm5_get_privs; + kadm5_init_with_creds; + kadm5_init_with_creds_ctx; + kadm5_init_with_password; + kadm5_init_with_password_ctx; + kadm5_init_with_skey; + kadm5_init_with_skey_ctx; + kadm5_modify_principal; + kadm5_randkey_principal; + kadm5_rename_principal; + kadm5_ret_key_data; + kadm5_ret_principal_ent; + kadm5_ret_principal_ent_mask; + kadm5_ret_tl_data; + kadm5_setup_passwd_quality_check; + kadm5_store_key_data; + kadm5_store_principal_ent; + kadm5_store_principal_ent_mask; + kadm5_store_tl_data; + kadm5_s_init_with_password_ctx; + kadm5_s_init_with_password; + kadm5_s_init_with_skey_ctx; + kadm5_s_init_with_skey; + kadm5_s_init_with_creds_ctx; + kadm5_s_init_with_creds; + kadm5_s_chpass_principal_cond; + kadm5_log_set_version; + kadm5_log_signal_socket; + kadm5_log_previous; + kadm5_log_goto_end; + kadm5_log_foreach; + kadm5_log_get_version_fd; + kadm5_log_get_version; + kadm5_log_replay; + kadm5_log_end; + kadm5_log_reinit; + kadm5_log_init; + kadm5_log_nop; + kadm5_log_truncate; + kadm5_log_modify; + _kadm5_acl_check_permission; + _kadm5_unmarshal_params; + _kadm5_s_get_db; + _kadm5_privs_to_string; + local: + *; +}; |