+++ /dev/null
-Thu Jun 13 22:08:34 1996 Tom Yu <tlyu@voltage-multiplier.mit.edu>
-
- * configure.in: remove ref to ET_RULES
-
-Mon Apr 8 03:35:08 1996 Ken Raeburn <raeburn@cygnus.com>
-
- * srv_key.c (key_init): Only pass one argument to
- key_get_admin_entry.
- (key_string2key_keysalt): After calling krb5_string_to_key, fix
- the length of AFS salts.
-
- * srv_main.c (main): Initialize def_expiration and def_flags, to
- keep codecenter happy.
-
- * srv_output.c (output_krb5_errmsg): Removed unused variable
- alen.
-
-Tue Apr 2 18:50:51 1996 Chris Provenzano <proven@cygnus.com>
-
- * srv_acl.c (acl_load_acl_file()) : Copy the static string to a temporary
- buffer for hpux 9 before passing it into sscanf. This is a kludge
- and the correct fix is to rewrite the entire file to not use
- sscanf and stdio.
-
-Thu Mar 28 20:03:35 1996 Ken Raeburn <raeburn@cygnus.com>
-
- * srv_net.c (net_dispatch): New argument DETACHED. Shut down on
- SIGHUP if not detached.
- * srv_main.c (main): Pass extra arg to net_dispatch.
- * kadm5_defs.h (net_dispatch): Updated prototype.
-
-Sun Mar 3 12:52:49 1996 Ezra Peisach <epeisach@kangaroo.mit.edu>
-
- * srv_main.c: Move inclusion of k5-int.h before testing if
- HAVE_STDARG_H is defined.
-
-Wed Feb 21 21:26:50 1996 Mark Eichin <eichin@cygnus.com>
-
- * srv_main.c (xprintf): handle VARARGS.
-
-Sun Feb 18 00:08:02 1996 Mark W. Eichin <eichin@cygnus.com>
-
- * admin.c (admin_merge_dbentries): rewrite for readability, and
- fix the year old bug of modify randomizing the password field.
- (admin_add_modify): rewrite for readability.
-
-Fri Feb 9 20:11:50 1996 Mark Eichin <eichin@cygnus.com>
-
- * srv_net.c (net_init): gethostbyname doesn't use errno,
- compensate by using KRB5_ERR_BAD_HOSTNAME.
-
-Tue Dec 12 19:14:51 1995 Mark Eichin <eichin@cygnus.com>
-
- * admin.c (admin_merge_dbentries): new argument mod_only, to
- distinguish between add and modify.
- (admin_add_modify): new argument mod_only, to distinguish between
- add and modify (and pass through to admin_merge_dbentries.)
- (admin_add_principal, admin_modify_principal, admin_change_opwd,
- admin_change_orandpw): pass flag indicating modify or add.
-
-Thu Nov 9 01:00:51 1995 Mark W. Eichin <eichin@cygnus.com>
-
- * srv_key.c (key_string_to_keys): support KRB5_KDB_SALTTYPE_AFS3
- using the same length -1 trick from lib/krb5/krb/get_in_tkt.c.
-
-Tue Sep 26 22:51:25 1995 Mark Eichin <eichin@cygnus.com>
-
- * admin.c (admin_add_modify): copy, don't just assign, principals
- to avoid double-freeing. Zero out "contents" and mod_name fields
- after freeing, likewise. Free cur_dbentry and new_dbentry properly.
-
-Tue Sep 26 02:56:41 1995 Mark Eichin <eichin@cygnus.com>
-
- * srv_acl.c (acl_free_entries): jump the ae_next link *before*
- freeing the item so we don't lose it.
-
-Tue Sep 26 02:28:35 1995 Mark Eichin <eichin@cygnus.com>
-
- * admin.c (admin_merge_dbentries): copy who into dbentp->mod_name
- because callers will free it after successful use.
-
-Wed Sep 13 22:08:56 1995 Theodore Y. Ts'o (tytso@dcl)
-
- * srv_key.c (key_string2key_keysalt and key_randomkey_keysalt):
- Install really ugly hack to prevent these routines from munging
- the master_encblock. This is not the correct fix. Proven
- will be making the correct fix which will involve removing
- these routines and using the corect libkdb functions.
-
- * srv_key.c (key_encrypt_keys): Remove equally errneous
- krb5_use_enctype() call from key_encrypt_keys().
-
- * srv_key.c (key_decrypt_keys): Keys are encrypted in the key of
- the master key encryption type, not in the keytype of the
- key!!! Removed erroneous krb5_use_enctype() call.
-
- Fixed -Wall flames all over the file.
-
-Thu Sep 7 17:52:24 1995 Theodore Y. Ts'o <tytso@dcl>
-
- * srv_key.c: Globally change use of ENCTYPE_DES_CBC_MD5 to
- DEFAULT_KDC_ENCTYPE, so that we use the same encryption
- type by default for all KDC server programs.
-
- * srv_main.c (main): Set the default realm from the -r argument,
- so that correct defaulting takes place for things like
- krb5_parse().
-
- * srv_net.c (net_init): Use KRB5_ADM_SERVICE_INSTANCE to determine
- the service instance, instance of KRB5_ADMIN_SERVICE_NAME.
-
-Wed Sep 06 14:20:57 1995 Chris Provenzano (proven@mit.edu)
-
- * admin.c, passwd.c, srv_key.c, srv_main.c :
- s/keytype/enctype/g, s/KEYTYPE/ENCTYPE/g
-
-Tue Sep 05 22:10:34 1995 Chris Provenzano (proven@mit.edu)
-
- * admin.c, kadm5_defs.h, srv_key.c, srv_main.c : Remove krb5_enctype
- references, and replace with krb5_keytype where appropriate.
-
-Thu Aug 31 16:07:24 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_acl.c, kadm5_defs.h - Change operation of acl_op_permitted(). It
- now takes another argument which is the name of the target of
- the operation. This allows finer granularity of control over
- administrative operations for clients.
- * srv_acl.c - Change SIGALRM to SIGHUP under POSIX_SIGNALS. We want
- SIGHUP to reread the ACL file.
- * admin.c, passwd.c - Conform to new ACL operations.
- * kadmind5.M - Change description of ACL file.
-
-
-Fri Aug 25 17:40:52 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_key.c - Fix automatic generation of changepw service which got
- screwed up when the database changes went in.
-
-
-Thu Aug 17 13:50:28 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_key.c, kadm5_defs.h - Add key_{open,close}_db(). Close database
- after initialization.
- * proto_serv.c - Open the database after reading a command and close
- it before sending a response.
-
-
-Tue Aug 15 14:28:03 EDT 1995 Paul Park (pjpark@mit.edu)
- * kadm5_defs.h, admin.c, passwd.c, srv_key.c - Replace key_name_to_data
- with krb5_dbe_find_keytype().
-
-
-Thu Aug 10 14:34:31 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_key.c - Consolidate handling of tagged database attributes here
- in key_update_tl_attrs(). Fix a bug which was never encountered
- * kadm5_defs.h - Add prototype for key_update_tl_attrs().
- * admin.c, passwd.c - Use key_update_tl_attrs() where appropriate.
-
-
-Wed Aug 9 17:09:35 EDT 1995 Paul Park (pjpark@mit.edu)
- * admin.c - Add code to use kdb5's change-password interfaces under
- USE_KDB5_CPW for now until it's fully shaken out.
- - Fix a memory leak in admin_add_modify.
- - Handle null return from krb5_dbe_decode_mod_princ_data().
- * passwd.c - Add code to use kdb5's change-password interfaces under
- USE_KDB5_CPW for now until it's fully shaken out.
- - Fix a memory leak in passwd_check_opass_ok()
- * proto_serv.c - Use krb5_auth_context_free() to free the auth_context
- instead of krb5_xfree().
- * srv_acl.c - Fix Purify complaint about reading freed data.
- * srv_key.c - Add krb5_use_keytype() for each keytype. Add key_master_
- encblock() for usage by kdb5's change-password interfaces.
- * srv_net.c - Change sense of test to mark slave entry freed. This
- allows us to work for a while while debugging and slave creation
- disable.
- * kadm5_defs.h - Add prototype for key_master_encblock().
-
-
-Tue Aug 8 17:30:36 EDT 1995 Paul Park (pjpark@mit.edu)
- * admin.c - Allow multiple key/salt strings to be parsed. Fix key
- merging logic. Fix some Purify complaints.
- * srv_key.c(key_string_to_key) - Don't deallocate key/salt tuples if
- supplied by caller.
- * proto_serv.c - Under POSIX_SETJMP use sigjmp_buf.
- * srv_main.c - Under POSIX_SETJMP, use sigjmp_buf.
- * srv_net.c - Under POSIX_SETJMP, use sigjmp_buf.
- * srv_output.c - Support new protocol error messages.
-
-
-Mon Aug 7 17:34:52 EDT 1995 Paul Park (pjpark@mit.edu)
- * admin.c - Fix key list merging so that key version numbers are
- generated and merged correctly.
- * srv_key.c - Handle V4 salttype correctly.
-
-
-Fri Aug 4 16:14:36 EDT 1995 Paul Park (pjpark@mit.edu)
- * admin.c - Add support for "ADD-KEY" and "DELETE-KEY" protocol requests
- as well as adding the ability to keep previous random keys
- lying around after change.
- * kadm5_defs.h - Update key handling prototypes and add prototypes for
- newly visible routines.
- * passwd.c - Make passwd_check_opass_ok() visible so that admin.c can
- use it to check the password against existing keys. Also, use
- macro to encode last_pwd_change and mod_date data.
- * proto_serv.c - Add support for "ADD-KEY" and "DELETE-KEY" protocol
- requests. Change KRB_ERR_GENERIC to KRB5KRB_ERR_GENERIC.
- * srv_key.c - Use krb5_keysalt_iterate() to iterate over the desired
- key/salt types for key_string_to_keys() and key_random_key().
- Find the latest admin key instead of assuming that the first
- key is the one to use.
-
-Thu Aug 3 11:40:24 EDT 1995 Paul Park (pjpark@mit.edu)
- * kadm5_defs.h - Include adm.h, update prototypes.
- * admin,passwd.c - Rework database entry merge logic to use new database
- entry format. Use new callling sequences to key_{string_to,
- encrypt,decrypt,random}_keys.
- * srv_key.c - Rework database handling logic to use new database entry
- format. Store all admin keys and use the first one as the
- admin key for now. Rework key_{string_to,encrypt,decrypt,
- random}_keys.
- * srv_main.c - Handle the key/salt pair list and pass it to key_init.
- * srv_net.c - Clean up debugging messages.
-
-
-Thu Jul 27 15:08:29 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_key.c - Remove inclusion of "mit-des.h", it's no longer needed.
- Use KRB5_MIT_DES_KEYSIZE instead of sizeof(mit_des_cblock).
-
-
-Mon Jul 17 15:07:08 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_main.c - Add stash-file handling and supply appropriate value to
- krb5_db_fetch_mkey(). Add KDC profile reading/handling to
- supercede any values supplied on the command line. Add call
- to new admin_init() which initializes the admin module.
- * srv_key.c - Add stash-file handling.
- * admin.c - Add admin_init() which takes supplied per-realm defaults to
- initialize the default database entry.
- * kadm5_defs.h - Change PROTOTYPE to KRB5_PROTOTYPE. Update prototype
- for key_init and add admin_init.
- * kadmind5.M - Add description of -s stashfile.
-
-
-Fri Jul 7 16:01:37 EDT 1995 Paul Park (pjpark@mit.edu)
- * Makefile.in - Remove all explicit library handling and LDFLAGS.
- * configure.in - Add USE_<mumble> and KRB5_LIBRARIES.
-
-
-Fri Jun 30 14:35:00 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_main.c - Instead of moving up the initialization and calls to
- key_init() before the call to daemon(), have daemon() not
- disassociate from the terminal if the -m flag is set.
- * configure.in - Add --with-dbm to select between Berkeley and DBM
- KDC database format.
-
-Tue Jun 27 18:14:33 1995 Sam Hartman <hartmans@tardis.MIT.EDU>
-
- * srv_main.c (main): Rearrange code so that we ask for the master key *before* we detach from the controlling terminal. This causes the Kerberos context to be initialized in the parent before the fork; I'm not sure if this is acceptable or not.
-
-Tue Jun 27 16:02:24 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_net.c, srv_acl.c, proto_serv.c - Add signal name parameter to
- signal handlers to conform to prototype.
-
-Thu Jun 15 17:54:31 EDT 1995 Paul Park (pjpark@mit.edu)
- * Makefile.in - Change explicit library names to -l<lib> form, and
- change target link line to use $(LD) and associated flags.
- Also, remove DBMLIB, it was not used.
- * configure.in - Remove dbm library checks, these are no longer needed
- with the Berkeley database code. Also, add shared library
- usage check.
-
-Wed Jun 14 17:19:09 1995 Sam Hartman <hartmans@tardis.MIT.EDU>
-
- * srv_acl.c (acl_get_line): Check to make sure we haven't exceeded
- the buffer size before overwriting the newline we may have just
- read. If the newline is clobbered, there is no way of
- distinguishing between a line that uses the full buffer from a
- line longer than the full buffer. Also, cast EOF to a char, so
- that it works on unsigned char systems. This means you can't
- distinguish reading 0xff at the beginning of a line from EOF, but
- the only other option is to introduce an intermediate variable.
-
-
-Tue Jun 13 11:36:52 1995 Sam Hartman <hartmans@tardis.MIT.EDU>
-
- * srv_net.c: Include sys/select.h if it is found.
-
- * configure.in: Check for sys/select.h; needed under AIX to define fd_set and associated macros.
-
-
-Sat Jun 10 23:04:00 1995 Tom Yu (tlyu@dragons-lair)
-
- * kadm5_defs.h, passwd.c, proto_serv.c: krb5_auth_context
- redefinitions
-
-Fri Jun 9 19:06:04 1995 <tytso@rsx-11.mit.edu>
-
- * configure.in: Remove standardized set of autoconf macros, which
- are now handled by CONFIG_RULES.
-
-Thu Jun 8 14:46:05 EDT 1995 Paul Park (pjpark@mit.edu)
- * admin.c, passwd.c, srv_acl.c - Supply severities for error messages.
- * proto_serv.c, srv_net.c - Supply severities for error messages and
- change DLOG to DPRINT.
- * srv_main.c - Supply severities for error messages. Remove com_err
- handling and syslog() logic for routines in libkadm.
-
-Wed Jun 7 12:03:10 1995 <tytso@rsx-11.mit.edu>
-
- * Makefile.in (CFLAGS), srv_acl.c (acl_init): Use
- KRB5_DEFAULT_ADMIN_ACL defined in osconf.h
-
-Tue Jun 6 19:42:18 1995 Ezra Peisach <epeisach@kangaroo.mit.edu>
-
- * srv_key.c (key_decrypt_keys): On error, when clearing keyblocks,
- set contents to null.
- (key_get_admin_entry): Allocate enough memory for
- admin_princ_name.
- Initialize akey and pkey to zero.
- Cannot use krb5_free_keyblock on stack
- based keyblock.
- (key_finish): Cannot use krb5_free_keyblock on bss based
- keyblock.
-
-Mon Jun 5 14:14:10 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_key.c(key_get_admin_entry) - When adding database entry for
- changepw principal, supply a maximum life and maximum renewable
- lifetime so that it doesn't end up being zero.
-
-
-Thu Jun 1 14:34:41 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_acl.c: Change default acl file name to be a #define. If it
- is not defined, then default to /krb5/krb5_adm.acl.
- * srv_key.c: Add logic to retrieve or create the database entry for
- the password changing service. Subsequently, squirrel away
- the key so that we do not need a srvtab.
- * proto_serv.c: If no srvtab is specified, then use the squirreled
- admin key so that we can live without a srvtab.
- * kadm5_defs.h: Add prototype for admin key routine.
- * Makefile.in: Set the default acl file to be $(KRB5ROOT)/krb5_adm.acl.
- * kadmind5.M: Add description of missing flags. Removed file names.
-
-Sun May 28 15:58:15 1995 Ezra Peisach <epeisach@kangaroo.mit.edu>
-
- * srv_main.c (main): Use exit instead of return from
- main. Otherwise may return to a signal interrupt on
- shutdown.
- On shutdown - do not output message as stdout may
- be closed on receivers end.
-
-Fri May 26 17:50:13 EDT 1995 Paul Park (pjpark@mit.edu)
- * Makefile.in - Add KDBLIB to dependency list.
-
-
-Mon May 22 09:46:53 EDT 1995 Paul Park (pjpark@mit.edu)
- * Makefile.in - Install kadmind5 in $(SERVER_BINDIR), install
- manpage in $(SERVER_MANDIR).
- * kadmind5.M - Change section to section 8.
-
-
-Tue May 16 10:31:12 EDT 1995 Paul Park (pjpark@mit.edu)
- * proto_serv.c - Don't destroy the replay cache when done.
-
-
-Fri May 12 16:06:24 EDT 1995 Paul Park (pjpark@mit.edu)
- * admin.c - Change for Ultrix: howmany->how_many because howmany
- is a macro used to count how many elements in an
- array.
- * kadm5_defs.h, srv_net.c
- - Use DEBUG_NOSLAVES to determine when to create a
- new slave for handling connections. Also, change
- max slaves to 2*SOMAXCONN and reduce sleep wait to
- 2 seconds.
- * configure.in, proto_serv.c, srv_acl.c, srv_main.c, srv_net.c
- - Use POSIX signals/setjmp/longjmp when present.
-
-
-Thu May 11 12:20:58 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_key.c - Defer setting keyb and encb init flags until we
- have successfully verified the master key. Avoids
- a core dump if we don't enter it correctly.
- * srv_net.c - Set SO_REUSEADDR on the socket if we're not binding
- to the standard port. Also remove logic which
- retried bind if bind failed.
-
-Sat May 9 17:46:31 1995 Ezra Peisach <epeisach@kangaroo.mit.edu>
-
- * srv_output.c (lang_error_message): Local variable is assigned
- from error_message() which returns a const char *. Should
- be assigned to same.
-
- * srv_acl.c: Added const to acl_acl_file
- definition. default_acl_file is a const char * and gets
- assigned to it.
-
-Tue May 9 15:29:10 EDT 1995 Paul Park (pjpark@mit.edu)
- Add new administrative protocol support functions and fix bugs.
- * kadm5_defs.h - Add extract operation. Move error subcodes
- to adm.h. Update prototypes.
- * kadmind5.M - Add descriptions of -n, -p and -T options. Change
- name of -i to -m option. Add description of
- 'e' acl entry.
- * passwd.c - Make passwd_check_npass_ok a global routine.
- * proto_serv.c - Use keytab supplied with -T option. Support
- new administrative protocol functions. Destroy
- replay cache when done with request.
- * srv_acl.c - Add catchall entry which allows principals to
- change their own passwords. This is the last entry
- inserted and can be overridden with an entry in
- the ACL file. By default, we now deny operations
- unless there is an entry.
- * srv_key.c - Use keytab supplied with -T option. Actually set
- the default realm to be the specified realm. Return
- salt values from key_string_to_keys(). Add random
- key generator.
- * srv_main.c - Add support for -T option. Change -i to -m. Add
- daemon() call if -n option is not specified. Add
- support for -p option.
- * srv_net.c - Close connected socket in parent. This was causing
- the connection to remain open even when the child
- was finished with it. Add support for -p option.
- Determine our port otherwise from the profile, and
- then the /etc/services entry.
- * srv_output.c - Add support for new error codes.
-
-Fri May 5 11:11:39 EDT 1995 Paul Park (pjpark@mit.edu)
- #ifdef out language flags. Remove description from manpage.
-
-
-Fri Apr 28 17:58:11 EDT 1995 Paul Park (pjpark@mit.edu)
-
- * proto_serv.c - ifdef-out commands which are not fully supported.
-
-
-Fri Apr 28 17:38:36 EDT 1995 Paul Park (pjpark@mit.edu)
-
- * srv_net.c, proto_serv.c - re-include <signal.h> for signal name
- definitions. Removal of them was over-zealous.
-
-Fri Apr 28 16:38:18 EDT 1995 Paul Park (pjpark@mit.edu)
- * srv_output.c - slight cleanup to allow output_lang_supported()
- to function correctly.
-
-
-Fri Apr 28 10:13:21 EDT 1995 Paul Park (pjpark@mit.edu)
- Add new library libkadm.
- * configure.in - Check for presence of vsprintf.
- * passwd.c - Use size_t for sizes.
- * proto_serv.c - Allow for case-insensitivity of commands.
- - Remove socket-dependent includes and add NEED_SOCKETS
- * srv_key.c - Use size_t for sizes.
- * srv_main.c - Check for presence of vsprintf.
- * srv_net.c - Remove socket-dependent includes and add NEED_SOCKETS
- - Use size_t for sizes.
- - Return success if bind succeeds.
- * srv_output.c - Add language name recoginition.
-
-Fri Apr 28 13:06:18 1995 Theodore Y. Ts'o <tytso@dcl>
-
- * srv_net.c: Linux doesn't have SOMAXCONN, assume 5 if not defined.
-
-Fri Apr 28 07:32:55 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
-
- * configure.in: Add check for -ldbm and -lndbm.
-
-Thu Apr 27 17:05:54 EDT 1995 Paul Park (pjpark@mit.edu)
-
- Update last_pwd_change, mod_name and kvno when changing password
- successfully.
-
-Wed Apr 26 16:00:00 EDT 1995 Paul Park (pjpark@mit.edu)
-
- Add new administrative protocol server which only responds to
- password requests for now.
-
+++ /dev/null
-CFLAGS = $(CCOPTS) $(DEFS) $(LOCALINCLUDE)
-
-all::
-
-SRCS = \
- $(srcdir)/srv_main.c $(srcdir)/srv_key.c \
- $(srcdir)/srv_acl.c $(srcdir)/srv_output.c $(srcdir)/srv_net.c \
- $(srcdir)/proto_serv.c $(srcdir)/passwd.c $(srcdir)/admin.c
-
-OBJS = \
- srv_main.o srv_key.o srv_acl.o srv_output.o srv_net.o \
- proto_serv.o passwd.o admin.o
-
-
-all:: kadmind5
-
-kadmind5: $(OBJS) $(DEPLIBS)
- $(LD) $(LDFLAGS) $(LDARGS) -o kadmind5 $(OBJS) $(LIBS)
-
-install::
- $(INSTALL_PROGRAM) $(C)kadmind5 ${DESTDIR}$(SERVER_BINDIR)$(S)kadmind5
- $(INSTALL_DATA) $(srcdir)$(S)kadmind5.M ${DESTDIR}$(SERVER_MANDIR)$(S)kadmind5.8
-
-clean::
- $(RM) kadmind5
-
+++ /dev/null
-/*
- * kadmin/v5server/admin.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * admin.c - Handle administrative requests.
- */
-
-#include "k5-int.h"
-#include "kadm5_defs.h"
-#include "adm.h"
-#include "adm_proto.h"
-\f
-/*
- * Data structure used to pass information in and out of krb5_db_iterate.
- */
-struct inq_context {
- krb5_context ic_context; /* in */
- int ic_level; /* in */
- krb5_principal ic_who; /* in */
- krb5_boolean ic_entry_found; /* out */
- krb5_int32 *ic_ncomps; /* out */
- krb5_data **ic_clist; /* out */
- char *ic_next; /* out */
-};
-
-static krb5_db_entry admin_def_dbent;
-
-static const char *admin_perm_denied_fmt = "\004ACL entry prevents %s operation on %s by %s";
-static const char *admin_db_write_err_fmt = "\004database write failed during %s operation by %s";
-static const char *admin_db_success_fmt = "\007%s operation for %s successfully issued by %s";
-static const char *admin_db_read_err_fmt = "\004database read failed during %s operation by %s";
-static const char *admin_no_cl_ident_fmt = "\004cannot get client identity from ticket for %s operation";
-static const char *admin_db_rename_fmt = "\007%s operation from %s to %s successfully issued by %s";
-static const char *admin_db_key_op_fmt = "\007%s operation for %s successfully issued by %s";
-static const char *admin_db_del_err_fmt = "\004database delete entry(%s) failed during %s operation by %s";
-static const char *admin_key_dec_err_fmt = "\004key decode failed for %s's key during %s operation by %s";
-
-static const char *admin_add_principal_text = "Add Principal";
-static const char *admin_modify_principal_text = "Modify Principal";
-static const char *admin_delete_principal_text = "Delete Principal";
-static const char *admin_rename_principal_text = "Rename Principal";
-static const char *admin_change_pwd_text = "Change Password";
-static const char *admin_change_rpwd_text = "Change Random Password";
-static const char *admin_inquire_text = "Inquire";
-static const char *admin_extract_key_text = "Extract Key";
-static const char *admin_add_key_text = "Add Keytype";
-static const char *admin_delete_key_text = "Delete Keytype";
-
-static const char *admin_fentry_text = "first entry";
-
-extern char *programname;
-\f
-/*
- * admin_init_def_dbent() - Initialize the default database entry.
- */
-static void
-admin_init_def_dbent(mlife, mrlife, evalid, e, fvalid, f)
- krb5_deltat mlife;
- krb5_deltat mrlife;
- krb5_boolean evalid;
- krb5_timestamp e;
- krb5_boolean fvalid;
- krb5_flags f;
-{
- /* Zero it all out, and fill in non-zero defaults */
- memset((char *) &admin_def_dbent, 0, sizeof(admin_def_dbent));
- admin_def_dbent.max_life = (mlife > 0) ? mlife : KRB5_KDB_MAX_LIFE;
- admin_def_dbent.max_renewable_life =
- (mrlife > 0) ? mrlife : KRB5_KDB_MAX_RLIFE;
- admin_def_dbent.expiration = (evalid) ? e : KRB5_KDB_EXPIRATION;
- admin_def_dbent.attributes = (fvalid) ? f : KRB5_KDB_DEF_FLAGS;
- admin_def_dbent.len = KRB5_KDB_V1_BASE_LENGTH;
-}
-\f
-/*
- * admin_client_identity() - Determine client identity from ticket
- */
-static krb5_error_code
-admin_client_identity(kcontext, debug_level, ticket, clientp, clnamep)
- krb5_context kcontext;
- int debug_level;
- krb5_ticket *ticket;
- krb5_principal *clientp;
- char **clnamep;
-{
- krb5_error_code kret = 0;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* admin_client_identity()\n"));
- *clientp = (krb5_principal) NULL;
- *clnamep = (char *) NULL;
-
- /* Copy principal out of ticket */
- if (!(kret = krb5_copy_principal(kcontext,
- ticket->enc_part2->client,
- clientp))) {
- /* Flatten name */
- if (kret = krb5_unparse_name(kcontext, *clientp, clnamep)) {
- krb5_free_principal(kcontext, *clientp);
- *clientp = (krb5_principal) NULL;
- }
- }
-
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_client_identity()=%d\n", kret));
- return(kret);
-}
-\f
-/*
- * admin_merge_keys() - Merge two keylists.
- *
- * Fold "in1" into "in2" and put the results in "outp"
- */
-static krb5_error_code
-admin_merge_keys(kcontext, dbentp, unique,
- nkeys1, in1, nkeys2, in2, nkeysout, outp)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_boolean unique;
- krb5_int32 nkeys1;
- krb5_key_data *in1;
- krb5_int32 nkeys2;
- krb5_key_data *in2;
- krb5_int32 *nkeysout;
- krb5_key_data **outp;
-{
- krb5_error_code kret;
- int i;
- krb5_int32 numout;
- krb5_key_salt_tuple *kslist;
- krb5_int32 nksents;
- krb5_key_data *keylist;
- krb5_db_entry xxx1,xxx2;
- krb5_key_data *kp1, *kp2;
-
- keylist = (krb5_key_data *) NULL;
- kret = 0;
- numout = 0;
- if ((keylist = (krb5_key_data *) malloc(sizeof(krb5_key_data) *
- (nkeys1+nkeys2)))) {
- memset(keylist, 0, sizeof(krb5_key_data) * (nkeys1+nkeys2));
- if (!unique) {
- /* The easy case */
- /*
- * Start with "in1" - it's newer.
- */
- for (i=0; i<nkeys1; i++) {
- if ((keylist[numout].key_data_contents[0] =
- (krb5_octet *) malloc(in1[i].key_data_length[0])) &&
- (!in1[i].key_data_length[1] ||
- (keylist[numout].key_data_contents[1] =
- (krb5_octet *) malloc(in1[i].key_data_length[1])))) {
- keylist[numout].key_data_ver = in1[i].key_data_ver;
- keylist[numout].key_data_kvno = in1[i].key_data_kvno;
- keylist[numout].key_data_type[0] = in1[i].key_data_type[0];
- keylist[numout].key_data_type[1] = in1[i].key_data_type[1];
- if (keylist[numout].key_data_length[0] =
- in1[i].key_data_length[0])
- memcpy(keylist[numout].key_data_contents[0],
- in1[i].key_data_contents[0],
- in1[i].key_data_length[0]);
- if (keylist[numout].key_data_length[1] =
- in1[i].key_data_length[1])
- memcpy(keylist[numout].key_data_contents[1],
- in1[i].key_data_contents[1],
- in1[i].key_data_length[1]);
- numout++;
- }
- }
- /*
- * Now put "in2"
- */
- for (i=0; i<nkeys2; i++) {
- if ((keylist[numout].key_data_contents[0] =
- (krb5_octet *) malloc(in2[i].key_data_length[0])) &&
- (!in2[i].key_data_length[1] ||
- (keylist[numout].key_data_contents[1] =
- (krb5_octet *) malloc(in2[i].key_data_length[1])))) {
- keylist[numout].key_data_ver = in2[i].key_data_ver;
- keylist[numout].key_data_kvno = in2[i].key_data_kvno;
- keylist[numout].key_data_type[0] = in2[i].key_data_type[0];
- keylist[numout].key_data_type[1] = in2[i].key_data_type[1];
- if (keylist[numout].key_data_length[0] =
- in2[i].key_data_length[0])
- memcpy(keylist[numout].key_data_contents[0],
- in2[i].key_data_contents[0],
- in2[i].key_data_length[0]);
- if (keylist[numout].key_data_length[1] =
- in2[i].key_data_length[1])
- memcpy(keylist[numout].key_data_contents[1],
- in2[i].key_data_contents[1],
- in2[i].key_data_length[1]);
- numout++;
- }
- }
- }
- else {
- /* Generate a unique list */
- memset(&xxx1, 0, sizeof(krb5_db_entry));
- memcpy(keylist, in2, sizeof(krb5_key_data) * nkeys2);
- memcpy(&keylist[nkeys2], in1, sizeof(krb5_key_data) * nkeys1);
- xxx1.n_key_data = (krb5_int16) (nkeys1+nkeys2);
- xxx1.key_data = keylist;
- numout = 0;
- if (!key_dbent_to_keysalts(&xxx1, &nksents, &kslist)) {
- memset(&xxx1, 0, sizeof(krb5_db_entry));
- memset(&xxx2, 0, sizeof(krb5_db_entry));
- memset(keylist, 0, sizeof(krb5_key_data) * (nkeys1+nkeys2));
- xxx1.n_key_data = nkeys1;
- xxx1.key_data = in1;
- xxx2.n_key_data = nkeys2;
- xxx2.key_data = in2;
- for (i=0; i<nksents; i++) {
- kp1 = 0; kp2 = 0;
- (void) krb5_dbe_find_enctype(kcontext,
- &xxx1,
- kslist[i].ks_enctype,
- kslist[i].ks_salttype,
- -1,
- &kp1);
- (void) krb5_dbe_find_enctype(kcontext,
- &xxx2,
- kslist[i].ks_enctype,
- kslist[i].ks_salttype,
- -1,
- &kp2);
- if (kp1 && kp2) {
- if (kp2->key_data_kvno > kp1->key_data_kvno)
- kp1 = kp2;
- }
- else {
- if (!kp1)
- kp1 = kp2;
- if (!kp1) {
- kret = KRB5KRB_ERR_GENERIC;
- break;
- }
- }
- if ((keylist[numout].key_data_contents[0] =
- (krb5_octet *) malloc(kp1->key_data_length[0])) &&
- (!kp1->key_data_length[1] ||
- (keylist[numout].key_data_contents[1] =
- (krb5_octet *) malloc(kp1->key_data_length[1])))) {
- keylist[numout].key_data_ver = kp1->key_data_ver;
- keylist[numout].key_data_kvno = kp1->key_data_kvno;
- keylist[numout].key_data_type[0] =
- kp1->key_data_type[0];
- keylist[numout].key_data_type[1] =
- kp1->key_data_type[1];
- if (keylist[numout].key_data_length[0] =
- kp1->key_data_length[0])
- memcpy(keylist[numout].key_data_contents[0],
- kp1->key_data_contents[0],
- kp1->key_data_length[0]);
- if (keylist[numout].key_data_length[1] =
- kp1->key_data_length[1])
- memcpy(keylist[numout].key_data_contents[1],
- kp1->key_data_contents[1],
- kp1->key_data_length[1]);
- numout++;
- }
- }
- krb5_xfree(kslist);
- }
- }
- }
- else
- kret = ENOMEM;
-
- if (!kret) {
- if (*outp && *nkeysout)
- key_free_key_data(*outp, *nkeysout);
- *outp = keylist;
- *nkeysout = numout;
- }
- else {
- if (keylist) {
- if (numout)
- key_free_key_data(keylist, numout);
- else
- free(keylist);
- }
- }
- return(kret);
-}
-\f
-/*
- * admin_merge_dbentries() - Merge two database entries and a password.
- */
-static krb5_error_code
-admin_merge_dbentries(kcontext, debug_level, who, defaultp,
- valid, dbentp, password, is_pwchange)
- krb5_context kcontext;
- int debug_level;
- krb5_principal who;
- krb5_db_entry *defaultp;
- krb5_ui_4 valid;
- krb5_db_entry *dbentp;
- char *password;
- krb5_boolean is_pwchange;
-{
- krb5_error_code kret = 0;
- krb5_int32 num_keys, num_ekeys, num_rkeys;
- krb5_key_data *key_list;
- krb5_key_data *ekey_list;
- DPRINT(DEBUG_CALLS, debug_level, ("* admin_merge_dbentries()\n"));
-
- /*
- * Ensure that there's a principal,
- * we have the current t-o-d,
- * and that we don't have a password and the random-password option.
- */
- kret = EINVAL;
- num_keys = num_ekeys = num_rkeys = 0;
- key_list = (krb5_key_data *) NULL;
- ekey_list = (krb5_key_data *) NULL;
- if (!dbentp->princ) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> no principal supplied???"));
- goto bailout;
- }
- if (password && (valid & KRB5_ADM_M_RANDOMKEY)) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> password and randomkey???"));
- goto bailout;
- }
- /*
- * Now fill in unsupplied values from defaults.
- */
- if ((valid & KRB5_ADM_M_MAXLIFE) == 0)
- dbentp->max_life = defaultp->max_life;
- if ((valid & KRB5_ADM_M_MAXRENEWLIFE) == 0)
- dbentp->max_renewable_life = defaultp->max_renewable_life;
- if ((valid & KRB5_ADM_M_EXPIRATION) == 0)
- dbentp->expiration = defaultp->expiration;
- if ((valid & KRB5_ADM_M_PWEXPIRATION) == 0)
- dbentp->pw_expiration = defaultp->pw_expiration;
- if ((valid & KRB5_ADM_M_FLAGS) == 0)
- dbentp->attributes = defaultp->attributes;
-
- /*
- * Now fill in un-suppliable values from our data.
- */
- dbentp->last_success = defaultp->last_success;
- dbentp->last_failed = defaultp->last_failed;
- dbentp->fail_auth_count = defaultp->fail_auth_count;
-
- dbentp->len = defaultp->len;
- kret = 0;
-
- /*
- * Update last password change (if appropriate) and modification
- * date and principal.
- */
- kret = key_update_tl_attrs(kcontext, dbentp, who,
- (password || is_pwchange));
- if (kret) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> update_tl_attrs FAILED???"));
- goto bailout;
- }
- /* See if this is a random key or not */
- if (password) {
- krb5_data pwdata;
- DPRINT(DEBUG_OPERATION, debug_level, ("> string-to-key\n"));
- /*
- * Now handle string-to-key and salt.
- */
- pwdata.data = password;
- pwdata.length = strlen(password);
-
- /* Convert password string to key */
- kret = key_string_to_keys(kcontext, ((is_pwchange) ? defaultp : dbentp),
- &pwdata, 0, (krb5_key_salt_tuple *) NULL,
- &num_keys, &key_list);
- if (kret) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> pw true, key_string_to_keys FAILED???"));
- goto bailout2;
- }
- /* Encrypt the keys */
- DPRINT(DEBUG_OPERATION, debug_level, ("> encode\n"));
- num_ekeys = num_keys;
- kret = key_encrypt_keys(kcontext, defaultp, &num_ekeys,
- key_list, &ekey_list);
- if (kret) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> pw true, key_encrypt_keys FAILED???"));
- goto bailout2;
- }
-
- num_rkeys = (krb5_int32) dbentp->n_key_data;
- kret = admin_merge_keys(kcontext, defaultp,
- 1,
- num_ekeys, ekey_list,
- (krb5_int32) defaultp->n_key_data,
- defaultp->key_data,
- &num_rkeys, &dbentp->key_data);
- dbentp->n_key_data = (krb5_int16) num_rkeys;
-
- } else if (valid & KRB5_ADM_M_RANDOMKEY) {
- /* Random key */
- DPRINT(DEBUG_OPERATION, debug_level, ("> random key\n"));
- kret = key_random_key(kcontext, ((is_pwchange) ? defaultp : dbentp),
- &num_keys, &key_list);
- if (kret) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> pw false, key_random_key FAILED???"));
- goto bailout2;
- }
-
- /* Encrypt the keys */
- DPRINT(DEBUG_OPERATION, debug_level, ("> encode\n"));
- num_ekeys = num_keys;
- kret = key_encrypt_keys(kcontext, defaultp, &num_ekeys, key_list,
- &ekey_list);
- if (kret) {
- DPRINT(DEBUG_OPERATION, debug_level, ("> pw false, key_encrypt_keys FAILED???"));
- goto bailout2;
- }
- num_rkeys = (krb5_int32) dbentp->n_key_data;
- kret = admin_merge_keys(kcontext, defaultp,
- 0,
- num_ekeys, ekey_list,
- (krb5_int32) defaultp->n_key_data,
- defaultp->key_data,
- &num_rkeys, &dbentp->key_data);
- dbentp->n_key_data = (krb5_int16) num_rkeys;
- } else {
- DPRINT(DEBUG_OPERATION, debug_level, ("> simple modify\n"));
- kret = admin_merge_keys(kcontext, defaultp,
- 0, /* only one list, so don't need unique */
- 0, 0, /* no keys in one list */
- (krb5_int32) defaultp->n_key_data,
- defaultp->key_data,
- &num_rkeys, &dbentp->key_data);
- dbentp->n_key_data = (krb5_int16) num_rkeys;
- }
- bailout2:
-
- /*
- * Finally, if this is a password change, clear the password-change
- * required bit.
- */
- if (password || is_pwchange)
- dbentp->attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
-
- bailout:
- if (key_list)
- key_free_key_data(key_list, num_keys);
- if (ekey_list)
- key_free_key_data(ekey_list, num_ekeys);
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_merge_dbentries()=%d\n", kret));
- return(kret);
-}
-\f
-/*
- * admin_add_modify() - Adds or modifies a database entry.
- *
- * Does all the work for add_principal, modify_principal, change_opwd,
- * and change_orandpwd.
- *
- * Supplied argument list must contain at least one entry, the name of the
- * target principal.
- */
-static krb5_int32
-admin_add_modify(kcontext, debug_level, ticket, nargs, arglist,
- should_exist, pwd_supplied, supp_pwd)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_int32 nargs; /* # rem. arguments */ /* In */
- krb5_data *arglist; /* Remaining arguments */ /* In */
- krb5_boolean should_exist; /* Should it exist? */ /* In */
- krb5_boolean pwd_supplied; /* Password supplied? */ /* In */
- char *supp_pwd; /* Supplied password */ /* In */
-{
- krb5_int32 retval = KRB5_ADM_SUCCESS;
- krb5_error_code kret = 0;
- krb5_principal client;
- char *client_name;
- krb5_ui_4 valid_mask;
- krb5_db_entry new_dbentry;
- krb5_db_entry cur_dbentry;
- krb5_principal principal;
- char *new_password;
- krb5_int32 operation;
- const char *op_msg;
-#ifdef DEBUG
- char *dbg_op_msg;
-#endif /* DEBUG */
- int how_many;
- krb5_boolean more;
- krb5_data pword_data;
- krb5_int32 temp;
- krb5_db_entry *merge;
- int nument;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_add_modify(%s)\n", arglist[0].data));
- /* Initialize */
- client = (krb5_principal) NULL;
- client_name = (char *) NULL;
- valid_mask = 0;
- memset((char *) &new_dbentry, 0, sizeof(new_dbentry));
- memset((char *) &cur_dbentry, 0, sizeof(cur_dbentry));
- principal = (krb5_principal) NULL;
- new_password = (char *) NULL;
-
- /* Determine what our operation is based on should_exist/pwd_supplied */
- if (should_exist) {
- if (pwd_supplied) {
- operation = ACL_CHANGEPW;
- op_msg = (supp_pwd) ? admin_change_pwd_text :
- admin_change_rpwd_text;
-#ifdef DEBUG
- dbg_op_msg = (supp_pwd) ? "CHANGE PASSWORD" :
- "CHANGE RANDOM PASSWORD";
-#endif /* DEBUG */
- } else {
- operation = ACL_MODIFY_PRINCIPAL;
- op_msg = admin_modify_principal_text;
-#ifdef DEBUG
- dbg_op_msg = "MODIFY PRINCIPAL";
-#endif /* DEBUG */
- }
- } else {
- if (pwd_supplied) {
- return(KRB5_ADM_SYSTEM_ERROR);
- } else {
- operation = ACL_ADD_PRINCIPAL;
- op_msg = admin_add_principal_text;
-#ifdef DEBUG
- dbg_op_msg = "ADD PRINCIPAL";
-#endif /* DEBUG */
- }
- }
-
- /* Get the identity of our client */
- kret = admin_client_identity(kcontext, debug_level, ticket,
- &client, &client_name);
- if (kret) {
- /* We really choked here. */
- com_err(programname, kret, admin_no_cl_ident_fmt, op_msg);
- retval = KRB5_ADM_SYSTEM_ERROR;
- goto bailout;
- }
-
- /* See if this client can perform this operation. */
- if (!acl_op_permitted(kcontext, client, operation, arglist[0].data)) {
- /* ACL check failed */
- com_err(programname, 0, admin_perm_denied_fmt,
- op_msg, arglist[0].data, client_name);
- retval = KRB5_ADM_NOT_AUTHORIZED;
- goto bailout2;
- }
-
- /* Parse the specified principal name */
- kret = krb5_parse_name(kcontext, arglist[0].data, &principal);
- if (kret) {
- /* Principal name parse failed */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> bad principal string \"%s\"\n", arglist[0].data));
- retval = (should_exist) ? KRB5_ADM_P_DOES_NOT_EXIST :
- KRB5_ADM_BAD_OPTION;
- goto bailout2;
- }
-
- how_many = 1;
- /* Try to get the entry */
- kret = krb5_db_get_principal(kcontext, principal, &cur_dbentry,
- &how_many, &more);
-
- /*
- * If we're modifying, there'd better be an entry.
- * If we're adding, there'd better not be an entry.
- */
- if (kret) {
- /* Database entry failed or yielded unexpected results */
- DPRINT(DEBUG_OPERATION, debug_level, ("> database read error\n"));
- com_err(programname, kret,
- admin_db_read_err_fmt, op_msg, client_name);
- retval = KRB5_ADM_SYSTEM_ERROR;
- goto bailout3;
- }
- if (should_exist && !how_many) {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal %s not in database\n", arglist[0].data));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- goto bailout3;
- }
- if (!should_exist && how_many) {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal %s already in database\n", arglist[0].data));
- retval = KRB5_ADM_P_ALREADY_EXISTS;
- goto bailout3;
- }
-
- /* We need to have a principal */
- /* new_dbentry.princ = principal; */
- krb5_copy_principal(kcontext, principal, &(new_dbentry.princ));
-
- /*
- * Parse the argument list and make sure that only valid
- * options are set.
- */
- kret = krb5_adm_proto_to_dbent(kcontext,
- nargs-1, &arglist[1], &valid_mask,
- &new_dbentry, &new_password);
- if (kret || (valid_mask & ~KRB5_ADM_M_SET_VALID)) {
- /* Argument list parse failed or bad options */
- DPRINT(DEBUG_PROTO, debug_level,
- ("= argument list bad for %s\n", dbg_op_msg));
- retval = KRB5_ADM_BAD_OPTION;
- goto bailout4;
- }
-
- pword_data.data = (pwd_supplied) ? supp_pwd : new_password;
- pword_data.length = (pword_data.data) ? strlen(pword_data.data) : 0;
-
- /*
- * Check viability of options specified. One
- * of the following must be true:
- * 1) randomkey was specified and no password.
- * 2) randomkey is not specified and there
- * is a password to change/set and it is
- * is suitable.
- * 3) randomkey is not specified and there is
- * no password to change and this is
- * is a modify entry request.
- *
- * Check the suitability of the new password, if
- * one was supplied.
- */
-
- if ((valid_mask & KRB5_ADM_M_RANDOMKEY) && pword_data.data) {
- /* claimed random key but gave a password */
- DPRINT(DEBUG_PROTO, debug_level,
- ("= conflicting options for %s\n", dbg_op_msg));
- retval = KRB5_ADM_BAD_OPTION;
- goto bailout5;
- }
- if (!(valid_mask & KRB5_ADM_M_RANDOMKEY)
- && pword_data.data
- && !passwd_check_npass_ok(kcontext, debug_level,
- new_dbentry.princ, &new_dbentry,
- &pword_data, &temp)
- ) {
- DPRINT(DEBUG_PROTO, debug_level,
- ("= bad password for %s\n", dbg_op_msg));
- retval = KRB5_ADM_PW_UNACCEPT;
- goto bailout5;
- }
-
- merge = (should_exist) ? &cur_dbentry : &admin_def_dbent;
-
- /* Merge the specified entries with the defaults */
- kret = admin_merge_dbentries(kcontext, debug_level,
- client, merge, valid_mask,
- &new_dbentry, pword_data.data,
- pwd_supplied);
- if (kret) { /* Option merge failed */
- DPRINT(DEBUG_PROTO, debug_level,
- ("= option merge failed for %s\n", dbg_op_msg));
- retval = KRB5_ADM_BAD_OPTION;
- goto bailout5;
- }
- nument = 1;
-
- /* Write the entry. */
- kret = krb5_db_put_principal(kcontext, &new_dbentry, &nument);
- if (kret || (nument != 1)) {
- /* Ultimate failure */
- com_err(programname, kret, admin_db_write_err_fmt, op_msg, client_name);
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> db write failed for %s\n", dbg_op_msg));
- retval = KRB5_ADM_SYSTEM_ERROR;
- } else {
- /* Ultimate success */
- com_err(programname, 0, admin_db_success_fmt,
- op_msg, arglist[0].data, client_name);
- }
-
- bailout5:
- /* Clean up droppings from krb5_adm_proto_to_dbent */
- if (new_password) {
- krb5_xfree(new_password);
- new_password = 0;
- }
-
- bailout4:
- if (should_exist)
- krb5_db_free_principal(kcontext, &cur_dbentry, 1);
- krb5_db_free_principal(kcontext, &new_dbentry, 1);
- principal = (krb5_principal) NULL;
-
- bailout3:
- /* Clean up from krb5_parse_name (If left over) */
- if (principal)
- krb5_free_principal(kcontext, principal);
-
- bailout2:
- /* Clean up admin_client_identity droppings */
- krb5_xfree(client_name);
- krb5_free_principal(kcontext, client);
-
- bailout:
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_add_modify() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_delete_rename() - Delete or rename a named principal.
- */
-static krb5_int32
-admin_delete_rename(kcontext, debug_level, ticket, original, new)
- krb5_context kcontext;
- int debug_level;
- krb5_ticket *ticket;
- char *original;
- char *new;
-{
- krb5_int32 retval = 0;
- krb5_error_code kret;
- krb5_principal client;
- char *client_name;
- krb5_db_entry orig_entry;
- krb5_principal orig_principal;
- krb5_int32 operation;
- const char * op_msg;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_delete_rename(%s,%s)\n",
- original,((new) ? new : "(null)")));
-
- /* Initialize */
- client = (krb5_principal) NULL;
- client_name = (char *) NULL;
- memset((char *) &orig_entry, 0, sizeof(orig_entry));
- orig_principal = (krb5_principal) NULL;
- operation = (new) ? ACL_RENAME_PRINCIPAL : ACL_DELETE_PRINCIPAL;
- op_msg = (new) ? admin_rename_principal_text : admin_delete_principal_text;
-
- /* Get the identity of our client */
- if (!(kret = admin_client_identity(kcontext,
- debug_level,
- ticket,
- &client,
- &client_name))) {
-
- /* See if this client can perform this operation. */
- if (acl_op_permitted(kcontext, client, operation, original)) {
-
- /* Parse the specified principal name */
- if (!(kret = krb5_parse_name(kcontext,
- original,
- &orig_principal))) {
- int how_many;
- krb5_boolean more;
-
- how_many = 1;
-
- /* Try to get the entry */
- if (!(kret = krb5_db_get_principal(kcontext,
- orig_principal,
- &orig_entry,
- &how_many,
- &more))
- && how_many) {
-
- /*
- * We've got the entry. If we're renaming, we have
- * to make sure that the new entry's not there. Then
- * we can put the new entry. If we're deleting or
- * renaming, we delete the entry last.
- */
- if (new) {
- krb5_principal new_principal;
-
- if (!(kret = krb5_parse_name(kcontext,
- new,
- &new_principal))) {
- int n_howmany;
- krb5_boolean n_more;
- krb5_db_entry xxx_dbentry;
-
- n_howmany = 1;
-
- /* Try to get the entry */
- if (!(kret = krb5_db_get_principal(kcontext,
- new_principal,
- &xxx_dbentry,
- &n_howmany,
- &n_more))
- && !n_howmany) {
- /* Change our name */
- krb5_free_principal(kcontext,
- orig_entry.princ);
- orig_entry.princ = new_principal;
-
- /* Update our stats */
- if (!(kret = key_update_tl_attrs(kcontext,
- &orig_entry,
- client,
- 0))) {
- n_howmany = 1;
- if ((kret = krb5_db_put_principal(kcontext,
- &orig_entry,
- &n_howmany))
- || (n_howmany != 1)) {
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- com_err(programname, 0,
- admin_db_rename_fmt,
- op_msg, original, new,
- client_name);
- }
- }
- else {
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- orig_entry.princ = (krb5_principal) NULL;
- }
- else {
- if (kret) {
- com_err(programname, kret,
- admin_db_read_err_fmt,
- op_msg,
- client_name);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal \"%s\" already exists\n",
- new));
- retval = KRB5_ADM_P_ALREADY_EXISTS;
- }
- if (!kret)
- krb5_db_free_principal(kcontext,
- &xxx_dbentry,
- n_howmany);
- }
- /* Clean up from krb5_parse_name */
- krb5_free_principal(kcontext, new_principal);
- }
- else {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> bad principal string \"%s\"\n",
- new));
- retval = KRB5_ADM_BAD_OPTION;
- }
- }
- /*
- * If we've fallen through, or if the new addition was
- * successful, delete the original entry.
- */
- if (!kret && !retval) {
- int num2do = 1;
- /* Delete operation */
- kret = krb5_db_delete_principal(kcontext,
- orig_principal,
- &num2do);
- if ((kret != 0) || (num2do != 1)) {
- if (kret) {
- com_err(programname, kret,
- admin_db_del_err_fmt,
- original, op_msg, client_name);
- }
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- if (!new)
- com_err(programname, 0,
- admin_db_success_fmt,
- op_msg, original, client_name);
- }
- }
- krb5_db_free_principal(kcontext, &orig_entry, 1);
- }
- else {
- /* Database lookup failed or returned unexpected result */
- if (kret) {
- com_err(programname, kret,
- admin_db_read_err_fmt, op_msg, client_name);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal %s not in database\n",
- original));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- }
-
- /* Clean up from krb5_parse_name */
- krb5_free_principal(kcontext, orig_principal);
- }
- else {
- /* Principal name parse failed */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> bad principal string \"%s\"\n", original));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- }
- else {
- /* ACL check failed */
- com_err(programname, 0, admin_perm_denied_fmt,
- op_msg, original, client_name);
- retval = KRB5_ADM_NOT_AUTHORIZED;
- }
-
- /* Clean up admin_client_identity droppings */
- krb5_xfree(client_name);
- krb5_free_principal(kcontext, client);
- }
- else {
- /* We really choked here. */
- com_err(programname, kret, admin_no_cl_ident_fmt, op_msg);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_delete_rename() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_keysalt_parse() - Parse a list of <key>:<salt>[:<kvno>].
- */
-static krb5_int32
-admin_keysalt_parse(kcontext, debug_level, nents, entries, dups,
- nksp, kslistp, kvnolistp)
- krb5_context kcontext;
- int debug_level;
- krb5_int32 nents;
- krb5_data *entries;
- krb5_boolean dups;
- krb5_int32 *nksp;
- krb5_key_salt_tuple **kslistp;
- krb5_int32 **kvnolistp;
-{
- krb5_int32 retval;
- krb5_key_salt_tuple *keysalts;
- krb5_int32 *kvnolist;
- krb5_int32 ndone;
- int i,j;
- char *kvnop;
- int ncolon;
- krb5_int32 nparsed, onparsed;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* admin_keysalt_parse()\n"));
- retval = 0;
- ndone = 0;
- keysalts = (krb5_key_salt_tuple *) NULL;
- nparsed = 0;
- if (kvnolist = (krb5_int32 *) malloc(nents * sizeof(krb5_int32))) {
- for (i=0; i<nents; i++)
- kvnolist[i] = -1;
-
- for (i=0; i<nents; i++) {
- /*
- * Count the number of colon separators. If there is one, then
- * there is only key:salt. If there are two, then it is key:salt:
- * kvno. Otherwise there's surely something wrong.
- */
- ncolon = 0;
- for (j=0; j<entries[i].length; j++) {
- if (entries[i].data[j] == ':') {
- ncolon++;
- kvnop = &entries[i].data[j];
- }
- }
- if (ncolon == 1) {
- kvnop = (char *) NULL;
- }
- else if (ncolon == 2) {
- /* Separate it */
- *kvnop = '\0';
- kvnop++;
- }
- else {
- retval = KRB5_ADM_BAD_OPTION;
- break;
- }
-
- /*
- * Parse the string. Don't allow more than one pair per entry,
- * but allow duplicate entries if we're told so.
- */
- onparsed = nparsed;
- if (!krb5_string_to_keysalts(entries[i].data,
- "",
- ":",
- dups,
- &keysalts,
- &nparsed)) {
- if (nparsed == (onparsed+1)) {
- if (kvnop) {
- if (sscanf(kvnop,"%d", &kvnolist[ndone]) != 1) {
- retval = KRB5_ADM_BAD_OPTION;
- break;
- }
- }
- ndone++;
- }
- else {
- retval = KRB5_ADM_BAD_OPTION;
- break;
- }
- }
- else {
- retval = KRB5_ADM_BAD_OPTION;
- break;
- }
- }
- if (retval) {
- ndone = 0;
- krb5_xfree(keysalts);
- keysalts = (krb5_key_salt_tuple *) NULL;
- krb5_xfree(kvnolist);
- kvnolist = (krb5_int32 *) NULL;
- }
- }
- else
- retval = KRB5_ADM_SYSTEM_ERROR;
- *nksp = ndone;
- *kslistp = keysalts;
- *kvnolistp = kvnolist;
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_keysalt_parse() = %d\n",
- retval));
- return(retval);
-}
-\f
-/*
- * admin_keysalt_verify() - Verify the disposition of the key/salts
- */
-static krb5_int32
-admin_keysalt_verify(kcontext, debug_level, dbentp, should_be_there,
- nksents, kslist, kvnolist)
- krb5_context kcontext;
- int debug_level;
- krb5_db_entry *dbentp;
- krb5_boolean should_be_there;
- krb5_int32 nksents;
- krb5_key_salt_tuple *kslist;
- krb5_int32 *kvnolist;
-{
- krb5_int32 retval = 0;
- int i;
- krb5_key_data *kdata;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* admin_keysalt_verify()\n"));
- for (i=0; i<nksents; i++) {
- kdata = (krb5_key_data *) NULL;
- (void) krb5_dbe_find_enctype(kcontext,
- dbentp,
- kslist[i].ks_enctype,
- kslist[i].ks_salttype,
- kvnolist[i],
- &kdata);
- if (should_be_there && !kdata) {
- retval = KRB5_ADM_KEY_DOES_NOT_EXIST;
- break;
- }
- else if (!should_be_there && kdata) {
- retval = KRB5_ADM_KEY_ALREADY_EXISTS;
- break;
- }
- }
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_keysalt_verify() = %d\n",
- retval));
- return(retval);
-}
-\f
-/*
- * admin_keysalt_operate() - Perform keysalt surgery
- */
-static krb5_int32
-admin_keysalt_operate(kcontext, debug_level, dbentp, password, keyectomy,
- nksents, kslist, kvnolist)
- krb5_context kcontext;
- int debug_level;
- krb5_db_entry *dbentp;
- krb5_data *password;
- krb5_boolean keyectomy;
- krb5_int32 nksents;
- krb5_key_salt_tuple *kslist;
- krb5_int32 *kvnolist;
-{
- krb5_int32 retval = 0;
- int i, j;
- krb5_key_data *kdata, *ekdata;
- krb5_int32 num_keys, num_ekeys;
- krb5_int16 count;
- krb5_db_entry tmpent;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* admin_keysalt_operate()\n"));
- memset(&tmpent, 0, sizeof(krb5_db_entry));
- tmpent.princ = dbentp->princ; /* Needed for salts in string2key */
- if (keyectomy) {
- count = dbentp->n_key_data;
- for (i=0; i<nksents; i++) {
- if (!krb5_dbe_find_enctype(kcontext,
- dbentp,
- kslist[i].ks_enctype,
- kslist[i].ks_salttype,
- kvnolist[i],
- &kdata)) {
- if (kdata->key_data_contents[0])
- krb5_xfree(kdata->key_data_contents[0]);
- if (kdata->key_data_contents[1])
- krb5_xfree(kdata->key_data_contents[1]);
- memset(kdata, 0, sizeof(krb5_key_data));
- count--;
- }
- else {
- retval = KRB5_ADM_SYSTEM_ERROR;
- break;
- }
- }
- kdata = dbentp->key_data;
- if (dbentp->key_data = (krb5_key_data *) malloc(count *
- sizeof(krb5_key_data))
- ) {
- j = 0;
- for (i = 0; i<dbentp->n_key_data; i++) {
- if (kdata[i].key_data_ver ||
- kdata[i].key_data_kvno ||
- kdata[i].key_data_type[0] ||
- kdata[i].key_data_type[1] ||
- kdata[i].key_data_length[0] ||
- kdata[i].key_data_length[1] ||
- kdata[i].key_data_contents[0] ||
- kdata[i].key_data_contents[1]) {
- memcpy(&dbentp->key_data[j],
- &kdata[i],
- sizeof(krb5_key_data));
- j++;
- }
- }
- krb5_xfree(kdata);
- dbentp->n_key_data = count;
- }
- else {
- dbentp->key_data = kdata;
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- }
- else {
- /* Convert the string to key for the new key types */
- kdata = ekdata = (krb5_key_data *) NULL;
- if (!key_string_to_keys(kcontext,
- &tmpent,
- password,
- nksents,
- kslist,
- &num_keys,
- &kdata) &&
- !key_encrypt_keys(kcontext,
- &tmpent,
- &num_keys,
- kdata,
- &ekdata)) {
- num_ekeys = (krb5_int32) dbentp->n_key_data;
- if (admin_merge_keys(kcontext,
- dbentp,
- 0,
- num_keys,
- ekdata,
- (krb5_int32) dbentp->n_key_data,
- dbentp->key_data,
- &num_ekeys,
- &dbentp->key_data)) {
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else
- dbentp->n_key_data = (krb5_int16) num_ekeys;
- }
- if (kdata && num_keys)
- key_free_key_data(kdata, num_keys);
- if (ekdata && num_keys)
- key_free_key_data(ekdata, num_keys);
- if (tmpent.key_data && tmpent.n_key_data)
- key_free_key_data(tmpent.key_data, tmpent.n_key_data);
- }
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_keysalt_operate() = %d\n",
- retval));
- return(retval);
-}
-\f
-/*
- * admin_key_op() - Handle an add_key or delete_key request.
- */
-static krb5_int32
-admin_key_op(kcontext, debug_level, ticket, nargs, arglist, is_delete)
- krb5_context kcontext;
- int debug_level;
- krb5_ticket *ticket;
- krb5_int32 nargs;
- krb5_data *arglist;
- krb5_boolean is_delete;
-{
- krb5_int32 retval = 0;
- krb5_error_code kret;
- krb5_principal client;
- char *client_name;
- krb5_db_entry entry;
- krb5_principal principal;
- krb5_int32 operation;
- const char * op_msg;
- krb5_int32 nkeysalts;
- krb5_key_salt_tuple *keysalt_list;
- krb5_int32 *kvno_list;
- int n_howmany;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_key_op(%s,%d)\n", arglist[0].data, is_delete));
-
- /* Initialize */
- client = (krb5_principal) NULL;
- client_name = (char *) NULL;
- memset((char *) &entry, 0, sizeof(entry));
- principal = (krb5_principal) NULL;
- operation = ACL_MODIFY_PRINCIPAL;
- op_msg = (is_delete) ? admin_delete_key_text : admin_add_key_text;
- keysalt_list = (krb5_key_salt_tuple *) NULL;
- kvno_list = (krb5_int32 *) NULL;
-
- /* Get the identity of our client */
- if (!(kret = admin_client_identity(kcontext,
- debug_level,
- ticket,
- &client,
- &client_name))) {
-
- /* See if this client can perform this operation. */
- if (acl_op_permitted(kcontext, client, operation, arglist[0].data)) {
-
- /* Parse the specified principal name */
- if (!(kret = krb5_parse_name(kcontext,
- arglist[0].data,
- &principal))) {
- int how_many;
- krb5_boolean more;
-
- how_many = 1;
-
- /* Try to get the entry */
- if (!(kret = krb5_db_get_principal(kcontext,
- principal,
- &entry,
- &how_many,
- &more))
- && how_many) {
-
- /* See if the supplied old password is good */
- if (passwd_check_opass_ok(kcontext,
- debug_level,
- principal,
- &entry,
- &arglist[1])) {
-
- if (
- /* Parse the keysalt arguments */
- !(retval = admin_keysalt_parse(kcontext,
- debug_level,
- nargs-2,
- &arglist[2],
- is_delete,
- &nkeysalts,
- &keysalt_list,
- &kvno_list)) &&
- /* Verify the disposition */
- !(retval = admin_keysalt_verify(kcontext,
- debug_level,
- &entry,
- is_delete,
- nkeysalts,
- keysalt_list,
- kvno_list)) &&
- /* Perform the surgery */
- !(retval = admin_keysalt_operate(kcontext,
- debug_level,
- &entry,
- &arglist[1],
- is_delete,
- nkeysalts,
- keysalt_list,
- kvno_list)) &&
- /* Update our statistics */
- !(retval = key_update_tl_attrs(kcontext,
- &entry,
- client,
- 0))) {
- n_howmany = 1;
- if ((kret = krb5_db_put_principal(kcontext,
- &entry,
- &n_howmany))
- || (n_howmany != 1)) {
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- com_err(programname, 0,
- admin_db_key_op_fmt,
- op_msg, arglist[0].data,
- client_name);
- }
- }
- else {
- if (kret)
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- if (keysalt_list)
- krb5_xfree(keysalt_list);
- if (kvno_list)
- free(kvno_list);
- }
- else
- retval = KRB5_ADM_BAD_PW;
- krb5_db_free_principal(kcontext, &entry, 1);
- }
- else {
- /* Database lookup failed or returned unexpected result */
- if (kret) {
- com_err(programname, kret,
- admin_db_read_err_fmt, op_msg, client_name);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal %s not in database\n",
- arglist[0].data));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- }
-
- /* Clean up from krb5_parse_name */
- krb5_free_principal(kcontext, principal);
- }
- else {
- /* Principal name parse failed */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> bad principal string \"%s\"\n", arglist[0].data));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- }
- else {
- /* ACL check failed */
- com_err(programname, 0, admin_perm_denied_fmt,
- op_msg, arglist[0].data, client_name);
- retval = KRB5_ADM_NOT_AUTHORIZED;
- }
-
- /* Clean up admin_client_identity droppings */
- krb5_xfree(client_name);
- krb5_free_principal(kcontext, client);
- }
- else {
- /* We really choked here. */
- com_err(programname, kret, admin_no_cl_ident_fmt, op_msg);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_key_op() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_inq_iterator() - Routine called by krb5_db_iterate to scan through the
- * database for a particular entry and its next entry.
- */
-static krb5_error_code
-admin_inq_iterator(pointer, dbentp)
- krb5_pointer pointer;
- krb5_db_entry *dbentp;
-{
- krb5_error_code kret;
- struct inq_context *iargp;
-
- kret = 0;
- iargp = (struct inq_context *) pointer;
- /*
- * See if we have found a target of our search.
- */
- if (!iargp->ic_entry_found) {
- /*
- * No, now we are looking for a particular entry.
- */
- if (!iargp->ic_who ||
- krb5_principal_compare(iargp->ic_context,
- iargp->ic_who,
- dbentp->princ)) {
- if (iargp->ic_who) {
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> found entry\n"));
- kret = krb5_adm_dbent_to_proto(iargp->ic_context,
- KRB5_ADM_M_GET_VALID,
- dbentp,
- (char *) NULL,
- iargp->ic_ncomps,
- iargp->ic_clist);
- if (!kret) {
- iargp->ic_entry_found = 1;
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> converted entry to protocol\n"));
- }
- else {
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> convert entry to protocol failed\n"));
- }
- }
- else {
- iargp->ic_entry_found = 1;
- *(iargp->ic_ncomps) = 0;
- *(iargp->ic_clist) = (krb5_data *) NULL;
- if (!iargp->ic_next) {
- kret = krb5_unparse_name(iargp->ic_context,
- dbentp->princ,
- &iargp->ic_next);
- if (kret) {
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> unparse next entry failed\n"));
- }
- else {
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> next entry is %s\n", iargp->ic_next));
- }
- }
- }
- }
- }
- else {
- if (!iargp->ic_next) {
- kret = krb5_unparse_name(iargp->ic_context,
- dbentp->princ,
- &iargp->ic_next);
- if (kret) {
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> unparse next entry failed\n"));
- }
- else {
- DPRINT(DEBUG_OPERATION, iargp->ic_level,
- ("> next entry is %s\n", iargp->ic_next));
- }
- }
- }
- return(kret);
-}
-\f
-/*
- * admin_add_principal() - Add a principal with the specified attributes
- */
-krb5_int32
-admin_add_principal(kcontext, debug_level, ticket, nargs, arglist)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_int32 nargs; /* # rem. arguments */ /* In */
- krb5_data *arglist; /* Remaining arguments */ /* In */
-{
- krb5_int32 retval;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_add_principal(%s)\n", arglist[0].data));
- retval = admin_add_modify(kcontext,
- debug_level,
- ticket,
- nargs,
- arglist,
- 0, /* should exist */
- 0, /* passwd supplied */
- (char *) NULL);
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_add_principal() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_delete_principal() - Delete the specified principal.
- */
-krb5_int32
-admin_delete_principal(kcontext, debug_level, ticket, principal)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_data *principal; /* Principal to delete */ /* In */
-{
- krb5_int32 retval;
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_delete_principal(%s)\n", principal->data));
- retval = admin_delete_rename(kcontext,
- debug_level,
- ticket,
- principal->data,
- (char *) NULL);
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_delete_principal() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_rename_principal() - Rename the original principal to the
- * specified principal.
- */
-krb5_int32
-admin_rename_principal(kcontext, debug_level, ticket, original, new)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_data *original; /* Original principal */ /* In */
- krb5_data *new; /* New Principal */ /* In */
-{
- krb5_int32 retval;
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_rename_principal(%s)\n", original->data));
- retval = admin_delete_rename(kcontext,
- debug_level,
- ticket,
- original->data,
- new->data);
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_rename_principal() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_modify_principal() - Modify the specified principal with the
- * specifed attributes using the existing
- * entry as a template.
- */
-krb5_int32
-admin_modify_principal(kcontext, debug_level, ticket, nargs, arglist)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_int32 nargs; /* # rem. arguments */ /* In */
- krb5_data *arglist; /* Remaining arguments */ /* In */
-{
- krb5_int32 retval;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_modify_principal(%s)\n", arglist[0].data));
- retval = admin_add_modify(kcontext,
- debug_level,
- ticket,
- nargs,
- arglist,
- 1, /* should exist */
- 0, /* passwd supplied */
- (char *) NULL);
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_modify_principal() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_change_opwd() - Change the password of a principal.
- */
-krb5_int32
-admin_change_opwd(kcontext, debug_level, ticket, principal, password)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_data *principal; /* Principal */ /* In */
- krb5_data *password; /* New Password */ /* In */
-{
- krb5_int32 retval;
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_change_opw(%s)\n", principal->data));
- retval = admin_add_modify(kcontext,
- debug_level,
- ticket,
- 1,
- principal,
- 1, /* should exist */
- 1, /* passwd supplied */
- password->data);
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_change_opw() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_change_orandpwd() - Change the random key of a principal.
- */
-krb5_int32
-admin_change_orandpwd(kcontext, debug_level, ticket, principal)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_data *principal; /* Principal */ /* In */
-{
- krb5_int32 retval = 0;
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_change_orandpw(%s)\n", principal->data));
- retval = admin_add_modify(kcontext,
- debug_level,
- ticket,
- 1,
- principal,
- 1, /* should exist */
- 1, /* passwd supplied */
- (char *) NULL);
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_change_orandpw() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_inquire() - Retrieve the attributes of a principal.
- */
-krb5_int32
-admin_inquire(kcontext, debug_level, ticket, principal, ncompp, complistp)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_data *principal; /* Principal */ /* In */
- krb5_int32 *ncompp; /* # reply components */ /* Out */
- krb5_data **complistp; /* Reply component list */ /* Out */
-{
- krb5_int32 retval = KRB5_ADM_SUCCESS;
- krb5_error_code kret = 0;
- krb5_principal client;
- krb5_principal target;
- char *client_name;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_inquire(%s)\n", principal->data));
- /* Initialize */
- client = target = (krb5_principal) NULL;
- client_name = (char *) NULL;
-
- /* Get the identity of our client */
- if (!(kret = admin_client_identity(kcontext,
- debug_level,
- ticket,
- &client,
- &client_name))) {
-
- /* See if this client can perform this operation. */
- if (acl_op_permitted(kcontext, client, ACL_INQUIRE, principal->data)) {
-
- /* Parse the specified principal name */
- if (!principal->length ||
- !(kret = krb5_parse_name(kcontext,
- principal->data,
- &target))) {
- struct inq_context iargs;
- krb5_data *tmplistp;
- krb5_int32 tmpncomp;
-
- /*
- * Now - if we had a "find/findnext" set of database operators
- * then we could do this easily, but here we're going to have
- * to iterate through the whole database and find our entry.
- * If we find it, continue to the next entry so that we can
- * return it.
- */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> Find entry %s\n",
- ((principal->length) ? principal->data : "(null)")));
- iargs.ic_context = kcontext;
- iargs.ic_level = debug_level;
- iargs.ic_who = (principal->length) ? target :
- (krb5_principal) NULL;
- iargs.ic_entry_found = 0;
- iargs.ic_ncomps = &tmpncomp;
- iargs.ic_clist = &tmplistp;
- iargs.ic_next = (char *) NULL;
- if (!(kret = krb5_db_iterate(kcontext,
- admin_inq_iterator,
- &iargs))) {
-
- /* After scanning, did we find it? */
- if (iargs.ic_entry_found) {
-
- /*
- * How inconvenient. We have the list already
- * packaged up, but we have to insert our next
- * element first.
- */
- if (*complistp = (krb5_data *)
- malloc((size_t) (tmpncomp+1) * sizeof(krb5_data))
- ) {
- memset((char *) &(*complistp)[0], 0,
- sizeof(krb5_data));
- if (iargs.ic_next) {
- (*complistp)[0].data = iargs.ic_next;
- (*complistp)[0].length =
- strlen((*complistp)[0].data);
- }
- memcpy(&(*complistp)[1], &tmplistp[0],
- (size_t) tmpncomp * sizeof(krb5_data));
- *ncompp = tmpncomp+1;
- krb5_xfree(tmplistp);
- }
- else {
- /* Could not get memory for new component list */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> could not get memory\n"));
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- }
- else {
- /* Could not find principal */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> cannot find principal \"%s\"\n",
- principal->data));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- }
- else {
- /* Could not iterate */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> could not iterate database\n"));
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- /* Cleanup */
- krb5_free_principal(kcontext, target);
- }
- else {
- /* Could not parse principal name */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> bad principal string \"%s\"\n", principal->data));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- }
- else {
- /* Not authorized to perform this function */
- com_err(programname, 0, admin_perm_denied_fmt,
- admin_inquire_text,
- (principal->length) ? principal->data : admin_fentry_text,
- client_name);
- retval = KRB5_ADM_NOT_AUTHORIZED;
- }
-
- /* Clean up */
- krb5_xfree(client_name);
- krb5_free_principal(kcontext, client);
- }
- else {
- /* Something is really wrong here. */
- com_err(programname, kret, admin_no_cl_ident_fmt, admin_inquire_text);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_inquire() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_extract_key() - Extract the service key entry for this name/instance
- */
-krb5_int32
-admin_extract_key(kcontext, debug_level, ticket,
- instance, name, ncompp, complistp)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_data *instance; /* Instance of principal*/ /* In */
- krb5_data *name; /* Name of principal */ /* In */
- krb5_int32 *ncompp; /* # reply components */ /* Out */
- krb5_data **complistp; /* Reply component list */ /* Out */
-{
- krb5_int32 retval = KRB5_ADM_SUCCESS;
- krb5_error_code kret = 0;
- krb5_principal client;
- char *client_name;
- char *realm;
- char *princname;
- krb5_principal principal;
- krb5_db_entry dbentry;
- int nentries;
- krb5_boolean more;
- krb5_keytab_entry ktabentry;
- krb5_int32 num_keys;
- krb5_key_data *dkey_list;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_extract_key(%s/%s)\n", name->data, instance->data));
-
- /* Get the identity of our client */
- if (!(kret = admin_client_identity(kcontext,
- debug_level,
- ticket,
- &client,
- &client_name))) {
-
- realm = key_master_realm();
- if (princname = (char *) malloc((size_t) name->length + 1 +
- instance->length + 1 +
- strlen(realm) + 1)) {
-
- /* Formulate the name of our target */
- sprintf(princname, "%s/%s@%s", name->data,
- instance->data, realm);
-
- /* See if it's a valid name */
- if (!(kret = krb5_parse_name(kcontext,
- princname,
- &principal))) {
-
- /* See if this client can perform this operation. */
- if (acl_op_permitted(kcontext, client, ACL_EXTRACT,
- princname)) {
-
- /* Get the database entry */
- nentries = 1;
- if (!(kret = krb5_db_get_principal(kcontext,
- principal,
- &dbentry,
- &nentries,
- &more)) &&
- (nentries == 1) && (!more)) {
-
- /* Decrypt the key entries. */
- memset((char *) &ktabentry, 0, sizeof(ktabentry));
- num_keys = (krb5_int32) dbentry.n_key_data;
- if (!(kret = key_decrypt_keys(kcontext,
- &dbentry,
- &num_keys,
- dbentry.key_data,
- &dkey_list))) {
- ktabentry.principal = principal;
- ktabentry.vno = dkey_list[0].key_data_kvno;
- ktabentry.key.enctype =
- dkey_list[0].key_data_type[0];
- ktabentry.key.length =
- dkey_list[0].key_data_length[0];
- ktabentry.key.contents =
- dkey_list[0].key_data_contents[0];
-
- /* Pack the response */
- if (kret = krb5_adm_ktent_to_proto(kcontext,
- &ktabentry,
- ncompp,
- complistp)) {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> cannot package keytab protocol\n"));
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
-
- /* Cleanup from key_decrypt_keys */
- if (num_keys && dkey_list)
- key_free_key_data(dkey_list, num_keys);
- }
- else {
- /* key_decrypt_keys failed */
- com_err(programname, kret,
- admin_key_dec_err_fmt,
- princname, admin_extract_key_text,
- client_name);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- krb5_db_free_principal(kcontext, &dbentry, nentries);
- }
- else {
- /*
- * Database lookup failed or produced unexpected
- * results.
- */
- if (kret) {
- com_err(programname, kret,
- admin_db_read_err_fmt,
- admin_extract_key_text,
- client_name);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- else {
- if (nentries == 0) {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal \"%s\" does not exist\n",
- princname));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- else {
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> principal \"%s\" not unique\n",
- princname));
- retval = KRB5_ADM_SYSTEM_ERROR;
- krb5_db_free_principal(kcontext,
- &dbentry,
- nentries);
- }
- }
- }
- krb5_free_principal(kcontext, principal);
- }
- else {
- /* Not authorized to perform this operation */
- com_err(programname, 0, admin_perm_denied_fmt,
- admin_extract_key_text, princname, client_name);
- retval = KRB5_ADM_NOT_AUTHORIZED;
- }
- }
- else {
- /* Name parse failed */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> bad principal string \"%s\"\n", princname));
- retval = KRB5_ADM_P_DOES_NOT_EXIST;
- }
- free(princname);
- }
- else {
- /* No memory. */
- DPRINT(DEBUG_OPERATION, debug_level,
- ("> no memory for principal name\n"));
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
-
- /* Clean up */
- krb5_xfree(client_name);
- krb5_free_principal(kcontext, client);
- }
- else {
- /* Cannot get our identity */
- com_err(programname, kret, admin_no_cl_ident_fmt,
- admin_extract_key_text);
- retval = KRB5_ADM_SYSTEM_ERROR;
- }
- DPRINT(DEBUG_CALLS, debug_level,
- ("X admin_extract_key() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_add_key() - Add new enctypes for the given principal.
- */
-krb5_int32
-admin_add_key(kcontext, debug_level, ticket, nargs, arglist)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_int32 nargs; /* # rem. arguments */ /* In */
- krb5_data *arglist; /* Remaining arguments */ /* In */
-{
- krb5_int32 retval;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_add_key(%s)\n", arglist[0].data));
- retval = admin_key_op(kcontext,
- debug_level,
- ticket,
- nargs,
- arglist,
- 0);
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_add_key() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * admin_delete_key() - Delete enctypes for the given principal.
- */
-krb5_int32
-admin_delete_key(kcontext, debug_level, ticket, nargs, arglist)
- krb5_context kcontext; /* Kerberos context */ /* In */
- int debug_level; /* Debug level */ /* In */
- krb5_ticket *ticket; /* Kerberos ticket */ /* In */
- krb5_int32 nargs; /* # rem. arguments */ /* In */
- krb5_data *arglist; /* Remaining arguments */ /* In */
-{
- krb5_int32 retval;
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("* admin_delete_key(%s)\n", arglist[0].data));
- retval = admin_key_op(kcontext,
- debug_level,
- ticket,
- nargs,
- arglist,
- 1);
- DPRINT(DEBUG_CALLS, debug_level, ("X admin_delete_key() = %d\n", retval));
- return(retval);
-}
-\f
-void
-admin_init(max_life, max_renew_life, e_valid, e, f_valid, f)
- krb5_deltat max_life;
- krb5_deltat max_renew_life;
- krb5_boolean e_valid;
- krb5_timestamp e;
- krb5_boolean f_valid;
- krb5_flags f;
-{
- admin_init_def_dbent(max_life, max_renew_life, e_valid, e, f_valid, f);
-}
+++ /dev/null
-AC_INIT(srv_main.c)
-CONFIG_RULES
-AC_PROG_INSTALL
-AC_FUNC_CHECK(waitpid,AC_DEFINE(HAVE_WAITPID))
-AC_FUNC_CHECK(vsprintf,AC_DEFINE(HAVE_VSPRINTF))
-AC_CHECK_HEADERS(sys/select.h)
-CHECK_SIGNALS
-CHECK_SETJMP
-CHECK_WAIT_TYPE
-AC_PROG_AWK
-USE_KADM_LIBRARY
-USE_KDB5_LIBRARY
-KRB5_LIBRARIES
-V5_USE_SHARED_LIB
-V5_AC_OUTPUT_MAKEFILE
+++ /dev/null
-/*
- * kadmin/v5server/kadm5_defs.h
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * kadmind5
- * Version 5 administrative daemon.
- */
-#ifndef KADM5_DEFS_H__
-#define KADM5_DEFS_H__
-
-#include "adm.h"
-
-/*
- * Debug definitions.
- */
-#define DEBUG_SPROC 1
-#define DEBUG_OPERATION 2
-#define DEBUG_HOST 4
-#define DEBUG_REALM 8
-#define DEBUG_REQUESTS 16
-#define DEBUG_ACL 32
-#define DEBUG_PROTO 64
-#define DEBUG_CALLS 128
-#define DEBUG_NOSLAVES 256
-#ifdef DEBUG
-#define DPRINT(l1, cl, al) if ((cl & l1) != 0) xprintf al
-#else /* DEBUG */
-#define DPRINT(l1, cl, al)
-#endif /* DEBUG */
-#define DLOG(l1, cl, msg) if ((cl & l1) != 0) \
- com_err(programname, 0, msg)
-
-/*
- * Access control bits.
- */
-#define ACL_ADD_PRINCIPAL 1
-#define ACL_DELETE_PRINCIPAL 2
-#define ACL_MODIFY_PRINCIPAL 4
-#define ACL_CHANGEPW 8
-#define ACL_CHANGE_OWN_PW 16
-#define ACL_INQUIRE 32
-#define ACL_EXTRACT 64
-#define ACL_RENAME_PRINCIPAL (ACL_ADD_PRINCIPAL+ACL_DELETE_PRINCIPAL)
-
-#define ACL_PRINCIPAL_MASK (ACL_ADD_PRINCIPAL|ACL_DELETE_PRINCIPAL|\
- ACL_MODIFY_PRINCIPAL)
-#define ACL_PASSWD_MASK (ACL_CHANGEPW|ACL_CHANGE_OWN_PW)
-#define ACL_ALL_MASK (ACL_ADD_PRINCIPAL | \
- ACL_DELETE_PRINCIPAL | \
- ACL_MODIFY_PRINCIPAL | \
- ACL_CHANGEPW | \
- ACL_CHANGE_OWN_PW | \
- ACL_INQUIRE | \
- ACL_EXTRACT)
-/*
- * Subcodes.
- */
-#define KADM_BAD_ARGS 10
-#define KADM_BAD_CMD 11
-#define KADM_NO_CMD 12
-#define KADM_BAD_PRINC 20
-#define KADM_PWD_TOO_SHORT 21
-#define KADM_PWD_WEAK 22
-#define KADM_NOT_ALLOWED 100
-
-/*
- * Inter-module function prototypes
- */
-
-/* srv_key.c */
-krb5_error_code key_init
- KRB5_PROTOTYPE((krb5_context,
- int,
- int,
- char *,
- int,
- char *,
- char *,
- char *,
- char *,
- krb5_int32,
- krb5_key_salt_tuple *));
-void key_finish
- KRB5_PROTOTYPE((krb5_context,
- int));
-krb5_error_code key_string_to_keys
- KRB5_PROTOTYPE((krb5_context,
- krb5_db_entry *,
- krb5_data *,
- krb5_int32,
- krb5_key_salt_tuple *,
- krb5_int32 *,
- krb5_key_data **));
-krb5_error_code key_random_key
- KRB5_PROTOTYPE((krb5_context,
- krb5_db_entry *,
- krb5_int32 *,
- krb5_key_data **));
-krb5_error_code key_encrypt_keys
- KRB5_PROTOTYPE((krb5_context,
- krb5_db_entry *,
- krb5_int32 *,
- krb5_key_data *,
- krb5_key_data **));
-krb5_error_code key_decrypt_keys
- KRB5_PROTOTYPE((krb5_context,
- krb5_db_entry *,
- krb5_int32 *,
- krb5_key_data *,
- krb5_key_data **));
-krb5_boolean key_pwd_is_weak
- KRB5_PROTOTYPE((krb5_context,
- krb5_db_entry *,
- krb5_data *));
-krb5_db_entry *key_master_entry();
-char *key_master_realm();
-krb5_keytab key_keytab_id();
-krb5_keyblock *key_admin_key();
-krb5_encrypt_block *key_master_encblock();
-void key_free_key_data KRB5_PROTOTYPE((krb5_key_data *,
- krb5_int32));
-krb5_error_code key_dbent_to_keysalts
- KRB5_PROTOTYPE((krb5_db_entry *,
- krb5_int32 *,
- krb5_key_salt_tuple **));
-krb5_error_code key_update_tl_attrs
- KRB5_PROTOTYPE((krb5_context,
- krb5_db_entry *,
- krb5_principal,
- krb5_boolean));
-krb5_error_code key_open_db KRB5_PROTOTYPE((krb5_context));
-krb5_error_code key_close_db KRB5_PROTOTYPE((krb5_context));
-
-/* srv_acl.c */
-krb5_error_code acl_init
- KRB5_PROTOTYPE((krb5_context,
- int,
- char *));
-void acl_finish
- KRB5_PROTOTYPE((krb5_context,
- int));
-krb5_boolean acl_op_permitted
- KRB5_PROTOTYPE((krb5_context,
- krb5_principal,
- krb5_int32,
- char *));
-
-/* srv_output.c */
-krb5_error_code output_init
- KRB5_PROTOTYPE((krb5_context,
- int,
- char *,
- krb5_boolean));
-void output_finish
- KRB5_PROTOTYPE((krb5_context,
- int));
-krb5_boolean output_lang_supported
- KRB5_PROTOTYPE((char *));
-char *output_krb5_errmsg
- KRB5_PROTOTYPE((char *,
- krb5_boolean,
- krb5_int32));
-char *output_adm_error
- KRB5_PROTOTYPE((char *,
- krb5_boolean,
- krb5_int32,
- krb5_int32,
- krb5_int32,
- krb5_data *));
-
-/* srv_net.c */
-krb5_error_code net_init
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_int32));
-void net_finish
- KRB5_PROTOTYPE((krb5_context,
- int));
-krb5_error_code net_dispatch
- KRB5_PROTOTYPE((krb5_context, int));
-krb5_principal net_server_princ();
-
-/* proto_serv.c */
-krb5_error_code proto_init
- KRB5_PROTOTYPE((krb5_context,
- int,
- int));
-void proto_finish
- KRB5_PROTOTYPE((krb5_context,
- int));
-krb5_error_code proto_serv
- KRB5_PROTOTYPE((krb5_context,
- krb5_int32,
- int,
- void *,
- void *));
-
-/* passwd.c */
-krb5_int32 passwd_check
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_auth_context,
- krb5_ticket *,
- krb5_data *,
- krb5_int32 *));
-krb5_int32 passwd_change
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_auth_context,
- krb5_ticket *,
- krb5_data *,
- krb5_data *,
- krb5_int32 *));
-krb5_boolean passwd_check_npass_ok
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_principal,
- krb5_db_entry *,
- krb5_data *,
- krb5_int32 *));
-krb5_boolean passwd_check_opass_ok
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_principal,
- krb5_db_entry *,
- krb5_data *));
-
-/* admin.c */
-krb5_error_code admin_add_principal
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_int32,
- krb5_data *));
-krb5_error_code admin_delete_principal
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_data *));
-krb5_error_code admin_rename_principal
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_data *,
- krb5_data *));
-krb5_error_code admin_modify_principal
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_int32,
- krb5_data *));
-krb5_error_code admin_change_opw
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_data *,
- krb5_data *));
-krb5_error_code admin_change_orandpw
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_data *));
-krb5_error_code admin_inquire
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_data *,
- krb5_int32 *,
- krb5_data **));
-krb5_error_code admin_extract_key
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_data *,
- krb5_data *,
- krb5_int32 *,
- krb5_data **));
-krb5_error_code admin_add_key
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_int32,
- krb5_data *));
-krb5_error_code admin_delete_key
- KRB5_PROTOTYPE((krb5_context,
- int,
- krb5_ticket *,
- krb5_int32,
- krb5_data *));
-void admin_init KRB5_PROTOTYPE((krb5_deltat,
- krb5_deltat,
- krb5_boolean,
- krb5_timestamp,
- krb5_boolean,
- krb5_flags));
-#endif /* KADM5_DEFS_H__ */
+++ /dev/null
-.\" kadmin/v5server/kadmind5.M
-.\"
-.\" Copyright 1995 by the Massachusetts Institute of Technology.
-.\"
-.\" Export of this software from the United States of America may
-.\" require a specific license from the United States Government.
-.\" It is the responsibility of any person or organization contemplating
-.\" export to obtain such a license before exporting.
-.\"
-.\" WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-.\" distribute this software and its documentation for any purpose and
-.\" without fee is hereby granted, provided that the above copyright
-.\" notice appear in all copies and that both that copyright notice and
-.\" this permission notice appear in supporting documentation, and that
-.\" the name of M.I.T. not be used in advertising or publicity pertaining
-.\" to distribution of the software without specific, written prior
-.\" permission. M.I.T. makes no representations about the suitability of
-.\" this software for any purpose. It is provided "as is" without express
-.\" or implied warranty.
-.\"
-.\"
-.TH KADMIND5 8 "Kerberos Version 5.0" "MIT Project Athena"
-.SH NAME
-kadmind5 \- network daemon for Kerberos version 5 database information
-.SH SYNOPSIS
-.B kadmind5
-[
-.B \-m
-] [
-.B \-n
-] [
-.B \-a
-aclfile
-] [
-.B \-d
-dbname
-] [
-.B \-e
-enctype
-] [
-.B \-k
-mkeytype
-] [
-.B \-p
-port
-] [
-.B \-r
-realm
-] [
-.B \-s
-keystash
-] [
-.B \-t
-timeout
-] [
-.B \-D
-debugmask
-] [
-.B \-M
-mkeyname
-] [
-.B \-T
-keytab
-]
-.SH DESCRIPTION
-.I kadmind5
-is the network database server for the Kerberos version 5
-password-changing and administration tools.
-
-.SH FLAGS
-.PP
-.B Database, Key and Realm flags
-.IP \-r
-.B realm
-specifies the realm that this server is to administer. The default is
-the local realm.
-.IP \-d
-.B dbname
-specifies the location of the database.
-.IP \-M
-.B mkeyname
-specifies the name of the master key.
-.IP \-k
-.B mkeytype
-specifies the master key type.
-.IP \-m
-Indicates that the master key name is to be entered manually.
-.IP \-e
-.B enctype
-specifies the encryption type which is to be used.
-.IP \-s
-.B keystash
-specifies the key stash file ( created by
-.I kdb5_stash(8)
-) used for automatic restart.
-.IP \-T
-.B keytab
-specifies the name of the service key table.
-.PP
-.B ACL flag
-.IP \-a
-.B aclfile
-specifies the location of the ACL file. This file controls remote
-principals' abilities to perform administrative functions. See the
-ACL FILE section below for the format of this file.
-.PP
-.B Connection flags
-.IP \-t
-Indicates that the server is to terminate a connection if it remains
-inactive for
-.B timeout
-seconds.
-.IP \-p
-Indicates that the administrative server is to listen on port
-.B port
-instead of the default port.
-.PP
-.B Debugging flags
-.IP \-D
-Enables certain debugging features and messages selected by
-.B debugmask.
-.IP \-n
-Specifies that the daemon is not to operate in the background.
-.PP
-
-.SH ACL FILE
-.PP
-The ACL file controls which principals can or cannot perform which
-administrative functions on which principals.
-This file can contain comment lines, null
-lines or lines which contain ACL entries. Comment lines start with
-the sharp sign (
-.B \#
-) and continue until the end of the line. Lines containing ACL
-entries have the format of
-.B principal
-.I whitespace
-.B operation-mask
-[
-.I whitespace
-.B operation-target
-]
-
-Ordering is important. The first matching entry is the one which will
-control access for a particular principal on a particular principal.
-.PP
-.IP principal
-may specify a partially or fully qualified Kerberos version 5
-principal name. Each component of the name may be wildcarded using
-the asterisk (
-.B *
-) character.
-.IP operation-target
-[Optional] may specify a partially or fully qualified Kerberos version 5
-principal name. Each component of the name may be wildcarded using the
-asterisk (
-.B *
-) character.
-.IP operation-mask
-Specifies what operations may or may not be peformed by a principal
-matching a particular entry. This is a string of one or more of the
-following list of characters or their upper-case counterparts. If the
-character is upper-case, then the operation is disallowed. If the
-character is lower-case, then the operation is permitted.
-.TP i
-.I a
-[Dis]allows the addition of principals from the database.
-.TP i
-.I d
-[Dis]allows the deletion of principals from the database.
-.TP i
-.I m
-[Dis]allows the modification of principals in the database.
-.TP i
-.I c
-[Dis]allows the changing of passwords for principals in the database.
-.TP i
-.I o
-[Dis]allows the changing of the principal's own password in the
-database.
-.TP i
-.I i
-[Dis]allows inquiries to the database.
-.TP i
-.I e
-[Dis]allows extraction of service key entries.
-.TP i
-.I p
-Short for
-.I adm.
-.TP i
-.I w
-Short for
-.I pw.
-.TP i
-.I x or *
-Short for
-.I admcoie.
-.PP
-Some examples of valid entries here are:
-.TP 2i
-.I user/instance@realm po
-A standard fully qualified name. The
-.B operation-mask
-only applies to this principal and specifies that [s]he may add,
-delete or modify principals and change his/her own password, but not
-anybody elses.
-.TP 2i
-.I user/instance@realm ceim service/instance@realm
-A standard fully qualified name and a standard fully qualified target. The
-.B operation-mask
-only applies to this principal operating on this target and specifies that
-[s]he may change the target's password, extract its service key, request
-information about the target and modify it.
-.TP 2i
-.I user/*@realm aw
-A wildcarded name. The
-.B operation-mask
-applies to all principals in realm "realm" whose first component is
-"user" and specifies that [s]he may add principals and change anybody
-else's password or change his/her own.
-.TP 2i
-.I user/*@realm ei */instance@realm
-A wildcarded name and target. The
-.B operation-mask
-applies to all principals in realm "realm" whose first component is
-"user" and specifies that [s]he may extract service keys for or perform
-inquiries on principals whose second component is "instance" and realm
-is "realm".
-.TP 2i
-.I * o
-The catchall entry. The
-.B operation-mask
-applies to all principals and indicates that they may change their own
-passwords. This entry is the default entry.
-
-.SH SEE ALSO
-kpasswd(1), kadmin5(8)
-.SH BUGS
-
+++ /dev/null
-/*
- * kadmin/v5server/passwd.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * passwd.c - handle server password-related functions.
- */
-
-#include "k5-int.h"
-#include "com_err.h"
-#include "kadm5_defs.h"
-#include "adm.h"
-
-/*
- * These defines turn on various checking in passwd_check_npass_ok.
- */
-#define KPWD_CHECK_LENGTH 0
-#define KPWD_CHECK_WEAKNESS 1
-
-#define KPWD_MIN_PWD_LENGTH 6
-
-extern char *programname;
-static const char *pwd_bad_old_pwd = "\004incorrect old password for %s";
-static const char *pwd_perm_denied = "\004ACL entry prevents password change for %s";
-static const char *pwd_changed_pwd = "\007changed password for %s";
-\f
-/*
- * passwd_check_princ() - Check if the principal specified in the ticket is ok
- */
-static krb5_error_code
-passwd_check_princ(kcontext, debug_level, ticket,
- princp, namep, db_entp, db_numentp, db_morep)
- krb5_context kcontext;
- int debug_level;
- krb5_ticket *ticket;
- krb5_principal *princp;
- char **namep;
- krb5_db_entry *db_entp;
- int *db_numentp;
- krb5_boolean *db_morep;
-{
- krb5_error_code kret;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* passwd_check_princ()\n"));
- *princp = (krb5_principal) NULL;
- *namep = (char *) NULL;
-
- /* Copy principal out of ticket */
- if (kret = krb5_copy_principal(kcontext,
- ticket->enc_part2->client,
- princp))
- goto cleanup;
-
- /* Flatten name */
- if (kret = krb5_unparse_name(kcontext, *princp, namep))
- goto cleanup;
-
- /* Get database entry */
- if (kret = krb5_db_get_principal(kcontext,
- *princp,
- db_entp,
- db_numentp,
- db_morep))
- goto cleanup;
-
- if (*db_numentp == 0)
- kret = KRB5_KDB_NOENTRY;
-
- cleanup:
- if (kret) {
- if (*namep) {
- krb5_xfree(*namep);
- *namep = (char *) NULL;
- }
- if (*princp) {
- krb5_free_principal(kcontext, *princp);
- *princp = (krb5_principal) NULL;
- }
- }
-
- DPRINT(DEBUG_CALLS, debug_level, ("X passwd_check_princ() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * passwd_check_opass_ok() - Check of specified old password is good.
- */
-krb5_boolean
-passwd_check_opass_ok(kcontext, debug_level, princ, dbentp, pwdata)
- krb5_context kcontext;
- int debug_level;
- krb5_principal princ;
- krb5_db_entry *dbentp;
- krb5_data *pwdata;
-{
- krb5_boolean pwret;
- krb5_int32 num_keys, num_dkeys, tmpn;
- krb5_key_data *key_list, *dkey_list, *kent, *tmp;
- krb5_error_code kret;
- krb5_key_data *skey_list;
- krb5_int16 nskeys;
- int i;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* passwd_check_opass_ok()\n"));
- pwret = 1;
-
- /* Initialize */
- num_keys = num_dkeys = 0;
- key_list = dkey_list = (krb5_key_data *) NULL;
- nskeys = dbentp->n_key_data;
- skey_list = dbentp->key_data;
- dbentp->n_key_data = 0;
- dbentp->key_data = (krb5_key_data *) NULL;
-
- /* Make key(s) using alleged old password */
- kret = key_string_to_keys(kcontext,
- dbentp,
- pwdata,
- 0,
- (krb5_key_salt_tuple *) NULL,
- &num_keys,
- &key_list);
-
- /* Now decrypt database entries */
- num_dkeys = nskeys;
- if (!kret)
- kret = key_decrypt_keys(kcontext,
- dbentp,
- &num_dkeys,
- skey_list,
- &dkey_list);
- if (kret)
- goto cleanup;
-
- /*
- * Compare decrypted keys. If they differ, then we're wrong!
- */
- tmp = dbentp->key_data;
- tmpn = dbentp->n_key_data;
- dbentp->key_data = dkey_list;
- dbentp->n_key_data = num_dkeys;
- for (i=0; i<num_keys; i++) {
- if (!krb5_dbe_find_enctype(kcontext,
- dbentp,
- (krb5_enctype) key_list[i].key_data_type[0],
- (krb5_int32) key_list[i].key_data_type[1],
- -1,
- &kent)) {
- if ((key_list[i].key_data_length[0] != kent->key_data_length[0]) ||
- memcmp(key_list[i].key_data_contents[0],
- kent->key_data_contents[0],
- kent->key_data_length[0])) {
- pwret = 0;
- break;
- }
- }
- }
- dbentp->key_data = tmp;
- dbentp->n_key_data = tmpn;
-
- cleanup:
- if (kret)
- pwret = 0;
- if (num_keys && key_list)
- key_free_key_data(key_list, num_keys);
- if (num_dkeys && dkey_list)
- key_free_key_data(dkey_list, num_dkeys);
- if (dbentp->key_data && dbentp->n_key_data)
- key_free_key_data(dbentp->key_data, dbentp->n_key_data);
- dbentp->key_data = skey_list;
- dbentp->n_key_data = nskeys;
- DPRINT(DEBUG_CALLS, debug_level,
- ("X passwd_check_opass_ok() = %d\n", pwret));
- return(pwret);
-}
-\f
-/*
- * passwd_set_npass() - Set new password
- */
-static krb5_error_code
-passwd_set_npass(kcontext, debug_level, princ, dbentp, pwdata)
- krb5_context kcontext;
- int debug_level;
- krb5_principal princ;
- krb5_db_entry *dbentp;
- krb5_data *pwdata;
-{
- krb5_error_code kret;
- krb5_db_entry entry2write;
- int nwrite;
-#ifdef USE_KDB5_CPW
- krb5_int32 n_keysalts;
- krb5_key_salt_tuple *keysalts;
- char *tmppw;
-#else /* USE_KDB5_CPW */
- krb5_int32 num_keys;
- krb5_key_data *key_list;
-#endif /* USE_KDB5_CPW */
-
- DPRINT(DEBUG_CALLS, debug_level, ("* passwd_set_npass()\n"));
-
-#ifdef USE_KDB5_CPW
- keysalts = (krb5_key_salt_tuple *) NULL;
- n_keysalts = 0;
-
- /* Copy our database entry */
- memcpy((char *) &entry2write, (char *) dbentp, sizeof(krb5_db_entry));
-
- /*
- * Zap stuff which we're not going to use.
- *
- * We're going to recreate the whole tl_data and key_data structures,
- * so blast what we copied from above.
- */
- entry2write.tl_data = (krb5_tl_data *) NULL;
- entry2write.n_tl_data = 0;
- entry2write.key_data = (krb5_key_data *) NULL;
- entry2write.n_key_data = 0;
- entry2write.princ = (krb5_principal) NULL;
-
- /*
- * Generate the key/salt tuple list from our key list.
- */
- if (!(kret = krb5_copy_principal(kcontext,
- dbentp->princ,
- &entry2write.princ)) &&
- !(kret = key_dbent_to_keysalts(dbentp, &n_keysalts, &keysalts))) {
- /* Get scratch space for our password */
- if (tmppw = (char *) malloc((size_t) (pwdata->length+1))) {
- memcpy(tmppw, pwdata->data, pwdata->length);
- tmppw[pwdata->length] = '\0';
- /*
- * Change the password.
- */
- kret = krb5_dbe_cpw(kcontext,
- key_master_encblock(),
- keysalts,
- n_keysalts,
- tmppw,
- &entry2write);
- memset(tmppw, 0, pwdata->length);
- free(tmppw);
- }
- else
- kret = ENOMEM;
- krb5_xfree(keysalts);
- }
- if (kret)
- goto cleanup;
-#else /* USE_KDB5_CPW */
- /* Initialize */
- num_keys = 0;
- key_list = (krb5_key_data *) NULL;
-
- /* Make key(s) using the new password */
- if (kret = key_string_to_keys(kcontext,
- dbentp,
- pwdata,
- 0,
- (krb5_key_salt_tuple *) NULL,
- &num_keys,
- &key_list))
- goto cleanup;
-
- /* Copy our database entry */
- memcpy((char *) &entry2write, (char *) dbentp, sizeof(krb5_db_entry));
-
- /*
- * Zap stuff which we're not going to use.
- *
- * We're going to recreate the whole tl_data and key_data structures,
- * so blast what we copied from above.
- */
- entry2write.tl_data = (krb5_tl_data *) NULL;
- entry2write.n_tl_data = 0;
- entry2write.key_data = (krb5_key_data *) NULL;
- entry2write.n_key_data = 0;
-
- /* Encrypt the new keys to the database entry. */
- if (kret = key_encrypt_keys(kcontext,
- &entry2write,
- &num_keys,
- key_list,
- &entry2write.key_data))
- goto cleanup;
- entry2write.n_key_data = num_keys;
-#endif /* USE_KDB5_CPW */
-
- /* Update the statistics */
- if (kret = key_update_tl_attrs(kcontext,
- &entry2write,
- entry2write.princ,
- 1))
- goto cleanup;
-
- /* Clear the password-change-required bit */
- entry2write.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
-
- /* Now write the entry */
- nwrite = 1;
- if (kret = krb5_db_put_principal(kcontext, &entry2write, &nwrite))
- goto cleanup;
-
- if (nwrite != 1)
- kret = KRB5KRB_ERR_GENERIC;
-
-#ifdef USE_KDB5_CPW
- /* it's only a copy under the new code, see memcpy above */
- (void) krb5_db_free_principal(kcontext, &entry2write, 1);
-#endif /* USE_KDB5_CPW */
-
- cleanup:
-#ifndef USE_KDB5_CPW
- if (num_keys && key_list)
- key_free_key_data(key_list, num_keys);
-#endif /* USE_KDB5_CPW */
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("X passwd_set_npass() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * passwd_check() - Check if a password is ok.
- */
-krb5_int32
-passwd_check(kcontext, debug_level, auth_context, ticket, pwdata, supp)
- krb5_context kcontext;
- int debug_level;
- krb5_auth_context auth_context;
- krb5_ticket *ticket;
- krb5_data *pwdata;
- krb5_int32 *supp;
-{
- krb5_int32 pwret;
- krb5_error_code kret;
- krb5_principal client;
- char *canon_name;
- krb5_db_entry tmp_entry;
- int tmp_nents;
- krb5_boolean tmp_more;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* passwd_check()\n"));
- pwret = KRB5_ADM_SUCCESS;
- client = (krb5_principal) NULL;
- canon_name = (char *) NULL;
-
- /*
- * Check out our principal
- */
- tmp_nents = 1;
- if (kret = passwd_check_princ(kcontext,
- debug_level,
- ticket,
- &client,
- &canon_name,
- &tmp_entry,
- &tmp_nents,
- &tmp_more)) {
- *supp = KADM_BAD_PRINC;
- goto cleanup;
- }
-
- DPRINT(DEBUG_REQUESTS, debug_level,
- ("> Checking password for client \"%s\"\n", canon_name));
-
- /*
- * And check out our password.
- */
- if (!passwd_check_npass_ok(kcontext,
- debug_level,
- client,
- &tmp_entry,
- pwdata,
- supp))
- pwret = KRB5_ADM_PW_UNACCEPT;
-
- cleanup:
- if (kret) {
- pwret = KRB5_ADM_PW_UNACCEPT;
- }
- if (tmp_nents > 0)
- krb5_db_free_principal(kcontext, &tmp_entry, tmp_nents);
- if (canon_name)
- krb5_xfree(canon_name);
- if (client)
- krb5_free_principal(kcontext, client);
-
- done:
- DPRINT(DEBUG_CALLS, debug_level, ("X passwd_check() = %d\n", pwret));
- return(pwret);
-}
-\f
-/*
- * passwd_change() - Change a password.
- */
-krb5_int32
-passwd_change(kcontext, debug_level, auth_context, ticket,
- olddata, newdata, supp)
- krb5_context kcontext;
- int debug_level;
- krb5_auth_context auth_context;
- krb5_ticket *ticket;
- krb5_data *olddata;
- krb5_data *newdata;
- krb5_int32 *supp;
-{
- krb5_int32 pwret;
- krb5_error_code kret;
- krb5_principal client;
- char *canon_name;
- krb5_db_entry tmp_entry;
- int tmp_nents;
- krb5_boolean tmp_more;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* passwd_change()\n"));
- pwret = KRB5_ADM_SUCCESS;
- client = (krb5_principal) NULL;
- canon_name = (char *) NULL;
-
- /* Make sure the ticket is initial, otherwise don't trust it */
- if ((ticket->enc_part2->flags & TKT_FLG_INITIAL) == 0) {
- pwret = KRB5_ADM_NOT_IN_TKT;
- goto done;
- }
-
- /*
- * Check out our principal
- */
- tmp_nents = 1;
- if (kret = passwd_check_princ(kcontext,
- debug_level,
- ticket,
- &client,
- &canon_name,
- &tmp_entry,
- &tmp_nents,
- &tmp_more)) {
- *supp = KADM_BAD_PRINC;
- goto cleanup;
- }
-
- /*
- * Check if we're restricted by an ACL from changing our own password.
- */
- if (!acl_op_permitted(kcontext, client, ACL_CHANGE_OWN_PW,
- (char *) NULL)) {
- com_err(programname, 0, pwd_perm_denied, canon_name);
- pwret = KRB5_ADM_CANT_CHANGE;
- *supp = KADM_NOT_ALLOWED;
- goto cleanup;
- }
-
- DPRINT(DEBUG_REQUESTS, debug_level,
- ("> Changing password for client \"%s\"\n", canon_name));
-
- /*
- * Check out our old password.
- */
- if (!passwd_check_opass_ok(kcontext,
- debug_level,
- client,
- &tmp_entry,
- olddata)) {
- com_err(programname, 0, pwd_bad_old_pwd, canon_name);
- pwret = KRB5_ADM_BAD_PW;
- goto cleanup;
- }
-
- /*
- * Check out the new password.
- */
- if (!passwd_check_npass_ok(kcontext,
- debug_level,
- client,
- &tmp_entry,
- newdata,
- supp)) {
- pwret = KRB5_ADM_PW_UNACCEPT;
- goto cleanup;
- }
-
- /* Now set the new entry */
- kret = passwd_set_npass(kcontext,
- debug_level,
- client,
- &tmp_entry,
- newdata);
- if (!kret) {
- com_err(programname, 0, pwd_changed_pwd, canon_name);
- }
-
- cleanup:
- if (kret) {
- pwret = KRB5_ADM_CANT_CHANGE;
- }
- if (tmp_nents > 0)
- krb5_db_free_principal(kcontext, &tmp_entry, tmp_nents);
- if (canon_name)
- krb5_xfree(canon_name);
- if (client)
- krb5_free_principal(kcontext, client);
-
- done:
- DPRINT(DEBUG_CALLS, debug_level, ("X passwd_change() = %d\n", pwret));
- return(pwret);
-}
-\f
-/*
- * passwd_check_npass_ok() - Check if new password is ok.
- */
-krb5_boolean
-passwd_check_npass_ok(kcontext, debug_level, princ, dbentp, pwdata, supp)
- krb5_context kcontext;
- int debug_level;
- krb5_principal princ;
- krb5_db_entry *dbentp;
- krb5_data *pwdata;
- krb5_int32 *supp;
-{
- krb5_boolean pwret;
-
- DPRINT(DEBUG_CALLS, debug_level, ("* passwd_check_npass_ok()\n"));
- pwret = 1;
-
- /*
- * Check whether a new password is good.
- */
-#if KPWD_CHECK_LENGTH
- /* Check length */
- if (pwdata->length < KPWD_MIN_PWD_LENGTH) {
- pwret = 0;
- *supp = KADM_PWD_TOO_SHORT;
- DPRINT(DEBUG_CALLS, debug_level,
- ("* passwd_check_npass_ok() - TOO SHORT\n"));
- }
-#endif /* KPWD_CHECK_LENGTH */
-
-#if KPWD_CHECK_WEAKNESS
- /* Check weakness of keys generated by password */
- if (key_pwd_is_weak(kcontext,
- dbentp,
- pwdata)) {
- pwret = 0;
- *supp = KADM_PWD_WEAK;
- DPRINT(DEBUG_CALLS, debug_level,
- ("* passwd_check_npass_ok() - WEAK\n"));
- }
-#endif /* KPWD_CHECK_WEAKNESS */
-
- DPRINT(DEBUG_CALLS, debug_level,
- ("X passwd_check_npass_ok() = %d\n", pwret));
- return(pwret);
-}
+++ /dev/null
-/*
- * kadmin/v5server/proto_serv.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * proto_serv.c - Engage in protocol. This module reflects the connection
- * protocol as implemented in lib/krb5/os/adm_conn.c. Any changes
- * in one module must be reflected in the other.
- */
-#include <signal.h>
-#define NEED_SOCKETS
-#include "k5-int.h"
-#include "com_err.h"
-#include "kadm5_defs.h"
-#include "adm.h"
-#include "adm_proto.h"
-#include <setjmp.h>
-
-static const char *proto_addrs_msg = "\004%d: cannot get memory for addresses";
-static const char *proto_rcache_msg = "\004%d: cannot get replay cache";
-static const char *proto_ap_req_msg = "\004%d: error reading AP_REQ message";
-static const char *proto_auth_con_msg = "\004%d: cannot get authorization context";
-static const char *proto_rd_req_msg = "\004%d: cannot decode AP_REQ message";
-static const char *proto_mk_rep_msg = "\004%d: cannot generate AP_REP message";
-static const char *proto_wr_rep_msg = "\004%d: cannot write AP_REP message";
-static const char *proto_conn_abort_msg = "\007%d: connection destroyed by client";
-static const char *proto_seq_err_msg = "\004%d: protocol sequence violation";
-static const char *proto_rd_cmd_msg = "\004%d: cannot read administrative protocol command";
-static const char *proto_db_open_msg = "\004%d: cannot open database";
-static const char *proto_db_close_msg = "\004%d: cannot close database";
-static const char *proto_wr_reply_msg = "\004%d: cannot write administrative protocol reply";
-static const char *proto_fmt_reply_msg = "\004%d: cannot format administrative protocol reply";
-extern char *programname;
-
-static int proto_proto_timeout = -1;
-static int proto_debug_level = 0;
-#if POSIX_SETJMP
-static sigjmp_buf timeout_jmp;
-#else /* POSIX_SETJMP */
-static jmp_buf timeout_jmp;
-#endif /* POSIX_SETJMP */
-
-static krb5_sigtype
-proto_alarmclock(signo)
- int signo;
-{
-#if POSIX_SETJMP
- siglongjmp(timeout_jmp, 1);
-#else /* POSIX_SETJMP */
- longjmp(timeout_jmp, 1);
-#endif /* POSIX_SETJMP */
- /* NOTREACHED */
-}
-
-krb5_error_code
-proto_init(kcontext, debug_level, timeo)
- krb5_context kcontext;
- int debug_level;
- int timeo;
-{
- krb5_error_code kret;
-
- proto_debug_level = debug_level;
- DPRINT(DEBUG_CALLS, proto_debug_level,
- ("* proto_init(timeo=%d)\n", timeo));
- kret = 0;
- proto_proto_timeout = timeo;
- DPRINT(DEBUG_CALLS, proto_debug_level, ("X proto_init() = %d\n", kret));
- return(kret);
-}
-
-void
-proto_finish(kcontext, debug_level)
- krb5_context kcontext;
- int debug_level;
-{
- DPRINT(DEBUG_CALLS, proto_debug_level, ("* proto_finish()\n"));
- DPRINT(DEBUG_CALLS, proto_debug_level, ("X proto_finish()\n"));
-}
-
-krb5_error_code
-proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p)
- krb5_context kcontext;
- krb5_int32 my_id;
- int cl_sock;
- void *sv_p;
- void *cl_p;
-{
- krb5_error_code kret;
- struct sockaddr_in *cl_addr;
- struct sockaddr_in *sv_addr;
-
- krb5_data in_data;
- krb5_data out_data;
- krb5_rcache rcache;
- krb5_auth_context auth_context;
- krb5_flags ap_options;
- krb5_ticket *ticket;
- krb5_address *local;
- krb5_address *remote;
-
-#if POSIX_SIGNALS
- struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
- char *curr_lang = (char *) NULL;
- krb5_boolean mime_setting = 0;
-
- krb5_int32 num_args;
- krb5_data *arglist;
-
- krb5_boolean db_opened;
-
- cl_addr = (struct sockaddr_in *) cl_p;
- sv_addr = (struct sockaddr_in *) sv_p;
- DPRINT(DEBUG_CALLS, proto_debug_level,
- ("* proto_serv(id=%d, sock=%d, local=%x, remote=%x)\n",
- my_id, cl_sock,
- ntohl(sv_addr->sin_addr.s_addr),
- ntohl(cl_addr->sin_addr.s_addr)));
-
- /* Initialize */
- memset((char *) &in_data, 0, sizeof(in_data));
- memset((char *) &out_data, 0, sizeof(out_data));
- num_args = 0;
- local = (krb5_address *) NULL;
- remote = (krb5_address *) NULL;
- ticket = (krb5_ticket *) NULL;
- rcache = (krb5_rcache) NULL;
-#if POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
-#endif /* POSIX_SIGNALS */
- db_opened = 0;
-
- /* Get memory for addresses */
- local = (krb5_address *) malloc(sizeof(krb5_address));
- remote = (krb5_address *) malloc(sizeof(krb5_address));
- if (!local || !remote) {
- kret = ENOMEM;
- com_err(programname, kret, proto_addrs_msg, my_id);
- goto cleanup;
- }
-
- local->contents = (krb5_octet *) malloc(sizeof(struct in_addr));
- remote->contents = (krb5_octet *) malloc(sizeof(struct in_addr));
- if (!local->contents || !remote->contents) {
- kret = ENOMEM;
- com_err(programname, kret, proto_addrs_msg, my_id);
- goto cleanup;
- }
-
- /*
- * First setup the replay cache.
- */
- if (kret = krb5_get_server_rcache(kcontext,
- krb5_princ_component(kcontext,
- net_server_princ(),
- 0),
- &rcache)) {
- com_err(programname, kret, proto_rcache_msg, my_id);
- goto cleanup;
- }
-
- /* Initialize the auth context */
- if (kret = krb5_auth_con_init(kcontext, &auth_context)) {
- com_err(programname, kret, proto_auth_con_msg, my_id);
- goto cleanup;
- }
-
- krb5_auth_con_setrcache(kcontext, auth_context, rcache);
-
- /*
- * Set up addresses.
- */
- local->addrtype = remote->addrtype = ADDRTYPE_INET;
- local->length = remote->length = sizeof(struct in_addr);
- memcpy((char *) local->contents,
- (char *) &sv_addr->sin_addr,
- sizeof(struct in_addr));
- memcpy((char *) remote->contents,
- (char *) &cl_addr->sin_addr,
- sizeof(struct in_addr));
- krb5_auth_con_setflags(kcontext, auth_context,
- KRB5_AUTH_CONTEXT_RET_SEQUENCE|
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
- krb5_auth_con_setaddrs(kcontext, auth_context, local, remote);
-
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:read message(local=%x, remote=%x)\n",
- my_id,
- ntohl(sv_addr->sin_addr.s_addr),
- ntohl(cl_addr->sin_addr.s_addr)));
- /* Now, read in the AP_REQ message and decode it. */
- if (kret = krb5_read_message(kcontext,
- (krb5_pointer) &cl_sock,
- &in_data)) {
- com_err(programname, kret, proto_ap_req_msg, my_id);
- goto cleanup;
- }
-
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:parse message(%d bytes)\n", my_id, in_data.length));
- /*
- * If we don't have a keytab, use our squirreled key.
- */
- if (!key_keytab_id())
- krb5_auth_con_setuseruserkey(kcontext, auth_context, key_admin_key());
- /* Parse the AP_REQ message */
- if (kret = krb5_rd_req(kcontext,
- &auth_context,
- &in_data,
- net_server_princ(),
- key_keytab_id(),
- &ap_options,
- &ticket)) {
- com_err(programname, kret, proto_rd_req_msg, my_id);
- goto err_reply;
- }
-
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:check AP_REQ(options are %x)\n", my_id, ap_options));
- /* Check our options */
- if ((ap_options & AP_OPTS_MUTUAL_REQUIRED) == 0) {
- kret = KRB5KRB_AP_ERR_MSG_TYPE;
- goto err_reply;
- }
-
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:make AP_REP\n", my_id));
- if (kret = krb5_mk_rep(kcontext, auth_context, &out_data)) {
- com_err(programname, kret, proto_mk_rep_msg, my_id);
- goto cleanup;
- }
-
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:write AP_REP(%d bytes)\n", my_id, out_data.length));
- if (kret = krb5_write_message(kcontext,
- (krb5_pointer) &cl_sock,
- &out_data)) {
- com_err(programname, kret, proto_wr_rep_msg, my_id);
- goto cleanup;
- }
-
- /*
- * Initialization is now complete.
- *
- * If enabled, the protocol times out after proto_proto_timeout seconds.
- */
- if (
-#if POSIX_SETJMP
- sigsetjmp(timeout_jmp, 1) == 0
-#else /* POSIX_SETJMP */
- setjmp(timeout_jmp) == 0
-#endif /* POSIX_SETJMP */
- ) {
- if (proto_proto_timeout > 0) {
-#if POSIX_SIGNALS
- s_action.sa_handler = proto_alarmclock;
- (void) sigaction(SIGALRM, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- signal(SIGALRM, proto_alarmclock);
-#endif /* POSIX_SIGNALS */
- }
- /*
- * Loop forever - or until somebody puts us out of our misery.
- */
- while (1) {
- krb5_int32 cmd_error;
- krb5_int32 err_aux;
- krb5_int32 cmd_repl_ncomps;
- krb5_data *cmd_repl_complist;
- int do_quit;
-
- /*
- * Read a command and figure out what to do.
- */
- if (proto_proto_timeout > 0)
- alarm(proto_proto_timeout);
- num_args = 0;
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:waiting for command\n", my_id));
- kret = krb5_read_adm_cmd(kcontext,
- (krb5_pointer) &cl_sock,
- auth_context,
- &num_args,
- &arglist);
- if (proto_proto_timeout > 0)
- alarm(0);
- if (kret) {
- /*
- * It's OK to have connections abort here.
- */
- if (kret == ECONNABORTED) {
- com_err(programname, kret, proto_conn_abort_msg, my_id);
- kret = 0;
- }
- else if (kret == KRB5KRB_AP_ERR_BADORDER) {
- com_err(programname, kret, proto_seq_err_msg, my_id);
- kret = 0;
- }
- else
- com_err(programname, kret, proto_rd_cmd_msg, my_id);
- goto cleanup;
- }
-
- cmd_error = KRB5_ADM_SUCCESS;
- do_quit = 0;
-
- /*
- * First open the database. We only have it open for the
- * lifetime of a command so that we are sure to close it after
- * performing an update. This also reduces the likelihood
- * that somebody'll have stale data lying around since we're
- * most likely going to change something here.
- */
- if ((kret = key_open_db(kcontext))) {
- com_err(programname, kret, proto_db_open_msg, my_id);
- goto cleanup;
- }
- else
- db_opened = 1;
-
- /*
- * Now check our arguments.
- */
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:parse command\n", my_id));
- cmd_repl_ncomps = 0;
- cmd_repl_complist = (krb5_data *) NULL;
- err_aux = 0;
- if (num_args > 0) {
- if (!strcasecmp(arglist[0].data, KRB5_ADM_QUIT_CMD)) {
- /*
- * QUIT command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:QUIT command\n", my_id));
- /* QUIT takes no arguments */
- if (num_args == 1) {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:QUIT command syntax OK\n", my_id));
- do_quit = 1;
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:QUIT command syntax BAD\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data, KRB5_ADM_CHECKPW_CMD)) {
- /*
- * CHECKPW command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHECKPW command\n", my_id));
- if (num_args == 2) {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHECKPW command syntax OK\n", my_id));
- cmd_error = passwd_check(kcontext,
- proto_debug_level,
- auth_context,
- ticket,
- &arglist[1],
- &err_aux);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHECKPW command syntax BAD\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data, KRB5_ADM_CHANGEPW_CMD)) {
- /*
- * CHANGEPW command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGEPW command\n", my_id));
- if (num_args == 3) {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGEPW command syntax OK\n", my_id));
- cmd_error = passwd_change(kcontext,
- proto_debug_level,
- auth_context,
- ticket,
- &arglist[1],
- &arglist[2],
- &err_aux);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGEPW command syntax BAD\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
-#ifdef MOTD_SUPPORTED
- else if (!strcasecmp(arglist[0].data, KRB5_ADM_MOTD_CMD)) {
- /*
- * MOTD command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MOTD command\n", my_id));
- if (num_args <= 2) {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MOTD command syntax OK\n", my_id));
- printf("@@@ motd command ");
- if (num_args == 2)
- printf("context is %s", arglist[2].data);
- printf("\n");
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MOTD command syntax BAD\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
-#endif /* MOTD_SUPPORTED */
-#ifdef MIME_SUPPORTED
- else if (!strcasecmp(arglist[0].data, KRB5_ADM_MIME_CMD)) {
- /*
- * MIME command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MIME command\n", my_id));
- if (num_args == 1) {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MIME command syntax OK\n", my_id));
- mime_setting = 1;
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MIME command syntax BAD\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
-#endif /* MIME_SUPPORTED */
-#ifdef LANGUAGES_SUPPORTED
- else if (!strcasecmp(arglist[0].data, KRB5_ADM_LANGUAGE_CMD)) {
- /*
- * LANGUAGE command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:LANGUAGE command\n", my_id));
- if (num_args == 2) {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:LANGUAGE command syntax OK\n", my_id));
- if (output_lang_supported(arglist[1].data)) {
- if (curr_lang)
- free(curr_lang);
- curr_lang = (char *)
- malloc(strlen(arglist[1].data));
- if (curr_lang)
- strcpy(curr_lang, arglist[1].data);
- }
- else
- cmd_error = KRB5_ADM_LANG_NOT_SUPPORTED;
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:LANGUAGE command syntax BAD\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
-#endif /* LANGUAGES_SUPPORTED */
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_ADD_PRINC_CMD)) {
- /*
- * ADD PRINCIPAL command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:ADD PRINCIPAL command\n", my_id));
- /* At least one argument */
- if (num_args > 1) {
- cmd_error = admin_add_principal(kcontext,
- proto_debug_level,
- ticket,
- num_args-1,
- &arglist[1]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:ADD PRINCIPAL command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_DEL_PRINC_CMD)) {
- /*
- * DELETE PRINCIPAL command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:DELETE PRINCIPAL command\n", my_id));
- /* Only one argument */
- if (num_args == 2) {
- cmd_error = admin_delete_principal(kcontext,
- proto_debug_level,
- ticket,
- &arglist[1]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:DELETE PRINCIPAL command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_REN_PRINC_CMD)) {
- /*
- * RENAME PRINCIPAL command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:RENAME PRINCIPAL command\n", my_id));
- /* Two arguments */
- if (num_args == 3) {
- cmd_error = admin_rename_principal(kcontext,
- proto_debug_level,
- ticket,
- &arglist[1],
- &arglist[2]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:RENAME PRINCIPAL command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_MOD_PRINC_CMD)) {
- /*
- * MODIFY PRINCIPAL command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MODIFY PRINCIPAL command\n", my_id));
- /* At least one argument */
- if (num_args > 1) {
- cmd_error = admin_modify_principal(kcontext,
- proto_debug_level,
- ticket,
- num_args-1,
- &arglist[1]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:MODIFY PRINCIPAL command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_CHG_OPW_CMD)) {
- /*
- * CHANGE OTHER'S PASSWORD command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGE OTHER'S PASSWORD command\n", my_id));
- /* Two arguments */
- if (num_args == 3) {
- cmd_error = admin_change_opwd(kcontext,
- proto_debug_level,
- ticket,
- &arglist[1],
- &arglist[2]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGE OTHER'S PASSWORD command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_CHG_ORPW_CMD)) {
- /*
- * CHANGE OTHER'S RANDOM PASSWORD command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGE OTHER'S RANDOM PASSWORD command\n", my_id));
- /* One argument */
- if (num_args == 2) {
- cmd_error = admin_change_orandpwd(kcontext,
- proto_debug_level,
- ticket,
- &arglist[1]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:CHANGE OTHER'S RANDOM PASSWORD command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_INQ_PRINC_CMD)) {
- /*
- * INQUIRE PRINCIPAL command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:INQUIRE PRINCIPAL command\n", my_id));
- /* One argument */
- if (num_args == 2) {
- cmd_error = admin_inquire(kcontext,
- proto_debug_level,
- ticket,
- &arglist[1],
- &cmd_repl_ncomps,
- &cmd_repl_complist);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:INQUIRE PRINCIPAL command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_EXT_KEY_CMD)) {
- /*
- * EXTRACT KEY command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:EXTRACT KEY command\n", my_id));
- /* Two arguments */
- if (num_args == 3) {
- cmd_error = admin_extract_key(kcontext,
- proto_debug_level,
- ticket,
- &arglist[1],
- &arglist[2],
- &cmd_repl_ncomps,
- &cmd_repl_complist);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:EXTRACT KEY command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_ADD_KEY_CMD)) {
- /*
- * ADD KEY command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:ADD KEY command\n", my_id));
- /* Must have at least three arguments */
- if (num_args > 3) {
- cmd_error = admin_add_key(kcontext,
- proto_debug_level,
- ticket,
- num_args-1,
- &arglist[1]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:ADD KEY command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else if (!strcasecmp(arglist[0].data,
- KRB5_ADM_DEL_KEY_CMD)) {
- /*
- * DELETE KEY command handling here.
- */
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:DELETE KEY command\n", my_id));
- /* At least three arguments */
- if (num_args > 3) {
- cmd_error = admin_delete_key(kcontext,
- proto_debug_level,
- ticket,
- num_args-1,
- &arglist[1]);
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:DELETE KEY command syntax BAD\n",
- my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_ARGS;
- }
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:UNKNOWN command %s\n", my_id,
- arglist[0].data));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_BAD_CMD;
- }
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level,
- ("> %d:NO command!\n", my_id));
- cmd_error = KRB5_ADM_CMD_UNKNOWN;
- err_aux = KADM_NO_CMD;
- }
-
- /*
- * Close the database.
- */
- if ((kret = key_close_db(kcontext))) {
- com_err(programname, kret, proto_db_close_msg, my_id);
- goto cleanup;
- }
- else
- db_opened = 0;
-
- /*
- * Now make the reply.
- */
- DPRINT(DEBUG_PROTO, proto_debug_level,
- ("= %d:sending reply(stat=%d)\n", my_id, cmd_error));
- if (cmd_error == KRB5_ADM_SUCCESS) {
- kret = krb5_send_adm_reply(kcontext,
- (krb5_pointer) &cl_sock,
- auth_context,
- cmd_error,
- cmd_repl_ncomps,
- cmd_repl_complist);
- if (kret) {
- com_err(programname, kret, proto_wr_reply_msg, my_id);
- goto cleanup;
- }
- }
- else {
- char *adm_errmsg;
- krb5_data reply_comps;
-
- adm_errmsg = output_adm_error(curr_lang,
- mime_setting,
- cmd_error,
- err_aux,
- num_args,
- arglist);
- if (!adm_errmsg) {
- com_err(programname, kret, proto_fmt_reply_msg, my_id);
- goto cleanup;
- }
- reply_comps.data = adm_errmsg;
- reply_comps.length = strlen(adm_errmsg);
- kret = krb5_send_adm_reply(kcontext,
- (krb5_pointer) &cl_sock,
- auth_context,
- cmd_error,
- 1,
- &reply_comps);
- free(adm_errmsg);
- if (kret) {
- com_err(programname, kret, proto_wr_reply_msg, my_id);
- goto cleanup;
- }
- }
- if (cmd_repl_ncomps > 0)
- krb5_free_adm_data(kcontext,
- cmd_repl_ncomps,
- cmd_repl_complist);
-
- if (do_quit)
- break;
- krb5_free_adm_data(kcontext, num_args, arglist);
- }
- }
- else {
- DPRINT(DEBUG_REQUESTS, proto_debug_level, ("connection timed out"));
- }
-
-
- err_reply:
- if (kret) {
- krb5_error_code er_kret;
- krb5_error errbuf;
- char *errmsg;
- krb5_data errout;
-
- memset((char *) &errbuf, 0, sizeof(errbuf));
- krb5_us_timeofday(kcontext, &errbuf.stime, &errbuf.susec);
- errbuf.server = net_server_princ();
- errbuf.error = kret - ERROR_TABLE_BASE_krb5;
- if (errbuf.error > 127)
- errbuf.error = KRB5KRB_ERR_GENERIC;
- /* Format the error message in our language */
- errmsg = output_krb5_errmsg(curr_lang, mime_setting, kret);
- errbuf.text.length = strlen(errmsg);
- errbuf.text.data = errmsg;
- er_kret = krb5_mk_error(kcontext, &errbuf, &errout);
- if (!er_kret)
- krb5_write_message(kcontext, (krb5_pointer) &cl_sock, &errout);
- free(errbuf.text.data);
- krb5_xfree(errout.data);
- }
-
- cleanup:
- /* If the alarm was set, make sure it's cancelled */
- if (proto_proto_timeout > 0)
- alarm(0);
- if (ticket)
- krb5_free_ticket(kcontext, ticket);
- /*
- * Don't need to close the replay cache because it's attached to the
- * auth context.
- */
- if (auth_context)
- krb5_auth_con_free(kcontext, auth_context);
- if (curr_lang)
- free(curr_lang);
- if (num_args)
- krb5_free_adm_data(kcontext, num_args, arglist);
- if (in_data.data)
- krb5_xfree(in_data.data);
- if (out_data.data)
- krb5_xfree(out_data.data);
- if (local && local->contents)
- free(local->contents);
- if (remote && remote->contents)
- free(remote->contents);
- if (local)
- free(local);
- if (remote)
- free(remote);
- if (db_opened)
- key_close_db(kcontext);
- close(cl_sock);
-
- done:
- DPRINT(DEBUG_CALLS, proto_debug_level, ("X proto_serv() = %d\n", kret));
- return(kret);
-}
+++ /dev/null
-/*
- * kadmin/v5server/srv_acl.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * srv_acl.c - Handle Kerberos ACL related functions.
- */
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/signal.h>
-#include "k5-int.h"
-#include "com_err.h"
-#include "kadm5_defs.h"
-
-typedef struct _acl_op_table {
- char ao_op;
- krb5_int32 ao_mask;
-} aop_t;
-
-typedef struct _acl_entry {
- struct _acl_entry *ae_next;
- char *ae_name;
- krb5_boolean ae_name_bad;
- krb5_principal ae_principal;
- krb5_int32 ae_op_allowed;
- char *ae_target;
- krb5_boolean ae_target_bad;
- krb5_principal ae_target_princ;
-} aent_t;
-
-static const aop_t acl_op_table[] = {
- { 'a', ACL_ADD_PRINCIPAL },
- { 'd', ACL_DELETE_PRINCIPAL },
- { 'e', ACL_EXTRACT },
- { 'm', ACL_MODIFY_PRINCIPAL },
- { 'c', ACL_CHANGEPW },
- { 'o', ACL_CHANGE_OWN_PW },
- { 'i', ACL_INQUIRE },
- { 'p', ACL_PRINCIPAL_MASK },
- { 'w', ACL_PASSWD_MASK },
- { 'x', ACL_ALL_MASK },
- { '*', ACL_ALL_MASK },
- { '\0', 0 }
-};
-
-static aent_t *acl_list_head = (aent_t *) NULL;
-static aent_t *acl_list_tail = (aent_t *) NULL;
-
-static const char *acl_acl_file = (char *) NULL;
-static int acl_inited = 0;
-static int acl_debug_level = 0;
-/*
- * This is the catchall entry. If nothing else appropriate is found, or in
- * the case where the ACL file is not present, this entry controls what can
- * be done. The default is that everybody can change their own password.
- */
-static const char *acl_catchall_entry = "* o ";
-
-static const char *acl_line2long_msg = "%s: line %d too long, truncated\n";
-static const char *acl_op_bad_msg = "Unrecognized ACL operation '%c' in %s\n";
-static const char *acl_syn_err_msg = "%s: syntax error at line %d <%10s...>\n";
-static const char *acl_cantopen_msg = "\007cannot open ACL file";
-\f
-/*
- * acl_get_line() - Get a line from the ACL file.
- */
-static char *
-acl_get_line(fp, lnp)
- FILE *fp;
- int *lnp;
-{
- int i, domore;
- static char acl_buf[BUFSIZ];
-
- for (domore = 1; domore && !feof(fp); ) {
- /* Copy in the line */
- for (i=0;
- ((i<BUFSIZ) &&
- (!feof(fp)) &&
- ((acl_buf[i] = fgetc(fp)) != '\n'));
- i++);
-
- /* Check if we exceeded our buffer size */
- if ((i == BUFSIZ) && (!feof(fp)) && (acl_buf[i] != '\n')) {
- fprintf(stderr, acl_line2long_msg, acl_acl_file, *lnp);
- while (fgetc(fp) != '\n');
- }
- acl_buf[i] = '\0';
- if (acl_buf[0] == (char) EOF) /* ptooey */
- acl_buf[0] = '\0';
- else
- (*lnp)++;
- if ((acl_buf[0] != '#') && (acl_buf[0] != '\0'))
- domore = 0;
- }
- if (domore || (strlen(acl_buf) == 0))
- return((char *) NULL);
- else
- return(acl_buf);
-}
-\f
-/*
- * acl_parse_line() - Parse the contents of an ACL line.
- */
-static aent_t *
-acl_parse_line(lp)
- char *lp;
-{
- static char acle_principal[BUFSIZ];
- static char acle_ops[BUFSIZ];
- static char acle_object[BUFSIZ];
- aent_t *acle;
- char *op;
- int t, found, opok, nmatch;
-
- DPRINT(DEBUG_CALLS, acl_debug_level,
- ("* acl_parse_line(line=%20s)\n", lp));
- /*
- * Format is very simple:
- * entry ::= <whitespace> <principal> <whitespace> <opstring> <whitespace>
- * [<target> <whitespace>]
- */
- acle = (aent_t *) NULL;
- acle_object[0] = '\0';
- nmatch = sscanf(lp, "%s %s %s", acle_principal, acle_ops, acle_object);
- if (nmatch >= 2) {
- acle = (aent_t *) malloc(sizeof(aent_t));
- if (acle) {
- acle->ae_next = (aent_t *) NULL;
- acle->ae_op_allowed = (krb5_int32) 0;
- acle->ae_target =
- (nmatch >= 3) ? strdup(acle_object) : (char *) NULL;
- acle->ae_target_bad = 0;
- acle->ae_target_princ = (krb5_principal) NULL;
- opok = 1;
- for (op=acle_ops; *op; op++) {
- char rop;
-
- rop = (isupper(*op)) ? tolower(*op) : *op;
- found = 0;
- for (t=0; acl_op_table[t].ao_op; t++) {
- if (rop == acl_op_table[t].ao_op) {
- found = 1;
- if (rop == *op)
- acle->ae_op_allowed |= acl_op_table[t].ao_mask;
- else
- acle->ae_op_allowed &= ~acl_op_table[t].ao_mask;
- }
- }
- if (!found) {
- fprintf(stderr, acl_op_bad_msg, *op, lp);
- opok = 0;
- }
- }
- if (opok) {
- acle->ae_name = (char *) malloc(strlen(acle_principal)+1);
- if (acle->ae_name) {
- strcpy(acle->ae_name, acle_principal);
- acle->ae_principal = (krb5_principal) NULL;
- acle->ae_name_bad = 0;
- DPRINT(DEBUG_ACL, acl_debug_level,
- ("A ACL entry %s -> opmask %x\n",
- acle->ae_name, acle->ae_op_allowed));
- }
- else {
- if (acle->ae_target)
- free(acle->ae_target);
- free(acle);
- acle = (aent_t *) NULL;
- }
- }
- else {
- if (acle->ae_target)
- free(acle->ae_target);
- free(acle);
- acle = (aent_t *) NULL;
- }
- }
- }
- DPRINT(DEBUG_CALLS, acl_debug_level,
- ("X acl_parse_line() = %x\n", (long) acle));
- return(acle);
-}
-\f
-/*
- * acl_free_entries() - Free all ACL entries.
- */
-static void
-acl_free_entries()
-{
- aent_t *ap;
- aent_t *np;
-
- DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_free_entries()\n"));
- for (ap=acl_list_head; ap; ap = np) {
- if (ap->ae_name)
- free(ap->ae_name);
- if (ap->ae_principal)
- krb5_free_principal((krb5_context) NULL, ap->ae_principal);
- if (ap->ae_target)
- free(ap->ae_target);
- if (ap->ae_target_princ)
- krb5_free_principal((krb5_context) NULL, ap->ae_target_princ);
- np = ap->ae_next;
- free(ap);
- }
- acl_list_head = acl_list_tail = (aent_t *) NULL;
- acl_inited = 0;
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_free_entries()\n"));
-}
-\f
-/*
- * acl_load_acl_file() - Open and parse the ACL file.
- */
-static int
-acl_load_acl_file()
-{
-char tmpbuf[10];
- FILE *afp;
- char *alinep;
- aent_t **aentpp;
- int alineno;
- int retval = 1;
-
- DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_load_acl_file()\n"));
- /* Open the ACL file for read */
- if (afp = fopen(acl_acl_file, "r")) {
- alineno = 1;
- aentpp = &acl_list_head;
-
- /* Get a non-comment line */
- while (alinep = acl_get_line(afp, &alineno)) {
- /* Parse it */
- *aentpp = acl_parse_line(alinep);
- /* If syntax error, then fall out */
- if (!*aentpp) {
- fprintf(stderr, acl_syn_err_msg,
- acl_acl_file, alineno, alinep);
- retval = 0;
- break;
- }
- acl_list_tail = *aentpp;
- aentpp = &(*aentpp)->ae_next;
- }
-strcpy(tmpbuf, acl_catchall_entry);
- if (*aentpp = acl_parse_line(tmpbuf)) {
- acl_list_tail = *aentpp;
- }
- else {
- retval = 0;
- DPRINT(DEBUG_OPERATION, acl_debug_level,
- ("> catchall acl entry (%s) load failed\n",
- acl_catchall_entry));
- }
- fclose(afp);
- }
- else {
- com_err(acl_acl_file, errno, acl_cantopen_msg);
- if (acl_list_head = acl_parse_line(acl_catchall_entry)) {
- acl_list_tail = acl_list_head;
- }
- else {
- retval = 0;
- DPRINT(DEBUG_OPERATION, acl_debug_level,
- ("> catchall acl entry (%s) load failed\n",
- acl_catchall_entry));
- }
- }
-
- if (!retval) {
- acl_free_entries();
- }
- DPRINT(DEBUG_CALLS, acl_debug_level,
- ("X acl_load_acl_file() = %d\n", retval));
- return(retval);
-}
-\f
-/*
- * acl_reload_acl_file() - Reload the acl file.
- */
-static krb5_sigtype
-acl_reload_acl_file(signo)
- int signo;
-{
- DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_reload_acl_file(%d)\n",
- signo));
- acl_free_entries();
- acl_inited = acl_load_acl_file();
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_reload_acl_file()\n"));
-}
-\f
-/*
- * acl_match_data() - See if two data entries match.
- *
- * Wildcarding is only supported for a whole component.
- */
-static krb5_boolean
-acl_match_data(e1, e2)
- krb5_data *e1, *e2;
-{
- krb5_boolean retval;
-
- DPRINT(DEBUG_CALLS, acl_debug_level,
- ("* acl_match_entry(%s, %s)\n", e1->data, e2->data));
- retval = 0;
- if (!strncmp(e1->data, "*", e1->length) ||
- !strncmp(e2->data, "*", e2->length)) {
- retval = 1;
- }
- else {
- if ((e1->length == e2->length) &&
- (!strncmp(e1->data, e2->data, e1->length)))
- retval = 1;
- }
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_match_entry()=%d\n",retval));
- return(retval);
-}
-\f
-/*
- * acl_find_entry() - Find a matching entry.
- */
-static aent_t *
-acl_find_entry(kcontext, principal, object)
- krb5_context kcontext;
- krb5_principal principal;
- char *object;
-{
- aent_t *entry;
- krb5_error_code kret;
- int i;
- int matchgood;
-
- DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_find_entry()\n"));
- for (entry=acl_list_head; entry; entry = entry->ae_next) {
- if (!strcmp(entry->ae_name, "*")) {
- DPRINT(DEBUG_ACL, acl_debug_level, ("A wildcard ACL match\n"));
- break;
- }
- if (!entry->ae_principal && !entry->ae_name_bad) {
- kret = krb5_parse_name(kcontext,
- entry->ae_name,
- &entry->ae_principal);
- if (kret)
- entry->ae_name_bad = 1;
- }
- if (entry->ae_name_bad) {
- DPRINT(DEBUG_ACL, acl_debug_level,
- ("A Bad ACL entry %s\n", entry->ae_name));
- continue;
- }
- if (entry->ae_target &&
- !entry->ae_target_princ &&
- !entry->ae_target_bad) {
- kret = krb5_parse_name(kcontext,
- entry->ae_target,
- &entry->ae_target_princ);
- if (kret)
- entry->ae_target_bad = 1;
- }
- if (entry->ae_target_bad) {
- DPRINT(DEBUG_ACL, acl_debug_level,
- ("A Bad target in an ACL entry for %s\n", entry->ae_name));
- entry->ae_name_bad = 1;
- continue;
- }
- matchgood = 0;
- if (acl_match_data(&entry->ae_principal->realm,
- &principal->realm) &&
- (entry->ae_principal->length == principal->length)) {
- matchgood = 1;
- for (i=0; i<principal->length; i++) {
- if (!acl_match_data(&entry->ae_principal->data[i],
- &principal->data[i])) {
- matchgood = 0;
- break;
- }
- }
- }
- if (!matchgood)
- continue;
-
- /* We've matched the principal. If we have a target, then try it */
- if (entry->ae_target && entry->ae_target_princ && object) {
- krb5_principal oprinc;
-
- if (!(kret = krb5_parse_name(kcontext, object, &oprinc))) {
- if (acl_match_data(&entry->ae_target_princ->realm,
- &oprinc->realm) &&
- (entry->ae_target_princ->length == oprinc->length)) {
- for (i=0; i<oprinc->length; i++) {
- if (!acl_match_data(&entry->ae_target_princ->data[i],
- &oprinc->data[i])) {
- matchgood = 0;
- break;
- }
- }
- }
- else
- matchgood = 0;
- krb5_free_principal(kcontext, oprinc);
- }
- else
- matchgood = 0;
- }
-
- if (matchgood)
- break;
- }
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_find_entry()=%x\n",entry));
- return(entry);
-}
-\f
-/*
- * acl_init() - Initialize ACL context.
- */
-krb5_error_code
-acl_init(kcontext, debug_level, acl_file)
- krb5_context kcontext;
- int debug_level;
- char *acl_file;
-{
- krb5_error_code kret;
-#if POSIX_SIGNALS
- struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
- kret = 0;
- acl_debug_level = debug_level;
- DPRINT(DEBUG_CALLS, acl_debug_level,
- ("* acl_init(afile=%s)\n",
- ((acl_file) ? acl_file : "(null)")));
- acl_acl_file = (acl_file) ? acl_file : (char *) KRB5_DEFAULT_ADMIN_ACL;
- acl_inited = acl_load_acl_file();
-#if POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
- s_action.sa_handler = acl_reload_acl_file;
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- signal(SIGHUP, acl_reload_acl_file);
-#endif /* POSIX_SIGNALS */
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_init() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * acl_finish - Terminate ACL context.
- */
-void
-acl_finish(kcontext, debug_level)
- krb5_context kcontext;
- int debug_level;
-{
- DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_finish()\n"));
- acl_free_entries();
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_finish()\n"));
-}
-\f
-/*
- * acl_op_permitted() - Is this operation permitted for this principal?
- */
-krb5_boolean
-acl_op_permitted(kcontext, principal, opmask, object)
- krb5_context kcontext;
- krb5_principal principal;
- krb5_int32 opmask;
- char *object;
-{
- krb5_boolean retval;
- aent_t *aentry;
-
- DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_op_permitted()\n"));
- retval = 0;
- if (aentry = acl_find_entry(kcontext, principal, object)) {
- if ((aentry->ae_op_allowed & opmask) == opmask)
- retval = 1;
- }
- DPRINT(DEBUG_CALLS, acl_debug_level, ("X acl_op_permitted()=%d\n",
- retval));
- return(retval);
-}
+++ /dev/null
-/*
- * kadmin/v5server/srv_key.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * srv_key.c - Handle Kerberos key related functions.
- */
-#include "k5-int.h"
-#include "adm.h"
-#include "adm_proto.h"
-#include "com_err.h"
-#include "kadm5_defs.h"
-
-struct keysalt_iterate_args {
- krb5_context context;
- krb5_data *string;
- krb5_db_entry *dbentry;
- krb5_key_data *keys;
- krb5_int32 index;
-};
-
-/*
- * These control the maximum [renewable] life of the changepw principal, if
- * it is created by us.
- */
-#define KEY_DEF_MAX_LIFE (2*60*60)
-#define KEY_DEF_MAX_RLIFE (2*60*60)
-
-static const char *key_cpw_decerr_fmt = "%s: cannot decode keys for %s.\n";
-static const char *key_add_cpw_err_fmt = "%s: cannot add entry for %s (%s).\n";
-static const char *key_add_cpw_succ_fmt = "Added password changing service principal (%s).";
-static const char *key_cpw_encerr_fmt = "%s: cannot encode keys for %s.\n";
-static const char *key_cpw_rkeyerr_fmt = "%s: cannot make random key for %s.\n";
-static const char *key_cpw_uniqerr_fmt = "%s: database entry for %s is not unique.\n";
-static const char *key_cpw_parserr_fmt = "%s: cannot parse %s.\n";
-static const char *key_keytab_fmt = "%s: cannot resolve keytab %s (%s).\n";
-static const char *key_def_realm_fmt = "%s: cannot find default realm (%s).\n";
-static const char *key_setup_mkey_fmt = "%s: cannot setup master key name (%s).\n";
-static const char *key_get_mkey_fmt = "%s: cannot retrieve master key (%s).\n";
-static const char *key_bad_name_fmt = "%s: cannot set database name to %s (%s).\n";
-static const char *key_cant_init_fmt = "%s: cannot initialize database (%s).\n";
-static const char *key_vmast_key_fmt = "%s: cannot verify master key (%s).\n";
-static const char *key_key_pp_fmt = "%s: cannot preprocess key (%s).\n";
-static const char *key_rkey_fmt = "%s: cannot initialize random key generator (%s).\n";
-static const char *key_getm_fmt = "%s: cannot get master entry (%s).\n";
-static const char *key_nomem_fmt = "%s: cannot get memory for string %s.\n";
-
-static int mprinc_init = 0;
-static krb5_principal master_principal;
-
-static int mkeyb_init = 0;
-static krb5_keyblock master_keyblock;
-
-static int mencb_init = 0;
-static krb5_encrypt_block master_encblock;
-
-static int mrand_init = 0;
-static krb5_pointer master_random;
-
-static int ment_init = 0;
-static krb5_db_entry master_entry;
-
-static int mrealm_init = 0;
-static char *master_realm = (char *) NULL;
-
-static int mkeytab_init = 0;
-static krb5_keytab key_keytab = (krb5_keytab) NULL;
-
-static int madmin_key_init = 0;
-static krb5_key_data *madmin_keys = (krb5_key_data *) NULL;
-static krb5_keyblock madmin_key;
-static krb5_int32 madmin_num_keys = 0;
-
-static int key_num_ktents = 0;
-static krb5_key_salt_tuple *key_ktents = (krb5_key_salt_tuple *) NULL;
-static int key_ktents_inited = 0;
-static krb5_key_salt_tuple default_ktent = {
- DEFAULT_KDC_ENCTYPE, KRB5_KDB_SALTTYPE_NORMAL
-};
-
-static char *key_db_name = (char *) NULL;
-
-static int key_debug_level = 0;
-
-extern char *programname;
-\f
-/*
- * key_get_admin_entry() - Find the admin entry or create one.
- */
-static krb5_error_code
-key_get_admin_entry(kcontext)
- krb5_context kcontext;
-{
- krb5_error_code kret;
- char *realm_name;
- char *admin_princ_name;
- krb5_principal admin_principal;
- int number_of_entries;
- krb5_boolean more_entries;
- krb5_db_entry madmin_entry;
-
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_get_admin_entry()\n"));
- kret = ENOMEM;
- realm_name = key_master_realm();
-
- /*
- * The admin principal format is:
- * <admin-service-name>/<realm>@<realm>
- */
- admin_princ_name = (char *) malloc((size_t)
- ((2*strlen(realm_name)) + 3 +
- strlen(KRB5_ADM_SERVICE_INSTANCE)));
- if (admin_princ_name) {
- /* Format the admin name */
- sprintf(admin_princ_name, "%s/%s@%s", KRB5_ADM_SERVICE_INSTANCE,
- realm_name, realm_name);
- DPRINT(DEBUG_REALM, key_debug_level,
- ("- setting up admin principal %s\n", admin_princ_name));
- /* Parse the admin name */
- if (!(kret = krb5_parse_name(kcontext,
- admin_princ_name,
- &admin_principal))) {
- number_of_entries = 1;
- more_entries = 0;
- /*
- * Attempt to get the database entry.
- */
- if (!(kret = krb5_db_get_principal(kcontext,
- admin_principal,
- &madmin_entry,
- &number_of_entries,
- &more_entries)) &&
- (number_of_entries == 1) &&
- (!more_entries)) {
- DPRINT(DEBUG_REALM, key_debug_level,
- ("- found database entry for %s\n", admin_princ_name));
- /*
- * If the entry's present and it's unique, then we can
- * just proceed and decrypt the key.
- */
- madmin_num_keys = madmin_entry.n_key_data;
- if (!(kret = key_decrypt_keys(kcontext,
- &madmin_entry,
- &madmin_num_keys,
- madmin_entry.key_data,
- &madmin_keys))) {
- DPRINT(DEBUG_REALM, key_debug_level,
- ("- found admin keys\n"));
- madmin_key_init = 1;
- }
- else
- fprintf(stderr,
- key_cpw_decerr_fmt,
- programname,
- admin_princ_name);
- krb5_db_free_principal(kcontext,
- &madmin_entry,
- number_of_entries);
- }
- else {
- /*
- * We failed to find a unique entry. See if the entry
- * wasn't present. If so, then try to create it.
- */
- if (!kret && !number_of_entries) {
- krb5_tl_mod_princ mprinc;
- krb5_timestamp now;
-
- DPRINT(DEBUG_REALM, key_debug_level,
- ("- no database entry for %s\n", admin_princ_name));
- /*
- * Not present - Set up our database entry.
- */
- memset((char *) &madmin_entry, 0, sizeof(madmin_entry));
- madmin_entry.attributes = KRB5_KDB_PWCHANGE_SERVICE;
- madmin_entry.princ = admin_principal;
- madmin_entry.max_life = KEY_DEF_MAX_LIFE;
- madmin_entry.max_renewable_life = KEY_DEF_MAX_RLIFE;
- madmin_entry.len = KRB5_KDB_V1_BASE_LENGTH;
- number_of_entries = 1;
-
- krb5_timeofday(kcontext, &now);
- /*
- * Argh - now set up our auxiliary data.
- */
- if ((madmin_entry.tl_data =
- (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) &&
- (madmin_entry.tl_data->tl_data_contents =
- (krb5_octet *) malloc(sizeof(krb5_timestamp)))) {
- madmin_entry.n_tl_data = 1;
- madmin_entry.tl_data->tl_data_next =
- (krb5_tl_data *) NULL;
- madmin_entry.tl_data->tl_data_type =
- KRB5_TL_LAST_PWD_CHANGE;
- madmin_entry.tl_data->tl_data_length =
- sizeof(krb5_timestamp);
- madmin_entry.tl_data->tl_data_contents[0] =
- (unsigned char) ((now >> 24) & 0xff);
- madmin_entry.tl_data->tl_data_contents[1] =
- (unsigned char) ((now >> 16) & 0xff);
- madmin_entry.tl_data->tl_data_contents[2] =
- (unsigned char) ((now >> 8) & 0xff);
- madmin_entry.tl_data->tl_data_contents[3] =
- (unsigned char) (now & 0xff);
- }
-
- mprinc.mod_date = now;
- if (!krb5_copy_principal(kcontext,
- admin_principal,
- &mprinc.mod_princ)) {
- krb5_dbe_encode_mod_princ_data(kcontext,
- &mprinc,
- &madmin_entry);
- krb5_free_principal(kcontext, mprinc.mod_princ);
- }
-
- /*
- * Generate a random key.
- */
- if (!(kret = key_random_key(kcontext,
- &madmin_entry,
- &madmin_num_keys,
- &madmin_keys))) {
- if (!(kret = key_encrypt_keys(kcontext,
- &madmin_entry,
- &madmin_num_keys,
- madmin_keys,
- &madmin_entry.key_data))
- ) {
- madmin_entry.n_key_data =
- (krb5_int16) madmin_num_keys;
- if ((kret = krb5_db_put_principal(kcontext,
- &madmin_entry,
- &number_of_entries))) {
- fprintf(stderr,
- key_add_cpw_err_fmt,
- programname,
- admin_princ_name,
- error_message(kret));
- }
- else
- com_err(programname, 0,
- key_add_cpw_succ_fmt,
- admin_princ_name);
- }
- else
- fprintf(stderr,
- key_cpw_encerr_fmt,
- programname,
- admin_princ_name);
- if (!kret)
- madmin_key_init = 1;
- }
- else
- fprintf(stderr,
- key_cpw_rkeyerr_fmt,
- programname,
- admin_princ_name);
- }
- else {
- if (!kret && more_entries)
- krb5_db_free_principal(kcontext,
- &madmin_entry,
- number_of_entries);
- fprintf(stderr,
- key_cpw_uniqerr_fmt,
- programname,
- admin_princ_name);
- }
- }
- krb5_free_principal(kcontext, admin_principal);
- }
- else
- fprintf(stderr,
- key_cpw_parserr_fmt,
- programname,
- admin_princ_name);
- free(admin_princ_name);
- }
-
- if (kret && madmin_num_keys && madmin_keys) {
- key_free_key_data(madmin_keys, madmin_num_keys);
- madmin_key_init = 0;
- }
-
- if (!kret && madmin_num_keys && madmin_keys) {
- krb5_key_data *kdata;
- krb5_db_entry xxx;
-
- /*
- * Find the latest key.
- */
- xxx.n_key_data = (krb5_int16) madmin_num_keys;
- xxx.key_data = madmin_keys;
- if (krb5_dbe_find_enctype(kcontext,
- &xxx,
- DEFAULT_KDC_ENCTYPE,
- -1,
- -1,
- &kdata))
- kdata = &madmin_keys[0];
-
- memset(&madmin_key, 0, sizeof(krb5_keyblock));
- madmin_key.enctype = DEFAULT_KDC_ENCTYPE;
- madmin_key.length = kdata->key_data_length[0];
- madmin_key.contents = kdata->key_data_contents[0];
- }
-
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("X key_get_admin_entry() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * key_init() - Initialize key context.
- */
-krb5_error_code
-key_init(kcontext, debug_level, key_type, master_key_name, manual,
- db_file, db_realm, kt_name, sf_name, nktent, ktents)
- krb5_context kcontext;
- int debug_level;
- int key_type;
- char *master_key_name;
- int manual;
- char *db_file;
- char *db_realm;
- char *kt_name;
- char *sf_name;
- krb5_int32 nktent;
- krb5_key_salt_tuple *ktents;
-{
- char *mkey_name;
-
- krb5_error_code kret;
- int number_of_entries;
- krb5_boolean more_entries;
-
- key_debug_level = debug_level;
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("* key_init(key-type=%d,\n\tmkeyname=%s, manual=%d,\n\tdb=%s,\n\trealm=%s,\n\tktab=%s)\n",
- key_type,
- ((master_key_name) ? master_key_name : "(null)"),
- manual,
- ((db_file) ? db_file : "(default)"),
- ((db_realm) ? db_realm : "(null)"),
- ((kt_name) ? kt_name : "(null)")));
- /*
- * Figure out arguments.
- */
- if (key_type == -1)
- master_keyblock.enctype =
- manual ? DEFAULT_KDC_ENCTYPE : ENCTYPE_UNKNOWN;
- else
- master_keyblock.enctype = key_type;
-
- mkey_name = ((!master_key_name) ? KRB5_KDB_M_NAME : master_key_name);
-
- /*
- * First, try to set up our keytab if supplied.
- */
- if (kt_name) {
- if ((kret = krb5_kt_resolve(kcontext, kt_name, &key_keytab))) {
- fprintf(stderr, key_keytab_fmt, programname,
- kt_name, error_message(kret));
- goto leave;
- }
- }
- mkeytab_init = 1;
-
- if (!db_realm) {
- kret = krb5_get_default_realm(kcontext, &master_realm);
- if (kret) {
- fprintf(stderr, key_def_realm_fmt, programname,
- error_message(kret));
- goto leave;
- }
- } else {
- if ((kret = krb5_set_default_realm(kcontext, db_realm)))
- goto leave;
- master_realm = (char *) malloc(strlen(db_realm)+1);
- if (!master_realm) {
- kret = ENOMEM;
- goto leave;
- }
- strcpy(master_realm, db_realm);
- }
- mrealm_init = 1;
- DPRINT(DEBUG_REALM, key_debug_level,
- ("- initializing for realm %s\n", master_realm));
-
- /* Set database name if supplied */
- if (db_file) {
- if (!(key_db_name = strdup(db_file))) {
- fprintf(stderr, key_nomem_fmt, programname, db_file);
- goto leave;
- }
- if ((kret = krb5_db_set_name(kcontext, db_file))) {
- fprintf(stderr, key_bad_name_fmt, programname, db_file,
- error_message(kret));
- goto leave;
- }
- }
-
- /* Initialize database */
- if ((kret = krb5_db_init(kcontext))) {
- fprintf(stderr, key_cant_init_fmt, programname,
- error_message(kret));
- goto leave;
- }
-
- /* Assemble and parse the master key name */
- kret = krb5_db_setup_mkey_name(kcontext,
- mkey_name,
- master_realm,
- (char **) NULL,
- &master_principal);
- if (kret) {
- fprintf(stderr, key_setup_mkey_fmt, programname,
- error_message(kret));
- goto cleanup;
- }
- mprinc_init = 1;
- DPRINT(DEBUG_HOST, key_debug_level,
- ("- master key is %s@%s\n", mkey_name, master_realm));
-
- /* Get the master database entry and save it. */
- number_of_entries = 1;
- kret = krb5_db_get_principal(kcontext,
- master_principal,
- &master_entry,
- &number_of_entries,
- &more_entries);
- if (!kret) {
- if (number_of_entries != 1) {
- if (number_of_entries)
- krb5_db_free_principal(kcontext,
- &master_entry,
- number_of_entries);
- kret = KRB5_KDB_NOMASTERKEY;
- }
- else if (more_entries) {
- krb5_db_free_principal(kcontext,
- &master_entry,
- number_of_entries);
- kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
- }
- }
- if (kret) {
- fprintf(stderr, key_getm_fmt, programname, error_message(kret));
- goto leave;
- }
- ment_init = 1;
-
- /* krb5_db_fetch_mkey will setup the eblock if it is reading the stash */
- if (manual)
- krb5_use_enctype(kcontext, &master_encblock, master_keyblock.enctype);
-
- /* Go get the master key */
- kret = krb5_db_fetch_mkey(kcontext,
- master_principal,
- &master_encblock,
- manual,
- FALSE, /* Only read once if manual */
- sf_name, /* stash file */
- 0, /* No salt */
- &master_keyblock);
- if (kret) {
- fprintf(stderr, key_get_mkey_fmt, programname,
- error_message(kret));
- goto cleanup;
- }
-
- /* Verify the master key */
- if ((kret = krb5_db_verify_master_key(kcontext,
- master_principal,
- &master_keyblock,
- &master_encblock))) {
- fprintf(stderr, key_vmast_key_fmt, programname,
- error_message(kret));
- goto leave;
- }
-
- /* Do any key pre-processing */
- if ((kret = krb5_process_key(kcontext,
- &master_encblock,
- &master_keyblock))) {
- fprintf(stderr, key_key_pp_fmt, programname, error_message(kret));
- goto leave;
- }
- mencb_init = 1;
- mkeyb_init = 1;
-
- /* Now initialize the random key */
- kret = krb5_init_random_key(kcontext,
- &master_encblock,
- &master_keyblock,
- &master_random);
- if (kret) {
- fprintf(stderr, key_rkey_fmt, programname, error_message(kret));
- goto leave;
- }
- mrand_init = 1;
-
- if (!kret) {
- if ((key_num_ktents = nktent))
- key_ktents = ktents;
- else {
- key_num_ktents = 1;
- key_ktents = &default_ktent;
- }
- key_ktents_inited = 1;
- }
-
- /*
- * We're almost home. We now want to find our service entry and if there
- * is none, then we want to create it. This way, kadmind5 becomes just
- * a plug in and go kind of utility.
- */
- kret = key_get_admin_entry(kcontext);
-
- cleanup:
- if (kret) {
- if (mrand_init) {
- krb5_finish_random_key(kcontext, &master_encblock, &master_random);
- mrand_init = 0;
- }
- if (mencb_init) {
- krb5_finish_key(kcontext, &master_encblock);
- mencb_init = 0;
- }
- if (mkeyb_init) {
- memset(master_keyblock.contents, 0,
- (size_t) master_keyblock.length);
- krb5_xfree(master_keyblock.contents);
- mkeyb_init = 0;
- }
- if (ment_init) {
- krb5_db_free_principal(kcontext, &master_entry, 1);
- ment_init = 0;
- }
- if (mrealm_init) {
- krb5_xfree(master_realm);
- mrealm_init = 0;
- }
- if (mkeytab_init) {
- if (key_keytab)
- krb5_kt_close(kcontext, key_keytab);
- key_keytab = (krb5_keytab) NULL;
- mkeytab_init = 0;
- }
- if (madmin_key_init) {
- key_free_key_data(madmin_keys, madmin_num_keys);
- madmin_key_init = 0;
- }
- if (key_db_name)
- free(key_db_name);
- }
- leave:
- krb5_db_fini(kcontext);
- DPRINT(DEBUG_CALLS, key_debug_level, ("X key_init() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * key_finish - Terminate key context.
- */
-void
-key_finish(kcontext, debug_level)
- krb5_context kcontext;
- int debug_level;
-{
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_finish()\n"));
- if (mrand_init) {
- krb5_finish_random_key(kcontext, &master_encblock, &master_random);
- mrand_init = 0;
- }
- if (mkeyb_init) {
- krb5_finish_key(kcontext, &master_encblock);
- memset((char *) &master_encblock, 0,
- sizeof(master_encblock));
- mkeyb_init = 0;
- }
- if (mprinc_init) {
- krb5_free_principal(kcontext, master_principal);
- mprinc_init = 0;
- }
- if (mencb_init) {
- master_encblock.crypto_entry = 0;
- mencb_init = 0;
- }
- if (ment_init) {
- krb5_db_free_principal(kcontext, &master_entry, 1);
- ment_init = 0;
- }
- if (mrealm_init) {
- krb5_xfree(master_realm);
- mrealm_init = 0;
- }
- if (mkeytab_init) {
- if (key_keytab)
- krb5_kt_close(kcontext, key_keytab);
- key_keytab = (krb5_keytab) NULL;
- mkeytab_init = 0;
- }
- if (madmin_key_init) {
- key_free_key_data(madmin_keys, madmin_num_keys);
- madmin_key_init = 0;
- }
- if (key_db_name)
- free(key_db_name);
- krb5_db_fini(kcontext);
- /* memset((char *) tgs_key.contents, 0, tgs_key.length); */
- DPRINT(DEBUG_CALLS, key_debug_level, ("X key_finish()\n"));
-}
-\f
-/*
- * key_string2key_keysalt() - Local iterator routine for keysalt_iterate.
- */
-static krb5_error_code
-key_string2key_keysalt(ksent, ptr)
- krb5_key_salt_tuple *ksent;
- krb5_pointer ptr;
-{
- struct keysalt_iterate_args *argp;
- krb5_boolean salted;
- krb5_key_data *kdata;
- krb5_error_code kret;
- krb5_data salt;
- krb5_keyblock key;
- krb5_key_data *okeyp;
- krb5_enctype old_enctype;
-
- argp = (struct keysalt_iterate_args *) ptr;
- kret = 0;
- /*
- * Determine if this key/salt pair is salted.
- */
- salted = 0;
- /*
- * XXXXX this is totally, totally wrong. We should never be using
- * krb5_use_enctype on master_encblock. In particular, it won't
- * work once we start having non-DES encryption systems.
- *
- * For now, we're going to do ths ugly kludge where we save the
- * master_encblock's old encryption system, and restore it at the
- * end of this routine. This is wrong, and it *will* break in the
- * future. We need to fix this before we let this code go out....
- */
- old_enctype = master_encblock.crypto_entry->proto_enctype;
- krb5_use_enctype(argp->context, &master_encblock, ksent->ks_enctype);
- if (!krb5_dbe_find_enctype(argp->context,
- argp->dbentry,
- ksent->ks_enctype,
- ksent->ks_salttype,
- -1,
- &kdata)) {
- if (kdata->key_data_length[1] && kdata->key_data_contents[1])
- salted = 1;
- }
- else {
- /*
- * Cannot find a name-to-data matching, so we must have to create a
- * new key entry.
- */
- if (!(kret = krb5_dbe_create_key_data(argp->context, argp->dbentry))) {
- kdata = &argp->dbentry->key_data[argp->dbentry->n_key_data-1];
- kdata->key_data_type[0] = (krb5_int16) ksent->ks_enctype;
- kdata->key_data_type[1] = (krb5_int16) ksent->ks_salttype;
- }
- }
-
- if (!kret) {
- /*
- * We have "kdata" pointing to the key entry we're to futz
- * with.
- */
- if (!salted) {
- switch (kdata->key_data_type[1]) {
- case KRB5_KDB_SALTTYPE_V4:
- salt.length = 0;
- salt.data = (char *) NULL;
- break;
- case KRB5_KDB_SALTTYPE_NORMAL:
- /* Normal salt */
- if ((kret = krb5_principal2salt(argp->context,
- argp->dbentry->princ,
- &salt)))
- goto done;
- break;
- case KRB5_KDB_SALTTYPE_NOREALM:
- if ((kret = krb5_principal2salt_norealm(argp->context,
- argp->dbentry->princ,
- &salt)))
- goto done;
- break;
- case KRB5_KDB_SALTTYPE_ONLYREALM:
- {
- krb5_data *xsalt;
- if ((kret = krb5_copy_data(argp->context,
- krb5_princ_realm(argp->context,
- argp->dbentry->princ),
- &xsalt)))
- goto done;
- salt.length = xsalt->length;
- salt.data = xsalt->data;
- krb5_xfree(xsalt);
- }
- break;
- case KRB5_KDB_SALTTYPE_AFS3:
- {
- /* use KDC-supplied realm for TransArc AFS style salt */
- /* malloc and copy to cover trailing 0, mit_afs_string_to_key
- takes care of free'ing it. */
- char *dat;
- int len;
- len = krb5_princ_realm(argp->context, argp->dbentry->princ)->length;
- dat = malloc(1+len);
- if (!dat)
- goto done;
- strncpy(dat, krb5_princ_realm(argp->context, argp->dbentry->princ)->data, len);
- dat[len] = 0;
- salt.data = dat;
- salt.length = -1; /* in order to get around API change */
- break;
- }
- default:
- goto done;
- }
- }
- else {
- if ((salt.length = kdata->key_data_length[1])) {
- if ((salt.data = (char *) malloc(salt.length)))
- memcpy(salt.data,
- (char *) kdata->key_data_contents[1],
- (size_t) salt.length);
- }
- else
- salt.data = (char *) NULL;
- }
-
- /*
- * salt contains the salt.
- */
- if ((kret = krb5_string_to_key(argp->context,
- &master_encblock,
- &key,
- argp->string,
- &salt)))
- goto done;
-
- if (salt.length == -1)
- salt.length = strlen (salt.data);
-
- /*
- * Now, salt contains the salt and key contains the decrypted
- * key. kdata contains the key/salt data. Fill in the output.
- */
- okeyp = &argp->keys[argp->index];
- argp->index++;
- okeyp->key_data_ver = KRB5_KDB_V1_KEY_DATA_ARRAY;
- okeyp->key_data_kvno = kdata->key_data_kvno + 1;
- okeyp->key_data_type[0] = kdata->key_data_type[0];
- okeyp->key_data_type[1] = kdata->key_data_type[1];
- okeyp->key_data_length[0] = (krb5_int16) key.length;
- okeyp->key_data_length[1] = (krb5_int16) salt.length;
- okeyp->key_data_contents[0] = (krb5_octet *) key.contents;
- okeyp->key_data_contents[1] = (krb5_octet *) salt.data;
- }
- done:
- krb5_use_enctype(argp->context, &master_encblock, old_enctype);
- return(kret);
-}
-\f
-/*
- * key_string_to_keys() - convert string to keys.
- */
-krb5_error_code
-key_string_to_keys(kcontext, dbentp, string, nksalt, ksaltp, nkeysp, keysp)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_data *string;
- krb5_int32 nksalt;
- krb5_key_salt_tuple *ksaltp;
- krb5_int32 *nkeysp;
- krb5_key_data **keysp;
-{
- krb5_error_code kret;
- krb5_key_salt_tuple *keysalts;
- krb5_int32 nkeysalts;
- krb5_key_data *keys;
- struct keysalt_iterate_args ksargs;
- krb5_boolean did_alloc;
-
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_string_to_keys()\n"));
-
- keys = (krb5_key_data *) NULL;
- /*
- * Determine how many and of what kind of keys to generate.
- */
- keysalts = ksaltp;
- nkeysalts = nksalt;
- did_alloc = 0;
- if (!keysalts || !nkeysalts) {
- kret = key_dbent_to_keysalts(dbentp, &nkeysalts, &keysalts);
- did_alloc = 1;
- }
- if (keysalts && nkeysalts) {
- if ((keys = (krb5_key_data *)
- malloc((size_t) (nkeysalts * sizeof(krb5_key_data))))) {
- memset(keys, 0, nkeysalts * sizeof(krb5_key_data));
- ksargs.context = kcontext;
- ksargs.string = string;
- ksargs.dbentry = dbentp;
- ksargs.keys = keys;
- ksargs.index = 0;
- kret = krb5_keysalt_iterate(keysalts,
- nkeysalts,
- 0,
- key_string2key_keysalt,
- (krb5_pointer) &ksargs);
- }
- else
- kret = ENOMEM;
- if (did_alloc)
- krb5_xfree(keysalts);
- }
- if (!kret) {
- *nkeysp = ksargs.index;
- *keysp = keys;
- }
- else {
- if (keys && nkeysalts)
- key_free_key_data(keys, nkeysalts);
- }
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("X key_string_to_keys() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * key_random_keysalt() - Local iterator routine for keysalt_iterate.
- */
-static krb5_error_code
-key_randomkey_keysalt(ksent, ptr)
- krb5_key_salt_tuple *ksent;
- krb5_pointer ptr;
-{
- struct keysalt_iterate_args *argp;
- krb5_key_data *kdata;
- krb5_error_code kret;
- krb5_keyblock *key;
- krb5_key_data *okeyp;
- krb5_enctype old_enctype;
-
- argp = (struct keysalt_iterate_args *) ptr;
- kret = 0;
-
- /*
- * XXXXX this is totally, totally wrong. We should never be using
- * krb5_use_enctype on master_encblock. In particular, it won't
- * work once we start having non-DES encryption systems.
- *
- * For now, we're going to do ths ugly kludge where we save the
- * master_encblock's old encryption system, and restore it at the
- * end of this routine. This is wrong, and it *will* break in the
- * future. We need to fix this before we let this code go out....
- */
- old_enctype = master_encblock.crypto_entry->proto_enctype;
- krb5_use_enctype(argp->context, &master_encblock, ksent->ks_enctype);
- if (krb5_dbe_find_enctype(argp->context,
- argp->dbentry,
- ksent->ks_enctype,
- ksent->ks_salttype,
- -1,
- &kdata)) {
- /*
- * Cannot find a name-to-data matching, so we must have to create a
- * new key entry.
- */
- if (!(kret = krb5_dbe_create_key_data(argp->context, argp->dbentry))) {
- kdata = &argp->dbentry->key_data[argp->dbentry->n_key_data-1];
- kdata->key_data_type[0] = (krb5_int16) ksent->ks_enctype;
- kdata->key_data_type[1] = (krb5_int16) 0;
- }
- }
-
- if (!kret) {
- /*
- * We have "kdata" pointing to the key entry we're to futz
- * with.
- */
- if (!(kret = krb5_random_key(kcontext,
- &master_encblock,
- master_random,
- &key))) {
- /*
- * Now, salt contains the salt and key contains the decrypted
- * key. kdata contains the key/salt data. Fill in the output.
- */
- okeyp = &argp->keys[argp->index];
- argp->index++;
- okeyp->key_data_ver = KRB5_KDB_V1_KEY_DATA_ARRAY;
- okeyp->key_data_kvno = kdata->key_data_kvno + 1;
- okeyp->key_data_type[0] = kdata->key_data_type[0];
- okeyp->key_data_type[1] = 0;
- okeyp->key_data_length[0] = (krb5_int16) key->length;
- okeyp->key_data_length[1] = 0;
- okeyp->key_data_contents[0] = (krb5_octet *) key->contents;
- okeyp->key_data_contents[1] = (krb5_octet *) NULL;
- krb5_xfree(key);
- }
- }
- /*
- * XXXX This is a kludge!!! See above.
- */
- krb5_use_enctype(argp->context, &master_encblock, old_enctype);
- return(kret);
-}
-\f
-/*
- * key_random_key() - generate a random key.
- */
-krb5_error_code
-key_random_key(kcontext, dbentp, nkeysp, keysp)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_int32 *nkeysp;
- krb5_key_data **keysp;
-{
- krb5_error_code kret;
- krb5_key_salt_tuple *keysalts;
- krb5_int32 nkeysalts;
- krb5_key_data *keys;
- struct keysalt_iterate_args ksargs;
-
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_random_key()\n"));
-
- keys = (krb5_key_data *) NULL;
- nkeysalts = 0;
- /*
- * Determine how many and of what kind of keys to generate.
- */
- if (!(kret = key_dbent_to_keysalts(dbentp, &nkeysalts, &keysalts))) {
- if ((keys = (krb5_key_data *)
- malloc((size_t) (nkeysalts * sizeof(krb5_key_data))))) {
- memset(keys, 0, nkeysalts * sizeof(krb5_key_data));
- ksargs.context = kcontext;
- ksargs.string = (krb5_data *) NULL;
- ksargs.dbentry = dbentp;
- ksargs.keys = keys;
- ksargs.index = 0;
- kret = krb5_keysalt_iterate(keysalts,
- nkeysalts,
- 1,
- key_randomkey_keysalt,
- (krb5_pointer) &ksargs);
- }
- else
- kret = ENOMEM;
- krb5_xfree(keysalts);
- }
- if (!kret) {
- *nkeysp = ksargs.index;
- *keysp = keys;
- }
- else {
- if (keys && nkeysalts)
- key_free_key_data(keys, nkeysalts);
- }
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("X key_random_keys() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * key_encrypt_keys() - encrypt keys.
- */
-krb5_error_code
-key_encrypt_keys(kcontext, dbentp, nkeysp, inkeys, outkeysp)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_int32 *nkeysp;
- krb5_key_data *inkeys;
- krb5_key_data **outkeysp;
-{
- krb5_error_code kret;
- krb5_db_entry loser;
- krb5_int32 nkeys, ndone;
- krb5_keyblock tmpkey;
- krb5_keysalt salt;
- int i;
-
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_encrypt_keys()\n"));
- memset(&loser, 0, sizeof(krb5_db_entry));
- ndone = 0;
- nkeys = *nkeysp;
- for (i=0; i<nkeys; i++) {
- if (!(kret = krb5_dbe_create_key_data(kcontext, &loser))) {
- tmpkey.enctype = inkeys[i].key_data_type[0];
- tmpkey.length = inkeys[i].key_data_length[0];
- if ((tmpkey.contents = (krb5_octet *) malloc((size_t)tmpkey.length)))
- memcpy(tmpkey.contents,
- inkeys[i].key_data_contents[0],
- tmpkey.length);
- else
- break;
- salt.type = inkeys[i].key_data_type[1];
- if ((salt.data.length = inkeys[i].key_data_length[1])) {
- if ((salt.data.data = (char *)
- malloc((size_t) salt.data.length)))
- memcpy(salt.data.data,
- inkeys[i].key_data_contents[1],
- (size_t) salt.data.length);
- else
- break;
- }
- else
- salt.data.data = (char *) NULL;
-
- if ((kret = krb5_dbekd_encrypt_key_data(kcontext,
- &master_encblock,
- &tmpkey,
- &salt,
- (int) inkeys[i].key_data_kvno,
- &loser.key_data[i])))
- break;
- else
- ndone++;
- }
- else
- break;
- }
- if (kret) {
- if (loser.key_data && loser.n_key_data)
- key_free_key_data(loser.key_data, (krb5_int32) loser.n_key_data);
- }
- else {
- *outkeysp = loser.key_data;
- *nkeysp = ndone;
- }
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("X key_encrypt_keys() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * key_decrypt_keys() - decrypt keys.
- */
-krb5_error_code
-key_decrypt_keys(kcontext, dbentp, nkeysp, inkeys, outkeysp)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_int32 *nkeysp;
- krb5_key_data *inkeys;
- krb5_key_data **outkeysp;
-{
- krb5_error_code kret;
- krb5_db_entry loser;
- krb5_int32 nkeys, ndone;
- krb5_keyblock tmpkey;
- krb5_keysalt salt;
- int i;
-
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_decrypt_keys()\n"));
- memset(&loser, 0, sizeof(krb5_db_entry));
- ndone = 0;
- nkeys = *nkeysp;
- for (i=0; i<nkeys; i++) {
- if (!(kret = krb5_dbe_create_key_data(kcontext, &loser))) {
- if ((kret = krb5_dbekd_decrypt_key_data(kcontext,
- &master_encblock,
- &inkeys[i],
- &tmpkey,
- &salt)))
- break;
- loser.key_data[i].key_data_ver = KRB5_KDB_V1_KEY_DATA_ARRAY;
- loser.key_data[i].key_data_type[0] = tmpkey.enctype;
- loser.key_data[i].key_data_length[0] = (krb5_int16) tmpkey.length;
- loser.key_data[i].key_data_contents[0] = tmpkey.contents;
- loser.key_data[i].key_data_kvno = inkeys[i].key_data_kvno;
- loser.key_data[i].key_data_type[1] = salt.type;
- loser.key_data[i].key_data_length[1] = salt.data.length;
- loser.key_data[i].key_data_contents[1] =
- (krb5_octet *) salt.data.data;
- ndone++;
- }
- else
- break;
- }
- if (kret) {
- if (loser.key_data && loser.n_key_data)
- key_free_key_data(loser.key_data, (krb5_int32) loser.n_key_data);
- }
- else {
- *outkeysp = loser.key_data;
- *nkeysp = ndone;
- }
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("X key_decrypt_keys() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * key_pwd_is_weak() - Check for weakness of key from password
- */
-krb5_boolean
-key_pwd_is_weak(kcontext, dbentp, string)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_data *string;
-{
- krb5_boolean weakness;
- krb5_error_code kret;
- krb5_int32 num_keys;
- krb5_key_data *key_list;
- int i;
-
- DPRINT(DEBUG_CALLS, key_debug_level, ("* key_pwd_is_weak()\n"));
- weakness = 0;
-
- kret = key_string_to_keys(kcontext,
- dbentp,
- string,
- 0,
- (krb5_key_salt_tuple *) NULL,
- &num_keys,
- &key_list);
- if (!kret) {
- for (i=0; i<num_keys; i++) {
- if (((key_list[i].key_data_type[0] == ENCTYPE_DES_CBC_MD5) ||
- (key_list[i].key_data_type[0] == ENCTYPE_DES_CBC_MD4) ||
- (key_list[i].key_data_type[0] == ENCTYPE_DES_CBC_CRC)) &&
- (key_list[i].key_data_length[0] == KRB5_MIT_DES_KEYSIZE) &&
- mit_des_is_weak_key(key_list[i].key_data_contents[0])) {
- weakness = 1;
- break;
- }
- }
- key_free_key_data(key_list, num_keys);
- }
- DPRINT(DEBUG_CALLS, key_debug_level,
- ("X key_pwd_is_weak() = %d\n", weakness));
- return(weakness);
-}
-\f
-/*
- * key_master_entry() - Return a pointer to the master entry (yuck).
- */
-krb5_db_entry *
-key_master_entry()
-{
- return((ment_init) ? &master_entry : (krb5_db_entry *) NULL);
-}
-\f
-/*
- * key_master_realm() - Return name of master realm (yuck).
- */
-char *
-key_master_realm()
-{
- return((mrealm_init) ? master_realm : (char *) NULL);
-}
-\f
-/*
- * key_keytab_id() - Which key table to use?
- */
-krb5_keytab
-key_keytab_id()
-{
- return((mkeytab_init) ? key_keytab : (krb5_keytab) NULL);
-}
-\f
-/*
- * key_admin_key() - Get a copy of the admin key.
- */
-krb5_keyblock *
-key_admin_key()
-{
- return((madmin_key_init) ? &madmin_key : (krb5_keyblock *) NULL);
-}
-\f
-/*
- * key_master_encblock() - Return pointer to master encryption block.
- */
-krb5_encrypt_block *
-key_master_encblock()
-{
- return((mencb_init) ? &master_encblock : (krb5_encrypt_block *) NULL);
-}
-\f
-/*
- * key_free_key_data() - Free a krb5_key_data array.
- */
-void
-key_free_key_data(keys, nkeys)
- krb5_key_data *keys;
- krb5_int32 nkeys;
-{
- /*
- * XXX - this should probably be a dbe routine.
- */
- int i, j;
-
- if (keys && nkeys) {
- for (i=0; i<nkeys; i++) {
- for (j=0; j<KRB5_KDB_V1_KEY_DATA_ARRAY; j++) {
- if (keys[i].key_data_length[j] &&
- keys[i].key_data_contents[j]) {
- memset(keys[i].key_data_contents[j], 0,
- keys[i].key_data_length[j]);
- free(keys[i].key_data_contents[j]);
- }
- }
- memset(&keys[i], 0, sizeof(krb5_key_data));
- }
- free(keys);
- }
-}
-\f
-/*
- * key_dbent_to_keysalts() - Generate a list of key/salt pairs.
- */
-krb5_error_code
-key_dbent_to_keysalts(dbentp, nentsp, ksentsp)
- krb5_db_entry *dbentp;
- krb5_int32 *nentsp;
- krb5_key_salt_tuple **ksentsp;
-{
- krb5_error_code kret;
- int i;
- krb5_int32 num;
- krb5_key_salt_tuple *ksp;
-
- kret = 0;
- if (dbentp->n_key_data) {
- /* The hard case */
- if ((ksp = (krb5_key_salt_tuple *)
- malloc(dbentp->n_key_data * sizeof(krb5_key_salt_tuple)))) {
- memset(ksp, 0,
- dbentp->n_key_data * sizeof(krb5_key_salt_tuple));
- num = 0;
- for (i=0; i<dbentp->n_key_data; i++) {
- if (krb5_keysalt_is_present(ksp, num,
- dbentp->key_data[i].
- key_data_type[0],
- dbentp->key_data[i].
- key_data_type[1]))
- continue;
- ksp[num].ks_enctype = dbentp->key_data[i].key_data_type[0];
- ksp[num].ks_salttype = dbentp->key_data[i].key_data_type[1];
- num++;
- }
- *ksentsp = ksp;
- *nentsp = num;
- }
- else
- kret = ENOMEM;
- }
- else {
- /* The easy case. */
- if ((*ksentsp = (krb5_key_salt_tuple *)
- malloc(key_num_ktents * sizeof(krb5_key_salt_tuple)))) {
- memcpy(*ksentsp, key_ktents,
- key_num_ktents * sizeof(krb5_key_salt_tuple));
- *nentsp = key_num_ktents;
- }
- else
- kret = ENOMEM;
- }
- return(kret);
-}
-
-krb5_error_code
-key_update_tl_attrs(kcontext, dbentp, mod_name, is_pwchg)
- krb5_context kcontext;
- krb5_db_entry *dbentp;
- krb5_principal mod_name;
- krb5_boolean is_pwchg;
-{
- krb5_error_code kret;
-
- kret = 0 ;
-
- /*
- * Handle modification principal.
- */
- if (mod_name) {
- krb5_tl_mod_princ mprinc;
-
- memset(&mprinc, 0, sizeof(mprinc));
- if (!(kret = krb5_copy_principal(kcontext,
- mod_name,
- &mprinc.mod_princ)) &&
- !(kret = krb5_timeofday(kcontext, &mprinc.mod_date)))
- kret = krb5_dbe_encode_mod_princ_data(kcontext,
- &mprinc,
- dbentp);
- if (mprinc.mod_princ)
- krb5_free_principal(kcontext, mprinc.mod_princ);
- }
-
- /*
- * Handle last password change.
- */
- if (!kret && is_pwchg) {
- krb5_tl_data *pwchg;
- krb5_timestamp now;
- krb5_boolean linked;
-
- /* Find a previously existing entry */
- for (pwchg = dbentp->tl_data;
- (pwchg) && (pwchg->tl_data_type != KRB5_TL_LAST_PWD_CHANGE);
- pwchg = pwchg->tl_data_next);
-
- /* Check to see if we found one. */
- linked = 0;
- if (!pwchg) {
- /* No, allocate a new one */
- if ((pwchg = (krb5_tl_data *) malloc(sizeof(krb5_tl_data)))) {
- memset(pwchg, 0, sizeof(krb5_tl_data));
- if (!(pwchg->tl_data_contents =
- (krb5_octet *) malloc(sizeof(krb5_timestamp)))) {
- free(pwchg);
- pwchg = (krb5_tl_data *) NULL;
- }
- else {
- pwchg->tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
- pwchg->tl_data_length =
- (krb5_int16) sizeof(krb5_timestamp);
- }
- }
- }
- else
- linked = 1;
-
- /* Do we have an entry? */
- if (pwchg && pwchg->tl_data_contents) {
- /* Yes, do the timestamp */
- if (!(kret = krb5_timeofday(kcontext, &now))) {
- /* Encode it */
- krb5_kdb_encode_int32(now, pwchg->tl_data_contents);
- /* Link it in if necessary */
- if (!linked) {
- pwchg->tl_data_next = dbentp->tl_data;
- dbentp->tl_data = pwchg;
- dbentp->n_tl_data++;
- }
- }
- }
- else
- kret = ENOMEM;
- }
-
- return(kret);
-}
-
-krb5_error_code
-key_open_db(kcontext)
- krb5_context kcontext;
-{
- krb5_error_code kret;
-
- if (!(key_db_name) || !(kret = krb5_db_set_name(kcontext, key_db_name))) {
- kret = krb5_db_init(kcontext);
- }
- return(kret);
-}
-
-krb5_error_code
-key_close_db(kcontext)
- krb5_context kcontext;
-{
- return(krb5_db_fini(kcontext));
-}
+++ /dev/null
-/*
- * kadmin/v5server/srv_main.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * srv_main.c
- * Main function of administrative server which speaks new Kerberos V5
- * administrative protocol.
- */
-\f
-#include <stdio.h>
-#include <sys/signal.h>
-#include <setjmp.h>
-#include "k5-int.h"
-#if defined(HAVE_STDARG_H) || defined(_WINDOWS) || defined (_MACINTOSH)
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#define VARARGS
-#endif
-#include "com_err.h"
-#include "adm.h"
-#include "adm_proto.h"
-#include "kadm5_defs.h"
-
-#ifdef LANGUAGES_SUPPORTED
-static const char *usage_format = "%s: usage is %s [-a aclfile] [-d database] [-m]\n\t[-k menctype] [-l langlist] [-p portnum] [-r realm] [-s stash] [-t timeout] [-n]\n\t[-D dbg] [-M mkeyname] [-T ktabname].\n";
-static const char *getopt_string = "a:d:e:k:l:mnp:r:t:D:M:T:";
-#else /* LANGUAGES_SUPPORTED */
-static const char *usage_format = "%s: usage is %s [-a aclfile] [-d database] [-m]\n\t[-k menctype] [-p portnum] [-r realm] [-s stash] [-t timeout] [-n]\n\t[-D dbg] [-M mkeyname] [-T ktabname].\n";
-static const char *getopt_string = "a:d:e:k:mnp:r:t:D:M:T:";
-#endif /* LANGUAGES_SUPPORTED */
-static const char *fval_not_number = "%s: value (%s) specified for -%c is not numeric.\n";
-static const char *extra_params = "%s extra paramters beginning with %s... \n";
-static const char *daemon_err = "%s: cannot spawn and detach.\n";
-static const char *grealm_err = "%s: cannot get default realm.\n";
-static const char *pinit_err = "%s: cannot open configuration file %s.\n";
-static const char *no_memory_fmt = "%s: cannot allocate %d bytes for %s.\n";
-static const char *begin_op_msg = "\007%s starting.";
-static const char *disp_err_fmt = "\004dispatch error.";
-static const char *happy_exit_fmt = "\007terminating normally.";
-static const char *init_error_fmt = "%s: cannot initialize %s.\n";
-static const char *unh_signal_fmt = "\007exiting on signal %d.";
-
-static const char *proto_msg = "protocol module";
-static const char *net_msg = "network";
-static const char *output_msg = "output";
-static const char *acl_msg = "ACLs";
-static const char *key_msg = "key and database";
-static const char *server_name_msg = "Kerberos V5 administrative server";
-
-char *programname = (char *) NULL;
-#if POSIX_SETJMP
-static sigjmp_buf terminal_jmp;
-#else /* POSIX_SETJMP */
-static jmp_buf terminal_jmp;
-#endif /* POSIX_SETJMP */
-\f
-static void
-usage(prog)
- char *prog;
-{
- fprintf(stderr, usage_format, prog, prog);
-}
-
-/*
- * An unhandled signal just proceeds from the setjmp() in main.
- */
-static krb5_sigtype
-unhandled_signal(signo)
- int signo;
-{
-#if POSIX_SETJMP
- siglongjmp(terminal_jmp, signo);
-#else /* POSIX_SETJMP */
- longjmp(terminal_jmp, signo);
-#endif /* POSIX_SETJMP */
- /* NOTREACHED */
-}
-\f
-#ifdef DEBUG
-#ifndef VARARGS
-void xprintf(const char *str, ...)
-{
-#else
-void xprintf(va_alist)
- va_dcl
-{
- const char *str;
-#endif
- va_list pvar;
- FILE* xfd;
- static opened = 0;
- time_t t = time(0);
-
-#ifdef VARARGS
- va_start (pvar);
- str = va_arg (pvar, const char *);
-#else
- va_start(pvar, str);
-#endif
- xfd = fopen("kadmind5-xprintf.log","a");
- if (!xfd) perror("xfd");
- else {
- if (!opened) {
- opened = 1;
- fprintf(xfd, "starting log pid %d time %s\n", getpid(), ctime(&t));
- }
- vfprintf(xfd,str,pvar);
- fflush(xfd);
- fclose(xfd);
- }
- va_end(pvar);
-}
-#endif /* DEBUG */
-\f
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern int optind;
- extern char *optarg;
- int option;
- krb5_error_code error;
-
- int key_type = -1;
- int manual_entry = 0;
- krb5_boolean mime_enabled = 0;
- int debug_level = 0;
- int nofork = 0;
- int timeout = -1;
- krb5_int32 service_port = -1;
- char *acl_file = (char *) NULL;
- char *db_file = (char *) NULL;
- char *language_list = (char *) NULL;
- char *db_realm = (char *) NULL;
- char *master_key_name = (char *) NULL;
- char *keytab_name = (char *) NULL;
- char *stash_name = (char *) NULL;
- krb5_deltat maxlife = -1;
- krb5_deltat maxrlife = -1;
- krb5_timestamp def_expiration = 0;
- krb5_flags def_flags = 0;
- krb5_boolean exp_valid, flags_valid;
- krb5_realm_params *rparams;
- krb5_int32 realm_num_keysalts;
- krb5_key_salt_tuple *realm_keysalts;
-
- /* Kerberatic contexts */
- krb5_context kcontext;
-
- const char *errmsg;
- int signal_number;
-
- /*
- * usage is:
- * kadmind5 [-a aclfile] <acl file>
- * [-d database] <database file>
- * [-e enctype] <encryption type>
- * [-k masterenctype] <master key type>
- * [-l languagelist] <language list>
- * [-m] <manual master key entry>
- * [-n] <do not fork/disassociate>
- * [-p portnumber] <listen on port>
- * [-r realmname] <realm>
- * [-s stashfile] <stashfile>
- * [-t timeout] <inactivity timeout>
- * [-D debugmask] <debug mask>
- * [-M masterkeyname] <name of master key>
- * [-T keytabname] <key table file>
- */
- error = 0;
- exp_valid = flags_valid = FALSE;
- realm_keysalts = (krb5_key_salt_tuple *) NULL;
- realm_num_keysalts = 0;
- while ((option = getopt(argc, argv, getopt_string)) != EOF) {
- switch (option) {
- case 'a':
- acl_file = optarg;
- break;
- case 'd':
- db_file = optarg;
- break;
- case 'm':
- manual_entry++;
- break;
- case 'k':
- if (sscanf(optarg, "%d", &key_type) != 1) {
- fprintf(stderr, fval_not_number, argv[0], optarg, 'k');
- error++;
- }
- break;
-#ifdef LANGUAGES_SUPPORTED
- case 'l':
- language_list = optarg;
- mime_enabled = 1;
- break;
-#endif /* LANGUAGES_SUPPORTED */
- case 'n':
- nofork++;
- break;
- case 'p':
- if (sscanf(optarg, "%d", &service_port) != 1) {
- fprintf(stderr, fval_not_number, argv[0], optarg, 'p');
- error++;
- }
- break;
- case 'r':
- db_realm = optarg;
- break;
- case 's':
- stash_name = optarg;
- break;
- case 't':
- if (sscanf(optarg, "%d", &timeout) != 1) {
- fprintf(stderr, fval_not_number, argv[0], optarg, 't');
- error++;
- }
- break;
- case 'D':
- if (sscanf(optarg, "%d", &debug_level) != 1) {
- fprintf(stderr, fval_not_number, argv[0], optarg, 'D');
- error++;
- }
- break;
- case 'M':
- master_key_name = optarg;
- break;
- case 'T':
- keytab_name = optarg;
- break;
- default:
- error++;
- break;
- }
- }
- if (optind - argc > 0) {
- fprintf(stderr, extra_params, argv[0], argv[optind+1]);
- error++;
- }
- if (error) {
- usage(argv[0]);
- return(1);
- }
-
-#ifndef DEBUG
- /*
- * If we're not debugging and we didn't specify -n, then detach from our
- * controlling terminal and exit.
- */
- if (!nofork && daemon(0, (manual_entry != 0))) {
- fprintf(stderr, daemon_err, argv[0]);
- perror(argv[0]);
- return(2);
- }
-#endif /* DEBUG */
-
- /*
- * We've come this far. Our arguments are good.
- */
-#ifndef DEBUG
- programname = (char *) strrchr(argv[0], '/');
- if (programname)
- programname++;
- else
- programname = argv[0];
-#else /* DEBUG */
- programname = argv[0];
-#endif /* DEBUG */
- krb5_init_context(&kcontext);
- krb5_init_ets(kcontext);
- krb5_klog_init(kcontext, "admin_server", programname, 1);
- if (db_realm) {
- if ((error = krb5_set_default_realm(kcontext, db_realm))) {
- com_err(programname, error, "while setting default realm name");
- return(1);
- }
- }
-
- /*
- * Attempt to read the KDC profile. If we do, then read appropriate values
- * from it and supercede values supplied on the command line.
- */
- if (!(error = krb5_read_realm_params(kcontext,
- db_realm,
- (char *) NULL,
- (char *) NULL,
- &rparams))) {
- /* Get the value for the database */
- if (rparams->realm_dbname)
- db_file = strdup(rparams->realm_dbname);
-
- /* Get the value for the master key name */
- if (rparams->realm_mkey_name)
- master_key_name = strdup(rparams->realm_mkey_name);
-
- /* Get the value for the master key type */
- if (rparams->realm_enctype_valid)
- key_type = rparams->realm_enctype;
-
- /* Get the value for the port */
- if (rparams->realm_kadmind_port_valid)
- service_port = rparams->realm_kadmind_port;
-
- /* Get the value for the stashfile */
- if (rparams->realm_stash_file)
- stash_name = strdup(rparams->realm_stash_file);
-
- /* Get the value for maximum ticket lifetime. */
- if (rparams->realm_max_life_valid)
- maxlife = rparams->realm_max_life;
-
- /* Get the value for maximum renewable ticket lifetime. */
- if (rparams->realm_max_rlife_valid)
- maxrlife = rparams->realm_max_rlife;
-
- /* Get the value for the default principal expiration */
- if (rparams->realm_expiration_valid) {
- def_expiration = rparams->realm_expiration;
- exp_valid = TRUE;
- }
-
- /* Get the value for the default principal flags */
- if (rparams->realm_flags_valid) {
- def_flags = rparams->realm_flags;
- flags_valid = TRUE;
- }
-
- /* Clone the value of the keysalt array */
- if (realm_num_keysalts = rparams->realm_num_keysalts) {
- if (realm_keysalts =
- (krb5_key_salt_tuple *) malloc(realm_num_keysalts *
- sizeof(krb5_key_salt_tuple))) {
- memcpy(realm_keysalts, rparams->realm_keysalts,
- (realm_num_keysalts * sizeof(krb5_key_salt_tuple)));
- }
- else
- realm_num_keysalts = 0;
- }
-
- krb5_free_realm_params(kcontext, rparams);
- }
-
- if ((signal_number =
-#if POSIX_SETJMP
- sigsetjmp(terminal_jmp, 1)
-#else /* POSIX_SETJMP */
- setjmp(terminal_jmp)
-#endif /* POSIX_SETJMP */
- ) == 0) {
-#if POSIX_SIGNALS
- struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
- /*
- * Initialize signal handling.
- */
-#if POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
- s_action.sa_handler = unhandled_signal;
- (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGALRM, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- signal(SIGINT, unhandled_signal);
- signal(SIGTERM, unhandled_signal);
- signal(SIGHUP, unhandled_signal);
- signal(SIGQUIT, unhandled_signal);
- signal(SIGPIPE, unhandled_signal);
- signal(SIGALRM, unhandled_signal);
- signal(SIGCHLD, unhandled_signal);
-#endif /* POSIX_SIGNALS */
-
- /*
- * Initialize our modules.
- */
- error = key_init(kcontext,
- debug_level,
- key_type,
- master_key_name,
- manual_entry,
- db_file,
- db_realm,
- keytab_name,
- stash_name,
- realm_num_keysalts,
- realm_keysalts);
- if (!error) {
- error = acl_init(kcontext, debug_level, acl_file);
- if (!error) {
- error = output_init(kcontext, debug_level,
- language_list, mime_enabled);
- if (!error) {
- error = net_init(kcontext, debug_level, service_port);
- if (!error) {
- error = proto_init(kcontext, debug_level, timeout);
- admin_init(maxlife,
- maxrlife,
- exp_valid,
- def_expiration,
- flags_valid,
- def_flags);
- if (error)
- errmsg = proto_msg;
- }
- else
- errmsg = net_msg;
- }
- else
- errmsg = output_msg;
- }
- else
- errmsg = acl_msg;
- }
- else
- errmsg = key_msg;
-
- if (!error) {
- /*
- * We've successfully initialized here.
- */
- com_err(programname, 0, begin_op_msg, server_name_msg);
-
- /*
- * net_dispatch() only returns when we're done for some reason.
- */
- error = net_dispatch(kcontext, !nofork);
-
- com_err(programname, error,
- ((error) ? disp_err_fmt : happy_exit_fmt));
- }
- else {
- /* Initialization error */
- fprintf(stderr, init_error_fmt, programname, errmsg);
- }
- }
- else {
- /* Received an unhandled signal */
-#ifndef DEBUG
- com_err(programname, 0, unh_signal_fmt, signal_number);
-#endif
- }
-
- /* Now clean up after ourselves */
- proto_finish(kcontext, debug_level);
- net_finish(kcontext, debug_level);
- output_finish(kcontext, debug_level);
- acl_finish(kcontext, debug_level);
- key_finish(kcontext, debug_level);
- krb5_klog_close(kcontext);
- krb5_xfree(kcontext);
- exit(error);
-}
+++ /dev/null
-/*
- * kadmin/v5server/srv_net.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * srv_net.c - handle networking functions of the administrative server.
- */
-#include <errno.h>
-#include <setjmp.h>
-#include <sys/wait.h>
-#include <signal.h>
-#ifdef USE_PTHREADS
-#include <pthread.h>
-#endif /* USE_PTHREADS */
-
-#define NEED_SOCKETS
-#include "k5-int.h"
-#include "com_err.h"
-#include "kadm5_defs.h"
-#include "adm.h"
-
-#if HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-/* linux doesn't have SOMAXCONN */
-#ifndef SOMAXCONN
-#define SOMAXCONN 5
-#endif
-
-/*
- * This module can use the pthreads library. To do so, define USE_PTHREADS.
- * You'll need to find out what else pthreads requires (e.g. -lmach -lc_r
- * under OSF/1).
- */
-#ifdef USE_PTHREADS
-#define net_slave_type pthread_t *
-#ifndef MAX_SLAVES
-#define MAX_SLAVES 2*SOMAXCONN
-#endif /* MAX_SLAVES */
-#else /* USE_PTHREADS */
-#define net_slave_type pid_t
-#ifndef MAX_SLAVES
-#define MAX_SLAVES 2*SOMAXCONN
-#endif /* MAX_SLAVES */
-#endif /* USE_PTHREADS */
-#define NET_SLAVE_FULL_SLEEP 2 /* seconds */
-
-/*
- * Slave information storage.
- */
-typedef struct _net_slave_info {
- int sl_inuse;
- net_slave_type sl_id;
- krb5_context sl_context;
- int sl_socket;
- struct sockaddr_in sl_local_addr; /* local address */
- struct sockaddr_in sl_remote_addr; /* remote address */
-} net_slave_info;
-
-/*
- * Error messages.
- */
-static const char *net_waiterr_msg = "\004child wait failed - cannot reap children";
-static const char *net_def_realm_fmt = "%s: cannot get default realm (%s).\n";
-static const char *net_no_mem_fmt = "%s: cannot get memory.\n";
-static const char *net_parse_srv_fmt = "%s: cannot parse server name %s (%s).\n";
-static const char *net_no_hostname_fmt = "%s: cannot get our host name (%s).\n";
-static const char *net_no_hostent_fmt = "%s: cannot get our host entry (%s).\n";
-static const char *net_no_servent_fmt = "%s: cannot get service entry for %s (%s).\n";
-static const char *net_sockerr_fmt = "%s: cannot open network socket (%s).\n";
-static const char *net_soerr_fmt = "%s: cannot set socket options (%s).\n";
-static const char *net_binderr_fmt = "%s: cannot bind to network address (%s).\n";
-
-static const char *net_select_fmt = "\004select failed";
-static const char *net_cl_disp_fmt = "\004client dispatch failed";
-static const char *net_not_ready_fmt = "\004select error - no socket to read";
-static const char *net_dispatch_msg = "network dispatch";
-
-static int net_debug_level = 0;
-
-static char *net_service_name = (char *) NULL;
-static int net_service_princ_init = 0;
-static krb5_principal net_service_principal = (krb5_principal) NULL;
-static int net_server_addr_init = 0;
-static struct sockaddr_in net_server_addr;
-static int net_listen_socket = -1;
-static int net_slaves_active = 0;
-static int net_max_slaves = 0;
-static net_slave_info *net_slave_table = (net_slave_info *) NULL;
-
-#if POSIX_SETJMP
-static sigjmp_buf shutdown_jmp;
-#else /* POSIX_SETJMP */
-static jmp_buf shutdown_jmp;
-#endif /* POSIX_SETJMP */
-
-extern char *programname;
-\f
-/*
- * net_find_free_entry() - Find a free entry in the slave table.
- */
-static net_slave_info *
-net_find_free_entry()
-{
- int i, found;
-
- /* Find a table entry */
- while (1) {
- found = 0;
- for (i=0; i<net_max_slaves; i++) {
- if (!net_slave_table[i].sl_inuse) {
- net_slave_table[i].sl_inuse = 1;
- found = 1;
- break;
- }
- }
- if (found)
- break;
- sleep(NET_SLAVE_FULL_SLEEP);
- }
- return(&net_slave_table[i]);
-}
-\f
-/*
- * net_find_slave() - Find a slave entry by its identity.
- */
-static net_slave_info *
-net_find_slave(id)
- net_slave_type id;
-{
- int i, found;
-
- for (i=0; i<net_max_slaves; i++) {
- if (net_slave_table[i].sl_inuse &&
- (net_slave_table[i].sl_id == id)) {
- found = 1;
- break;
- }
- }
- if (found)
- return(&net_slave_table[i]);
- else
- return((net_slave_info *) NULL);
-}
-
-/*
- * net_free_slave_entry() - Mark an entry as free.
- */
-static void
-net_free_slave_entry(entp)
- net_slave_info *entp;
-{
- entp->sl_inuse = 0;
-}
-\f
-/*
- * net_shutdown() - Destroy all slaves on signal reception
- */
-static krb5_sigtype
-net_shutdown(signo)
- int signo;
-{
- int i;
-
- /* Loop through all slaves */
- for (i=0; i<net_max_slaves; i++) {
- if (net_slave_table[i].sl_inuse){
-#ifdef DEBUG
- /* If not us (see net_dispatch_client) */
- if (net_slave_table[i].sl_id != (net_slave_type) getpid()) {
-#endif /* DEBUG */
-#if USE_PTHREADS
- pthread_cancel(*net_slave_table[i].sl_id);
-#else /* USE_PTHREADS */
- kill(net_slave_table[i].sl_id, SIGKILL);
-#endif /* USE_PTHREADS */
-#ifdef DEBUG
- }
-#endif /* DEBUG */
- }
- }
- sleep(5); /* to allow children to die and be reaped */
-#if POSIX_SETJMP
- siglongjmp(shutdown_jmp, 1);
-#else /* POSIX_SETJMP */
- longjmp(shutdown_jmp, 1);
-#endif /* POSIX_SETJMP */
- /* NOTREACHED */
-}
-\f
-#if !USE_PTHREADS
-/*
- * net_reaper() - Child process termination handler.
- */
-static krb5_sigtype
-net_reaper(signo)
- int signo;
-{
-#ifdef WAIT_USES_INT
- int child_exit;
-#else /* WAIT_USES_INT */
- union wait child_exit;
-#endif /* WAIT_USES_INT */
- pid_t deadmeat;
- net_slave_info *slent;
-
- /* Reap everybody we can */
- while (
- (
-#ifdef HAVE_WAITPID
- deadmeat = waitpid((pid_t) -1, &child_exit, WNOHANG)
-#else /* HAVE_WAITPID */
- deadmeat = wait3(&child_exit, WNOHANG, (struct rusage *) NULL)
-#endif /* HAVE_WAITPID */
- ) > 0) {
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| process %d finished with %d\n", deadmeat, child_exit));
- slent = net_find_slave(deadmeat);
- if (slent) {
- net_free_slave_entry(slent);
- }
- else {
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| cannot find slave entry for %d\n", deadmeat));
- }
- }
- if ((deadmeat == -1) && (errno != ECHILD))
- com_err(programname, errno, net_waiterr_msg);
-}
-#endif /* USE_PTHREADS */
-\f
-#if USE_PTHREADS
-/*
- * net_slave_proto() - pthread main routine.
- */
-static krb5_error_code
-net_slave_proto(stent)
- net_slave_info *stent;
-{
- krb5_error_code kret;
-
- DPRINT(DEBUG_CALLS, net_debug_level,
- ("* net_slave_proto()\n"));
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| thread %d starting\n", stent->sl_id));
- kret = proto_serv(stent->sl_context,
- (krb5_int32) stent->sl_id,
- stent->sl_socket,
- &stent->sl_local_addr,
- &stent->sl_remote_addr);
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| thread %d finished with %d\n", stent->sl_id, kret));
- DPRINT(DEBUG_CALLS, net_debug_level,
- ("* net_slave_proto() = %d\n", kret));
- net_free_slave_entry(stent);
- return(kret);
-}
-#endif /* USE_PTHREADS */
-\f
-/*
- * net_dispatch_client() - Handle client dispatch.
- */
-static krb5_error_code
-net_dispatch_client(kcontext, listen_sock, conn_sock, client_addr)
- krb5_context kcontext;
- int listen_sock;
- int conn_sock;
- struct sockaddr_in *client_addr;
-{
- krb5_error_code kret;
- net_slave_info *slent;
-
- DPRINT(DEBUG_CALLS, net_debug_level,
- ("* net_dispatch_client(listen=%d)\n", listen_sock));
- kret = 0;
-
- /* Find a free entry */
- slent = net_find_free_entry();
-
- /* Initialize the slave entry */
- slent->sl_context = kcontext;
- slent->sl_socket = conn_sock;
- memcpy((char *) &slent->sl_remote_addr,
- (char *) client_addr,
- sizeof(struct sockaddr_in));
- memcpy((char *) &slent->sl_local_addr,
- (char *) &net_server_addr,
- sizeof(struct sockaddr_in));
-
-#ifdef DEBUG
- if ((net_debug_level & DEBUG_NOSLAVES) == 0) {
-#endif /* DEBUG */
- /* Do a real slave creation */
-#if USE_PTHREADS
- if (!slent->sl_id)
- slent->sl_id = (pthread_t *) malloc(sizeof(pthread_t));
- if (slent->sl_id == (pthread_t *) NULL) {
- kret = ENOMEM;
- goto done;
- }
- if (kret = pthread_create(slent->sl_id,
- pthread_attr_default,
- (pthread_startroutine_t) net_slave_proto,
- (pthread_addr_t) slent)) {
- kret = errno;
- goto done;
- }
- if (pthread_detach(slent->sl_id)) {
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| (%d) child thread %d detach failed (%d)\n",
- getpid(), slent->sl_id, errno));
- }
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| (%d) created child thread %d\n",
- getpid(), slent->sl_id));
-#else /* USE_PTHREADS */
- slent->sl_id = fork();
- if (slent->sl_id < 0) {
- kret = errno;
- slent->sl_inuse = 0;
- goto done;
- }
-
- if (slent->sl_id > 0) {
- /* parent */
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| (%d) created child process %d\n",
- getpid(), slent->sl_id));
- close(conn_sock);
- kret = 0;
- goto done;
- }
- else {
-#if POSIX_SIGNALS
- struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
- /* child */
-#if POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
- /* Ignore SIGINT, SIGTERM, SIGHUP, SIGQUIT and SIGPIPE */
- s_action.sa_handler = SIG_IGN;
- (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
- /* Restore to default SIGCHLD */
- s_action.sa_handler = SIG_DFL;
- (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- signal(SIGINT, SIG_IGN); /* Ignore SIGINT */
- signal(SIGTERM, SIG_IGN); /* Ignore SIGTERM */
- signal(SIGHUP, SIG_IGN); /* Ignore SIGHUP */
- signal(SIGQUIT, SIG_IGN); /* Ignore SIGQUIT */
- signal(SIGPIPE, SIG_IGN); /* Ignore SIGPIPE */
- signal(SIGCHLD, SIG_DFL); /* restore SIGCHLD handling */
-#endif /* POSIX_SIGNALS */
- close(listen_sock);
- slent->sl_id = getpid();
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| process %d starting\n", slent->sl_id));
- kret = proto_serv(slent->sl_context,
- (krb5_int32) slent->sl_id,
- slent->sl_socket,
- &slent->sl_local_addr,
- &slent->sl_remote_addr);
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| process %d exiting with %d\n", getpid(), kret));
- exit(kret);
- }
-#endif /* USE_PTHREADS */
-#ifdef DEBUG
- }
- else {
- net_slave_info *sl1;
-#if POSIX_SIGNALS
- struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
- /*
- * Ignore SIGPIPE.
- */
-#if POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
- s_action.sa_handler = SIG_IGN;
- (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- signal(SIGPIPE, SIG_IGN); /* Ignore SIGPIPE */
-#endif /* POSIX_SIGNALS */
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| (%d) not doing child creation\n", getpid()));
- slent->sl_id = (net_slave_type) getpid();
- kret = proto_serv(slent->sl_context,
- (krb5_int32) slent->sl_id,
- slent->sl_socket,
- &slent->sl_local_addr,
- &slent->sl_remote_addr);
- sl1 = net_find_slave(slent->sl_id);
- if (sl1)
- net_free_slave_entry(sl1);
- DPRINT(DEBUG_SPROC, net_debug_level,
- ("| (%d) returned with %d\n", getpid(), kret));
- kret = 0;
- }
-#endif /* DEBUG */
- done:
- DPRINT(DEBUG_CALLS, net_debug_level,
- ("X net_dispatch_client() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * net_init() - Initialize network context.
- */
-krb5_error_code
-net_init(kcontext, debug_level, port)
- krb5_context kcontext;
- int debug_level;
- krb5_int32 port;
-{
- krb5_error_code kret;
- char our_host_name[MAXHOSTNAMELEN];
- struct hostent *our_hostent;
- struct servent *our_servent;
- char *realm;
-
- net_debug_level = debug_level;
- DPRINT(DEBUG_CALLS, net_debug_level, ("* net_init(port=%d)\n", port));
-
- /* Get our realm name */
- realm = key_master_realm();
-
- /* Allocate the slave table */
- net_slave_table = (net_slave_info *)
- malloc((size_t) (MAX_SLAVES * sizeof(net_slave_info)));
- /* Make our service name */
- net_service_name = (char *) malloc(strlen(realm) +
- strlen(KRB5_ADM_SERVICE_INSTANCE) + 2);
- if ((net_service_name == (char *) NULL) ||
- (net_slave_table == (net_slave_info *) NULL)) {
- kret = ENOMEM;
- fprintf(stderr, net_no_mem_fmt, programname);
- goto done;
- }
- (void) sprintf(net_service_name, "%s%s%s",
- KRB5_ADM_SERVICE_INSTANCE, "/", realm);
- memset((char *) net_slave_table, 0,
- (size_t) (MAX_SLAVES * sizeof(net_slave_info)));
- net_max_slaves = MAX_SLAVES;
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- name of service is %s\n", net_service_name));
-
- /* Now formulate the principal name */
- if (kret = krb5_parse_name(kcontext,
- net_service_name,
- &net_service_principal)) {
- fprintf(stderr, net_parse_srv_fmt, programname, net_service_name,
- error_message(kret));
- goto done;
- }
- net_service_princ_init = 1;
-
-#ifdef KRB5_USE_INET
- /* Now get our host name/entry */
- if (gethostname(our_host_name, sizeof(our_host_name))) {
- kret = errno;
- fprintf(stderr, net_no_hostname_fmt, programname, error_message(kret));
- goto done;
- }
- if (!(our_hostent = gethostbyname(our_host_name))) {
- kret = KRB5_ERR_BAD_HOSTNAME; /* perhaps put h_errno in the msg */
- fprintf(stderr, net_no_hostent_fmt, programname, error_message(kret));
- goto done;
- }
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- name of host is %s\n", our_hostent->h_name));
-
- /* Now initialize our network address */
- net_server_addr.sin_family = AF_INET;
- memcpy((char *) &net_server_addr.sin_addr,
- (char *) our_hostent->h_addr,
- sizeof(net_server_addr.sin_addr));
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- address of host is %x\n",
- ntohl(net_server_addr.sin_addr.s_addr)));
-
- /*
- * Fill in the port address.
- * If the port is supplied by the invoker, then use that one.
- * If not, then try the profile, and if all fails, then use the service
- * entry.
- */
- if (port > 0) {
- net_server_addr.sin_port = htons(port);
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- service name (%s) is on port %d from options\n",
- KRB5_ADM_SERVICE_NAME,
- ntohs(net_server_addr.sin_port)));
- }
- else {
- char **admin_hostlist;
- const char *realm_admin_names[4]; /* XXX */
- krb5_boolean found;
-
- /*
- * Try to get the service entry out of the profile.
- */
- admin_hostlist = (char **) NULL;
- realm_admin_names[0] = "realms";
- realm_admin_names[1] = realm;
- realm_admin_names[2] = "admin_server";
- realm_admin_names[3] = (char *) NULL;
- found = 0;
-#ifndef OLD_CONFIG_FILES
- if (!(kret = profile_get_values(kcontext->profile,
- realm_admin_names,
- &admin_hostlist))) {
- int hi;
- char *cport;
- char *cp;
- krb5_int32 pport;
- int ai;
-
- cport = (char *) NULL;
- pport = KRB5_ADM_DEFAULT_PORT;
- for (hi=0; admin_hostlist[hi]; hi++) {
- /*
- * This knows a little too much about the format of profile
- * entries. Shouldn't it just be some sort of tuple?
- *
- * The form is assumed to be:
- * admin_server = <hostname>[:<portname>[<whitespace>]]
- */
- cp = strchr(admin_hostlist[hi], ' ');
- if (cp)
- *cp = '\0';
- cp = strchr(admin_hostlist[hi], '\t');
- if (cp)
- *cp = '\0';
- cport = strchr(admin_hostlist[hi], ':');
- if (cport) {
- *cport = '\0';
- cport++;
- if (sscanf(cport, "%d", &pport) != 1) {
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- profile entry for %s has bad port %s\n",
- admin_hostlist[hi],
- cport));
- pport = KRB5_ADM_DEFAULT_PORT;
- }
- }
- /*
- * We've stripped away the crud. Now check to see if the
- * profile entry matches our hostname. If so, then this
- * is the one to use. Additionally, check the host alias
- * list.
- */
- if (!strcmp(admin_hostlist[hi], our_hostent->h_name)) {
- net_server_addr.sin_port = ntohs((u_short) pport);
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- service name (%s) is on port %d from profile\n",
- KRB5_ADM_SERVICE_NAME,
- pport));
- found = 1;
- }
- else {
- for (ai=0; our_hostent->h_aliases[ai]; ai++) {
- if (!strcmp(admin_hostlist[hi],
- our_hostent->h_aliases[ai])) {
- net_server_addr.sin_port = ntohs(pport);
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- service name (%s) is on port %d from profile and alias\n",
- KRB5_ADM_SERVICE_NAME,
- pport));
- found = 1;
- break;
- }
- }
- }
- }
- krb5_xfree(admin_hostlist);
- }
-#endif /* OLD_CONFIG_FILES */
-
- /*
- * If we didn't find an entry in the profile, then as a last gasp
- * effort, attempt to find it in /etc/services.
- */
- if (!found) {
- /* Get the service entry out of /etc/services */
- if (!(our_servent = getservbyname(KRB5_ADM_SERVICE_NAME, "tcp"))) {
- kret = errno;
- fprintf(stderr, net_no_servent_fmt, programname,
- KRB5_ADM_SERVICE_NAME, error_message(kret));
- goto done;
- }
- net_server_addr.sin_port = our_servent->s_port;
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- service name (%s) is on port %d from services\n",
- our_servent->s_name,
- ntohs(our_servent->s_port)));
- }
- }
- net_server_addr_init = 1;
-
- /* Now open the listen socket */
- net_listen_socket = socket(AF_INET, SOCK_STREAM, 0);
- if (net_listen_socket < 0) {
- kret = errno;
- fprintf(stderr, net_sockerr_fmt, programname, error_message(kret));
- goto done;
- }
-
- /* If we have a non-default port number, then allow reuse of address */
- if (net_server_addr.sin_port != htons(KRB5_ADM_DEFAULT_PORT)) {
- int allowed;
-
- allowed = 1;
- if (setsockopt(net_listen_socket,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char *) &allowed,
- sizeof(allowed)) < 0) {
- kret = errno;
- fprintf(stderr, net_soerr_fmt, programname, error_message(kret));
- goto done;
- }
- }
-
- /* Bind socket */
- if (bind(net_listen_socket,
- (struct sockaddr *) &net_server_addr,
- sizeof(net_server_addr)) < 0) {
- kret = errno;
- fprintf(stderr, net_binderr_fmt, programname, error_message(kret));
- goto done;
- }
- else {
- DPRINT(DEBUG_HOST, net_debug_level,
- ("- bound socket %d on port\n", net_listen_socket));
- kret = 0;
- }
-#else /* KRB5_USE_INET */
- /* Don't know how to do anything else. */
- kret = ENOENT;
-#endif /* KRB5_USE_INET */
-
- done:
- DPRINT(DEBUG_CALLS, net_debug_level, ("X net_init() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * net_finish() - Finish network context.
- */
-void
-net_finish(kcontext, debug_level)
- krb5_context kcontext;
- int debug_level;
-{
- DPRINT(DEBUG_CALLS, net_debug_level, ("* net_finish()\n"));
- if (net_max_slaves) {
- net_max_slaves = 0;
- free(net_slave_table);
- }
- if (net_listen_socket >= 0)
- close(net_listen_socket);
- if (net_service_princ_init)
- krb5_free_principal(kcontext, net_service_principal);
- if (net_service_name)
- free(net_service_name);
- DPRINT(DEBUG_CALLS, net_debug_level, ("X net_finish()\n"));
-}
-\f
-/*
- * net_dispatch() - Listen and dispatch request.
- *
- * Loop forever selecting on the listen socket. When an incoming connection
- * comes in, dispatch to net_client_connect().
- */
-krb5_error_code
-net_dispatch(kcontext, detached)
- krb5_context kcontext;
- int detached;
-{
- krb5_error_code kret;
- fd_set mask, readfds;
- int nready;
-#if POSIX_SIGNALS
- struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
- DPRINT(DEBUG_CALLS, net_debug_level, ("* net_dispatch()\n"));
-
- kret = 0;
-
- /* Set up the fdset mask */
- FD_ZERO(&mask);
- FD_SET(net_listen_socket, &mask);
-
-#if POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
- s_action.sa_handler = net_shutdown;
- (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
-#ifdef DEBUG
- (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
-#endif /* DEBUG */
- if (!detached)
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- /*
- * SIGTERM (or SIGINT, if debug, or SIGHUP if not detached) shuts us down.
- */
- signal(SIGTERM, net_shutdown);
-#ifdef DEBUG
- signal(SIGINT, net_shutdown);
-#endif /* DEBUG */
- if (!detached)
- signal(SIGHUP, net_shutdown);
-#endif /* POSIX_SIGNALS */
-
-#if !USE_PTHREADS
-#if POSIX_SIGNALS
- s_action.sa_handler = net_reaper;
- (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- /*
- * SIGCHILD indicates end of child process life.
- */
- signal(SIGCHLD, net_reaper);
-#endif /* POSIX_SIGNALS */
-#endif /* !USE_PTHREADS */
-
- /* Receive connections on the socket */
- DPRINT(DEBUG_OPERATION, net_debug_level, ("+ listening on socket\n"));
- if (
-#if POSIX_SETJMP
- sigsetjmp(shutdown_jmp, 1) == 0
-#else /* POSIX_SETJMP */
- setjmp(shutdown_jmp) == 0
-#endif /* POSIX_SETJMP */
- ) {
- if (listen(net_listen_socket, SOMAXCONN) < 0)
- kret = errno;
- }
- else
- kret = EINTR;
- DPRINT(DEBUG_OPERATION, net_debug_level, ("+ listen done\n"));
-
- while (kret == 0) {
- /*
- * Prepare to catch signals.
- */
- if (
-#if POSIX_SETJMP
- sigsetjmp(shutdown_jmp, 1) == 0
-#else /* POSIX_SETJMP */
- setjmp(shutdown_jmp) == 0
-#endif /* POSIX_SETJMP */
- ) {
- readfds = mask;
- DPRINT(DEBUG_OPERATION, net_debug_level, ("+ doing select\n"));
- if ((nready = select(net_listen_socket+1,
- &readfds,
- (fd_set *) NULL,
- (fd_set *) NULL,
- (struct timeval *) NULL)) == 0) {
- DPRINT(DEBUG_OPERATION, net_debug_level, ("+ nobody ready\n"));
- continue; /* Nobody ready */
- }
-
- if ((nready < 0) && (errno != EINTR)) {
- com_err(net_dispatch_msg, errno, net_select_fmt);
- continue;
- }
-
- if (FD_ISSET(net_listen_socket, &readfds)) {
- struct sockaddr_in client_addr;
- int addrlen;
- int conn_sock;
-
- addrlen = sizeof(client_addr);
- DPRINT(DEBUG_OPERATION, net_debug_level,
- ("+ accept connection\n"));
- while (((conn_sock = accept(net_listen_socket,
- (struct sockaddr *) &client_addr,
- &addrlen)) < 0) &&
- (errno == EINTR));
-
- if (conn_sock < 0) {
- kret = errno;
- break;
- }
- DPRINT(DEBUG_OPERATION, net_debug_level,
- ("+ accepted connection\n"));
- kret = net_dispatch_client(kcontext,
- net_listen_socket,
- conn_sock,
- &client_addr);
- if (kret) {
- com_err(net_dispatch_msg, kret, net_cl_disp_fmt);
- continue;
- }
- DPRINT(DEBUG_OPERATION, net_debug_level,
- ("+ dispatch done\n"));
- }
- else {
- com_err(net_dispatch_msg, 0, net_not_ready_fmt);
- kret = EIO;
- }
- }
- else {
- DPRINT(DEBUG_OPERATION, net_debug_level,
- ("+ dispatch interrupted by SIGTERM\n"));
- kret = 0;
- break;
- }
- }
-
- DPRINT(DEBUG_CALLS, net_debug_level, ("X net_dispatch() = %d\n", kret));
- return(kret);
-}
-\f
-/*
- * Return our service principal.
- */
-krb5_principal
-net_server_princ()
-{
- if (net_service_princ_init)
- return(net_service_principal);
- else
- return((krb5_principal) NULL);
-}
+++ /dev/null
-/*
- * kadmin/v5server/srv_output.c
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-/*
- * srv_output.c - Handle Kerberos output related functions.
- */
-#include "k5-int.h"
-#include "com_err.h"
-#include "kadm5_defs.h"
-#include "adm.h"
-
-static const char *out_adm_success = "Operation successful.";
-static const char *out_adm_cmd_unknown = "Command %s unknown.";
-static const char *out_adm_pw_unaccept = "Password unacceptable.";
-static const char *out_adm_bad_princ = "Principal unknown.";
-static const char *out_adm_pwd_too_short = "Password is too short.";
-static const char *out_adm_pwd_weak = "Password generates weak key.";
-static const char *out_adm_not_allowed = "You are not allowed to change your password.";
-static const char *out_adm_bad_pw = "Password incorrect.";
-static const char *out_adm_not_in_tkt = "Not an initial ticket.";
-static const char *out_adm_cant_change = "Cannot change password.";
-static const char *out_adm_lang_unsupp = "Language %s unsupported.";
-static const char *out_adm_p_exists = "Principal %s already exists.";
-static const char *out_adm_p_not_exist = "Principal %s does not exist.";
-static const char *out_adm_not_auth = "Not authorized for this operation.";
-static const char *out_adm_bad_option = "Bad option supplied.";
-static const char *out_adm_value_req = "Value required for option.";
-static const char *out_adm_sys_error = "Unspecified system error.";
-static const char *out_adm_key_exists = "Key type already exists.";
-static const char *out_adm_key_missing = "Key type does not exist.";
-static const char *out_adm_bad_args = "Bad argument list format for %s command.";
-static const char *out_adm_bad_cmd = "Command %s not supported.";
-static const char *out_adm_no_cmd = "No command in message.";
-static const char *out_adm_no_err = "Unknown error.";
-static int output_debug_level = 0;
-static int output_mime_enabled = 0;
-static int output_lang_inited = 0;
-static char **output_lang_list = (char **) NULL;
-static char *output_langstring = (char *) NULL;
-\f
-/*
- * lang_error_message() - Return language-dependent Kerberos error message.
- *
- * This is just a hook.
- */
-static char *
-lang_error_message(lang, kval)
- char *lang;
- krb5_error_code kval;
-{
- char *ret;
- const char *ermsg;
-
- ermsg = (char *) error_message(kval);
- if (lang && output_lang_supported(lang)) {
- /*
- * Just for demonstration purposes.
- */
- ret = (char *) malloc(strlen(ermsg)+strlen(lang)+3+1);
- if (ret)
- sprintf(ret, "%s - %s", lang, ermsg);
- }
- else {
- ret = (char *) malloc(strlen(ermsg)+1);
- if (ret)
- strcpy(ret, ermsg);
- }
- return(ret);
-}
-
-/*
- * lang_adm_message() - Return language-dependent administrative message.
- *
- * This is just a hook.
- */
-static char *
-lang_adm_message(lang, ecode, aux, nargs, alist)
- char *lang;
- krb5_int32 ecode;
- krb5_int32 aux;
- krb5_int32 nargs;
- krb5_data *alist;
-{
- char *ret;
- const char *ermsg;
- char *erarg;
- size_t alen;
-
- erarg = (char *) NULL;
- switch (ecode) {
- case KRB5_ADM_SUCCESS:
- ermsg = out_adm_success; break;
- case KRB5_ADM_CMD_UNKNOWN:
- switch (aux) {
- case KADM_BAD_ARGS:
- ermsg = out_adm_bad_args;
- erarg = ((nargs >= 1) ? alist[0].data : (char *) NULL);
- break;
- case KADM_BAD_CMD:
- ermsg = out_adm_bad_cmd;
- erarg = ((nargs >= 1) ? alist[0].data : (char *) NULL);
- break;
- case KADM_NO_CMD:
- ermsg = out_adm_no_cmd;
- break;
- default:
- ermsg = out_adm_bad_args;
- erarg = ((nargs >= 1) ? alist[0].data : (char *) NULL);
- break;
- }
- break;
- case KRB5_ADM_PW_UNACCEPT:
- switch (aux) {
- case KADM_BAD_PRINC:
- ermsg = out_adm_bad_princ;
- break;
- case KADM_PWD_TOO_SHORT:
- ermsg = out_adm_pwd_too_short;
- break;
- case KADM_PWD_WEAK:
- ermsg = out_adm_pwd_weak;
- break;
- default:
- ermsg = out_adm_pw_unaccept;
- break;
- }
- break;
- case KRB5_ADM_BAD_PW:
- ermsg = out_adm_bad_pw; break;
- case KRB5_ADM_NOT_IN_TKT:
- ermsg = out_adm_not_in_tkt; break;
- case KRB5_ADM_CANT_CHANGE:
- switch (aux) {
- case KADM_BAD_PRINC:
- ermsg = out_adm_bad_princ;
- break;
- case KADM_PWD_TOO_SHORT:
- ermsg = out_adm_pwd_too_short;
- break;
- case KADM_PWD_WEAK:
- ermsg = out_adm_pwd_weak;
- break;
- case KADM_NOT_ALLOWED:
- ermsg = out_adm_not_allowed;
- break;
- default:
- ermsg = out_adm_cant_change;
- break;
- }
- break;
- case KRB5_ADM_LANG_NOT_SUPPORTED:
- ermsg = out_adm_lang_unsupp;
- erarg = ((nargs >= 2) ? alist[1].data : (char *) NULL);
- break;
- case KRB5_ADM_P_ALREADY_EXISTS:
- ermsg = out_adm_p_exists;
- erarg = ((nargs >= 2) ? alist[1].data : (char *) NULL);
- break;
- case KRB5_ADM_P_DOES_NOT_EXIST:
- ermsg = out_adm_p_not_exist;
- erarg = ((nargs >= 2) ? alist[1].data : (char *) NULL);
- break;
- case KRB5_ADM_NOT_AUTHORIZED:
- ermsg = out_adm_not_auth;
- break;
- case KRB5_ADM_BAD_OPTION:
- ermsg = out_adm_bad_option;
- break;
- case KRB5_ADM_VALUE_REQUIRED:
- ermsg = out_adm_value_req;
- break;
- case KRB5_ADM_SYSTEM_ERROR:
- ermsg = out_adm_sys_error;
- break;
- case KRB5_ADM_KEY_ALREADY_EXISTS:
- ermsg = out_adm_key_exists;
- break;
- case KRB5_ADM_KEY_DOES_NOT_EXIST:
- ermsg = out_adm_key_missing;
- break;
- default:
- ermsg = out_adm_no_err; break;
- }
-
- alen = strlen(ermsg)+1;
- if (erarg)
- alen += strlen(erarg);
- if (lang && output_lang_supported(lang)) {
- alen += strlen(lang)+3;
- }
- ret = (char *) malloc(alen);
- if (lang && output_lang_supported(lang)) {
- char *xxx;
-
- /*
- * Just for demonstration purposes.
- */
- if (ret) {
- sprintf(ret, "%s - ", lang);
- xxx = &ret[strlen(ret)];
- sprintf(xxx, ermsg, erarg);
- }
- }
- else {
- if (ret)
- sprintf(ret, ermsg, erarg);
- }
- return(ret);
-}
-
-/*
- * mimeify_text() - MIME encode text.
- *
- * This is just a hook.
- */
-static char *
-mimeify_text(msg)
- char *msg;
-{
- char *ret;
- /*
- * Just for demonstration purposes.
- */
-
- if (output_mime_enabled) {
- ret = (char *) malloc(strlen(msg)+6+3);
- if (ret)
- sprintf(ret, "MIME: %s\r\n", msg);
- if (!ret)
- ret = msg;
- }
- else
- ret = msg;
- return(ret);
-}
-
-/*
- * lang_init_slist() - Initialize list of supported languages.
- */
-static krb5_boolean
-lang_init_slist(llist)
- char *llist;
-{
- int ret;
-
- DPRINT(DEBUG_CALLS, output_debug_level, ("* lang_init_slist()\n"));
- ret = 1;
- if (llist) {
- int nseps, i;
- char *sepp;
-
- /* First count the number of commas. */
- sepp = llist;
- for (nseps=1;
- (sepp = strchr(sepp, (int) ',')) != (char *) NULL;
- nseps++)
- sepp++;
-
- output_langstring =
- (char *) malloc((size_t) (strlen(llist)+1));
- output_lang_list =
- (char **) malloc((size_t) ((nseps+1) * sizeof(char *)));
- if (output_lang_list && output_langstring) {
- strcpy(output_langstring, llist);
- sepp = output_langstring;
- for (i=0; i<nseps; i++) {
- output_lang_list[i] = sepp;
- sepp = strchr(sepp, (int) ',');
- if (sepp) {
- *sepp = '\0';
- sepp++;
- }
- }
- output_lang_list[nseps] = (char *) NULL;
- }
- else {
- if (output_langstring)
- free(output_langstring);
- ret = 0;
- }
- }
- DPRINT(DEBUG_CALLS, output_debug_level,
- ("X lang_init_slist() = %d\n", ret));
- return(ret);
-}
-
-/*
- * output_init() - Initialize output context.
- */
-krb5_error_code
-output_init(kcontext, debug_level, language_list, mime_enabled)
- krb5_context kcontext;
- int debug_level;
- char *language_list;
- krb5_boolean mime_enabled;
-{
- krb5_error_code kret;
-
- kret = 0;
- output_debug_level = debug_level;
- DPRINT(DEBUG_CALLS, output_debug_level,
- ("* output_init(llist=%s, mime=%d)\n",
- ((language_list) ? language_list : "(null)"),
- mime_enabled));
- output_mime_enabled = mime_enabled;
- output_lang_inited = lang_init_slist(language_list);
- DPRINT(DEBUG_CALLS, output_debug_level, ("X output_init() = %d\n", kret));
- return(kret);
-}
-
-/*
- * output_finish - Terminate output context.
- */
-void
-output_finish(kcontext, debug_level)
- krb5_context kcontext;
- int debug_level;
-{
- DPRINT(DEBUG_CALLS, output_debug_level, ("* output_finish()\n"));
- if (output_lang_inited) {
- if (output_langstring)
- free(output_langstring);
- if (output_lang_list)
- free(output_lang_list);
- }
- DPRINT(DEBUG_CALLS, output_debug_level, ("X output_finish()\n"));
-}
-
-/*
- * output_lang_supported- Is a language supported?
- */
-krb5_boolean
-output_lang_supported(lname)
- char *lname;
-{
- krb5_boolean ret;
- int i;
- DPRINT(DEBUG_CALLS, output_debug_level,
- ("* output_lang_supported(lang=%s)\n",
- ((lname) ? lname : "(default)")));
- ret = 1;
- if (lname) {
- ret = 0;
- if (output_lang_inited && output_lang_list) {
- for (i=0; output_lang_list[i]; i++)
- if (!strcmp(output_lang_list[i], lname))
- ret = 1;
- }
- }
- DPRINT(DEBUG_CALLS, output_debug_level,
- ("X output_lang_supported() = %d\n", ret));
- return(ret);
-}
-
-/*
- * output_errmsg - Return an error message.
- */
-char *
-output_krb5_errmsg(lang, mime, kval)
- char * lang;
- krb5_boolean mime;
- krb5_error_code kval;
-{
- char *ret;
- char *ermsg;
-
- DPRINT(DEBUG_CALLS, output_debug_level,
- ("* output_krb5_errmsg(v=%d, lang=%s, mime=%d)\n",
- kval, ((lang) ? lang : "(default)", mime)));
- ermsg = lang_error_message(lang, kval);
- if (mime) {
- ret = mimeify_text(ermsg);
- if (ret != ermsg)
- free(ermsg);
- }
- else
- ret = ermsg;
- DPRINT(DEBUG_CALLS, output_debug_level, ("X output_krb5_errmsg()\n"));
- return(ret);
-}
-
-/*
- * output_adm_error - Output an administrative error message string.
- */
-char *
-output_adm_error(lang, mime, ecode, aux, nargs, alist)
- char *lang;
- krb5_boolean mime;
- krb5_int32 ecode;
- krb5_int32 aux;
- krb5_int32 nargs;
- krb5_data *alist;
-{
- char *ermsg;
- char *ret;
-
- DPRINT(DEBUG_CALLS, output_debug_level,
- ("* output_adm_err(lang=%s, mime=%d, code=%d/%d)\n",
- ((lang) ? lang : "(default)"), mime, ecode, aux));
- ermsg = lang_adm_message(lang, ecode, aux, nargs, alist);
- if (mime) {
- ret = mimeify_text(ermsg);
- if (ret != ermsg)
- free(ermsg);
- }
- else
- ret = ermsg;
- DPRINT(DEBUG_CALLS, output_debug_level, ("X output_adm_err()\n"));
- return(ret);
-}