new 1.10 krb5_init_context_profile
Chris Hecker
checker at d6.com
Thu Feb 16 00:55:56 EST 2012
greg:
> In principle I'd be okay with making libprofile support memory-only
> profiles (which could then be copied without having to reference the
> filesystem), probably via passing a null files argument to
> profile_init(). In practice, I think the implementation might get a
> little tangled.
It wasn't too bad, in my experience. Patch is below against 1.9.x, and
most of it is passing the profile around, which is now handled by the
new api. I added a flag, and then checked it in a couple places.
To use the new api with this, we'd either need to add a deep copy that
ignores the file part like you say, or just not copy it with a flag,
letting the user pass it in (which seems fine, and is more efficient,
since the usual use-case is going to be to make one and then delete it
right after it's passed in, not sure what the advantage of the copy is.
I have a patch for adding that NO_COPY flag and porting this against
1.10 too, if you want.
I've tested this in my simple use cases pretty extensively, but haven't
tested it against other use cases. To make this real, you'd change the
way profile_init_empty worked a bit, and rename it, etc.
The kinit.c change is just the test code showing how to use it, it
wouldn't be part of the patch.
I only do this on Win32, where I staticly link krb5, so I don't know if
the libprofile version on linux would have to have other changes to make
the prof functions available. I have to include profile.h in kinit.c as
well, obviously.
Chris
=== modified file 'src/clients/kinit/kinit.c'
--- src/clients/kinit/kinit.c 2011-07-01 06:18:12 +0000
+++ src/clients/kinit/kinit.c 2011-07-16 09:55:22 +0000
@@ -451,7 +451,28 @@
krb5_error_code code = 0;
int flags = opts->enterprise ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0;
- code = krb5_init_context(&k5->ctx);
+ profile_t profile = 0;
+ char* profile_names[4] = { 0, 0, 0, 0 };
+ int retval;
+
+ retval = profile_init_empty(&profile);
+ if (retval) {
+ com_err(progname, retval, "while initializing profile");
+ exit(1);
+ }
+ profile_names[0] = "libdefaults"; profile_names[1] =
"default_realm"; profile_names[2] = 0;
+ profile_add_relation(profile,profile_names,"EXAMPLE.COM");
+ profile_names[0] = "realms"; profile_names[1] = "EXAMPLE.COM";
profile_names[2] = "kdc";
+ profile_add_relation(profile,profile_names,"kerberos.example.com:88");
+ profile_names[2] = "default_domain";
+ profile_add_relation(profile,profile_names,"example.com");
+ profile_names[0] = "domain_realm"; profile_names[1] =
".example.com"; profile_names[2] = 0;
+ profile_add_relation(profile,profile_names,"EXAMPLE.COM");
+ profile_names[1] = "example.com";
+ profile_add_relation(profile,profile_names,"EXAMPLE.COM");
+
+
+ code = krb5_init_context_profile(&k5->ctx,profile);
if (code) {
com_err(progname, code, "while initializing Kerberos 5 library");
return 0;
=== modified file 'src/include/k5-int.h'
--- src/include/k5-int.h 2011-04-09 08:50:00 +0000
+++ src/include/k5-int.h 2011-07-16 09:55:22 +0000
@@ -605,7 +605,7 @@
krb5_error_code krb5int_init_context_kdc(krb5_context *);
-krb5_error_code krb5_os_init_context(krb5_context, krb5_boolean);
+krb5_error_code krb5_os_init_context(krb5_context, krb5_boolean,
profile_t);
void krb5_os_free_context(krb5_context);
=== modified file 'src/lib/krb5/krb/init_ctx.c'
--- src/lib/krb5/krb/init_ctx.c 2011-04-09 17:33:43 +0000
+++ src/lib/krb5/krb/init_ctx.c 2011-07-16 09:55:22 +0000
@@ -79,13 +79,20 @@
extern void krb5_win_ccdll_load(krb5_context context);
#endif
-static krb5_error_code init_common (krb5_context *, krb5_boolean,
krb5_boolean);
+static krb5_error_code init_common (krb5_context *, krb5_boolean,
krb5_boolean, profile_t);
krb5_error_code KRB5_CALLCONV
krb5_init_context(krb5_context *context)
{
- return init_common (context, FALSE, FALSE);
+ return init_common (context, FALSE, FALSE, 0);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_init_context_profile(krb5_context *context, profile_t profile)
+{
+
+ return init_common (context, FALSE, FALSE, profile);
}
krb5_error_code KRB5_CALLCONV
@@ -94,17 +101,17 @@
/* This is to make gcc -Wall happy */
if(0) krb5_brand[0] = krb5_brand[0];
- return init_common (context, TRUE, FALSE);
+ return init_common (context, TRUE, FALSE, 0);
}
krb5_error_code
krb5int_init_context_kdc(krb5_context *context)
{
- return init_common (context, FALSE, TRUE);
+ return init_common (context, FALSE, TRUE, 0);
}
static krb5_error_code
-init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc)
+init_common (krb5_context *context, krb5_boolean secure, krb5_boolean
kdc, profile_t profile)
{
krb5_context ctx = 0;
krb5_error_code retval;
@@ -163,7 +170,7 @@
ctx->profile_secure = secure;
- if ((retval = krb5_os_init_context(ctx, kdc)))
+ if ((retval = krb5_os_init_context(ctx, kdc, profile)))
goto cleanup;
retval = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS,
=== modified file 'src/lib/krb5/os/init_os_ctx.c'
--- src/lib/krb5/os/init_os_ctx.c 2011-04-09 17:33:43 +0000
+++ src/lib/krb5/os/init_os_ctx.c 2011-07-16 09:55:22 +0000
@@ -379,7 +379,7 @@
}
krb5_error_code
-krb5_os_init_context(krb5_context ctx, krb5_boolean kdc)
+krb5_os_init_context(krb5_context ctx, krb5_boolean kdc, profile_t profile)
{
krb5_os_context os_ctx;
krb5_error_code retval = 0;
@@ -400,7 +400,12 @@
PLUGIN_DIR_INIT(&ctx->preauth_plugins);
ctx->preauth_context = NULL;
- retval = os_init_paths(ctx, kdc);
+ if(!profile) {
+ retval = os_init_paths(ctx, kdc);
+ } else {
+ ctx->profile = profile;
+ }
+
/*
* If there's an error in the profile, return an error. Just
* ignoring the error is a Bad Thing (tm).
=== modified file 'src/util/profile/prof_file.c'
--- src/util/profile/prof_file.c 2011-04-09 08:50:00 +0000
+++ src/util/profile/prof_file.c 2011-07-16 09:55:22 +0000
@@ -313,6 +313,10 @@
#endif
FILE *f;
+ if(data->flags & PROFILE_FILE_NOUPDATE) {
+ return 0;
+ }
+
#ifdef HAVE_STAT
now = time(0);
if (now == data->last_stat && data->root != NULL) {
@@ -497,6 +501,10 @@
if (!data || data->magic != PROF_MAGIC_FILE_DATA)
return PROF_MAGIC_FILE_DATA;
+ if(data->flags & PROFILE_FILE_NOUPDATE) {
+ return 0;
+ }
+
retval = k5_mutex_lock(&data->lock);
if (retval)
return retval;
=== modified file 'src/util/profile/prof_init.c'
--- src/util/profile/prof_init.c 2011-04-09 08:50:00 +0000
+++ src/util/profile/prof_init.c 2011-07-16 09:55:22 +0000
@@ -21,6 +21,40 @@
#endif
typedef int32_t prof_int32;
+long KRB5_CALLCONV profile_init_empty(profile_t *ret_profile)
+{
+ profile_t profile;
+ errcode_t retval = 0, access_retval = 0;
+ prf_file_t prf;
+ prf_data_t data;
+ struct profile_node* root;
+
+ profile = malloc(sizeof(struct _profile_t));
+ if (!profile)
+ return ENOMEM;
+ memset(profile, 0, sizeof(struct _profile_t));
+ profile->magic = PROF_MAGIC_PROFILE;
+
+ prf = malloc(sizeof(struct _prf_file_t));
+ if (!prf)
+ return ENOMEM;
+ memset(prf, 0, sizeof(struct _prf_file_t));
+ prf->magic = PROF_MAGIC_FILE;
+ profile->first_file = prf;
+
+ data = profile_make_prf_data("dynamic");
+ prf->data = data;
+ data->flags |= PROFILE_FILE_DIRTY | PROFILE_FILE_NOUPDATE;
+ k5_mutex_init(&data->lock);
+
+ retval = profile_create_node("(root)", 0, &root);
+ data->root = root;
+
+ *ret_profile = profile;
+ return 0;
+}
+
+
errcode_t KRB5_CALLCONV
profile_init(const_profile_filespec_t *files, profile_t *ret_profile)
{
=== modified file 'src/util/profile/prof_int.h'
--- src/util/profile/prof_int.h 2011-04-09 08:50:00 +0000
+++ src/util/profile/prof_int.h 2011-07-16 09:55:22 +0000
@@ -78,6 +78,7 @@
#define PROFILE_FILE_DEPRECATED_RW 0x0001
#define PROFILE_FILE_DIRTY 0x0002
#define PROFILE_FILE_SHARED 0x0004
+#define PROFILE_FILE_NOUPDATE 0x0008
/*
* This structure defines the high-level, user visible profile_t
More information about the Kerberos
mailing list