3791 lines
126 KiB
Plaintext
3791 lines
126 KiB
Plaintext
Index: src/plugins/kdb/db2/kdb_db2.c
|
|
===================================================================
|
|
--- src/plugins/kdb/db2/kdb_db2.c.orig
|
|
+++ src/plugins/kdb/db2/kdb_db2.c
|
|
@@ -702,25 +702,22 @@ krb5_db2_db_create(krb5_context context,
|
|
}
|
|
db = k5db2_dbopen(db_ctx, db_name, O_RDWR | O_CREAT | O_EXCL, 0600, db_ctx->tempdb);
|
|
if (db == NULL)
|
|
- retval = errno;
|
|
- else
|
|
- (*db->close) (db);
|
|
- if (retval == 0) {
|
|
+ return errno;
|
|
+ (*db->close) (db);
|
|
|
|
- db_name2 = db_ctx->tempdb ? gen_dbsuffix(db_name, "~") : strdup(db_name);
|
|
- if (db_name2 == NULL)
|
|
- return ENOMEM;
|
|
- okname = gen_dbsuffix(db_name2, KDB2_LOCK_EXT);
|
|
- if (!okname)
|
|
- retval = ENOMEM;
|
|
- else {
|
|
- fd = open(okname, O_CREAT | O_RDWR | O_TRUNC, 0600);
|
|
- if (fd < 0)
|
|
- retval = errno;
|
|
- else
|
|
- close(fd);
|
|
- free_dbsuffix(okname);
|
|
- }
|
|
+ db_name2 = db_ctx->tempdb ? gen_dbsuffix(db_name, "~") : strdup(db_name);
|
|
+ if (db_name2 == NULL)
|
|
+ return ENOMEM;
|
|
+ okname = gen_dbsuffix(db_name2, KDB2_LOCK_EXT);
|
|
+ if (!okname)
|
|
+ retval = ENOMEM;
|
|
+ else {
|
|
+ fd = open(okname, O_CREAT | O_RDWR | O_TRUNC, 0600);
|
|
+ if (fd < 0)
|
|
+ retval = errno;
|
|
+ else
|
|
+ close(fd);
|
|
+ free_dbsuffix(okname);
|
|
}
|
|
|
|
sprintf(policy_db_name, "%s.kadm5", db_name2);
|
|
Index: src/plugins/preauth/cksum_body/cksum_body_main.c
|
|
===================================================================
|
|
--- src/plugins/preauth/cksum_body/cksum_body_main.c.orig
|
|
+++ src/plugins/preauth/cksum_body/cksum_body_main.c
|
|
@@ -78,6 +78,7 @@ static krb5_error_code
|
|
client_process(krb5_context kcontext,
|
|
void *client_plugin_context,
|
|
void *client_request_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
preauth_get_client_data_proc client_get_data_proc,
|
|
struct _krb5_preauth_client_rock *rock,
|
|
krb5_kdc_req *request,
|
|
@@ -99,6 +100,27 @@ client_process(krb5_context kcontext,
|
|
krb5_error_code status = 0;
|
|
krb5_int32 cksumtype, *enctypes;
|
|
unsigned int i, n_enctypes, cksumtype_count;
|
|
+ int num_gic_info = 0;
|
|
+ krb5_gic_opt_pa_data *gic_info;
|
|
+
|
|
+ status = krb5_get_init_creds_opt_get_pa(kcontext, opt,
|
|
+ &num_gic_info, &gic_info);
|
|
+ if (status && status != ENOENT) {
|
|
+#ifdef DEBUG
|
|
+ fprintf(stderr, "Error from krb5_get_init_creds_opt_get_pa: %s\n",
|
|
+ error_message(status));
|
|
+#endif
|
|
+ return status;
|
|
+ }
|
|
+#ifdef DEBUG
|
|
+ fprintf(stderr, "(cksum_body) Got the following gic options:\n");
|
|
+#endif
|
|
+ for (i = 0; i < num_gic_info; i++) {
|
|
+#ifdef DEBUG
|
|
+ fprintf(stderr, " '%s' = '%s'\n", gic_info[i].attr, gic_info[i].value);
|
|
+#endif
|
|
+ }
|
|
+ krb5_get_init_creds_opt_free_pa(kcontext, num_gic_info, gic_info);
|
|
|
|
memset(&checksum, 0, sizeof(checksum));
|
|
|
|
@@ -193,6 +215,20 @@ client_process(krb5_context kcontext,
|
|
return 0;
|
|
}
|
|
|
|
+static krb5_error_code
|
|
+client_gic_opt(krb5_context kcontext,
|
|
+ void *plugin_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ const char *attr,
|
|
+ const char *value)
|
|
+{
|
|
+#ifdef DEBUG
|
|
+ fprintf(stderr, "(cksum_body) client_gic_opt: received '%s' = '%s'\n",
|
|
+ attr, value);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Initialize and tear down the server-side module, and do stat tracking. */
|
|
static krb5_error_code
|
|
server_init(krb5_context kcontext, void **module_context)
|
|
@@ -200,7 +236,7 @@ server_init(krb5_context kcontext, void
|
|
struct server_stats *stats;
|
|
stats = malloc(sizeof(struct server_stats));
|
|
if (stats == NULL)
|
|
- return ENOMEM;
|
|
+ return ENOMEM;
|
|
stats->successes = 0;
|
|
stats->failures = 0;
|
|
*module_context = stats;
|
|
@@ -506,6 +542,7 @@ struct krb5plugin_preauth_client_ftable_
|
|
NULL, /* request fini function */
|
|
client_process, /* process function */
|
|
NULL, /* try_again function */
|
|
+ client_gic_opt /* get init creds opt function */
|
|
};
|
|
|
|
struct krb5plugin_preauth_server_ftable_v0 preauthentication_server_0 = {
|
|
Index: src/plugins/preauth/wpse/wpse_main.c
|
|
===================================================================
|
|
--- src/plugins/preauth/wpse/wpse_main.c.orig
|
|
+++ src/plugins/preauth/wpse/wpse_main.c
|
|
@@ -90,6 +90,7 @@ static krb5_error_code
|
|
client_process(krb5_context kcontext,
|
|
void *plugin_context,
|
|
void *request_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
preauth_get_client_data_proc client_get_data_proc,
|
|
struct _krb5_preauth_client_rock *rock,
|
|
krb5_kdc_req *request,
|
|
@@ -208,6 +209,21 @@ client_req_cleanup(krb5_context kcontext
|
|
return;
|
|
}
|
|
|
|
+static krb5_error_code
|
|
+client_gic_opt(krb5_context kcontext,
|
|
+ void *plugin_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ const char *attr,
|
|
+ const char *value)
|
|
+{
|
|
+#ifdef DEBUG
|
|
+ fprintf(stderr, "(wpse) client_gic_opt: received '%s' = '%s'\n",
|
|
+ attr, value);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
/* Free state. */
|
|
static krb5_error_code
|
|
server_free_pa_request_context(krb5_context kcontext, void *plugin_context,
|
|
@@ -378,6 +394,7 @@ struct krb5plugin_preauth_client_ftable_
|
|
client_req_cleanup, /* request fini function */
|
|
client_process, /* process function */
|
|
NULL, /* try_again function */
|
|
+ client_gic_opt /* get init creds opts function */
|
|
};
|
|
|
|
struct krb5plugin_preauth_server_ftable_v0 preauthentication_server_0 = {
|
|
Index: src/Makefile.in
|
|
===================================================================
|
|
--- src/Makefile.in.orig
|
|
+++ src/Makefile.in
|
|
@@ -69,6 +69,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROO
|
|
$(FILE_MANDIR) $(KRB5_LIBDIR) $(KRB5_INCDIR) \
|
|
$(KRB5_DB_MODULE_DIR) \
|
|
$(KRB5_LIBKRB5_MODULE_DIR) \
|
|
+ @localstatedir@ @localstatedir@/krb5kdc \
|
|
$(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR)
|
|
|
|
install-strip:
|
|
Index: src/include/win-mac.h
|
|
===================================================================
|
|
--- src/include/win-mac.h.orig
|
|
+++ src/include/win-mac.h
|
|
@@ -82,6 +82,17 @@ typedef int int32_t;
|
|
typedef unsigned __int64 uint64_t;
|
|
typedef __int64 int64_t;
|
|
#endif
|
|
+#ifndef SSIZE_T_DEFINED
|
|
+#ifdef ssize_t
|
|
+#undef ssize_t
|
|
+#endif
|
|
+#ifdef _WIN64
|
|
+typedef __int64 ssize_t;
|
|
+#else
|
|
+typedef _W64 int ssize_t;
|
|
+#endif
|
|
+#define SSIZE_T_DEFINED
|
|
+#endif
|
|
#endif /* KRB5_SYSTYPES__ */
|
|
|
|
#define MAXHOSTNAMELEN 512
|
|
Index: src/include/Makefile.in
|
|
===================================================================
|
|
--- src/include/Makefile.in.orig
|
|
+++ src/include/Makefile.in
|
|
@@ -85,8 +85,13 @@ krb5/krb5.h: $(srcdir)/krb5/krb5.hin krb
|
|
asn1_err.h >> krb5/krb5.h
|
|
echo "#endif /* KRB5_KRB5_H_INCLUDED */" >> krb5/krb5.h
|
|
|
|
-verify-calling-conventions-krb5: krb5/krb5.h
|
|
- $(PERL) -w $(SRCTOP)/util/def-check.pl krb5/krb5.h $(SRCTOP)/lib/krb5_32.def
|
|
+verify-calling-conventions-krb5: private-and-public-decls
|
|
+ $(PERL) -w $(SRCTOP)/util/def-check.pl private-and-public-decls $(SRCTOP)/lib/krb5_32.def
|
|
+
|
|
+HEADERS_TO_CHECK = krb5/krb5.h $(srcdir)/k5-int.h $(srcdir)/krb5/preauth_plugin.h
|
|
+
|
|
+private-and-public-decls: $(HEADERS_TO_CHECK)
|
|
+ cat $(HEADERS_TO_CHECK) > $@
|
|
|
|
#
|
|
# Build the error table include files:
|
|
Index: src/include/k5-int.h
|
|
===================================================================
|
|
--- src/include/k5-int.h.orig
|
|
+++ src/include/k5-int.h
|
|
@@ -876,6 +876,7 @@ typedef struct _krb5_preauth_context {
|
|
krb5_error_code (*client_process)(krb5_context context,
|
|
void *plugin_context,
|
|
void *request_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
preauth_get_client_data_proc get_data_proc,
|
|
krb5_preauth_client_rock *rock,
|
|
krb5_kdc_req *request,
|
|
@@ -893,6 +894,7 @@ typedef struct _krb5_preauth_context {
|
|
krb5_error_code (*client_tryagain)(krb5_context context,
|
|
void *plugin_context,
|
|
void *request_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
preauth_get_client_data_proc get_data_proc,
|
|
krb5_preauth_client_rock *rock,
|
|
krb5_kdc_req *request,
|
|
@@ -908,6 +910,7 @@ typedef struct _krb5_preauth_context {
|
|
krb5_data *s2kparams,
|
|
krb5_keyblock *as_key,
|
|
krb5_pa_data **new_pa_data);
|
|
+ supply_gic_opts_proc client_supply_gic_opts;
|
|
void (*client_req_init)(krb5_context context, void *plugin_context,
|
|
void **request_context);
|
|
void (*client_req_fini)(krb5_context context, void *plugin_context,
|
|
@@ -1014,6 +1017,74 @@ void krb5_free_etype_info
|
|
/*
|
|
* End "preauth.h"
|
|
*/
|
|
+
|
|
+/*
|
|
+ * Extending the krb5_get_init_creds_opt structure. The original
|
|
+ * krb5_get_init_creds_opt structure is defined publicly. The
|
|
+ * new extended version is private. The original interface
|
|
+ * assumed a pre-allocated structure which was passed to
|
|
+ * krb5_get_init_creds_init(). The new interface assumes that
|
|
+ * the caller will call krb5_get_init_creds_alloc() and
|
|
+ * krb5_get_init_creds_free().
|
|
+ *
|
|
+ * Callers MUST NOT call krb5_get_init_creds_init() after allocating an
|
|
+ * opts structure using krb5_get_init_creds_alloc(). To do so will
|
|
+ * introduce memory leaks. Unfortunately, there is no way to enforce
|
|
+ * this behavior.
|
|
+ *
|
|
+ * Two private flags are added for backward compatibility.
|
|
+ * KRB5_GET_INIT_CREDS_OPT_EXTENDED says that the structure was allocated
|
|
+ * with the new krb5_get_init_creds_opt_alloc() function.
|
|
+ * KRB5_GET_INIT_CREDS_OPT_SHADOWED is set to indicate that the extended
|
|
+ * structure is a shadow copy of an original krb5_get_init_creds_opt
|
|
+ * structure.
|
|
+ * If KRB5_GET_INIT_CREDS_OPT_SHADOWED is set after a call to
|
|
+ * krb5int_gic_opt_to_opte(), the resulting extended structure should be
|
|
+ * freed (using krb5_get_init_creds_free). Otherwise, the original
|
|
+ * structure was already extended and there is no need to free it.
|
|
+ */
|
|
+
|
|
+#define KRB5_GET_INIT_CREDS_OPT_EXTENDED 0x80000000
|
|
+#define KRB5_GET_INIT_CREDS_OPT_SHADOWED 0x40000000
|
|
+
|
|
+#define krb5_gic_opt_is_extended(s) \
|
|
+ (((s)->flags & KRB5_GET_INIT_CREDS_OPT_EXTENDED) ? 1 : 0)
|
|
+#define krb5_gic_opt_is_shadowed(s) \
|
|
+ (((s)->flags & KRB5_GET_INIT_CREDS_OPT_SHADOWED) ? 1 : 0)
|
|
+
|
|
+
|
|
+typedef struct _krb5_gic_opt_private {
|
|
+ int num_preauth_data;
|
|
+ krb5_gic_opt_pa_data *preauth_data;
|
|
+} krb5_gic_opt_private;
|
|
+
|
|
+typedef struct _krb5_gic_opt_ext {
|
|
+ krb5_flags flags;
|
|
+ krb5_deltat tkt_life;
|
|
+ krb5_deltat renew_life;
|
|
+ int forwardable;
|
|
+ int proxiable;
|
|
+ krb5_enctype *etype_list;
|
|
+ int etype_list_length;
|
|
+ krb5_address **address_list;
|
|
+ krb5_preauthtype *preauth_list;
|
|
+ int preauth_list_length;
|
|
+ krb5_data *salt;
|
|
+ /*
|
|
+ * Do not change anything above this point in this structure.
|
|
+ * It is identical to the public krb5_get_init_creds_opt structure.
|
|
+ * New members must be added below.
|
|
+ */
|
|
+ krb5_gic_opt_private *opt_private;
|
|
+} krb5_gic_opt_ext;
|
|
+
|
|
+krb5_error_code
|
|
+krb5int_gic_opt_to_opte(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ krb5_gic_opt_ext **opte,
|
|
+ unsigned int force,
|
|
+ const char *where);
|
|
+
|
|
krb5_error_code
|
|
krb5int_copy_data_contents (krb5_context, const krb5_data *, krb5_data *);
|
|
|
|
@@ -1037,14 +1108,14 @@ krb5_get_init_creds
|
|
void *prompter_data,
|
|
krb5_deltat start_time,
|
|
char *in_tkt_service,
|
|
- krb5_get_init_creds_opt *gic_options,
|
|
+ krb5_gic_opt_ext *gic_options,
|
|
krb5_gic_get_as_key_fct gak,
|
|
void *gak_data,
|
|
int *master,
|
|
krb5_kdc_rep **as_reply);
|
|
|
|
-void krb5int_populate_gic_opt (
|
|
- krb5_context, krb5_get_init_creds_opt *,
|
|
+krb5_error_code krb5int_populate_gic_opt (
|
|
+ krb5_context, krb5_gic_opt_ext **,
|
|
krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
|
|
krb5_preauthtype *pre_auth_types, krb5_creds *creds);
|
|
|
|
@@ -1059,7 +1130,8 @@ krb5_error_code KRB5_CALLCONV krb5_do_pr
|
|
krb5_enctype *etype, krb5_keyblock *as_key,
|
|
krb5_prompter_fct prompter, void *prompter_data,
|
|
krb5_gic_get_as_key_fct gak_fct, void *gak_data,
|
|
- krb5_preauth_client_rock *get_data_rock);
|
|
+ krb5_preauth_client_rock *get_data_rock,
|
|
+ krb5_gic_opt_ext *opte);
|
|
krb5_error_code KRB5_CALLCONV krb5_do_preauth_tryagain
|
|
(krb5_context context,
|
|
krb5_kdc_req *request,
|
|
@@ -1071,7 +1143,8 @@ krb5_error_code KRB5_CALLCONV krb5_do_pr
|
|
krb5_enctype *etype, krb5_keyblock *as_key,
|
|
krb5_prompter_fct prompter, void *prompter_data,
|
|
krb5_gic_get_as_key_fct gak_fct, void *gak_data,
|
|
- krb5_preauth_client_rock *get_data_rock);
|
|
+ krb5_preauth_client_rock *get_data_rock,
|
|
+ krb5_gic_opt_ext *opte);
|
|
void KRB5_CALLCONV krb5_init_preauth_context
|
|
(krb5_context);
|
|
void KRB5_CALLCONV krb5_free_preauth_context
|
|
@@ -1079,7 +1152,7 @@ void KRB5_CALLCONV krb5_free_preauth_con
|
|
void KRB5_CALLCONV krb5_clear_preauth_context_use_counts
|
|
(krb5_context);
|
|
void KRB5_CALLCONV krb5_preauth_prepare_request
|
|
- (krb5_context, krb5_get_init_creds_opt *, krb5_kdc_req *);
|
|
+ (krb5_context, krb5_gic_opt_ext *, krb5_kdc_req *);
|
|
void KRB5_CALLCONV krb5_preauth_request_context_init
|
|
(krb5_context);
|
|
void KRB5_CALLCONV krb5_preauth_request_context_fini
|
|
Index: src/include/krb5/krb5.hin
|
|
===================================================================
|
|
--- src/include/krb5/krb5.hin.orig
|
|
+++ src/include/krb5/krb5.hin
|
|
@@ -1469,8 +1469,20 @@ krb5_error_code krb5_get_cred_from_kdc_r
|
|
krb5_creds *,
|
|
krb5_creds **,
|
|
krb5_creds *** );
|
|
+
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5int_server_decrypt_ticket_keyblock
|
|
+ (krb5_context context,
|
|
+ const krb5_keyblock *key,
|
|
+ krb5_ticket *ticket);
|
|
#endif
|
|
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_server_decrypt_ticket_keytab
|
|
+ (krb5_context context,
|
|
+ const krb5_keytab kt,
|
|
+ krb5_ticket *ticket);
|
|
+
|
|
void KRB5_CALLCONV krb5_free_tgt_creds
|
|
(krb5_context,
|
|
krb5_creds **); /* XXX too hard to do with const */
|
|
@@ -2431,6 +2443,16 @@ typedef struct _krb5_get_init_creds_opt
|
|
#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
|
|
#define KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT 0x0100
|
|
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_alloc
|
|
+(krb5_context context,
|
|
+ krb5_get_init_creds_opt **opt);
|
|
+
|
|
+void KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_free
|
|
+(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt);
|
|
+
|
|
void KRB5_CALLCONV
|
|
krb5_get_init_creds_opt_init
|
|
(krb5_get_init_creds_opt *opt);
|
|
@@ -2482,6 +2504,27 @@ krb5_get_init_creds_opt_set_change_passw
|
|
(krb5_get_init_creds_opt *opt,
|
|
int prompt);
|
|
|
|
+/* Generic preauth option attribute/value pairs */
|
|
+typedef struct _krb5_gic_opt_pa_data {
|
|
+ char *attr;
|
|
+ char *value;
|
|
+} krb5_gic_opt_pa_data;
|
|
+
|
|
+/*
|
|
+ * This function allows the caller to supply options to preauth
|
|
+ * plugins. Preauth plugin modules are given a chance to look
|
|
+ * at each option at the time this function is called in ordre
|
|
+ * to check the validity of the option.
|
|
+ * The 'opt' pointer supplied to this function must have been
|
|
+ * obtained using krb5_get_init_creds_opt_alloc()
|
|
+ */
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_set_pa
|
|
+ (krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ const char *attr,
|
|
+ const char *value);
|
|
+
|
|
krb5_error_code KRB5_CALLCONV
|
|
krb5_get_init_creds_password
|
|
(krb5_context context,
|
|
Index: src/include/krb5/preauth_plugin.h
|
|
===================================================================
|
|
--- src/include/krb5/preauth_plugin.h.orig
|
|
+++ src/include/krb5/preauth_plugin.h
|
|
@@ -158,6 +158,17 @@ typedef krb5_error_code
|
|
void *gak_data);
|
|
|
|
/*
|
|
+ * Client function which receives krb5_get_init_creds_opt information.
|
|
+ * The attr and value information supplied should be copied locally by
|
|
+ * the module if it wishes to reference it after returning from this call.
|
|
+ */
|
|
+typedef krb5_error_code
|
|
+(*supply_gic_opts_proc)(krb5_context context,
|
|
+ void *plugin_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ const char *attr,
|
|
+ const char *value);
|
|
+/*
|
|
* The function table / structure which a preauth client module must export as
|
|
* "preauthentication_client_0". If the interfaces work correctly, future
|
|
* versions of the table will add either more callbacks or more arguments to
|
|
@@ -207,6 +218,7 @@ typedef struct krb5plugin_preauth_client
|
|
krb5_error_code (*process)(krb5_context context,
|
|
void *plugin_context,
|
|
void *request_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
preauth_get_client_data_proc get_data_proc,
|
|
struct _krb5_preauth_client_rock *rock,
|
|
krb5_kdc_req *request,
|
|
@@ -227,8 +239,9 @@ typedef struct krb5plugin_preauth_client
|
|
krb5_error_code (*tryagain)(krb5_context context,
|
|
void *plugin_context,
|
|
void *request_context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
preauth_get_client_data_proc get_data_proc,
|
|
- struct _krb5_preauth_client_rock *rock,
|
|
+ struct _krb5_preauth_client_rock *rock,
|
|
krb5_kdc_req *request,
|
|
krb5_data *encoded_request_body,
|
|
krb5_data *encoded_previous_request,
|
|
@@ -241,6 +254,12 @@ typedef struct krb5plugin_preauth_client
|
|
krb5_data *salt, krb5_data *s2kparams,
|
|
krb5_keyblock *as_key,
|
|
krb5_pa_data **out_pa_data);
|
|
+ /*
|
|
+ * Client function which receives krb5_get_init_creds_opt information.
|
|
+ * The attr and value information supplied should be copied locally by
|
|
+ * the module if it wishes to reference it after returning from this call.
|
|
+ */
|
|
+ supply_gic_opts_proc gic_opts;
|
|
} krb5plugin_preauth_client_ftable_v0;
|
|
|
|
/*
|
|
@@ -323,4 +342,31 @@ typedef struct krb5plugin_preauth_server
|
|
void *pa_module_context,
|
|
void **request_pa_context);
|
|
} krb5plugin_preauth_server_ftable_v0;
|
|
+
|
|
+
|
|
+/*
|
|
+ * This function allows a preauth plugin to obtain preauth
|
|
+ * options. The preauth_data returned from this function
|
|
+ * should be freed by calling krb5_get_init_creds_opt_free_pa().
|
|
+ *
|
|
+ * The 'opt' pointer supplied to this function must have been
|
|
+ * obtained using krb5_get_init_creds_opt_alloc()
|
|
+ */
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_get_pa
|
|
+ (krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ int *num_preauth_data,
|
|
+ krb5_gic_opt_pa_data **preauth_data);
|
|
+
|
|
+/*
|
|
+ * This function frees the preauth_data that was returned by
|
|
+ * krb5_get_init_creds_opt_get_pa().
|
|
+ */
|
|
+void KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_free_pa
|
|
+ (krb5_context context,
|
|
+ int num_preauth_data,
|
|
+ krb5_gic_opt_pa_data *preauth_data);
|
|
+
|
|
#endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */
|
|
Index: src/appl/telnet/telnetd/sys_term.c
|
|
===================================================================
|
|
--- src/appl/telnet/telnetd/sys_term.c.orig
|
|
+++ src/appl/telnet/telnetd/sys_term.c
|
|
@@ -1287,12 +1287,25 @@ start_login(host, autologin, name)
|
|
#endif
|
|
#if defined (AUTHENTICATION)
|
|
if (auth_level >= 0 && autologin == AUTH_VALID) {
|
|
+ if (name[0] == '-') {
|
|
+ /*
|
|
+ * Authenticated and authorized to log in to an
|
|
+ * account starting with '-'? Even if that
|
|
+ * unlikely case comes to pass, the current login
|
|
+ * program will not parse the resulting command
|
|
+ * line properly.
|
|
+ */
|
|
+ syslog(LOG_ERR, "user name cannot start with '-'");
|
|
+ fatal(net, "user name cannot start with '-'");
|
|
+ exit(1);
|
|
+ }
|
|
# if !defined(NO_LOGIN_F)
|
|
#if defined(LOGIN_CAP_F)
|
|
argv = addarg(argv, "-F");
|
|
#else
|
|
argv = addarg(argv, "-f");
|
|
#endif
|
|
+ argv = addarg(argv, "--");
|
|
argv = addarg(argv, name);
|
|
# else
|
|
# if defined(LOGIN_R)
|
|
@@ -1371,17 +1384,27 @@ start_login(host, autologin, name)
|
|
pty = xpty;
|
|
}
|
|
# else
|
|
+ argv = addarg(argv, "--");
|
|
argv = addarg(argv, name);
|
|
# endif
|
|
# endif
|
|
} else
|
|
#endif
|
|
if (getenv("USER")) {
|
|
- argv = addarg(argv, getenv("USER"));
|
|
+ char *user = getenv("USER");
|
|
+ if (user[0] == '-') {
|
|
+ /* "telnet -l-x ..." */
|
|
+ syslog(LOG_ERR, "user name cannot start with '-'");
|
|
+ fatal(net, "user name cannot start with '-'");
|
|
+ exit(1);
|
|
+ }
|
|
+ argv = addarg(argv, "--");
|
|
+ argv = addarg(argv, user);
|
|
#if defined(LOGIN_ARGS) && defined(NO_LOGIN_P)
|
|
{
|
|
register char **cpp;
|
|
for (cpp = environ; *cpp; cpp++)
|
|
+ if ((*cpp)[0] != '-')
|
|
argv = addarg(argv, *cpp);
|
|
}
|
|
#endif
|
|
Index: src/appl/telnet/telnetd/state.c
|
|
===================================================================
|
|
--- src/appl/telnet/telnetd/state.c.orig
|
|
+++ src/appl/telnet/telnetd/state.c
|
|
@@ -1665,7 +1665,8 @@ static int envvarok(varp)
|
|
strcmp(varp, "RESOLV_HOST_CONF") && /* linux */
|
|
strcmp(varp, "NLSPATH") && /* locale stuff */
|
|
strncmp(varp, "LC_", strlen("LC_")) && /* locale stuff */
|
|
- strcmp(varp, "IFS")) {
|
|
+ strcmp(varp, "IFS") &&
|
|
+ (varp[0] != '-')) {
|
|
return 1;
|
|
} else {
|
|
syslog(LOG_INFO, "Rejected the attempt to modify the environment variable \"%s\"", varp);
|
|
Index: src/kdc/kdc_util.c
|
|
===================================================================
|
|
--- src/kdc/kdc_util.c.orig
|
|
+++ src/kdc/kdc_util.c
|
|
@@ -404,6 +404,7 @@ kdc_get_server_key(krb5_ticket *ticket,
|
|
|
|
krb5_db_free_principal(kdc_context, &server, nprincs);
|
|
if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) {
|
|
+ limit_string(sname);
|
|
krb5_klog_syslog(LOG_ERR,"TGS_REQ: UNKNOWN SERVER: server='%s'",
|
|
sname);
|
|
free(sname);
|
|
Index: src/kdc/do_tgs_req.c
|
|
===================================================================
|
|
--- src/kdc/do_tgs_req.c.orig
|
|
+++ src/kdc/do_tgs_req.c
|
|
@@ -491,28 +491,38 @@ tgt_again:
|
|
newtransited = 1;
|
|
}
|
|
if (!isflagset (request->kdc_options, KDC_OPT_DISABLE_TRANSITED_CHECK)) {
|
|
+ unsigned int tlen;
|
|
+ char *tdots;
|
|
+
|
|
errcode = krb5_check_transited_list (kdc_context,
|
|
&enc_tkt_reply.transited.tr_contents,
|
|
krb5_princ_realm (kdc_context, header_ticket->enc_part2->client),
|
|
krb5_princ_realm (kdc_context, request->server));
|
|
+ tlen = enc_tkt_reply.transited.tr_contents.length;
|
|
+ tdots = tlen > 125 ? "..." : "";
|
|
+ tlen = tlen > 125 ? 125 : tlen;
|
|
+
|
|
if (errcode == 0) {
|
|
setflag (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED);
|
|
} else if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT)
|
|
krb5_klog_syslog (LOG_INFO,
|
|
- "bad realm transit path from '%s' to '%s' via '%.*s'",
|
|
+ "bad realm transit path from '%s' to '%s' "
|
|
+ "via '%.*s%s'",
|
|
cname ? cname : "<unknown client>",
|
|
sname ? sname : "<unknown server>",
|
|
- enc_tkt_reply.transited.tr_contents.length,
|
|
- enc_tkt_reply.transited.tr_contents.data);
|
|
+ tlen,
|
|
+ enc_tkt_reply.transited.tr_contents.data,
|
|
+ tdots);
|
|
else {
|
|
const char *emsg = krb5_get_error_message(kdc_context, errcode);
|
|
krb5_klog_syslog (LOG_ERR,
|
|
- "unexpected error checking transit from '%s' to '%s' via '%.*s': %s",
|
|
+ "unexpected error checking transit from "
|
|
+ "'%s' to '%s' via '%.*s%s': %s",
|
|
cname ? cname : "<unknown client>",
|
|
sname ? sname : "<unknown server>",
|
|
- enc_tkt_reply.transited.tr_contents.length,
|
|
+ tlen,
|
|
enc_tkt_reply.transited.tr_contents.data,
|
|
- emsg);
|
|
+ tdots, emsg);
|
|
krb5_free_error_message(kdc_context, emsg);
|
|
}
|
|
} else
|
|
@@ -542,6 +552,9 @@ tgt_again:
|
|
if (!krb5_principal_compare(kdc_context, request->server, client2)) {
|
|
if ((errcode = krb5_unparse_name(kdc_context, client2, &tmp)))
|
|
tmp = 0;
|
|
+ if (tmp != NULL)
|
|
+ limit_string(tmp);
|
|
+
|
|
krb5_klog_syslog(LOG_INFO,
|
|
"TGS_REQ %s: 2ND_TKT_MISMATCH: "
|
|
"authtime %d, %s for %s, 2nd tkt client %s",
|
|
@@ -816,6 +829,7 @@ find_alternate_tgs(krb5_kdc_req *request
|
|
krb5_klog_syslog(LOG_INFO,
|
|
"TGS_REQ: issuing alternate <un-unparseable> TGT");
|
|
} else {
|
|
+ limit_string(sname);
|
|
krb5_klog_syslog(LOG_INFO,
|
|
"TGS_REQ: issuing TGT %s", sname);
|
|
free(sname);
|
|
Index: src/clients/kpasswd/ksetpwd.c
|
|
===================================================================
|
|
--- src/clients/kpasswd/ksetpwd.c.orig
|
|
+++ src/clients/kpasswd/ksetpwd.c
|
|
@@ -34,8 +34,6 @@ static void get_init_creds_opt_init( krb
|
|
{
|
|
krb5_preauthtype preauth[] = { KRB5_PADATA_ENC_TIMESTAMP };
|
|
krb5_enctype etypes[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC};
|
|
- memset( outOptions, 0, sizeof(*outOptions) );
|
|
- krb5_get_init_creds_opt_init(outOptions);
|
|
krb5_get_init_creds_opt_set_address_list(outOptions, NULL);
|
|
krb5_get_init_creds_opt_set_etype_list( outOptions, etypes, sizeof(etypes)/sizeof(krb5_enctype) );
|
|
krb5_get_init_creds_opt_set_preauth_list(outOptions, preauth, sizeof(preauth)/sizeof(krb5_preauthtype) );
|
|
@@ -128,17 +126,21 @@ static kbrccache_t userinitcontext(
|
|
}
|
|
if( kres != 0 || have_credentials == 0 )
|
|
{
|
|
- krb5_get_init_creds_opt options;
|
|
- get_init_creds_opt_init(&options);
|
|
+ krb5_get_init_creds_opt *options = NULL;
|
|
+ kres = krb5_get_init_creds_opt_alloc(kcontext, &options);
|
|
+ if ( kres == 0 )
|
|
+ {
|
|
+ get_init_creds_opt_init(options);
|
|
/*
|
|
** no valid credentials - get new ones
|
|
*/
|
|
- kres = krb5_get_init_creds_password( kcontext, &kcreds, kme, pPass,
|
|
- NULL /*prompter*/,
|
|
- NULL /*data*/,
|
|
- 0 /*starttime*/,
|
|
- 0 /*in_tkt_service*/,
|
|
- &options /*options*/ );
|
|
+ kres = krb5_get_init_creds_password( kcontext, &kcreds, kme, pPass,
|
|
+ NULL /*prompter*/,
|
|
+ NULL /*data*/,
|
|
+ 0 /*starttime*/,
|
|
+ 0 /*in_tkt_service*/,
|
|
+ options /*options*/ );
|
|
+ }
|
|
if( kres == 0 )
|
|
{
|
|
if( numCreds <= 0 )
|
|
@@ -148,6 +150,7 @@ static kbrccache_t userinitcontext(
|
|
if( kres == 0 )
|
|
have_credentials = 1;
|
|
}
|
|
+ krb5_get_init_creds_opt_free(kcontext, options);
|
|
}
|
|
#ifdef NOTUSED
|
|
if( have_credentials )
|
|
Index: src/clients/kpasswd/kpasswd.c
|
|
===================================================================
|
|
--- src/clients/kpasswd/kpasswd.c.orig
|
|
+++ src/clients/kpasswd/kpasswd.c
|
|
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
|
krb5_principal princ;
|
|
char *pname;
|
|
krb5_ccache ccache;
|
|
- krb5_get_init_creds_opt opts;
|
|
+ krb5_get_init_creds_opt *opts = NULL;
|
|
krb5_creds creds;
|
|
|
|
char pw[1024];
|
|
@@ -102,26 +102,31 @@ int main(int argc, char *argv[])
|
|
get_name_from_passwd_file(argv[0], context, &princ);
|
|
}
|
|
|
|
- krb5_get_init_creds_opt_init(&opts);
|
|
- krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
|
|
- krb5_get_init_creds_opt_set_renew_life(&opts, 0);
|
|
- krb5_get_init_creds_opt_set_forwardable(&opts, 0);
|
|
- krb5_get_init_creds_opt_set_proxiable(&opts, 0);
|
|
+ if ((ret = krb5_get_init_creds_opt_alloc(context, &opts))) {
|
|
+ com_err(argv[0], ret, "allocating krb5_get_init_creds_opt");
|
|
+ exit(1);
|
|
+ }
|
|
+ krb5_get_init_creds_opt_set_tkt_life(opts, 5*60);
|
|
+ krb5_get_init_creds_opt_set_renew_life(opts, 0);
|
|
+ krb5_get_init_creds_opt_set_forwardable(opts, 0);
|
|
+ krb5_get_init_creds_opt_set_proxiable(opts, 0);
|
|
|
|
if ((ret = krb5_get_init_creds_password(context, &creds, princ, NULL,
|
|
krb5_prompter_posix, NULL,
|
|
- 0, "kadmin/changepw", &opts))) {
|
|
+ 0, "kadmin/changepw", opts))) {
|
|
if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
|
|
com_err(argv[0], 0,
|
|
"Password incorrect while getting initial ticket");
|
|
else
|
|
com_err(argv[0], ret, "getting initial ticket");
|
|
+ krb5_get_init_creds_opt_free(context, opts);
|
|
exit(1);
|
|
}
|
|
|
|
pwlen = sizeof(pw);
|
|
if ((ret = krb5_read_password(context, P1, P2, pw, &pwlen))) {
|
|
com_err(argv[0], ret, "while reading password");
|
|
+ krb5_get_init_creds_opt_free(context, opts);
|
|
exit(1);
|
|
}
|
|
|
|
@@ -129,6 +134,7 @@ int main(int argc, char *argv[])
|
|
&result_code, &result_code_string,
|
|
&result_string))) {
|
|
com_err(argv[0], ret, "changing password");
|
|
+ krb5_get_init_creds_opt_free(context, opts);
|
|
exit(1);
|
|
}
|
|
|
|
@@ -138,6 +144,7 @@ int main(int argc, char *argv[])
|
|
result_string.length?": ":"",
|
|
(int) result_string.length,
|
|
result_string.data ? result_string.data : "");
|
|
+ krb5_get_init_creds_opt_free(context, opts);
|
|
exit(2);
|
|
}
|
|
|
|
@@ -145,6 +152,7 @@ int main(int argc, char *argv[])
|
|
free(result_string.data);
|
|
if (result_code_string.data != NULL)
|
|
free(result_code_string.data);
|
|
+ krb5_get_init_creds_opt_free(context, opts);
|
|
|
|
printf("Password changed.\n");
|
|
exit(0);
|
|
Index: src/clients/kvno/kvno.c
|
|
===================================================================
|
|
--- src/clients/kvno/kvno.c.orig
|
|
+++ src/clients/kvno/kvno.c
|
|
@@ -41,10 +41,10 @@ static void xusage()
|
|
{
|
|
#ifdef KRB5_KRB4_COMPAT
|
|
fprintf(stderr,
|
|
- "usage: %s [-4 | [-c ccache] [-e etype]] service1 service2 ...\n",
|
|
+ "usage: %s [-4 | [-c ccache] [-e etype] [-k keytab]] service1 service2 ...\n",
|
|
prog);
|
|
#else
|
|
- fprintf(stderr, "usage: %s [-c ccache] [-e etype] service1 service2 ...\n",
|
|
+ fprintf(stderr, "usage: %s [-c ccache] [-e etype] [-k keytab] service1 service2 ...\n",
|
|
prog);
|
|
#endif
|
|
exit(1);
|
|
@@ -54,7 +54,7 @@ int quiet = 0;
|
|
|
|
static void do_v4_kvno (int argc, char *argv[]);
|
|
static void do_v5_kvno (int argc, char *argv[],
|
|
- char *ccachestr, char *etypestr);
|
|
+ char *ccachestr, char *etypestr, char *keytab_name);
|
|
|
|
#include <com_err.h>
|
|
static void extended_com_err_fn (const char *, errcode_t, const char *,
|
|
@@ -63,7 +63,7 @@ static void extended_com_err_fn (const c
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int option;
|
|
- char *etypestr = 0, *ccachestr = 0;
|
|
+ char *etypestr = NULL, *ccachestr = NULL, *keytab_name = NULL;
|
|
int v4 = 0;
|
|
|
|
set_com_err_hook (extended_com_err_fn);
|
|
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
|
|
prog = strrchr(argv[0], '/');
|
|
prog = prog ? (prog + 1) : argv[0];
|
|
|
|
- while ((option = getopt(argc, argv, "c:e:hq4")) != -1) {
|
|
+ while ((option = getopt(argc, argv, "c:e:hk:q4")) != -1) {
|
|
switch (option) {
|
|
case 'c':
|
|
ccachestr = optarg;
|
|
@@ -82,6 +82,9 @@ int main(int argc, char *argv[])
|
|
case 'h':
|
|
xusage();
|
|
break;
|
|
+ case 'k':
|
|
+ keytab_name = optarg;
|
|
+ break;
|
|
case 'q':
|
|
quiet = 1;
|
|
break;
|
|
@@ -97,13 +100,13 @@ int main(int argc, char *argv[])
|
|
if ((argc - optind) < 1)
|
|
xusage();
|
|
|
|
- if ((ccachestr != 0 || etypestr != 0) && v4)
|
|
+ if ((ccachestr != NULL || etypestr != NULL || keytab_name != NULL) && v4)
|
|
xusage();
|
|
|
|
if (v4)
|
|
do_v4_kvno(argc - optind, argv + optind);
|
|
else
|
|
- do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr);
|
|
+ do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr, keytab_name);
|
|
return 0;
|
|
}
|
|
|
|
@@ -169,7 +172,7 @@ static void extended_com_err_fn (const c
|
|
}
|
|
|
|
static void do_v5_kvno (int count, char *names[],
|
|
- char * ccachestr, char *etypestr)
|
|
+ char * ccachestr, char *etypestr, char *keytab_name)
|
|
{
|
|
krb5_error_code ret;
|
|
int i, errors;
|
|
@@ -179,6 +182,7 @@ static void do_v5_kvno (int count, char
|
|
krb5_creds in_creds, *out_creds;
|
|
krb5_ticket *ticket;
|
|
char *princ;
|
|
+ krb5_keytab keytab = NULL;
|
|
|
|
ret = krb5_init_context(&context);
|
|
if (ret) {
|
|
@@ -205,6 +209,14 @@ static void do_v5_kvno (int count, char
|
|
exit(1);
|
|
}
|
|
|
|
+ if (keytab_name) {
|
|
+ ret = krb5_kt_resolve(context, keytab_name, &keytab);
|
|
+ if (ret) {
|
|
+ com_err(prog, ret, "resolving keytab %s", keytab_name);
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
ret = krb5_cc_get_principal(context, ccache, &me);
|
|
if (ret) {
|
|
com_err(prog, ret, "while getting client principal name");
|
|
@@ -261,14 +273,32 @@ static void do_v5_kvno (int count, char
|
|
continue;
|
|
}
|
|
|
|
- if (!quiet)
|
|
- printf("%s: kvno = %d\n", princ, ticket->enc_part.kvno);
|
|
+ if (keytab) {
|
|
+ ret = krb5_server_decrypt_ticket_keytab(context, keytab, ticket);
|
|
+ if (ret) {
|
|
+ if (!quiet)
|
|
+ printf("%s: kvno = %d, keytab entry invalid", princ, ticket->enc_part.kvno);
|
|
+ com_err(prog, ret, "while decrypting ticket for %s", princ);
|
|
+ krb5_free_ticket(context, ticket);
|
|
+ krb5_free_creds(context, out_creds);
|
|
+ krb5_free_unparsed_name(context, princ);
|
|
+
|
|
+ errors++;
|
|
+ continue;
|
|
+ }
|
|
+ if (!quiet)
|
|
+ printf("%s: kvno = %d, keytab entry valid\n", princ, ticket->enc_part.kvno);
|
|
+ } else {
|
|
+ if (!quiet)
|
|
+ printf("%s: kvno = %d\n", princ, ticket->enc_part.kvno);
|
|
+ }
|
|
|
|
- krb5_free_ticket(context, ticket);
|
|
krb5_free_creds(context, out_creds);
|
|
krb5_free_unparsed_name(context, princ);
|
|
}
|
|
|
|
+ if (keytab)
|
|
+ krb5_kt_close(context, keytab);
|
|
krb5_free_principal(context, me);
|
|
krb5_cc_close(context, ccache);
|
|
krb5_free_context(context);
|
|
Index: src/clients/kinit/kinit.c
|
|
===================================================================
|
|
--- src/clients/kinit/kinit.c.orig
|
|
+++ src/clients/kinit/kinit.c
|
|
@@ -38,6 +38,7 @@
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
+#include <errno.h>
|
|
#include <com_err.h>
|
|
|
|
#ifdef GETOPT_LONG
|
|
@@ -143,6 +144,9 @@ struct k_opts
|
|
char* k4_cache_name;
|
|
|
|
action_type action;
|
|
+
|
|
+ int num_pa_opts;
|
|
+ krb5_gic_opt_pa_data *pa_opts;
|
|
};
|
|
|
|
struct k5_data
|
|
@@ -283,6 +287,37 @@ static void extended_com_err_fn (const c
|
|
fprintf (stderr, "\n");
|
|
}
|
|
|
|
+static int
|
|
+add_preauth_opt(struct k_opts *opts, char *av)
|
|
+{
|
|
+ char *sep, *v;
|
|
+ krb5_gic_opt_pa_data *p, *x;
|
|
+
|
|
+ if (opts->num_pa_opts == 0) {
|
|
+ opts->pa_opts = malloc(sizeof(krb5_gic_opt_pa_data));
|
|
+ if (opts->pa_opts == NULL)
|
|
+ return ENOMEM;
|
|
+ } else {
|
|
+ size_t newsize = (opts->num_pa_opts + 1) * sizeof(krb5_gic_opt_pa_data);
|
|
+ x = realloc(opts->pa_opts, newsize);
|
|
+ if (x == NULL)
|
|
+ return ENOMEM;
|
|
+ opts->pa_opts = x;
|
|
+ }
|
|
+ p = &opts->pa_opts[opts->num_pa_opts];
|
|
+ sep = strchr(av, '=');
|
|
+ if (sep) {
|
|
+ *sep = '\0';
|
|
+ v = ++sep;
|
|
+ p->value = v;
|
|
+ } else {
|
|
+ p->value = "yes";
|
|
+ }
|
|
+ p->attr = av;
|
|
+ opts->num_pa_opts++;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static char *
|
|
parse_options(argc, argv, opts, progname)
|
|
int argc;
|
|
@@ -296,7 +331,7 @@ parse_options(argc, argv, opts, progname
|
|
int use_k5 = 0;
|
|
int i;
|
|
|
|
- while ((i = GETOPT(argc, argv, "r:fpFP54aAVl:s:c:kt:RS:v"))
|
|
+ while ((i = GETOPT(argc, argv, "r:fpFP54aAVl:s:c:kt:RS:vX:"))
|
|
!= -1) {
|
|
switch (i) {
|
|
case 'V':
|
|
@@ -380,6 +415,14 @@ parse_options(argc, argv, opts, progname
|
|
opts->k5_cache_name = optarg;
|
|
}
|
|
break;
|
|
+ case 'X':
|
|
+ code = add_preauth_opt(opts, optarg);
|
|
+ if (code)
|
|
+ {
|
|
+ com_err(progname, code, "while adding preauth option");
|
|
+ errflg++;
|
|
+ }
|
|
+ break;
|
|
#if 0
|
|
/*
|
|
A little more work is needed before we can enable this
|
|
@@ -752,12 +795,15 @@ k5_kinit(opts, k5)
|
|
krb5_keytab keytab = 0;
|
|
krb5_creds my_creds;
|
|
krb5_error_code code = 0;
|
|
- krb5_get_init_creds_opt options;
|
|
+ krb5_get_init_creds_opt *options = NULL;
|
|
+ int i;
|
|
|
|
if (!got_k5)
|
|
return 0;
|
|
|
|
- krb5_get_init_creds_opt_init(&options);
|
|
+ code = krb5_get_init_creds_opt_alloc(k5->ctx, &options);
|
|
+ if (code)
|
|
+ goto cleanup;
|
|
memset(&my_creds, 0, sizeof(my_creds));
|
|
|
|
/*
|
|
@@ -766,17 +812,17 @@ k5_kinit(opts, k5)
|
|
*/
|
|
|
|
if (opts->lifetime)
|
|
- krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime);
|
|
+ krb5_get_init_creds_opt_set_tkt_life(options, opts->lifetime);
|
|
if (opts->rlife)
|
|
- krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife);
|
|
+ krb5_get_init_creds_opt_set_renew_life(options, opts->rlife);
|
|
if (opts->forwardable)
|
|
- krb5_get_init_creds_opt_set_forwardable(&options, 1);
|
|
+ krb5_get_init_creds_opt_set_forwardable(options, 1);
|
|
if (opts->not_forwardable)
|
|
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
|
|
+ krb5_get_init_creds_opt_set_forwardable(options, 0);
|
|
if (opts->proxiable)
|
|
- krb5_get_init_creds_opt_set_proxiable(&options, 1);
|
|
+ krb5_get_init_creds_opt_set_proxiable(options, 1);
|
|
if (opts->not_proxiable)
|
|
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
|
|
+ krb5_get_init_creds_opt_set_proxiable(options, 0);
|
|
if (opts->addresses)
|
|
{
|
|
krb5_address **addresses = NULL;
|
|
@@ -785,10 +831,10 @@ k5_kinit(opts, k5)
|
|
com_err(progname, code, "getting local addresses");
|
|
goto cleanup;
|
|
}
|
|
- krb5_get_init_creds_opt_set_address_list(&options, addresses);
|
|
+ krb5_get_init_creds_opt_set_address_list(options, addresses);
|
|
}
|
|
if (opts->no_addresses)
|
|
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
|
|
+ krb5_get_init_creds_opt_set_address_list(options, NULL);
|
|
|
|
if ((opts->action == INIT_KT) && opts->keytab_name)
|
|
{
|
|
@@ -800,20 +846,31 @@ k5_kinit(opts, k5)
|
|
}
|
|
}
|
|
|
|
+ for (i = 0; i < opts->num_pa_opts; i++) {
|
|
+ code = krb5_get_init_creds_opt_set_pa(k5->ctx, options,
|
|
+ opts->pa_opts[i].attr,
|
|
+ opts->pa_opts[i].value);
|
|
+ if (code != 0) {
|
|
+ com_err(progname, code, "while setting '%s'='%s'",
|
|
+ opts->pa_opts[i].attr, opts->pa_opts[i].value);
|
|
+ goto cleanup;
|
|
+ }
|
|
+ }
|
|
+
|
|
switch (opts->action) {
|
|
case INIT_PW:
|
|
code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
|
|
0, kinit_prompter, 0,
|
|
opts->starttime,
|
|
opts->service_name,
|
|
- &options);
|
|
+ options);
|
|
break;
|
|
case INIT_KT:
|
|
code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
|
|
keytab,
|
|
opts->starttime,
|
|
opts->service_name,
|
|
- &options);
|
|
+ options);
|
|
break;
|
|
case VALIDATE:
|
|
code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc,
|
|
@@ -876,9 +933,16 @@ k5_kinit(opts, k5)
|
|
notix = 0;
|
|
|
|
cleanup:
|
|
+ if (options)
|
|
+ krb5_get_init_creds_opt_free(k5->ctx, options);
|
|
if (my_creds.client == k5->me) {
|
|
my_creds.client = 0;
|
|
}
|
|
+ if (opts->pa_opts) {
|
|
+ free(opts->pa_opts);
|
|
+ opts->pa_opts = NULL;
|
|
+ opts->num_pa_opts = 0;
|
|
+ }
|
|
krb5_free_cred_contents(k5->ctx, &my_creds);
|
|
if (keytab)
|
|
krb5_kt_close(k5->ctx, keytab);
|
|
Index: src/tests/gssapi/t_imp_name.c
|
|
===================================================================
|
|
--- src/tests/gssapi/t_imp_name.c.orig
|
|
+++ src/tests/gssapi/t_imp_name.c
|
|
@@ -88,7 +88,9 @@ static int test_import_name(name)
|
|
display_buffer(buffer_name);
|
|
printf("\n");
|
|
(void) gss_release_buffer(&min_stat, &buffer_name);
|
|
-
|
|
+#ifdef GSSAPI_V2
|
|
+ (void) gss_release_oid(&min_stat, &name_oid);
|
|
+#endif
|
|
(void) gss_release_name(&min_stat, &gss_name);
|
|
return 0;
|
|
}
|
|
Index: src/kadmin/dbutil/kadm5_create.c
|
|
===================================================================
|
|
--- src/kadmin/dbutil/kadm5_create.c.orig
|
|
+++ src/kadmin/dbutil/kadm5_create.c
|
|
@@ -40,6 +40,8 @@
|
|
#include <kadm5/admin.h>
|
|
#include <adm_proto.h>
|
|
|
|
+#include "fake-addrinfo.h"
|
|
+
|
|
|
|
#include <krb5.h>
|
|
#include <kdb.h>
|
|
@@ -172,20 +174,33 @@ static int add_admin_princs(void *handle
|
|
krb5_error_code ret = 0;
|
|
char service_name[MAXHOSTNAMELEN + 8];
|
|
char localname[MAXHOSTNAMELEN];
|
|
- struct hostent *hp;
|
|
+ struct addrinfo *ai, ai_hints;
|
|
+ int gai_error;
|
|
|
|
if (gethostname(localname, MAXHOSTNAMELEN)) {
|
|
ret = errno;
|
|
perror("gethostname");
|
|
goto clean_and_exit;
|
|
}
|
|
- hp = gethostbyname(localname);
|
|
- if (hp == NULL) {
|
|
- ret = errno;
|
|
- perror("gethostbyname");
|
|
+ memset(&ai_hints, 0, sizeof(ai_hints));
|
|
+ ai_hints.ai_flags = AI_CANONNAME;
|
|
+ gai_error = getaddrinfo(localname, (char *)NULL, &ai_hints, &ai);
|
|
+ if (gai_error) {
|
|
+ ret = EINVAL;
|
|
+ fprintf(stderr, "getaddrinfo(%s): %s\n", localname,
|
|
+ gai_strerror(gai_error));
|
|
+ goto clean_and_exit;
|
|
+ }
|
|
+ if (ai->ai_canonname == NULL) {
|
|
+ ret = EINVAL;
|
|
+ fprintf(stderr,
|
|
+ "getaddrinfo(%s): Cannot determine canonical hostname.\n",
|
|
+ localname);
|
|
+ freeaddrinfo(ai);
|
|
goto clean_and_exit;
|
|
}
|
|
- sprintf(service_name, "kadmin/%s", hp->h_name);
|
|
+ sprintf(service_name, "kadmin/%s", ai->ai_canonname);
|
|
+ freeaddrinfo(ai);
|
|
|
|
if ((ret = add_admin_princ(handle, context,
|
|
service_name, realm,
|
|
Index: src/kadmin/server/ovsec_kadmd.c
|
|
===================================================================
|
|
--- src/kadmin/server/ovsec_kadmd.c.orig
|
|
+++ src/kadmin/server/ovsec_kadmd.c
|
|
@@ -992,6 +992,8 @@ void log_badverf(gss_name_t client_name,
|
|
rpcproc_t proc;
|
|
int i;
|
|
const char *procname;
|
|
+ size_t clen, slen;
|
|
+ char *cdots, *sdots;
|
|
|
|
client.length = 0;
|
|
client.value = NULL;
|
|
@@ -1000,10 +1002,20 @@ void log_badverf(gss_name_t client_name,
|
|
|
|
(void) gss_display_name(&minor, client_name, &client, &gss_type);
|
|
(void) gss_display_name(&minor, server_name, &server, &gss_type);
|
|
- if (client.value == NULL)
|
|
+ if (client.value == NULL) {
|
|
client.value = "(null)";
|
|
- if (server.value == NULL)
|
|
+ clen = sizeof("(null)") -1;
|
|
+ } else {
|
|
+ clen = client.length;
|
|
+ }
|
|
+ trunc_name(&clen, &cdots);
|
|
+ if (server.value == NULL) {
|
|
server.value = "(null)";
|
|
+ slen = sizeof("(null)") - 1;
|
|
+ } else {
|
|
+ slen = server.length;
|
|
+ }
|
|
+ trunc_name(&slen, &sdots);
|
|
a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
|
|
|
|
proc = msg->rm_call.cb_proc;
|
|
@@ -1016,14 +1028,14 @@ void log_badverf(gss_name_t client_name,
|
|
}
|
|
if (procname != NULL)
|
|
krb5_klog_syslog(LOG_NOTICE, "WARNING! Forged/garbled request: %s, "
|
|
- "claimed client = %s, server = %s, addr = %s",
|
|
- procname, client.value,
|
|
- server.value, a);
|
|
+ "claimed client = %.*s%s, server = %.*s%s, addr = %s",
|
|
+ procname, clen, client.value, cdots,
|
|
+ slen, server.value, sdots, a);
|
|
else
|
|
krb5_klog_syslog(LOG_NOTICE, "WARNING! Forged/garbled request: %d, "
|
|
- "claimed client = %s, server = %s, addr = %s",
|
|
- proc, client.value,
|
|
- server.value, a);
|
|
+ "claimed client = %.*s%s, server = %.*s%s, addr = %s",
|
|
+ proc, clen, client.value, cdots,
|
|
+ slen, server.value, sdots, a);
|
|
|
|
(void) gss_release_buffer(&minor, &client);
|
|
(void) gss_release_buffer(&minor, &server);
|
|
Index: src/kadmin/server/misc.h
|
|
===================================================================
|
|
--- src/kadmin/server/misc.h.orig
|
|
+++ src/kadmin/server/misc.h
|
|
@@ -45,3 +45,5 @@ krb5_error_code process_chpw_request(krb
|
|
#ifdef SVC_GETARGS
|
|
void kadm_1(struct svc_req *, SVCXPRT *);
|
|
#endif
|
|
+
|
|
+void trunc_name(size_t *len, char **dots);
|
|
Index: src/kadmin/server/schpw.c
|
|
===================================================================
|
|
--- src/kadmin/server/schpw.c.orig
|
|
+++ src/kadmin/server/schpw.c
|
|
@@ -40,6 +40,8 @@ process_chpw_request(context, server_han
|
|
int numresult;
|
|
char strresult[1024];
|
|
char *clientstr;
|
|
+ size_t clen;
|
|
+ char *cdots;
|
|
|
|
ret = 0;
|
|
rep->length = 0;
|
|
@@ -258,9 +260,12 @@ process_chpw_request(context, server_han
|
|
free(ptr);
|
|
clear.length = 0;
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, "chpw request from %s for %s: %s",
|
|
+ clen = strlen(clientstr);
|
|
+ trunc_name(&clen, &cdots);
|
|
+ krb5_klog_syslog(LOG_NOTICE, "chpw request from %s for %.*s%s: %s",
|
|
inet_ntoa(((struct sockaddr_in *)&remote_addr)->sin_addr),
|
|
- clientstr, ret ? krb5_get_error_message (context, ret) : "success");
|
|
+ clen, clientstr, cdots,
|
|
+ ret ? krb5_get_error_message (context, ret) : "success");
|
|
krb5_free_unparsed_name(context, clientstr);
|
|
|
|
if (ret) {
|
|
Index: src/kadmin/server/server_stubs.c
|
|
===================================================================
|
|
--- src/kadmin/server/server_stubs.c.orig
|
|
+++ src/kadmin/server/server_stubs.c
|
|
@@ -14,6 +14,7 @@
|
|
#include <arpa/inet.h> /* inet_ntoa */
|
|
#include <adm_proto.h> /* krb5_klog_syslog */
|
|
#include "misc.h"
|
|
+#include <string.h>
|
|
|
|
#define LOG_UNAUTH "Unauthorized request: %s, %s, client=%s, service=%s, addr=%s"
|
|
#define LOG_DONE "Request: %s, %s, %s, client=%s, service=%s, addr=%s"
|
|
@@ -237,6 +238,61 @@ gss_name_to_string(gss_name_t gss_name,
|
|
return 0;
|
|
}
|
|
|
|
+static int
|
|
+log_unauth(
|
|
+ char *op,
|
|
+ char *target,
|
|
+ gss_buffer_t client,
|
|
+ gss_buffer_t server,
|
|
+ struct svc_req *rqstp)
|
|
+{
|
|
+ size_t tlen, clen, slen;
|
|
+ char *tdots, *cdots, *sdots;
|
|
+
|
|
+ tlen = strlen(target);
|
|
+ trunc_name(&tlen, &tdots);
|
|
+ clen = client->length;
|
|
+ trunc_name(&clen, &cdots);
|
|
+ slen = server->length;
|
|
+ trunc_name(&slen, &sdots);
|
|
+
|
|
+ return krb5_klog_syslog(LOG_NOTICE,
|
|
+ "Unauthorized request: %s, %.*s%s, "
|
|
+ "client=%.*s%s, service=%.*s%s, addr=%s",
|
|
+ op, tlen, target, tdots,
|
|
+ clen, client->value, cdots,
|
|
+ slen, server->value, sdots,
|
|
+ inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+}
|
|
+
|
|
+static int
|
|
+log_done(
|
|
+ char *op,
|
|
+ char *target,
|
|
+ char *errmsg,
|
|
+ gss_buffer_t client,
|
|
+ gss_buffer_t server,
|
|
+ struct svc_req *rqstp)
|
|
+{
|
|
+ size_t tlen, clen, slen;
|
|
+ char *tdots, *cdots, *sdots;
|
|
+
|
|
+ tlen = strlen(target);
|
|
+ trunc_name(&tlen, &tdots);
|
|
+ clen = client->length;
|
|
+ trunc_name(&clen, &cdots);
|
|
+ slen = server->length;
|
|
+ trunc_name(&slen, &sdots);
|
|
+
|
|
+ return krb5_klog_syslog(LOG_NOTICE,
|
|
+ "Request: %s, %.*s%s, %s, "
|
|
+ "client=%.*s%s, service=%.*s%s, addr=%s",
|
|
+ op, tlen, target, tdots, errmsg,
|
|
+ clen, client->value, cdots,
|
|
+ slen, server->value, sdots,
|
|
+ inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+}
|
|
+
|
|
generic_ret *
|
|
create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
|
|
{
|
|
@@ -275,9 +331,8 @@ create_principal_2_svc(cprinc_arg *arg,
|
|
|| kadm5int_acl_impose_restrictions(handle->context,
|
|
&arg->rec, &arg->mask, rp)) {
|
|
ret.code = KADM5_AUTH_ADD;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_create_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_create_principal((void *)handle,
|
|
&arg->rec, arg->mask,
|
|
@@ -287,10 +342,8 @@ create_principal_2_svc(cprinc_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_create_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
/* no need to check for NULL. Even if it is NULL, atleast error_code will be returned */
|
|
}
|
|
@@ -341,9 +394,8 @@ create_principal3_2_svc(cprinc3_arg *arg
|
|
|| kadm5int_acl_impose_restrictions(handle->context,
|
|
&arg->rec, &arg->mask, rp)) {
|
|
ret.code = KADM5_AUTH_ADD;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_create_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_create_principal_3((void *)handle,
|
|
&arg->rec, arg->mask,
|
|
@@ -355,10 +407,8 @@ create_principal3_2_svc(cprinc3_arg *arg
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_create_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
/* no need to check for NULL. Even if it is NULL, atleast error_code will be returned */
|
|
}
|
|
@@ -406,9 +456,8 @@ delete_principal_2_svc(dprinc_arg *arg,
|
|
|| !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_DELETE,
|
|
arg->princ, NULL)) {
|
|
ret.code = KADM5_AUTH_DELETE;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_delete_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_delete_principal((void *)handle, arg->princ);
|
|
if( ret.code == 0 )
|
|
@@ -416,10 +465,8 @@ delete_principal_2_svc(dprinc_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_delete_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
/* no need to check for NULL. Even if it is NULL, atleast error_code will be returned */
|
|
}
|
|
@@ -469,9 +516,8 @@ modify_principal_2_svc(mprinc_arg *arg,
|
|
|| kadm5int_acl_impose_restrictions(handle->context,
|
|
&arg->rec, &arg->mask, rp)) {
|
|
ret.code = KADM5_AUTH_MODIFY;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_modify_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_modify_principal((void *)handle, &arg->rec,
|
|
arg->mask);
|
|
@@ -480,10 +526,8 @@ modify_principal_2_svc(mprinc_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_modify_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
/* no need to check for NULL. Even if it is NULL, atleast error_code will be returned */
|
|
}
|
|
@@ -546,9 +590,8 @@ rename_principal_2_svc(rprinc_arg *arg,
|
|
} else
|
|
ret.code = KADM5_AUTH_INSUFFICIENT;
|
|
if (ret.code != KADM5_OK) {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_rename_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_rename_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_rename_principal((void *)handle, arg->src,
|
|
arg->dest);
|
|
@@ -557,10 +600,8 @@ rename_principal_2_svc(rprinc_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_rename_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_rename_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
free(prime_arg1);
|
|
@@ -614,9 +655,8 @@ get_principal_2_svc(gprinc_arg *arg, str
|
|
arg->princ,
|
|
NULL))) {
|
|
ret.code = KADM5_AUTH_GET;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth(funcname, prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
if (handle->api_version == KADM5_API_VERSION_1) {
|
|
ret.code = kadm5_get_principal_v1((void *)handle,
|
|
@@ -636,11 +676,8 @@ get_principal_2_svc(gprinc_arg *arg, str
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
|
|
- prime_arg,
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done(funcname, prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
}
|
|
free_server_handle(handle);
|
|
@@ -688,9 +725,8 @@ get_princs_2_svc(gprincs_arg *arg, struc
|
|
NULL,
|
|
NULL)) {
|
|
ret.code = KADM5_AUTH_LIST;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_principals",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_get_principals", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_get_principals((void *)handle,
|
|
arg->exp, &ret.princs,
|
|
@@ -700,11 +736,8 @@ get_princs_2_svc(gprincs_arg *arg, struc
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_principals",
|
|
- prime_arg,
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_get_principals", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
}
|
|
free_server_handle(handle);
|
|
@@ -755,9 +788,8 @@ chpass_principal_2_svc(chpass_arg *arg,
|
|
ret.code = kadm5_chpass_principal((void *)handle, arg->princ,
|
|
arg->pass);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_chpass_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_CHANGEPW;
|
|
}
|
|
|
|
@@ -767,10 +799,8 @@ chpass_principal_2_svc(chpass_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_chpass_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
|
|
free_server_handle(handle);
|
|
@@ -828,9 +858,8 @@ chpass_principal3_2_svc(chpass3_arg *arg
|
|
arg->ks_tuple,
|
|
arg->pass);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_chpass_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_CHANGEPW;
|
|
}
|
|
|
|
@@ -840,10 +869,8 @@ chpass_principal3_2_svc(chpass3_arg *arg
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_chpass_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
|
|
free_server_handle(handle);
|
|
@@ -892,9 +919,8 @@ setv4key_principal_2_svc(setv4key_arg *a
|
|
ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
|
|
arg->keyblock);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setv4key_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_setv4key_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_SETKEY;
|
|
}
|
|
|
|
@@ -904,10 +930,8 @@ setv4key_principal_2_svc(setv4key_arg *a
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setv4key_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_setv4key_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
|
|
free_server_handle(handle);
|
|
@@ -956,9 +980,8 @@ setkey_principal_2_svc(setkey_arg *arg,
|
|
ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
|
|
arg->keyblocks, arg->n_keys);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_setkey_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_SETKEY;
|
|
}
|
|
|
|
@@ -968,10 +991,8 @@ setkey_principal_2_svc(setkey_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_setkey_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
|
|
free_server_handle(handle);
|
|
@@ -1023,9 +1044,8 @@ setkey_principal3_2_svc(setkey3_arg *arg
|
|
arg->ks_tuple,
|
|
arg->keyblocks, arg->n_keys);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_setkey_principal", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_SETKEY;
|
|
}
|
|
|
|
@@ -1035,10 +1055,8 @@ setkey_principal3_2_svc(setkey3_arg *arg
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal",
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_setkey_principal", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
|
|
free_server_handle(handle);
|
|
@@ -1097,9 +1115,8 @@ chrand_principal_2_svc(chrand_arg *arg,
|
|
ret.code = kadm5_randkey_principal((void *)handle, arg->princ,
|
|
&k, &nkeys);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth(funcname, prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_CHANGEPW;
|
|
}
|
|
|
|
@@ -1119,10 +1136,8 @@ chrand_principal_2_svc(chrand_arg *arg,
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done(funcname, prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
free(prime_arg);
|
|
@@ -1185,9 +1200,8 @@ chrand_principal3_2_svc(chrand3_arg *arg
|
|
arg->ks_tuple,
|
|
&k, &nkeys);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth(funcname, prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_CHANGEPW;
|
|
}
|
|
|
|
@@ -1207,10 +1221,8 @@ chrand_principal3_2_svc(chrand3_arg *arg
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
|
|
- prime_arg, errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done(funcname, prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
free(prime_arg);
|
|
@@ -1253,10 +1265,9 @@ create_policy_2_svc(cpol_arg *arg, struc
|
|
rqst2name(rqstp),
|
|
ACL_ADD, NULL, NULL)) {
|
|
ret.code = KADM5_AUTH_ADD;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_policy",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
-
|
|
+ log_unauth("kadm5_create_policy", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
+
|
|
} else {
|
|
ret.code = kadm5_create_policy((void *)handle, &arg->rec,
|
|
arg->mask);
|
|
@@ -1265,11 +1276,9 @@ create_policy_2_svc(cpol_arg *arg, struc
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_policy",
|
|
- ((prime_arg == NULL) ? "(null)" : prime_arg),
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_create_policy",
|
|
+ ((prime_arg == NULL) ? "(null)" : prime_arg), errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
@@ -1310,9 +1319,8 @@ delete_policy_2_svc(dpol_arg *arg, struc
|
|
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
|
|
rqst2name(rqstp),
|
|
ACL_DELETE, NULL, NULL)) {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_policy",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_delete_policy", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_DELETE;
|
|
} else {
|
|
ret.code = kadm5_delete_policy((void *)handle, arg->name);
|
|
@@ -1321,11 +1329,9 @@ delete_policy_2_svc(dpol_arg *arg, struc
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_policy",
|
|
- ((prime_arg == NULL) ? "(null)" : prime_arg),
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_delete_policy",
|
|
+ ((prime_arg == NULL) ? "(null)" : prime_arg), errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
@@ -1366,9 +1372,8 @@ modify_policy_2_svc(mpol_arg *arg, struc
|
|
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
|
|
rqst2name(rqstp),
|
|
ACL_MODIFY, NULL, NULL)) {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_policy",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_modify_policy", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
ret.code = KADM5_AUTH_MODIFY;
|
|
} else {
|
|
ret.code = kadm5_modify_policy((void *)handle, &arg->rec,
|
|
@@ -1378,11 +1383,9 @@ modify_policy_2_svc(mpol_arg *arg, struc
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_policy",
|
|
- ((prime_arg == NULL) ? "(null)" : prime_arg),
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_modify_policy",
|
|
+ ((prime_arg == NULL) ? "(null)" : prime_arg), errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
@@ -1464,15 +1467,12 @@ get_policy_2_svc(gpol_arg *arg, struct s
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname,
|
|
- ((prime_arg == NULL) ? "(null)" : prime_arg),
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done(funcname,
|
|
+ ((prime_arg == NULL) ? "(null)" : prime_arg), errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname,
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth(funcname, prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
@@ -1517,9 +1517,8 @@ get_pols_2_svc(gpols_arg *arg, struct sv
|
|
rqst2name(rqstp),
|
|
ACL_LIST, NULL, NULL)) {
|
|
ret.code = KADM5_AUTH_LIST;
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_policies",
|
|
- prime_arg, client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_unauth("kadm5_get_policies", prime_arg,
|
|
+ &client_name, &service_name, rqstp);
|
|
} else {
|
|
ret.code = kadm5_get_policies((void *)handle,
|
|
arg->exp, &ret.pols,
|
|
@@ -1529,11 +1528,8 @@ get_pols_2_svc(gpols_arg *arg, struct sv
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_policies",
|
|
- prime_arg,
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_get_policies", prime_arg, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
}
|
|
free_server_handle(handle);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
@@ -1573,11 +1569,8 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4
|
|
else
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_privs",
|
|
- client_name.value,
|
|
- errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
|
|
+ log_done("kadm5_get_privs", client_name.value, errmsg,
|
|
+ &client_name, &service_name, rqstp);
|
|
|
|
free_server_handle(handle);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
@@ -1594,6 +1587,8 @@ generic_ret *init_2_svc(krb5_ui_4 *arg,
|
|
kadm5_server_handle_t handle;
|
|
OM_uint32 minor_stat;
|
|
char *errmsg = 0;
|
|
+ size_t clen, slen;
|
|
+ char *cdots, *sdots;
|
|
|
|
xdr_free(xdr_generic_ret, &ret);
|
|
|
|
@@ -1612,14 +1607,22 @@ generic_ret *init_2_svc(krb5_ui_4 *arg,
|
|
|
|
if (ret.code != 0)
|
|
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
|
|
- krb5_klog_syslog(LOG_NOTICE, LOG_DONE ", flavor=%d",
|
|
- (ret.api_version == KADM5_API_VERSION_1 ?
|
|
- "kadm5_init (V1)" : "kadm5_init"),
|
|
- client_name.value,
|
|
- (ret.code == 0) ? "success" : errmsg,
|
|
- client_name.value, service_name.value,
|
|
- inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
|
|
- rqstp->rq_cred.oa_flavor);
|
|
+ else
|
|
+ errmsg = "success";
|
|
+
|
|
+ clen = client_name.length;
|
|
+ trunc_name(&clen, &cdots);
|
|
+ slen = service_name.length;
|
|
+ trunc_name(&slen, &sdots);
|
|
+ krb5_klog_syslog(LOG_NOTICE, "Request: %s, %.*s%s, %s, "
|
|
+ "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d",
|
|
+ (ret.api_version == KADM5_API_VERSION_1 ?
|
|
+ "kadm5_init (V1)" : "kadm5_init"),
|
|
+ clen, client_name.value, cdots, errmsg,
|
|
+ clen, client_name.value, cdots,
|
|
+ slen, service_name.value, sdots,
|
|
+ inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
|
|
+ rqstp->rq_cred.oa_flavor);
|
|
gss_release_buffer(&minor_stat, &client_name);
|
|
gss_release_buffer(&minor_stat, &service_name);
|
|
|
|
Index: src/kadmin/server/kadm_rpc_svc.c
|
|
===================================================================
|
|
--- src/kadmin/server/kadm_rpc_svc.c.orig
|
|
+++ src/kadmin/server/kadm_rpc_svc.c
|
|
@@ -250,6 +250,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
|
|
krb5_data *c1, *c2, *realm;
|
|
gss_buffer_desc gss_str;
|
|
kadm5_server_handle_t handle;
|
|
+ size_t slen;
|
|
+ char *sdots;
|
|
|
|
success = 0;
|
|
handle = (kadm5_server_handle_t)global_server_handle;
|
|
@@ -274,6 +276,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
|
|
if (ret == 0)
|
|
goto fail_name;
|
|
|
|
+ slen = gss_str.length;
|
|
+ trunc_name(&slen, &sdots);
|
|
/*
|
|
* Since we accept with GSS_C_NO_NAME, the client can authenticate
|
|
* against the entire kdb. Therefore, ensure that the service
|
|
@@ -296,8 +300,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
|
|
|
|
fail_princ:
|
|
if (!success) {
|
|
- krb5_klog_syslog(LOG_ERR, "bad service principal %.*s",
|
|
- gss_str.length, gss_str.value);
|
|
+ krb5_klog_syslog(LOG_ERR, "bad service principal %.*s%s",
|
|
+ slen, gss_str.value, sdots);
|
|
}
|
|
gss_release_buffer(&min_stat, &gss_str);
|
|
krb5_free_principal(kctx, princ);
|
|
Index: src/kadmin/server/misc.c
|
|
===================================================================
|
|
--- src/kadmin/server/misc.c.orig
|
|
+++ src/kadmin/server/misc.c
|
|
@@ -171,3 +171,12 @@ check_min_life(void *server_handle, krb5
|
|
|
|
return kadm5_free_principal_ent(handle->lhandle, &princ);
|
|
}
|
|
+
|
|
+#define MAXPRINCLEN 125
|
|
+
|
|
+void
|
|
+trunc_name(size_t *len, char **dots)
|
|
+{
|
|
+ *dots = *len > MAXPRINCLEN ? "..." : "";
|
|
+ *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
|
|
+}
|
|
Index: src/kadmin/cli/k5srvutil.sh
|
|
===================================================================
|
|
--- src/kadmin/cli/k5srvutil.sh.orig
|
|
+++ src/kadmin/cli/k5srvutil.sh
|
|
@@ -4,7 +4,7 @@
|
|
# returns a list of principals in the keytab
|
|
# sorted and uniquified
|
|
list_princs() {
|
|
- klist -k $keytab | tail +4 | awk '{print $2}' | sort | uniq
|
|
+ klist -k $keytab | awk '(NR > 3) {print $2}' | sort | uniq
|
|
}
|
|
|
|
set_command() {
|
|
Index: src/config-files/kdc.conf.M
|
|
===================================================================
|
|
--- src/config-files/kdc.conf.M.orig
|
|
+++ src/config-files/kdc.conf.M
|
|
@@ -57,9 +57,13 @@ port 88 and port 750.
|
|
.IP v4_mode
|
|
This
|
|
.B string
|
|
-specifies how the KDC should respond to Kerberos IV packets. If this
|
|
-relation is not specified, the compiled-in default of
|
|
-.I nopreauth
|
|
+specifies how the KDC should respond to Kerberos IV packets. Valid
|
|
+values for this relation are the same as the valid arguments to the
|
|
+.B -4
|
|
+flag to
|
|
+.BR krb5kdc .
|
|
+If this relation is not specified, the compiled-in default of
|
|
+.I none
|
|
is used.
|
|
|
|
.SH REALMS SECTION
|
|
Index: src/config/shlib.conf
|
|
===================================================================
|
|
--- src/config/shlib.conf.orig
|
|
+++ src/config/shlib.conf
|
|
@@ -58,7 +58,7 @@ alpha*-dec-osf*)
|
|
# Alpha OSF/1 doesn't need separate PIC objects
|
|
SHOBJEXT=.o
|
|
INIT_FINI_PREP=initfini=
|
|
- LDCOMBINE='$(CC) $(PTHREAD_CFLAGS) -shared -Wl,-expect_unresolved -Wl,\* -Wl,-update_registry -Wl,$(BUILDTOP)/so_locations -Wl,-soname -Wl,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -Wl,-hidden -Wl,-input,osf1.exports $$initfini'
|
|
+ LDCOMBINE='$(CC) $(CFLAGS) $(PTHREAD_CFLAGS) -shared -Wl,-expect_unresolved -Wl,\* -Wl,-update_registry -Wl,$(BUILDTOP)/so_locations -Wl,-soname -Wl,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -Wl,-hidden -Wl,-input,osf1.exports $$initfini'
|
|
SHLIB_EXPORT_FILE_DEP=osf1.exports
|
|
use_linker_init_option=yes
|
|
use_linker_fini_option=yes
|
|
Index: src/lib/gssapi/krb5/k5sealv3.c
|
|
===================================================================
|
|
--- src/lib/gssapi/krb5/k5sealv3.c.orig
|
|
+++ src/lib/gssapi/krb5/k5sealv3.c
|
|
@@ -412,10 +412,16 @@ gss_krb5int_unseal_token_v3(krb5_context
|
|
if (load_16_be(althdr) != 0x0504
|
|
|| althdr[2] != ptr[2]
|
|
|| althdr[3] != ptr[3]
|
|
- || memcmp(althdr+8, ptr+8, 8))
|
|
+ || memcmp(althdr+8, ptr+8, 8)) {
|
|
+ free(plain.data);
|
|
goto defective;
|
|
+ }
|
|
message_buffer->value = plain.data;
|
|
message_buffer->length = plain.length - ec - 16;
|
|
+ if(message_buffer->length == 0) {
|
|
+ free(message_buffer->value);
|
|
+ message_buffer->value = NULL;
|
|
+ }
|
|
} else {
|
|
/* no confidentiality */
|
|
if (conf_state)
|
|
Index: src/lib/gssapi/krb5/k5unseal.c
|
|
===================================================================
|
|
--- src/lib/gssapi/krb5/k5unseal.c.orig
|
|
+++ src/lib/gssapi/krb5/k5unseal.c
|
|
@@ -457,8 +457,11 @@ kg_unseal_v1(context, minor_status, ctx,
|
|
|
|
if ((ctx->initiate && direction != 0xff) ||
|
|
(!ctx->initiate && direction != 0)) {
|
|
- if (toktype == KG_TOK_SEAL_MSG)
|
|
+ if (toktype == KG_TOK_SEAL_MSG) {
|
|
xfree(token.value);
|
|
+ message_buffer->value = NULL;
|
|
+ message_buffer->length = 0;
|
|
+ }
|
|
*minor_status = G_BAD_DIRECTION;
|
|
return(GSS_S_BAD_SIG);
|
|
}
|
|
Index: src/lib/gssapi/mechglue/g_canon_name.c
|
|
===================================================================
|
|
--- src/lib/gssapi/mechglue/g_canon_name.c.orig
|
|
+++ src/lib/gssapi/mechglue/g_canon_name.c
|
|
@@ -96,6 +96,7 @@ gss_name_t *output_name;
|
|
out_union->mech_name = 0;
|
|
out_union->name_type = 0;
|
|
out_union->external_name = 0;
|
|
+ out_union->loopback = out_union;
|
|
|
|
/* Allocate the buffer for the user specified representation */
|
|
if (gssint_create_copy_buffer(in_union->external_name,
|
|
Index: src/lib/gssapi/mechglue/g_imp_name.c
|
|
===================================================================
|
|
--- src/lib/gssapi/mechglue/g_imp_name.c.orig
|
|
+++ src/lib/gssapi/mechglue/g_imp_name.c
|
|
@@ -65,7 +65,10 @@ val_imp_name_args(
|
|
if (input_name_buffer == GSS_C_NO_BUFFER)
|
|
return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
|
|
|
|
- if (GSS_EMPTY_BUFFER(input_name_buffer))
|
|
+ if (input_name_buffer->length == 0)
|
|
+ return GSS_S_BAD_NAME;
|
|
+
|
|
+ if (input_name_buffer->value == NULL)
|
|
return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
|
|
|
|
return (GSS_S_COMPLETE);
|
|
Index: src/lib/gssapi/generic/util_ordering.c
|
|
===================================================================
|
|
--- src/lib/gssapi/generic/util_ordering.c.orig
|
|
+++ src/lib/gssapi/generic/util_ordering.c
|
|
@@ -96,6 +96,12 @@ g_order_init(void **vqueue, gssint_uint6
|
|
if ((q = (queue *) malloc(sizeof(queue))) == NULL)
|
|
return(ENOMEM);
|
|
|
|
+ /* This stops valgrind from complaining about writing uninitialized
|
|
+ data if the caller exports the context and writes it to a file.
|
|
+ We don't actually use those bytes at all, but valgrind still
|
|
+ complains. */
|
|
+ memset(q, 0xfe, sizeof(*q));
|
|
+
|
|
q->do_replay = do_replay;
|
|
q->do_sequence = do_sequence;
|
|
q->mask = wide_nums ? ~(gssint_uint64)0 : 0xffffffffUL;
|
|
Index: src/lib/kadm5/logger.c
|
|
===================================================================
|
|
--- src/lib/kadm5/logger.c.orig
|
|
+++ src/lib/kadm5/logger.c
|
|
@@ -45,7 +45,7 @@
|
|
#include <varargs.h>
|
|
#endif /* HAVE_STDARG_H */
|
|
|
|
-#define KRB5_KLOG_MAX_ERRMSG_SIZE 1024
|
|
+#define KRB5_KLOG_MAX_ERRMSG_SIZE 2048
|
|
#ifndef MAXHOSTNAMELEN
|
|
#define MAXHOSTNAMELEN 256
|
|
#endif /* MAXHOSTNAMELEN */
|
|
@@ -261,7 +261,9 @@ klog_com_err_proc(const char *whoami, lo
|
|
#endif /* HAVE_SYSLOG */
|
|
|
|
/* Now format the actual message */
|
|
-#if HAVE_VSPRINTF
|
|
+#if HAVE_VSNPRINTF
|
|
+ vsnprintf(cp, sizeof(outbuf) - (cp - outbuf), actual_format, ap);
|
|
+#elif HAVE_VSPRINTF
|
|
vsprintf(cp, actual_format, ap);
|
|
#else /* HAVE_VSPRINTF */
|
|
sprintf(cp, actual_format, ((int *) ap)[0], ((int *) ap)[1],
|
|
@@ -850,7 +852,9 @@ klog_vsyslog(int priority, const char *f
|
|
syslogp = &outbuf[strlen(outbuf)];
|
|
|
|
/* Now format the actual message */
|
|
-#ifdef HAVE_VSPRINTF
|
|
+#ifdef HAVE_VSNPRINTF
|
|
+ vsnprintf(syslogp, sizeof(outbuf) - (syslogp - outbuf), format, arglist);
|
|
+#elif HAVE_VSPRINTF
|
|
vsprintf(syslogp, format, arglist);
|
|
#else /* HAVE_VSPRINTF */
|
|
sprintf(syslogp, format, ((int *) arglist)[0], ((int *) arglist)[1],
|
|
Index: src/lib/krb5/keytab/kt_file.c
|
|
===================================================================
|
|
--- src/lib/krb5/keytab/kt_file.c.orig
|
|
+++ src/lib/krb5/keytab/kt_file.c
|
|
@@ -193,6 +193,7 @@ krb5_ktfile_resolve(krb5_context context
|
|
|
|
err = k5_mutex_init(&data->lock);
|
|
if (err) {
|
|
+ krb5_xfree(data);
|
|
krb5_xfree(*id);
|
|
return err;
|
|
}
|
|
@@ -791,6 +792,7 @@ krb5_ktfile_wresolve(krb5_context contex
|
|
|
|
err = k5_mutex_init(&data->lock);
|
|
if (err) {
|
|
+ krb5_xfree(data);
|
|
krb5_xfree(*id);
|
|
return err;
|
|
}
|
|
Index: src/lib/krb5/os/ccdefname.c
|
|
===================================================================
|
|
--- src/lib/krb5/os/ccdefname.c.orig
|
|
+++ src/lib/krb5/os/ccdefname.c
|
|
@@ -148,6 +148,15 @@ static krb5_error_code get_from_os(char
|
|
char *prefix = krb5_cc_dfl_ops->prefix;
|
|
int size;
|
|
char *p;
|
|
+ DWORD gle;
|
|
+
|
|
+ SetLastError(0);
|
|
+ GetEnvironmentVariable(KRB5_ENV_CCNAME, name_buf, name_size);
|
|
+ gle = GetLastError();
|
|
+ if (gle == 0)
|
|
+ return 0;
|
|
+ else if (gle != ERROR_ENVVAR_NOT_FOUND)
|
|
+ return ENOMEM;
|
|
|
|
if (get_from_registry(HKEY_CURRENT_USER,
|
|
name_buf, name_size) != 0)
|
|
Index: src/lib/krb5/os/locate_kdc.c
|
|
===================================================================
|
|
--- src/lib/krb5/os/locate_kdc.c.orig
|
|
+++ src/lib/krb5/os/locate_kdc.c
|
|
@@ -157,13 +157,18 @@ static int translate_ai_error (int err)
|
|
#ifdef EAI_ADDRFAMILY
|
|
case EAI_ADDRFAMILY:
|
|
#endif
|
|
-#if EAI_NODATA != EAI_NONAME
|
|
+#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
|
|
case EAI_NODATA:
|
|
#endif
|
|
case EAI_NONAME:
|
|
/* Name not known or no address data, but no error. Do
|
|
nothing more. */
|
|
return 0;
|
|
+#ifdef EAI_OVERFLOW
|
|
+ case EAI_OVERFLOW:
|
|
+ /* An argument buffer overflowed. */
|
|
+ return EINVAL; /* XXX */
|
|
+#endif
|
|
#ifdef EAI_SYSTEM
|
|
case EAI_SYSTEM:
|
|
/* System error, obviously. */
|
|
@@ -778,28 +783,28 @@ krb5int_locate_server (krb5_context cont
|
|
|
|
code = module_locate_server(context, realm, &al, svc, socktype, family);
|
|
Tprintf("module_locate_server returns %d\n", code);
|
|
- if (code != KRB5_PLUGIN_NO_HANDLE) {
|
|
- *addrlist = al;
|
|
- return code;
|
|
- }
|
|
-
|
|
- /*
|
|
- * We always try the local file before DNS
|
|
- */
|
|
-
|
|
- code = prof_locate_server(context, realm, &al, svc, socktype, family);
|
|
+ if (code == KRB5_PLUGIN_NO_HANDLE) {
|
|
+ /*
|
|
+ * We always try the local file before DNS. Note that there
|
|
+ * is no way to indicate "service not available" via the
|
|
+ * config file.
|
|
+ */
|
|
|
|
- /* We could put more heuristics here, like looking up a hostname
|
|
- of "kerberos."+REALM, etc. */
|
|
+ code = prof_locate_server(context, realm, &al, svc, socktype, family);
|
|
|
|
#ifdef KRB5_DNS_LOOKUP
|
|
- if (code) {
|
|
- krb5_error_code code2;
|
|
- code2 = dns_locate_server(context, realm, &al, svc, socktype, family);
|
|
- if (code2 != KRB5_PLUGIN_NO_HANDLE)
|
|
- code = code2;
|
|
- }
|
|
+ if (code) { /* Try DNS for all profile errors? */
|
|
+ krb5_error_code code2;
|
|
+ code2 = dns_locate_server(context, realm, &al, svc, socktype,
|
|
+ family);
|
|
+ if (code2 != KRB5_PLUGIN_NO_HANDLE)
|
|
+ code = code2;
|
|
+ }
|
|
#endif /* KRB5_DNS_LOOKUP */
|
|
+
|
|
+ /* We could put more heuristics here, like looking up a hostname
|
|
+ of "kerberos."+REALM, etc. */
|
|
+ }
|
|
if (code == 0)
|
|
Tprintf ("krb5int_locate_server found %d addresses\n",
|
|
al.naddrs);
|
|
Index: src/lib/krb5/os/sendto_kdc.c
|
|
===================================================================
|
|
--- src/lib/krb5/os/sendto_kdc.c.orig
|
|
+++ src/lib/krb5/os/sendto_kdc.c
|
|
@@ -1127,7 +1127,7 @@ krb5int_sendto (krb5_context context, co
|
|
return ENOMEM;
|
|
}
|
|
|
|
- memset(conns, 0, n_conns * sizeof(conns[i]));
|
|
+ memset(conns, 0, n_conns * sizeof(struct conn_state));
|
|
|
|
if (callback_info) {
|
|
callback_data = malloc(n_conns * sizeof(krb5_data));
|
|
@@ -1135,7 +1135,7 @@ krb5int_sendto (krb5_context context, co
|
|
return ENOMEM;
|
|
}
|
|
|
|
- memset(conns, 0, n_conns * sizeof(callback_data[i]));
|
|
+ memset(callback_data, 0, n_conns * sizeof(krb5_data));
|
|
}
|
|
|
|
for (i = 0; i < n_conns; i++) {
|
|
Index: src/lib/krb5/os/hst_realm.c
|
|
===================================================================
|
|
--- src/lib/krb5/os/hst_realm.c.orig
|
|
+++ src/lib/krb5/os/hst_realm.c
|
|
@@ -302,12 +302,16 @@ krb5int_translate_gai_error (int num)
|
|
return EAFNOSUPPORT;
|
|
case EAI_MEMORY:
|
|
return ENOMEM;
|
|
-#if EAI_NODATA != EAI_NONAME
|
|
+#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
|
|
case EAI_NODATA:
|
|
return KRB5_EAI_NODATA;
|
|
#endif
|
|
case EAI_NONAME:
|
|
return KRB5_EAI_NONAME;
|
|
+#if defined(EAI_OVERFLOW)
|
|
+ case EAI_OVERFLOW:
|
|
+ return EINVAL; /* XXX */
|
|
+#endif
|
|
case EAI_SERVICE:
|
|
return KRB5_EAI_SERVICE;
|
|
case EAI_SOCKTYPE:
|
|
Index: src/lib/krb5/os/init_os_ctx.c
|
|
===================================================================
|
|
--- src/lib/krb5/os/init_os_ctx.c.orig
|
|
+++ src/lib/krb5/os/init_os_ctx.c
|
|
@@ -336,7 +336,7 @@ os_init_paths(krb5_context ctx, krb5_boo
|
|
|
|
retval = os_get_default_config_files(&files, secure);
|
|
|
|
- if (retval == 0)
|
|
+ if (retval == 0 && kdc)
|
|
retval = add_kdc_config_file(&files);
|
|
|
|
if (!retval) {
|
|
Index: src/lib/krb5/os/changepw.c
|
|
===================================================================
|
|
--- src/lib/krb5/os/changepw.c.orig
|
|
+++ src/lib/krb5/os/changepw.c
|
|
@@ -70,12 +70,14 @@ krb5_locate_kpasswd(krb5_context context
|
|
locate_service_kadmin, SOCK_STREAM, 0);
|
|
if (!code) {
|
|
/* Success with admin_server but now we need to change the
|
|
- port number to use DEFAULT_KPASSWD_PORT. */
|
|
+ port number to use DEFAULT_KPASSWD_PORT and the socktype. */
|
|
int i;
|
|
for (i=0; i<addrlist->naddrs; i++) {
|
|
struct addrinfo *a = addrlist->addrs[i].ai;
|
|
if (a->ai_family == AF_INET)
|
|
sa2sin (a->ai_addr)->sin_port = htons(DEFAULT_KPASSWD_PORT);
|
|
+ if (sockType != SOCK_STREAM)
|
|
+ a->ai_socktype = sockType;
|
|
}
|
|
}
|
|
}
|
|
Index: src/lib/krb5/ccache/ccapi/stdcc.c
|
|
===================================================================
|
|
--- src/lib/krb5/ccache/ccapi/stdcc.c.orig
|
|
+++ src/lib/krb5/ccache/ccapi/stdcc.c
|
|
@@ -56,6 +56,7 @@
|
|
|
|
#ifdef USE_CCAPI_V3
|
|
cc_context_t gCntrlBlock = NULL;
|
|
+cc_int32 gCCVersion = 0;
|
|
#else
|
|
apiCB *gCntrlBlock = NULL;
|
|
#endif
|
|
@@ -222,13 +223,59 @@ static krb5_error_code cc_err_xlate(int
|
|
|
|
|
|
#ifdef USE_CCAPI_V3
|
|
+
|
|
+static krb5_error_code stdccv3_get_timeoffset (krb5_context in_context,
|
|
+ cc_ccache_t in_ccache)
|
|
+{
|
|
+ krb5_error_code err = 0;
|
|
+
|
|
+ if (gCCVersion >= ccapi_version_5) {
|
|
+ krb5_os_context os_ctx = (krb5_os_context) in_context->os_context;
|
|
+ cc_time_t time_offset = 0;
|
|
+
|
|
+ err = cc_ccache_get_kdc_time_offset (in_ccache, cc_credentials_v5,
|
|
+ &time_offset);
|
|
+
|
|
+ if (!err) {
|
|
+ os_ctx->time_offset = time_offset;
|
|
+ os_ctx->usec_offset = 0;
|
|
+ os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) |
|
|
+ KRB5_OS_TOFFSET_VALID);
|
|
+ }
|
|
+
|
|
+ if (err == ccErrTimeOffsetNotSet) {
|
|
+ err = 0; /* okay if there is no time offset */
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return err; /* Don't translate. Callers will translate for us */
|
|
+}
|
|
+
|
|
+static krb5_error_code stdccv3_set_timeoffset (krb5_context in_context,
|
|
+ cc_ccache_t in_ccache)
|
|
+{
|
|
+ krb5_error_code err = 0;
|
|
+
|
|
+ if (gCCVersion >= ccapi_version_5) {
|
|
+ krb5_os_context os_ctx = (krb5_os_context) in_context->os_context;
|
|
+
|
|
+ if (!err && os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) {
|
|
+ err = cc_ccache_set_kdc_time_offset (in_ccache,
|
|
+ cc_credentials_v5,
|
|
+ os_ctx->time_offset);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return err; /* Don't translate. Callers will translate for us */
|
|
+}
|
|
+
|
|
static krb5_error_code stdccv3_setup (krb5_context context,
|
|
stdccCacheDataPtr ccapi_data)
|
|
{
|
|
krb5_error_code err = 0;
|
|
|
|
if (!err && !gCntrlBlock) {
|
|
- err = cc_initialize (&gCntrlBlock, ccapi_version_max, NULL, NULL);
|
|
+ err = cc_initialize (&gCntrlBlock, ccapi_version_max, &gCCVersion, NULL);
|
|
}
|
|
|
|
if (!err && ccapi_data && !ccapi_data->NamedCache) {
|
|
@@ -237,6 +284,10 @@ static krb5_error_code stdccv3_setup (kr
|
|
&ccapi_data->NamedCache);
|
|
}
|
|
|
|
+ if (!err && ccapi_data && ccapi_data->NamedCache) {
|
|
+ err = stdccv3_get_timeoffset (context, ccapi_data->NamedCache);
|
|
+ }
|
|
+
|
|
return err; /* Don't translate. Callers will translate for us */
|
|
}
|
|
|
|
@@ -245,6 +296,7 @@ void krb5_stdcc_shutdown()
|
|
{
|
|
if (gCntrlBlock) { cc_context_release(gCntrlBlock); }
|
|
gCntrlBlock = NULL;
|
|
+ gCCVersion = 0;
|
|
}
|
|
|
|
/*
|
|
@@ -278,11 +330,15 @@ krb5_stdccv3_generate_new (krb5_context
|
|
}
|
|
|
|
if (!err) {
|
|
- err = cc_context_create_new_ccache (gCntrlBlock, cc_credentials_v5, 0L,
|
|
+ err = cc_context_create_new_ccache (gCntrlBlock, cc_credentials_v5, "",
|
|
&ccache);
|
|
}
|
|
|
|
if (!err) {
|
|
+ err = stdccv3_set_timeoffset (context, ccache);
|
|
+ }
|
|
+
|
|
+ if (!err) {
|
|
err = cc_ccache_get_name (ccache, &ccstring);
|
|
}
|
|
|
|
@@ -395,6 +451,7 @@ krb5_stdccv3_initialize (krb5_context co
|
|
krb5_error_code err = 0;
|
|
stdccCacheDataPtr ccapi_data = id->data;
|
|
char *name = NULL;
|
|
+ cc_ccache_t ccache = NULL;
|
|
|
|
if (id == NULL) { err = KRB5_CC_NOMEM; }
|
|
|
|
@@ -406,22 +463,27 @@ krb5_stdccv3_initialize (krb5_context co
|
|
err = krb5_unparse_name(context, princ, &name);
|
|
}
|
|
|
|
- if (!err && ccapi_data->NamedCache) {
|
|
- err = cc_ccache_release(ccapi_data->NamedCache);
|
|
- ccapi_data->NamedCache = NULL;
|
|
- }
|
|
-
|
|
if (!err) {
|
|
err = cc_context_create_ccache (gCntrlBlock, ccapi_data->cache_name,
|
|
cc_credentials_v5, name,
|
|
- &ccapi_data->NamedCache);
|
|
+ &ccache);
|
|
}
|
|
|
|
if (!err) {
|
|
- cache_changed();
|
|
+ err = stdccv3_set_timeoffset (context, ccache);
|
|
+ }
|
|
+
|
|
+ if (!err) {
|
|
+ if (ccapi_data->NamedCache) {
|
|
+ err = cc_ccache_release (ccapi_data->NamedCache);
|
|
+ }
|
|
+ ccapi_data->NamedCache = ccache;
|
|
+ ccache = NULL; /* take ownership */
|
|
+ cache_changed ();
|
|
}
|
|
|
|
- if (name) { krb5_free_unparsed_name(context, name); }
|
|
+ if (ccache) { cc_ccache_release (ccache); }
|
|
+ if (name ) { krb5_free_unparsed_name(context, name); }
|
|
|
|
return cc_err_xlate(err);
|
|
}
|
|
Index: src/lib/krb5/ccache/cc_mslsa.c
|
|
===================================================================
|
|
--- src/lib/krb5/ccache/cc_mslsa.c.orig
|
|
+++ src/lib/krb5/ccache/cc_mslsa.c
|
|
@@ -1,6 +1,8 @@
|
|
/*
|
|
* lib/krb5/ccache/cc_mslsa.c
|
|
*
|
|
+ * Copyright 2007 Secure Endpoints Inc.
|
|
+ *
|
|
* Copyright 2003,2004 by the Massachusetts Institute of Technology.
|
|
* All Rights Reserved.
|
|
*
|
|
@@ -60,16 +62,25 @@
|
|
#include <stdlib.h>
|
|
#include <conio.h>
|
|
#include <time.h>
|
|
+
|
|
#define SECURITY_WIN32
|
|
#include <security.h>
|
|
+#ifdef _WIN32_WINNT
|
|
+#undef _WIN32_WINNT
|
|
+#endif
|
|
+#define _WIN32_WINNT 0x0600
|
|
#include <ntsecapi.h>
|
|
#include <ntstatus.h>
|
|
|
|
-#ifdef COMMENT
|
|
-/* The following two features can only be built using a version of the
|
|
- * Microsoft Windows Platform SDK which is not currently public. These
|
|
- * features will be disabled until the SDK is made publicly available.
|
|
+
|
|
+/* The following two features can only be built using the version of the
|
|
+ * Platform SDK for Microsoft Windows Vista. If AES support is defined
|
|
+ * in NTSecAPI.h then we know that we have the required data structures.
|
|
+ *
|
|
+ * To build with the Windows XP SP2 SDK, the NTSecAPI.h from the Vista
|
|
+ * SDK should be used in place of the XP SP2 SDK version.
|
|
*/
|
|
+#ifdef TRUST_ATTRIBUTE_TRUST_USES_AES_KEYS
|
|
#define KERB_SUBMIT_TICKET 1
|
|
#define HAVE_CACHE_INFO_EX2 1
|
|
#endif
|
|
@@ -136,6 +147,61 @@ is_windows_xp (void)
|
|
return fIsWinXP;
|
|
}
|
|
|
|
+static BOOL
|
|
+is_windows_vista (void)
|
|
+{
|
|
+ static BOOL fChecked = FALSE;
|
|
+ static BOOL fIsVista = FALSE;
|
|
+
|
|
+ if (!fChecked)
|
|
+ {
|
|
+ OSVERSIONINFO Version;
|
|
+
|
|
+ memset (&Version, 0x00, sizeof(Version));
|
|
+ Version.dwOSVersionInfoSize = sizeof(Version);
|
|
+
|
|
+ if (GetVersionEx (&Version))
|
|
+ {
|
|
+ if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6)
|
|
+ fIsVista = TRUE;
|
|
+ }
|
|
+ fChecked = TRUE;
|
|
+ }
|
|
+
|
|
+ return fIsVista;
|
|
+}
|
|
+
|
|
+static BOOL
|
|
+is_process_uac_limited (void)
|
|
+{
|
|
+ static BOOL fChecked = FALSE;
|
|
+ static BOOL fIsUAC = FALSE;
|
|
+
|
|
+ if (!fChecked)
|
|
+ {
|
|
+ NTSTATUS Status = 0;
|
|
+ HANDLE TokenHandle;
|
|
+ DWORD ElevationLevel;
|
|
+ DWORD ReqLen;
|
|
+ BOOL Success;
|
|
+
|
|
+ if (is_windows_vista()) {
|
|
+ Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
|
|
+ if ( Success ) {
|
|
+ Success = GetTokenInformation( TokenHandle,
|
|
+ TokenOrigin+1 /* ElevationLevel */,
|
|
+ &ElevationLevel, sizeof(DWORD), &ReqLen );
|
|
+ CloseHandle( TokenHandle );
|
|
+ if ( Success && ElevationLevel == 3 /* Limited */ )
|
|
+ fIsUAC = TRUE;
|
|
+ }
|
|
+ }
|
|
+ fChecked = TRUE;
|
|
+ }
|
|
+ return fIsUAC;
|
|
+
|
|
+}
|
|
+
|
|
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
|
|
|
static BOOL
|
|
@@ -375,6 +441,24 @@ MSSessionKeyToMITKeyblock(KERB_CRYPTO_KE
|
|
krb5_copy_keyblock_contents(context, &tmpblock, keyblock);
|
|
}
|
|
|
|
+static BOOL
|
|
+IsMSSessionKeyNull(KERB_CRYPTO_KEY *mskey)
|
|
+{
|
|
+ DWORD i;
|
|
+
|
|
+ if (is_process_uac_limited())
|
|
+ return TRUE;
|
|
+
|
|
+ if (mskey->KeyType == KERB_ETYPE_NULL)
|
|
+ return TRUE;
|
|
+
|
|
+ for ( i=0; i<mskey->Length; i++ ) {
|
|
+ if (mskey->Value[i])
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
|
|
static void
|
|
MSFlagsToMITFlags(ULONG msflags, ULONG *mitflags)
|
|
@@ -1036,8 +1120,10 @@ KerbSubmitTicket( HANDLE LogonHandle, UL
|
|
krb5_auth_con_getsendsubkey(context, auth_context, &keyblock);
|
|
if (keyblock == NULL)
|
|
krb5_auth_con_getkey(context, auth_context, &keyblock);
|
|
-#ifdef TESTING
|
|
- /* do not use this code unless testing the LSA */
|
|
+
|
|
+ /* make up a key, any key, that can be used to generate the
|
|
+ * encrypted KRB_CRED pdu. The Vista release LSA requires
|
|
+ * that an enctype other than NULL be used. */
|
|
if (keyblock == NULL) {
|
|
keyblock = (krb5_keyblock *)malloc(sizeof(krb5_keyblock));
|
|
keyblock->enctype = ENCTYPE_ARCFOUR_HMAC;
|
|
@@ -1061,7 +1147,6 @@ KerbSubmitTicket( HANDLE LogonHandle, UL
|
|
keyblock->contents[15] = 0xd;
|
|
krb5_auth_con_setsendsubkey(context, auth_context, keyblock);
|
|
}
|
|
-#endif
|
|
rc = krb5_mk_1cred(context, auth_context, cred, &krb_cred, &replaydata);
|
|
if (rc) {
|
|
krb5_auth_con_free(context, auth_context);
|
|
@@ -1191,6 +1276,11 @@ GetMSTGT(krb5_context context, HANDLE Lo
|
|
int ignore_cache = 0;
|
|
krb5_enctype *etype_list = NULL, *ptr = NULL, etype = 0;
|
|
|
|
+ if (is_process_uac_limited()) {
|
|
+ Status = STATUS_ACCESS_DENIED;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
memset(&CacheRequest, 0, sizeof(KERB_QUERY_TKT_CACHE_REQUEST));
|
|
CacheRequest.MessageType = KerbRetrieveTicketMessage;
|
|
CacheRequest.LogonId.LowPart = 0;
|
|
@@ -1286,7 +1376,7 @@ GetMSTGT(krb5_context context, HANDLE Lo
|
|
#else
|
|
/* Check Supported Enctypes */
|
|
if ( !enforce_tgs_enctypes ||
|
|
- pTicketResponse->Ticket.SessionKey.KeyType == KERB_ETYPE_NULL ||
|
|
+ IsMSSessionKeyNull(&pTicketResponse->Ticket.SessionKey) ||
|
|
krb5_is_permitted_tgs_enctype(context, NULL, pTicketResponse->Ticket.SessionKey.KeyType) ) {
|
|
FILETIME Now, MinLife, EndTime, LocalEndTime;
|
|
__int64 temp;
|
|
@@ -2264,7 +2354,7 @@ krb5_lcc_next_cred(krb5_context context,
|
|
}
|
|
|
|
/* Don't return tickets with NULL Session Keys */
|
|
- if ( msticket->SessionKey.KeyType == KERB_ETYPE_NULL) {
|
|
+ if ( IsMSSessionKeyNull(&msticket->SessionKey) ) {
|
|
LsaFreeReturnBuffer(msticket);
|
|
goto next_cred;
|
|
}
|
|
Index: src/lib/krb5/libkrb5.exports
|
|
===================================================================
|
|
--- src/lib/krb5/libkrb5.exports.orig
|
|
+++ src/lib/krb5/libkrb5.exports
|
|
@@ -436,11 +436,16 @@ krb5_get_in_tkt_with_password
|
|
krb5_get_in_tkt_with_skey
|
|
krb5_get_init_creds
|
|
krb5_get_init_creds_keytab
|
|
+krb5_get_init_creds_opt_alloc
|
|
+krb5_get_init_creds_opt_free
|
|
+krb5_get_init_creds_opt_free_pa
|
|
+krb5_get_init_creds_opt_get_pa
|
|
krb5_get_init_creds_opt_init
|
|
krb5_get_init_creds_opt_set_address_list
|
|
krb5_get_init_creds_opt_set_change_password_prompt
|
|
krb5_get_init_creds_opt_set_etype_list
|
|
krb5_get_init_creds_opt_set_forwardable
|
|
+krb5_get_init_creds_opt_set_pa
|
|
krb5_get_init_creds_opt_set_preauth_list
|
|
krb5_get_init_creds_opt_set_proxiable
|
|
krb5_get_init_creds_opt_set_renew_life
|
|
@@ -614,6 +619,7 @@ krb5_ser_rcache_init
|
|
krb5_ser_unpack_bytes
|
|
krb5_ser_unpack_int32
|
|
krb5_ser_unpack_int64
|
|
+krb5_server_decrypt_ticket_keytab
|
|
krb5_set_config_files
|
|
krb5_set_debugging_time
|
|
krb5_set_default_in_tkt_ktypes
|
|
Index: src/lib/krb5/krb/gic_keytab.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/gic_keytab.c.orig
|
|
+++ src/lib/krb5/krb/gic_keytab.c
|
|
@@ -76,11 +76,18 @@ krb5_get_as_key_keytab(
|
|
}
|
|
|
|
krb5_error_code KRB5_CALLCONV
|
|
-krb5_get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, char *in_tkt_service, krb5_get_init_creds_opt *options)
|
|
+krb5_get_init_creds_keytab(krb5_context context,
|
|
+ krb5_creds *creds,
|
|
+ krb5_principal client,
|
|
+ krb5_keytab arg_keytab,
|
|
+ krb5_deltat start_time,
|
|
+ char *in_tkt_service,
|
|
+ krb5_get_init_creds_opt *options)
|
|
{
|
|
krb5_error_code ret, ret2;
|
|
int use_master;
|
|
krb5_keytab keytab;
|
|
+ krb5_gic_opt_ext *opte = NULL;
|
|
|
|
if (arg_keytab == NULL) {
|
|
if ((ret = krb5_kt_default(context, &keytab)))
|
|
@@ -89,12 +96,17 @@ krb5_get_init_creds_keytab(krb5_context
|
|
keytab = arg_keytab;
|
|
}
|
|
|
|
+ ret = krb5int_gic_opt_to_opte(context, options, &opte, 1,
|
|
+ "krb5_get_init_creds_keytab");
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
use_master = 0;
|
|
|
|
/* first try: get the requested tkt from any kdc */
|
|
|
|
ret = krb5_get_init_creds(context, creds, client, NULL, NULL,
|
|
- start_time, in_tkt_service, options,
|
|
+ start_time, in_tkt_service, opte,
|
|
krb5_get_as_key_keytab, (void *) keytab,
|
|
&use_master,NULL);
|
|
|
|
@@ -115,7 +127,7 @@ krb5_get_init_creds_keytab(krb5_context
|
|
use_master = 1;
|
|
|
|
ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL,
|
|
- start_time, in_tkt_service, options,
|
|
+ start_time, in_tkt_service, opte,
|
|
krb5_get_as_key_keytab, (void *) keytab,
|
|
&use_master, NULL);
|
|
|
|
@@ -139,6 +151,8 @@ krb5_get_init_creds_keytab(krb5_context
|
|
do any prompting or changing for keytabs, that's it. */
|
|
|
|
cleanup:
|
|
+ if (opte && krb5_gic_opt_is_shadowed(opte))
|
|
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
|
|
if (arg_keytab == NULL)
|
|
krb5_kt_close(context, keytab);
|
|
|
|
@@ -152,15 +166,18 @@ krb5_get_in_tkt_with_keytab(krb5_context
|
|
krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
|
|
{
|
|
krb5_error_code retval;
|
|
- krb5_get_init_creds_opt opt;
|
|
+ krb5_gic_opt_ext *opte;
|
|
char * server = NULL;
|
|
krb5_keytab keytab;
|
|
krb5_principal client_princ, server_princ;
|
|
int use_master = 0;
|
|
|
|
- krb5int_populate_gic_opt(context, &opt,
|
|
- options, addrs, ktypes,
|
|
- pre_auth_types, creds);
|
|
+ retval = krb5int_populate_gic_opt(context, &opte,
|
|
+ options, addrs, ktypes,
|
|
+ pre_auth_types, creds);
|
|
+ if (retval)
|
|
+ return retval;
|
|
+
|
|
if (arg_keytab == NULL) {
|
|
retval = krb5_kt_default(context, &keytab);
|
|
if (retval)
|
|
@@ -176,10 +193,11 @@ krb5_get_in_tkt_with_keytab(krb5_context
|
|
retval = krb5_get_init_creds (context,
|
|
creds, creds->client,
|
|
krb5_prompter_posix, NULL,
|
|
- 0, server, &opt,
|
|
+ 0, server, opte,
|
|
krb5_get_as_key_keytab, (void *)keytab,
|
|
&use_master, ret_as_reply);
|
|
krb5_free_unparsed_name( context, server);
|
|
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
|
|
if (retval) {
|
|
goto cleanup;
|
|
}
|
|
Index: src/lib/krb5/krb/Makefile.in
|
|
===================================================================
|
|
--- src/lib/krb5/krb/Makefile.in.orig
|
|
+++ src/lib/krb5/krb/Makefile.in
|
|
@@ -89,6 +89,7 @@ STLIBOBJS= \
|
|
ser_princ.o \
|
|
serialize.o \
|
|
set_realm.o \
|
|
+ srv_dec_tkt.o \
|
|
srv_rcache.o \
|
|
str_conv.o \
|
|
tgtname.o \
|
|
@@ -175,6 +176,7 @@ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \
|
|
$(OUTPRE)ser_princ.$(OBJEXT) \
|
|
$(OUTPRE)serialize.$(OBJEXT) \
|
|
$(OUTPRE)set_realm.$(OBJEXT) \
|
|
+ $(OUTPRE)srv_dec_tkt.$(OBJEXT) \
|
|
$(OUTPRE)srv_rcache.$(OBJEXT) \
|
|
$(OUTPRE)str_conv.$(OBJEXT) \
|
|
$(OUTPRE)tgtname.$(OBJEXT) \
|
|
@@ -262,6 +264,7 @@ SRCS= $(srcdir)/addr_comp.c \
|
|
$(srcdir)/ser_princ.c \
|
|
$(srcdir)/serialize.c \
|
|
$(srcdir)/set_realm.c \
|
|
+ $(srcdir)/srv_dec_tkt.c \
|
|
$(srcdir)/srv_rcache.c \
|
|
$(srcdir)/str_conv.c \
|
|
$(srcdir)/tgtname.c \
|
|
@@ -1041,6 +1044,15 @@ set_realm.so set_realm.po $(OUTPRE)set_r
|
|
$(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
|
|
$(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
|
|
set_realm.c
|
|
+srv_dec_tkt.so srv_dec_tkt.po $(OUTPRE)srv_dec_tkt.$(OBJEXT): \
|
|
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
|
|
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
|
|
+ $(COM_ERR_DEPS) $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int.h \
|
|
+ $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
|
|
+ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \
|
|
+ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
|
|
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
|
|
+ srv_dec_tkt.c
|
|
srv_rcache.so srv_rcache.po $(OUTPRE)srv_rcache.$(OBJEXT): \
|
|
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
|
|
$(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
|
|
Index: src/lib/krb5/krb/srv_dec_tkt.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ src/lib/krb5/krb/srv_dec_tkt.c
|
|
@@ -0,0 +1,94 @@
|
|
+/*
|
|
+ * lib/krb5/krb/srv_dec_tkt.c
|
|
+ *
|
|
+ * Copyright 2006 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. Furthermore if you modify this software you must label
|
|
+ * your software as modified software and not distribute it in such a
|
|
+ * fashion that it might be confused with the original M.I.T. software.
|
|
+ * 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.
|
|
+ *
|
|
+ *
|
|
+ * Server decrypt ticket via keytab or keyblock.
|
|
+ *
|
|
+ * Different from krb5_rd_req_decoded. (krb5/src/lib/krb5/krb/rd_req_dec.c)
|
|
+ * - No krb5_principal_compare or KRB5KRB_AP_ERR_BADMATCH error.
|
|
+ * - No replay cache processing.
|
|
+ * - No skew checking or KRB5KRB_AP_ERR_SKEW error.
|
|
+ * - No address checking or KRB5KRB_AP_ERR_BADADDR error.
|
|
+ * - No time validation.
|
|
+ * - No permitted enctype validation or KRB5_NOPERM_ETYPE error.
|
|
+ * - Does not free ticket->enc_part2 on error.
|
|
+ */
|
|
+
|
|
+#include <k5-int.h>
|
|
+
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5int_server_decrypt_ticket_keyblock(krb5_context context,
|
|
+ const krb5_keyblock *key,
|
|
+ krb5_ticket *ticket)
|
|
+{
|
|
+ krb5_error_code retval;
|
|
+ krb5_data *realm;
|
|
+ krb5_transited *trans;
|
|
+
|
|
+ retval = krb5_decrypt_tkt_part(context, key, ticket);
|
|
+ if (retval)
|
|
+ goto done;
|
|
+
|
|
+ trans = &ticket->enc_part2->transited;
|
|
+ realm = &ticket->enc_part2->client->realm;
|
|
+ if (trans->tr_contents.data && *trans->tr_contents.data) {
|
|
+ retval = krb5_check_transited_list(context, &trans->tr_contents,
|
|
+ realm, &ticket->server->realm);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (ticket->enc_part2->flags & TKT_FLG_INVALID) { /* ie, KDC_OPT_POSTDATED */
|
|
+ retval = KRB5KRB_AP_ERR_TKT_INVALID;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ done:
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_server_decrypt_ticket_keytab(krb5_context context,
|
|
+ const krb5_keytab kt,
|
|
+ krb5_ticket *ticket)
|
|
+{
|
|
+ krb5_error_code retval;
|
|
+ krb5_enctype enctype;
|
|
+ krb5_keytab_entry ktent;
|
|
+
|
|
+ enctype = ticket->enc_part.enctype;
|
|
+
|
|
+ if ((retval = krb5_kt_get_entry(context, kt, ticket->server,
|
|
+ ticket->enc_part.kvno,
|
|
+ enctype, &ktent)))
|
|
+ return retval;
|
|
+
|
|
+ retval = krb5int_server_decrypt_ticket_keyblock(context,
|
|
+ &ktent.key, ticket);
|
|
+ /* Upon error, Free keytab entry first, then return */
|
|
+
|
|
+ (void) krb5_kt_free_entry(context, &ktent);
|
|
+ return retval;
|
|
+}
|
|
Index: src/lib/krb5/krb/gc_frm_kdc.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/gc_frm_kdc.c.orig
|
|
+++ src/lib/krb5/krb/gc_frm_kdc.c
|
|
@@ -462,6 +462,7 @@ find_nxt_kdc(struct tr_state *ts)
|
|
if (ts->ntgts > 0) {
|
|
/* Punt NXT_TGT from KDC_TGTS if bogus. */
|
|
krb5_free_creds(ts->ctx, ts->kdc_tgts[--ts->ntgts]);
|
|
+ ts->kdc_tgts[ts->ntgts] = NULL;
|
|
}
|
|
TR_DBG_RET(ts, "find_nxt_kdc", KRB5_KDCREP_MODIFIED);
|
|
return KRB5_KDCREP_MODIFIED;
|
|
Index: src/lib/krb5/krb/gic_opt.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/gic_opt.c.orig
|
|
+++ src/lib/krb5/krb/gic_opt.c
|
|
@@ -72,3 +72,357 @@ krb5_get_init_creds_opt_set_change_passw
|
|
else
|
|
opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT;
|
|
}
|
|
+
|
|
+/*
|
|
+ * Extending the krb5_get_init_creds_opt structure. The original
|
|
+ * krb5_get_init_creds_opt structure is defined publicly. The
|
|
+ * new extended version is private. The original interface
|
|
+ * assumed a pre-allocated structure which was passed to
|
|
+ * krb5_get_init_creds_init(). The new interface assumes that
|
|
+ * the caller will call krb5_get_init_creds_alloc() and
|
|
+ * krb5_get_init_creds_free().
|
|
+ *
|
|
+ * Callers MUST NOT call krb5_get_init_creds_init() after allocating an
|
|
+ * opts structure using krb5_get_init_creds_alloc(). To do so will
|
|
+ * introduce memory leaks. Unfortunately, there is no way to enforce
|
|
+ * this behavior.
|
|
+ *
|
|
+ * Two private flags are added for backward compatibility.
|
|
+ * KRB5_GET_INIT_CREDS_OPT_EXTENDED says that the structure was allocated
|
|
+ * with the new krb5_get_init_creds_opt_alloc() function.
|
|
+ * KRB5_GET_INIT_CREDS_OPT_SHADOWED is set to indicate that the extended
|
|
+ * structure is a shadow copy of an original krb5_get_init_creds_opt
|
|
+ * structure.
|
|
+ * If KRB5_GET_INIT_CREDS_OPT_SHADOWED is set after a call to
|
|
+ * krb5int_gic_opt_to_opte(), the resulting extended structure should be
|
|
+ * freed (using krb5_get_init_creds_free). Otherwise, the original
|
|
+ * structure was already extended and there is no need to free it.
|
|
+ */
|
|
+
|
|
+/* Forward prototype */
|
|
+static void
|
|
+free_gic_opt_ext_preauth_data(krb5_context context,
|
|
+ krb5_gic_opt_ext *opte);
|
|
+
|
|
+static krb5_error_code
|
|
+krb5int_gic_opte_private_alloc(krb5_context context, krb5_gic_opt_ext *opte)
|
|
+{
|
|
+ if (NULL == opte || !krb5_gic_opt_is_extended(opte))
|
|
+ return EINVAL;
|
|
+
|
|
+ opte->opt_private = calloc(1, sizeof(*opte->opt_private));
|
|
+ if (NULL == opte->opt_private) {
|
|
+ return ENOMEM;
|
|
+ }
|
|
+ /* Allocate any private stuff */
|
|
+ opte->opt_private->num_preauth_data = 0;
|
|
+ opte->opt_private->preauth_data = NULL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5int_gic_opte_private_free(krb5_context context, krb5_gic_opt_ext *opte)
|
|
+{
|
|
+ if (NULL == opte || !krb5_gic_opt_is_extended(opte))
|
|
+ return EINVAL;
|
|
+
|
|
+ /* Free up any private stuff */
|
|
+ if (opte->opt_private->preauth_data != NULL)
|
|
+ free_gic_opt_ext_preauth_data(context, opte);
|
|
+ free(opte->opt_private);
|
|
+ opte->opt_private = NULL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static krb5_gic_opt_ext *
|
|
+krb5int_gic_opte_alloc(krb5_context context)
|
|
+{
|
|
+ krb5_gic_opt_ext *opte;
|
|
+ krb5_error_code code;
|
|
+
|
|
+ opte = calloc(1, sizeof(*opte));
|
|
+ if (NULL == opte)
|
|
+ return NULL;
|
|
+ opte->flags = KRB5_GET_INIT_CREDS_OPT_EXTENDED;
|
|
+
|
|
+ code = krb5int_gic_opte_private_alloc(context, opte);
|
|
+ if (code) {
|
|
+ krb5int_set_error(&context->err, code,
|
|
+ "krb5int_gic_opte_alloc: krb5int_gic_opte_private_alloc failed");
|
|
+ free(opte);
|
|
+ return NULL;
|
|
+ }
|
|
+ return(opte);
|
|
+}
|
|
+
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_alloc(krb5_context context,
|
|
+ krb5_get_init_creds_opt **opt)
|
|
+{
|
|
+ krb5_gic_opt_ext *opte;
|
|
+
|
|
+ if (NULL == opt)
|
|
+ return EINVAL;
|
|
+ *opt = NULL;
|
|
+
|
|
+ /*
|
|
+ * We return a new extended structure cast as a krb5_get_init_creds_opt
|
|
+ */
|
|
+ opte = krb5int_gic_opte_alloc(context);
|
|
+ if (NULL == opte)
|
|
+ return ENOMEM;
|
|
+
|
|
+ *opt = (krb5_get_init_creds_opt *) opte;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_free(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt)
|
|
+{
|
|
+ krb5_gic_opt_ext *opte;
|
|
+
|
|
+ if (NULL == opt)
|
|
+ return;
|
|
+
|
|
+ /* Don't touch it if we didn't allocate it */
|
|
+ if (!krb5_gic_opt_is_extended(opt))
|
|
+ return;
|
|
+
|
|
+ opte = (krb5_gic_opt_ext *)opt;
|
|
+ if (opte->opt_private)
|
|
+ krb5int_gic_opte_private_free(context, opte);
|
|
+
|
|
+ free(opte);
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5int_gic_opte_copy(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ krb5_gic_opt_ext **opte)
|
|
+{
|
|
+ krb5_gic_opt_ext *oe;
|
|
+
|
|
+ oe = krb5int_gic_opte_alloc(context);
|
|
+ if (NULL == oe)
|
|
+ return ENOMEM;
|
|
+ memcpy(oe, opt, sizeof(*opt));
|
|
+ /* Fix these -- overwritten by the copy */
|
|
+ oe->flags |= ( KRB5_GET_INIT_CREDS_OPT_EXTENDED |
|
|
+ KRB5_GET_INIT_CREDS_OPT_SHADOWED);
|
|
+
|
|
+ *opte = oe;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Convert a krb5_get_init_creds_opt pointer to a pointer to
|
|
+ * an extended, krb5_gic_opt_ext pointer. If the original
|
|
+ * pointer already points to an extended structure, then simply
|
|
+ * return the original pointer. Otherwise, if 'force' is non-zero,
|
|
+ * allocate an extended structure and copy the original over it.
|
|
+ * If the original pointer did not point to an extended structure
|
|
+ * and 'force' is zero, then return an error. This is used in
|
|
+ * cases where the original *should* be an extended structure.
|
|
+ */
|
|
+krb5_error_code
|
|
+krb5int_gic_opt_to_opte(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ krb5_gic_opt_ext **opte,
|
|
+ unsigned int force,
|
|
+ const char *where)
|
|
+{
|
|
+ if (!krb5_gic_opt_is_extended(opt)) {
|
|
+ if (force) {
|
|
+ return krb5int_gic_opte_copy(context, opt, opte);
|
|
+ } else {
|
|
+ krb5int_set_error(&context->err, EINVAL,
|
|
+ "%s: attempt to convert non-extended krb5_get_init_creds_opt",
|
|
+ where);
|
|
+ return EINVAL;
|
|
+ }
|
|
+ }
|
|
+ /* If it is already extended, just return it */
|
|
+ *opte = (krb5_gic_opt_ext *)opt;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void
|
|
+free_gic_opt_ext_preauth_data(krb5_context context,
|
|
+ krb5_gic_opt_ext *opte)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (NULL == opte || !krb5_gic_opt_is_extended(opte))
|
|
+ return;
|
|
+ if (NULL == opte->opt_private || NULL == opte->opt_private->preauth_data)
|
|
+ return;
|
|
+
|
|
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
|
|
+ if (opte->opt_private->preauth_data[i].attr != NULL)
|
|
+ free(opte->opt_private->preauth_data[i].attr);
|
|
+ if (opte->opt_private->preauth_data[i].value != NULL)
|
|
+ free(opte->opt_private->preauth_data[i].value);
|
|
+ }
|
|
+ free(opte->opt_private->preauth_data);
|
|
+ opte->opt_private->preauth_data = NULL;
|
|
+ opte->opt_private->num_preauth_data = 0;
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+add_gic_opt_ext_preauth_data(krb5_context context,
|
|
+ krb5_gic_opt_ext *opte,
|
|
+ const char *attr,
|
|
+ const char *value)
|
|
+{
|
|
+ size_t newsize;
|
|
+ int i;
|
|
+ krb5_gic_opt_pa_data *newpad;
|
|
+
|
|
+ newsize = opte->opt_private->num_preauth_data + 1;
|
|
+ newsize = newsize * sizeof(*opte->opt_private->preauth_data);
|
|
+ if (opte->opt_private->preauth_data == NULL)
|
|
+ newpad = malloc(newsize);
|
|
+ else
|
|
+ newpad = realloc(opte->opt_private->preauth_data, newsize);
|
|
+ if (newpad == NULL)
|
|
+ return ENOMEM;
|
|
+
|
|
+ i = opte->opt_private->num_preauth_data;
|
|
+ newpad[i].attr = strdup(attr);
|
|
+ if (newpad[i].attr == NULL)
|
|
+ return ENOMEM;
|
|
+ newpad[i].value = strdup(value);
|
|
+ if (newpad[i].value == NULL) {
|
|
+ free(newpad[i].attr);
|
|
+ return ENOMEM;
|
|
+ }
|
|
+ opte->opt_private->num_preauth_data += 1;
|
|
+ opte->opt_private->preauth_data = newpad;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function allows the caller to supply options to preauth
|
|
+ * plugins. Preauth plugin modules are given a chance to look
|
|
+ * at each option at the time this function is called in ordre
|
|
+ * to check the validity of the option.
|
|
+ * The 'opt' pointer supplied to this function must have been
|
|
+ * obtained using krb5_get_init_creds_opt_alloc()
|
|
+ */
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_set_pa(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ const char *attr,
|
|
+ const char *value)
|
|
+{
|
|
+ krb5_error_code retval;
|
|
+ krb5_gic_opt_ext *opte;
|
|
+
|
|
+ retval = krb5int_gic_opt_to_opte(context, opt, &opte, 0,
|
|
+ "krb5_get_init_creds_opt_set_pa");
|
|
+ if (retval)
|
|
+ return retval;
|
|
+
|
|
+ /*
|
|
+ * Copy the option into the extended get_init_creds_opt structure
|
|
+ */
|
|
+ retval = add_gic_opt_ext_preauth_data(context, opte, attr, value);
|
|
+ if (retval)
|
|
+ return retval;
|
|
+
|
|
+ /*
|
|
+ * Give the plugins a chance to look at the option now.
|
|
+ */
|
|
+ retval = krb5_preauth_supply_preauth_data(context, opte, attr, value);
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function allows a preauth plugin to obtain preauth
|
|
+ * options. The preauth_data returned from this function
|
|
+ * should be freed by calling krb5_get_init_creds_opt_free_pa().
|
|
+ *
|
|
+ * The 'opt' pointer supplied to this function must have been
|
|
+ * obtained using krb5_get_init_creds_opt_alloc()
|
|
+ */
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_get_pa(krb5_context context,
|
|
+ krb5_get_init_creds_opt *opt,
|
|
+ int *num_preauth_data,
|
|
+ krb5_gic_opt_pa_data **preauth_data)
|
|
+{
|
|
+ krb5_error_code retval;
|
|
+ krb5_gic_opt_ext *opte;
|
|
+ krb5_gic_opt_pa_data *p = NULL;
|
|
+ int i;
|
|
+ size_t allocsize;
|
|
+
|
|
+ retval = krb5int_gic_opt_to_opte(context, opt, &opte, 0,
|
|
+ "krb5_get_init_creds_opt_get_pa");
|
|
+ if (retval)
|
|
+ return retval;
|
|
+
|
|
+ if (num_preauth_data == NULL || preauth_data == NULL)
|
|
+ return EINVAL;
|
|
+
|
|
+ *num_preauth_data = 0;
|
|
+ *preauth_data = NULL;
|
|
+
|
|
+ if (opte->opt_private->num_preauth_data == 0)
|
|
+ return 0;
|
|
+
|
|
+ allocsize =
|
|
+ opte->opt_private->num_preauth_data * sizeof(krb5_gic_opt_pa_data);
|
|
+ p = malloc(allocsize);
|
|
+ if (p == NULL)
|
|
+ return ENOMEM;
|
|
+
|
|
+ /* Init these to make cleanup easier */
|
|
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
|
|
+ p[i].attr = NULL;
|
|
+ p[i].value = NULL;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
|
|
+ p[i].attr = strdup(opte->opt_private->preauth_data[i].attr);
|
|
+ p[i].value = strdup(opte->opt_private->preauth_data[i].value);
|
|
+ if (p[i].attr == NULL || p[i].value == NULL)
|
|
+ goto cleanup;
|
|
+ }
|
|
+ *num_preauth_data = i;
|
|
+ *preauth_data = p;
|
|
+ return 0;
|
|
+cleanup:
|
|
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
|
|
+ if (p[i].attr != NULL)
|
|
+ free(p[i].attr);
|
|
+ if (p[i].value != NULL)
|
|
+ free(p[i].value);
|
|
+ }
|
|
+ free(p);
|
|
+ return ENOMEM;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function frees the preauth_data that was returned by
|
|
+ * krb5_get_init_creds_opt_get_pa().
|
|
+ */
|
|
+void KRB5_CALLCONV
|
|
+krb5_get_init_creds_opt_free_pa(krb5_context context,
|
|
+ int num_preauth_data,
|
|
+ krb5_gic_opt_pa_data *preauth_data)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (num_preauth_data <= 0 || preauth_data == NULL)
|
|
+ return;
|
|
+
|
|
+ for (i = 0; i < num_preauth_data; i++) {
|
|
+ if (preauth_data[i].attr != NULL)
|
|
+ free(preauth_data[i].attr);
|
|
+ if (preauth_data[i].value != NULL)
|
|
+ free(preauth_data[i].value);
|
|
+ }
|
|
+ free(preauth_data);
|
|
+}
|
|
Index: src/lib/krb5/krb/get_in_tkt.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/get_in_tkt.c.orig
|
|
+++ src/lib/krb5/krb/get_in_tkt.c
|
|
@@ -843,7 +843,7 @@ krb5_get_init_creds(krb5_context context
|
|
void *prompter_data,
|
|
krb5_deltat start_time,
|
|
char *in_tkt_service,
|
|
- krb5_get_init_creds_opt *options,
|
|
+ krb5_gic_opt_ext *options,
|
|
krb5_gic_get_as_key_fct gak_fct,
|
|
void *gak_data,
|
|
int *use_master,
|
|
@@ -1111,7 +1111,7 @@ krb5_get_init_creds(krb5_context context
|
|
&salt, &s2kparams, &etype, &as_key,
|
|
prompter, prompter_data,
|
|
gak_fct, gak_data,
|
|
- &get_data_rock)))
|
|
+ &get_data_rock, options)))
|
|
goto cleanup;
|
|
} else {
|
|
if (preauth_to_use != NULL) {
|
|
@@ -1129,7 +1129,7 @@ krb5_get_init_creds(krb5_context context
|
|
&as_key,
|
|
prompter, prompter_data,
|
|
gak_fct, gak_data,
|
|
- &get_data_rock);
|
|
+ &get_data_rock, options);
|
|
} else {
|
|
/* No preauth supplied, so can't query the plug-ins. */
|
|
ret = KRB5KRB_ERR_GENERIC;
|
|
@@ -1214,7 +1214,7 @@ krb5_get_init_creds(krb5_context context
|
|
local_as_reply->padata, &kdc_padata,
|
|
&salt, &s2kparams, &etype, &as_key, prompter,
|
|
prompter_data, gak_fct, gak_data,
|
|
- &get_data_rock)))
|
|
+ &get_data_rock, options)))
|
|
goto cleanup;
|
|
|
|
/* XXX For 1.1.1 and prior KDC's, when SAM is used w/ USE_SAD_AS_KEY,
|
|
Index: src/lib/krb5/krb/preauth2.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/preauth2.c.orig
|
|
+++ src/lib/krb5/krb/preauth2.c
|
|
@@ -163,6 +163,10 @@ krb5_init_preauth_context(krb5_context k
|
|
context->modules[k].use_count = 0;
|
|
context->modules[k].client_process = table->process;
|
|
context->modules[k].client_tryagain = table->tryagain;
|
|
+ if (j == 0)
|
|
+ context->modules[k].client_supply_gic_opts = table->gic_opts;
|
|
+ else
|
|
+ context->modules[k].client_supply_gic_opts = NULL;
|
|
context->modules[k].request_context = NULL;
|
|
/*
|
|
* Only call request_init and request_fini once per plugin.
|
|
@@ -211,6 +215,52 @@ krb5_clear_preauth_context_use_counts(kr
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * Give all the preauth plugins a look at the preauth option which
|
|
+ * has just been set
|
|
+ */
|
|
+krb5_error_code
|
|
+krb5_preauth_supply_preauth_data(krb5_context context,
|
|
+ krb5_gic_opt_ext *opte,
|
|
+ const char *attr,
|
|
+ const char *value)
|
|
+{
|
|
+ krb5_error_code retval;
|
|
+ int i;
|
|
+ void *pctx;
|
|
+ const char *emsg = NULL;
|
|
+
|
|
+ if (context->preauth_context == NULL)
|
|
+ krb5_init_preauth_context(context);
|
|
+ if (context->preauth_context == NULL) {
|
|
+ retval = EINVAL;
|
|
+ krb5int_set_error(&context->err, retval,
|
|
+ "krb5_preauth_supply_preauth_data: "
|
|
+ "Unable to initialize preauth context");
|
|
+ return retval;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Go down the list of preauth modules, and supply them with the
|
|
+ * attribute/value pair.
|
|
+ */
|
|
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
|
|
+ if (context->preauth_context->modules[i].client_supply_gic_opts == NULL)
|
|
+ continue;
|
|
+ pctx = context->preauth_context->modules[i].plugin_context;
|
|
+ retval = (*context->preauth_context->modules[i].client_supply_gic_opts)
|
|
+ (context, pctx,
|
|
+ (krb5_get_init_creds_opt *)opte, attr, value);
|
|
+ if (retval) {
|
|
+ emsg = krb5_get_error_message(context, retval);
|
|
+ krb5int_set_error(&context->err, retval, "Preauth plugin %s: %s",
|
|
+ context->preauth_context->modules[i].name, emsg);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return retval;
|
|
+}
|
|
+
|
|
/* Free the per-krb5_context preauth_context. This means clearing any
|
|
* plugin-specific context which may have been created, and then
|
|
* freeing the context itself. */
|
|
@@ -405,7 +455,7 @@ client_data_proc(krb5_context kcontext,
|
|
* involved things. */
|
|
void KRB5_CALLCONV
|
|
krb5_preauth_prepare_request(krb5_context kcontext,
|
|
- krb5_get_init_creds_opt *options,
|
|
+ krb5_gic_opt_ext *opte,
|
|
krb5_kdc_req *request)
|
|
{
|
|
int i, j;
|
|
@@ -415,7 +465,7 @@ krb5_preauth_prepare_request(krb5_contex
|
|
}
|
|
/* Add the module-specific enctype list to the request, but only if
|
|
* it's something we can safely modify. */
|
|
- if (!(options && (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST))) {
|
|
+ if (!(opte && (opte->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST))) {
|
|
for (i = 0; i < kcontext->preauth_context->n_modules; i++) {
|
|
if (kcontext->preauth_context->modules[i].enctypes == NULL)
|
|
continue;
|
|
@@ -448,7 +498,8 @@ krb5_run_preauth_plugins(krb5_context kc
|
|
krb5_pa_data ***out_pa_list,
|
|
int *out_pa_list_size,
|
|
int *module_ret,
|
|
- int *module_flags)
|
|
+ int *module_flags,
|
|
+ krb5_gic_opt_ext *opte)
|
|
{
|
|
int i;
|
|
krb5_pa_data *out_pa_data;
|
|
@@ -487,6 +538,7 @@ krb5_run_preauth_plugins(krb5_context kc
|
|
ret = module->client_process(kcontext,
|
|
module->plugin_context,
|
|
*module->request_context_pp,
|
|
+ (krb5_get_init_creds_opt *)opte,
|
|
client_data_proc,
|
|
get_data_rock,
|
|
request,
|
|
@@ -1299,7 +1351,8 @@ krb5_do_preauth_tryagain(krb5_context kc
|
|
krb5_keyblock *as_key,
|
|
krb5_prompter_fct prompter, void *prompter_data,
|
|
krb5_gic_get_as_key_fct gak_fct, void *gak_data,
|
|
- krb5_preauth_client_rock *get_data_rock)
|
|
+ krb5_preauth_client_rock *get_data_rock,
|
|
+ krb5_gic_opt_ext *opte)
|
|
{
|
|
krb5_error_code ret;
|
|
krb5_pa_data *out_padata;
|
|
@@ -1330,6 +1383,7 @@ krb5_do_preauth_tryagain(krb5_context kc
|
|
if ((*module->client_tryagain)(kcontext,
|
|
module->plugin_context,
|
|
*module->request_context_pp,
|
|
+ (krb5_get_init_creds_opt *)opte,
|
|
client_data_proc,
|
|
get_data_rock,
|
|
request,
|
|
@@ -1362,7 +1416,8 @@ krb5_do_preauth(krb5_context context,
|
|
krb5_keyblock *as_key,
|
|
krb5_prompter_fct prompter, void *prompter_data,
|
|
krb5_gic_get_as_key_fct gak_fct, void *gak_data,
|
|
- krb5_preauth_client_rock *get_data_rock)
|
|
+ krb5_preauth_client_rock *get_data_rock,
|
|
+ krb5_gic_opt_ext *opte)
|
|
{
|
|
int h, i, j, out_pa_list_size;
|
|
int seen_etype_info2 = 0;
|
|
@@ -1555,7 +1610,8 @@ krb5_do_preauth(krb5_context context,
|
|
&out_pa_list,
|
|
&out_pa_list_size,
|
|
&module_ret,
|
|
- &module_flags);
|
|
+ &module_flags,
|
|
+ opte);
|
|
if (ret == 0) {
|
|
if (module_ret == 0) {
|
|
if (paorder[h] == PA_REAL) {
|
|
Index: src/lib/krb5/krb/gic_pwd.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/gic_pwd.c.orig
|
|
+++ src/lib/krb5/krb/gic_pwd.c
|
|
@@ -85,18 +85,28 @@ krb5_get_as_key_password(
|
|
}
|
|
|
|
krb5_error_code KRB5_CALLCONV
|
|
-krb5_get_init_creds_password(krb5_context context, krb5_creds *creds, krb5_principal client, char *password, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, char *in_tkt_service, krb5_get_init_creds_opt *options)
|
|
+krb5_get_init_creds_password(krb5_context context,
|
|
+ krb5_creds *creds,
|
|
+ krb5_principal client,
|
|
+ char *password,
|
|
+ krb5_prompter_fct prompter,
|
|
+ void *data,
|
|
+ krb5_deltat start_time,
|
|
+ char *in_tkt_service,
|
|
+ krb5_get_init_creds_opt *options)
|
|
{
|
|
krb5_error_code ret, ret2;
|
|
int use_master;
|
|
krb5_kdc_rep *as_reply;
|
|
int tries;
|
|
krb5_creds chpw_creds;
|
|
- krb5_get_init_creds_opt chpw_opts;
|
|
+ krb5_get_init_creds_opt *chpw_opts = NULL;
|
|
krb5_data pw0, pw1;
|
|
char banner[1024], pw0array[1024], pw1array[1024];
|
|
krb5_prompt prompt[2];
|
|
krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])];
|
|
+ krb5_gic_opt_ext *opte = NULL;
|
|
+ krb5_gic_opt_ext *chpw_opte = NULL;
|
|
|
|
use_master = 0;
|
|
as_reply = NULL;
|
|
@@ -119,10 +129,15 @@ krb5_get_init_creds_password(krb5_contex
|
|
pw1.data[0] = '\0';
|
|
pw1.length = sizeof(pw1array);
|
|
|
|
+ ret = krb5int_gic_opt_to_opte(context, options, &opte, 1,
|
|
+ "krb5_get_init_creds_password");
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+
|
|
/* first try: get the requested tkt from any kdc */
|
|
|
|
ret = krb5_get_init_creds(context, creds, client, prompter, data,
|
|
- start_time, in_tkt_service, options,
|
|
+ start_time, in_tkt_service, opte,
|
|
krb5_get_as_key_password, (void *) &pw0,
|
|
&use_master, &as_reply);
|
|
|
|
@@ -151,7 +166,7 @@ krb5_get_init_creds_password(krb5_contex
|
|
as_reply = NULL;
|
|
}
|
|
ret2 = krb5_get_init_creds(context, creds, client, prompter, data,
|
|
- start_time, in_tkt_service, options,
|
|
+ start_time, in_tkt_service, opte,
|
|
krb5_get_as_key_password, (void *) &pw0,
|
|
&use_master, &as_reply);
|
|
|
|
@@ -197,15 +212,21 @@ krb5_get_init_creds_password(krb5_contex
|
|
|
|
/* use a minimal set of options */
|
|
|
|
- krb5_get_init_creds_opt_init(&chpw_opts);
|
|
- krb5_get_init_creds_opt_set_tkt_life(&chpw_opts, 5*60);
|
|
- krb5_get_init_creds_opt_set_renew_life(&chpw_opts, 0);
|
|
- krb5_get_init_creds_opt_set_forwardable(&chpw_opts, 0);
|
|
- krb5_get_init_creds_opt_set_proxiable(&chpw_opts, 0);
|
|
+ ret = krb5_get_init_creds_opt_alloc(context, &chpw_opts);
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+ krb5_get_init_creds_opt_set_tkt_life(chpw_opts, 5*60);
|
|
+ krb5_get_init_creds_opt_set_renew_life(chpw_opts, 0);
|
|
+ krb5_get_init_creds_opt_set_forwardable(chpw_opts, 0);
|
|
+ krb5_get_init_creds_opt_set_proxiable(chpw_opts, 0);
|
|
+ ret = krb5int_gic_opt_to_opte(context, chpw_opts, &chpw_opte, 0,
|
|
+ "krb5_get_init_creds_password (changing password)");
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
|
|
if ((ret = krb5_get_init_creds(context, &chpw_creds, client,
|
|
prompter, data,
|
|
- start_time, "kadmin/changepw", &chpw_opts,
|
|
+ start_time, "kadmin/changepw", chpw_opte,
|
|
krb5_get_as_key_password, (void *) &pw0,
|
|
&use_master, NULL)))
|
|
goto cleanup;
|
|
@@ -293,7 +314,7 @@ krb5_get_init_creds_password(krb5_contex
|
|
is final. */
|
|
|
|
ret = krb5_get_init_creds(context, creds, client, prompter, data,
|
|
- start_time, in_tkt_service, options,
|
|
+ start_time, in_tkt_service, opte,
|
|
krb5_get_as_key_password, (void *) &pw0,
|
|
&use_master, &as_reply);
|
|
|
|
@@ -373,6 +394,10 @@ cleanup:
|
|
}
|
|
}
|
|
|
|
+ if (chpw_opts)
|
|
+ krb5_get_init_creds_opt_free(context, chpw_opts);
|
|
+ if (opte && krb5_gic_opt_is_shadowed(opte))
|
|
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
|
|
memset(pw0array, 0, sizeof(pw0array));
|
|
memset(pw1array, 0, sizeof(pw1array));
|
|
krb5_free_cred_contents(context, &chpw_creds);
|
|
@@ -381,15 +406,20 @@ cleanup:
|
|
|
|
return(ret);
|
|
}
|
|
-void krb5int_populate_gic_opt (
|
|
- krb5_context context, krb5_get_init_creds_opt *opt,
|
|
+krb5_error_code krb5int_populate_gic_opt (
|
|
+ krb5_context context, krb5_gic_opt_ext **opte,
|
|
krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
|
|
krb5_preauthtype *pre_auth_types, krb5_creds *creds)
|
|
{
|
|
int i;
|
|
krb5_int32 starttime;
|
|
+ krb5_get_init_creds_opt *opt;
|
|
+ krb5_error_code retval;
|
|
+
|
|
+ retval = krb5_get_init_creds_opt_alloc(context, &opt);
|
|
+ if (retval)
|
|
+ return(retval);
|
|
|
|
- krb5_get_init_creds_opt_init(opt);
|
|
if (addrs)
|
|
krb5_get_init_creds_opt_set_address_list(opt, (krb5_address **) addrs);
|
|
if (ktypes) {
|
|
@@ -413,6 +443,8 @@ void krb5int_populate_gic_opt (
|
|
if (creds->times.starttime) starttime = creds->times.starttime;
|
|
krb5_get_init_creds_opt_set_tkt_life(opt, creds->times.endtime - starttime);
|
|
}
|
|
+ return krb5int_gic_opt_to_opte(context, opt, opte, 0,
|
|
+ "krb5int_populate_gic_opt");
|
|
}
|
|
|
|
/*
|
|
@@ -445,10 +477,10 @@ krb5_get_in_tkt_with_password(krb5_conte
|
|
krb5_error_code retval;
|
|
krb5_data pw0;
|
|
char pw0array[1024];
|
|
- krb5_get_init_creds_opt opt;
|
|
char * server;
|
|
krb5_principal server_princ, client_princ;
|
|
int use_master = 0;
|
|
+ krb5_gic_opt_ext *opte = NULL;
|
|
|
|
pw0array[0] = '\0';
|
|
pw0.data = pw0array;
|
|
@@ -462,21 +494,26 @@ krb5_get_in_tkt_with_password(krb5_conte
|
|
} else {
|
|
pw0.length = sizeof(pw0array);
|
|
}
|
|
- krb5int_populate_gic_opt(context, &opt,
|
|
- options, addrs, ktypes,
|
|
- pre_auth_types, creds);
|
|
- retval = krb5_unparse_name( context, creds->server, &server);
|
|
+ retval = krb5int_populate_gic_opt(context, &opte,
|
|
+ options, addrs, ktypes,
|
|
+ pre_auth_types, creds);
|
|
if (retval)
|
|
return (retval);
|
|
+ retval = krb5_unparse_name( context, creds->server, &server);
|
|
+ if (retval) {
|
|
+ return (retval);
|
|
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
|
|
+ }
|
|
server_princ = creds->server;
|
|
client_princ = creds->client;
|
|
retval = krb5_get_init_creds (context,
|
|
creds, creds->client,
|
|
krb5_prompter_posix, NULL,
|
|
- 0, server, &opt,
|
|
+ 0, server, opte,
|
|
krb5_get_as_key_password, &pw0,
|
|
&use_master, ret_as_reply);
|
|
krb5_free_unparsed_name( context, server);
|
|
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
|
|
if (retval) {
|
|
return (retval);
|
|
}
|
|
Index: src/lib/krb5_32.def
|
|
===================================================================
|
|
--- src/lib/krb5_32.def.orig
|
|
+++ src/lib/krb5_32.def
|
|
@@ -155,7 +155,12 @@ krb5_c_string_to_key_with_params
|
|
krb5_get_in_tkt_with_password ; DEPRECATED
|
|
krb5_get_in_tkt_with_skey ; DEPRECATED
|
|
krb5_get_init_creds_keytab
|
|
+ krb5_get_init_creds_opt_alloc
|
|
+ krb5_get_init_creds_opt_free
|
|
+ krb5_get_init_creds_opt_free_pa
|
|
+ krb5_get_init_creds_opt_get_pa
|
|
krb5_get_init_creds_opt_init
|
|
+ krb5_get_init_creds_opt_set_pa
|
|
krb5_get_init_creds_opt_set_address_list
|
|
krb5_get_init_creds_opt_set_etype_list
|
|
krb5_get_init_creds_opt_set_forwardable
|
|
@@ -219,6 +224,7 @@ krb5_c_string_to_key_with_params
|
|
krb5_recvauth_version
|
|
krb5_salttype_to_string
|
|
krb5_sendauth
|
|
+ krb5_server_decrypt_ticket_keytab
|
|
krb5_set_default_realm
|
|
krb5_set_default_tgs_enctypes
|
|
krb5_set_password
|
|
Index: src/krb524/Makefile.in
|
|
===================================================================
|
|
--- src/krb524/Makefile.in.orig
|
|
+++ src/krb524/Makefile.in
|
|
@@ -33,11 +33,11 @@ PROG_RPATH=$(KRB5_LIBDIR)
|
|
CFLAGS += -fPIE
|
|
LDFLAGS += -pie
|
|
|
|
-##WIN32##!ifdef USE_ALTERNATE_KRB4_INCLUDES
|
|
+##WIN32##!if ("$(CPU)" == "i386") && defined(USE_ALTERNATE_KRB4_INCLUDES)
|
|
##WIN32##KRB4_INCLUDES=-I$(USE_ALTERNATE_KRB4_INCLUDES)
|
|
##WIN32##!endif
|
|
|
|
-##WIN32##!ifdef USE_ALTERNATE_KRB4_LIB
|
|
+##WIN32##!if ("$(CPU)" == "i386") && defined(USE_ALTERNATE_KRB4_LIB)
|
|
##WIN32##K4LIB=$(USE_ALTERNATE_KRB4_LIB)
|
|
##WIN32##!endif
|
|
|
|
Index: src/util/def-check.pl
|
|
===================================================================
|
|
--- src/util/def-check.pl.orig
|
|
+++ src/util/def-check.pl
|
|
@@ -165,7 +165,7 @@ while (! $h->eof()) {
|
|
goto Hadcallc;
|
|
}
|
|
# deal with no CALLCONV indicator
|
|
- s/^.* (\w+) *$/$1/;
|
|
+ s/^.* \**(\w+) *$/$1/;
|
|
die "Invalid function name: '$_'" if (!/^[A-Za-z0-9_]+$/);
|
|
push @convD, $_;
|
|
push @vararg, $_ if $vararg;
|
|
Index: src/util/et/com_err.c
|
|
===================================================================
|
|
--- src/util/et/com_err.c.orig
|
|
+++ src/util/et/com_err.c
|
|
@@ -33,6 +33,16 @@
|
|
static /*@null@*/ et_old_error_hook_func com_err_hook = 0;
|
|
k5_mutex_t com_err_hook_lock = K5_MUTEX_PARTIAL_INITIALIZER;
|
|
|
|
+#if defined(_WIN32)
|
|
+BOOL isGuiApp() {
|
|
+ DWORD mypid;
|
|
+ HANDLE myprocess;
|
|
+ mypid = GetCurrentProcessId();
|
|
+ myprocess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, mypid);
|
|
+ return GetGuiResources(myprocess, 1) > 0;
|
|
+ }
|
|
+#endif
|
|
+
|
|
static void default_com_err_proc (const char *whoami, errcode_t code,
|
|
const char *fmt, va_list ap)
|
|
{
|
|
@@ -55,14 +65,12 @@ static void default_com_err_proc (const
|
|
vsprintf (errbuf + strlen (errbuf), fmt, ap);
|
|
errbuf[sizeof(errbuf) - 1] = '\0';
|
|
|
|
-#ifdef _WIN32
|
|
- if (_isatty(_fileno(stderr))) {
|
|
+ if (_isatty(_fileno(stderr)) || !isGuiApp()) {
|
|
fputs(errbuf, stderr);
|
|
fputc('\r', stderr);
|
|
fputc('\n', stderr);
|
|
fflush(stderr);
|
|
} else
|
|
-#endif /* _WIN32 */
|
|
MessageBox ((HWND)NULL, errbuf, "Kerberos", MB_ICONEXCLAMATION);
|
|
|
|
#else /* !_WIN32 */
|
|
Index: src/util/support/plugins.c
|
|
===================================================================
|
|
--- src/util/support/plugins.c.orig
|
|
+++ src/util/support/plugins.c
|
|
@@ -455,17 +455,9 @@ krb5int_open_plugin_dirs (const char * c
|
|
} else {
|
|
/* load all plugins in each directory */
|
|
#ifndef _WIN32
|
|
- DIR *dir = NULL;
|
|
+ DIR *dir = opendir (dirnames[i]);
|
|
|
|
- if (!err) {
|
|
- dir = opendir(dirnames[i]);
|
|
- if (dir == NULL) {
|
|
- err = errno;
|
|
- Tprintf ("-> error %d/%s\n", err, strerror (err));
|
|
- }
|
|
- }
|
|
-
|
|
- while (!err) {
|
|
+ while (dir != NULL && !err) {
|
|
struct dirent *d = NULL;
|
|
char *filepath = NULL;
|
|
struct plugin_file_handle *handle = NULL;
|
|
Index: src/util/support/fake-addrinfo.c
|
|
===================================================================
|
|
--- src/util/support/fake-addrinfo.c.orig
|
|
+++ src/util/support/fake-addrinfo.c
|
|
@@ -545,6 +545,7 @@ static inline int fai_add_entry (struct
|
|
sin4 = malloc (sizeof (struct sockaddr_in));
|
|
if (sin4 == 0)
|
|
return EAI_MEMORY;
|
|
+ memset (sin4, 0, sizeof (struct sockaddr_in)); /* for sin_zero */
|
|
n->ai_addr = (struct sockaddr *) sin4;
|
|
sin4->sin_family = AF_INET;
|
|
sin4->sin_addr = *(struct in_addr *)addr;
|
|
@@ -559,6 +560,7 @@ static inline int fai_add_entry (struct
|
|
sin6 = malloc (sizeof (struct sockaddr_in6));
|
|
if (sin6 == 0)
|
|
return EAI_MEMORY;
|
|
+ memset (sin6, 0, sizeof (struct sockaddr_in6)); /* for sin_zero */
|
|
n->ai_addr = (struct sockaddr *) sin6;
|
|
sin6->sin6_family = AF_INET6;
|
|
sin6->sin6_addr = *(struct in6_addr *)addr;
|