* length. Returns a Kerberos error code.
*/
krb5_error_code
-pwupdate_ad_change(kadm5_hook_modinfo *config, krb5_context ctx,
- krb5_principal principal, const char *password,
- int pwlen UNUSED)
+sync_ad_chpass(kadm5_hook_modinfo *config, krb5_context ctx,
+ krb5_principal principal, const char *password,
+ int pwlen UNUSED)
{
krb5_error_code code;
char *target = NULL;
* length.
*/
krb5_error_code
-pwupdate_ad_status(kadm5_hook_modinfo *config, krb5_context ctx,
- krb5_principal principal, int enabled)
+sync_ad_status(kadm5_hook_modinfo *config, krb5_context ctx,
+ krb5_principal principal, int enabled)
{
krb5_ccache ccache;
krb5_principal ad_principal = NULL;
* This function returns failure only if it could not allocate memory.
*/
krb5_error_code
-pwupdate_init(krb5_context ctx, kadm5_hook_modinfo **result)
+sync_init(krb5_context ctx, kadm5_hook_modinfo **result)
{
kadm5_hook_modinfo *config;
* since we don't store any other local state.
*/
void
-pwupdate_close(kadm5_hook_modinfo *config)
+sync_close(kadm5_hook_modinfo *config)
{
free(config->ad_keytab);
free(config->ad_principal);
* Otherwise, if the principal is multi-part, check the instance.
*/
if (pwchange && ncomp == 1 && config->ad_base_instance != NULL) {
- okay = !pwupdate_instance_exists(config, ctx, principal,
- config->ad_base_instance);
+ okay = !sync_instance_exists(config, ctx, principal,
+ config->ad_base_instance);
if (!okay) {
code = krb5_unparse_name(ctx, principal, &display);
if (code != 0)
* Currently, we can't do anything in that case, so just skip it.
*/
krb5_error_code
-pwupdate_precommit_password(kadm5_hook_modinfo *config, krb5_context ctx,
- krb5_principal principal,
- const char *password, int pwlen)
+sync_chpass(kadm5_hook_modinfo *config, krb5_context ctx,
+ krb5_principal principal, const char *password, int pwlen)
{
krb5_error_code code;
const char *message;
return 0;
if (!principal_allowed(config, ctx, principal, 1))
return 0;
- if (pwupdate_queue_conflict(config, ctx, principal, "ad", "password"))
+ if (sync_queue_conflict(config, ctx, principal, "ad", "password"))
goto queue;
if (config->ad_queue_only)
goto queue;
- code = pwupdate_ad_change(config, ctx, principal, password, pwlen);
+ code = sync_ad_chpass(config, ctx, principal, password, pwlen);
if (code != 0) {
message = krb5_get_error_message(ctx, code);
syslog(LOG_INFO, "krb5-sync: AD password change failed, queuing: %s",
return 0;
queue:
- return pwupdate_queue_write(config, ctx, principal, "ad", "password",
- password);
-}
-
-
-/*
- * Actions to take after the password is changed in the local database.
- * Currently, there are none.
- */
-krb5_error_code
-pwupdate_postcommit_password(kadm5_hook_modinfo *config UNUSED,
- krb5_context ctx UNUSED,
- krb5_principal principal UNUSED,
- const char *password UNUSED, int pwlen UNUSED)
-{
- return 0;
+ return sync_queue_write(config, ctx, principal, "ad", "password",
+ password);
}
* queue it for later processing.
*/
krb5_error_code
-pwupdate_postcommit_status(kadm5_hook_modinfo *config, krb5_context ctx,
- krb5_principal principal, int enabled)
+sync_status(kadm5_hook_modinfo *config, krb5_context ctx,
+ krb5_principal principal, int enabled)
{
krb5_error_code code;
return 0;
if (!principal_allowed(config, ctx, principal, 0))
return 0;
- if (pwupdate_queue_conflict(config, ctx, principal, "ad", "enable"))
+ if (sync_queue_conflict(config, ctx, principal, "ad", "enable"))
goto queue;
if (config->ad_queue_only)
goto queue;
- code = pwupdate_ad_status(config, ctx, principal, enabled);
+ code = sync_ad_status(config, ctx, principal, enabled);
if (code != 0)
goto queue;
return 0;
queue:
- return pwupdate_queue_write(config, ctx, principal, "ad",
- enabled ? "enable" : "disable", NULL);
+ return sync_queue_write(config, ctx, principal, "ad",
+ enabled ? "enable" : "disable", NULL);
}
static krb5_error_code
init(krb5_context ctx, void **data)
{
- return pwupdate_init(ctx, (kadm5_hook_modinfo **) data);
+ return sync_init(ctx, (kadm5_hook_modinfo **) data);
}
static void
fini(krb5_context ctx UNUSED, void *data)
{
- pwupdate_close(data);
+ sync_close(data);
}
/* Dispatch to the appropriate function. */
if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
- code = pwupdate_precommit_password(data, ctx, princ, password, length);
- else if (stage == KADM5_HOOK_STAGE_POSTCOMMIT)
- code = pwupdate_postcommit_password(data, ctx, princ, password,
- length);
+ code = sync_chpass(data, ctx, princ, password, length);
return code;
}
if (mask & KADM5_ATTRIBUTES && stage == KADM5_HOOK_STAGE_POSTCOMMIT) {
enabled = !(entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX);
- return pwupdate_postcommit_status(data, ctx, entry->principal,
- enabled);
+ return sync_status(data, ctx, entry->principal, enabled);
}
return 0;
}
* or on any other error.
*/
int
-pwupdate_instance_exists(kadm5_hook_modinfo *config UNUSED,
- krb5_context ctx, krb5_principal base,
- const char *instance)
+sync_instance_exists(kadm5_hook_modinfo *config UNUSED, krb5_context ctx,
+ krb5_principal base, const char *instance)
{
krb5_principal princ = NULL;
krb5_error_code code;
/* Default to a hidden visibility for all internal functions. */
#pragma GCC visibility push(hidden)
-/* General public API. */
-krb5_error_code pwupdate_init(krb5_context, kadm5_hook_modinfo **);
-void pwupdate_close(kadm5_hook_modinfo *);
-krb5_error_code pwupdate_precommit_password(kadm5_hook_modinfo *,
- krb5_context, krb5_principal,
- const char *password,
- int pwlen);
-krb5_error_code pwupdate_postcommit_password(kadm5_hook_modinfo *,
- krb5_context, krb5_principal,
- const char *password,
- int pwlen);
-krb5_error_code pwupdate_postcommit_status(kadm5_hook_modinfo *,
- krb5_context, krb5_principal,
- int enabled);
-
-/* Password changing. */
-krb5_error_code pwupdate_ad_change(kadm5_hook_modinfo *, krb5_context,
- krb5_principal, const char *password,
- int pwlen);
-
-/* Account status update. */
-krb5_error_code pwupdate_ad_status(kadm5_hook_modinfo *, krb5_context,
- krb5_principal, int enabled);
-
-/* Instance lookups. */
-int pwupdate_instance_exists(kadm5_hook_modinfo *, krb5_context,
- krb5_principal, const char *instance);
-
-/* Queuing. */
-int pwupdate_queue_conflict(kadm5_hook_modinfo *, krb5_context,
- krb5_principal, const char *domain,
- const char *operation);
-krb5_error_code pwupdate_queue_write(kadm5_hook_modinfo *, krb5_context,
- krb5_principal, const char *domain,
- const char *operation,
- const char *password);
+/* Initialize the plugin and set up configuration. */
+krb5_error_code sync_init(krb5_context, kadm5_hook_modinfo **);
+
+/* Free the internal plugin state. */
+void sync_close(kadm5_hook_modinfo *);
+
+/* Handle a password change. */
+krb5_error_code sync_chpass(kadm5_hook_modinfo *, krb5_context,
+ krb5_principal, const char *password, int pwlen);
+
+/* Handle an account status change. */
+krb5_error_code sync_status(kadm5_hook_modinfo *, krb5_context,
+ krb5_principal, int enabled);
+
+/* Password changing in Active Directory. */
+krb5_error_code sync_ad_chpass(kadm5_hook_modinfo *, krb5_context,
+ krb5_principal, const char *password,
+ int pwlen);
+
+/* Account status update in Active Directory. */
+krb5_error_code sync_ad_status(kadm5_hook_modinfo *, krb5_context,
+ krb5_principal, int enabled);
+
+/*
+ * Returns true if the principal has only one component and two-component
+ * principal with instance added exists in the Kerberos database.
+ */
+int sync_instance_exists(kadm5_hook_modinfo *, krb5_context, krb5_principal,
+ const char *instance);
+
+/* Returns true if there is a queue conflict for this operation. */
+int sync_queue_conflict(kadm5_hook_modinfo *, krb5_context, krb5_principal,
+ const char *domain, const char *operation);
+
+/* Writes an operation to the queue. */
+krb5_error_code sync_queue_write(kadm5_hook_modinfo *, krb5_context,
+ krb5_principal, const char *domain,
+ const char *operation, const char *password);
/*
* Obtain configuration settings from krb5.conf. These are wrappers around
static kadm5_ret_t
init(krb5_context ctx, kadm5_hook_modinfo **data)
{
- return pwupdate_init(ctx, data);
+ return sync_init(ctx, data);
}
static void
fini(krb5_context ctx UNUSED, kadm5_hook_modinfo *data)
{
- pwupdate_close(data);
+ sync_close(data);
}
/* Dispatch to the appropriate function. */
length = strlen(password);
if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
- code = pwupdate_precommit_password(data, ctx, princ, password, length);
- else if (stage == KADM5_HOOK_STAGE_POSTCOMMIT)
- code = pwupdate_postcommit_password(data, ctx, princ, password,
- length);
+ code = sync_chpass(data, ctx, princ, password, length);
return code;
}
if (mask & KADM5_ATTRIBUTES && stage == KADM5_HOOK_STAGE_POSTCOMMIT) {
enabled = !(entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX);
- return pwupdate_postcommit_status(data, ctx, entry->principal,
- enabled);
+ return sync_status(data, ctx, entry->principal, enabled);
}
return 0;
}
* On failure, return -1 (still true but distinguished).
*/
int
-pwupdate_queue_conflict(kadm5_hook_modinfo *config, krb5_context ctx,
- krb5_principal principal, const char *domain,
- const char *operation)
+sync_queue_conflict(kadm5_hook_modinfo *config, krb5_context ctx,
+ krb5_principal principal, const char *domain,
+ const char *operation)
{
int lock = -1;
char *prefix = NULL;
* enable and disable). Returns a Kerberos error code.
*/
krb5_error_code
-pwupdate_queue_write(kadm5_hook_modinfo *config, krb5_context ctx,
- krb5_principal principal, const char *domain,
- const char *operation, const char *password)
+sync_queue_write(kadm5_hook_modinfo *config, krb5_context ctx,
+ krb5_principal principal, const char *domain,
+ const char *operation, const char *password)
{
char *prefix = NULL, *timestamp = NULL, *path = NULL, *user = NULL;
char *p;
plan(24);
/* Test init. */
- is_int(0, pwupdate_init(ctx, &config), "pwupdate_init succeeds");
+ is_int(0, sync_init(ctx, &config), "sync_init succeeds");
ok(config != NULL, "...and config is non-NULL");
/* Create a password change and be sure it's queued. */
- code = pwupdate_precommit_password(config, ctx, princ, "foobar",
- strlen("foobar"));
- is_int(0, code, "pwupdate_precommit_password succeeds");
+ code = sync_chpass(config, ctx, princ, "foobar", strlen("foobar"));
+ is_int(0, code, "sync_chpass succeeds");
queue = NULL;
now = time(NULL);
for (try = now - 1; try <= now; try++) {
free(queue);
/* Test queuing of enable. */
- code = pwupdate_postcommit_status(config, ctx, princ, 1);
- is_int(0, code, "pwupdate_postcommit_status enable succeeds");
+ code = sync_status(config, ctx, princ, 1);
+ is_int(0, code, "sync_status enable succeeds");
queue = NULL;
now = time(NULL);
for (try = now - 1; try <= now; try++) {
ok(unlink(queue) == 0, "Remove queued enable");
/* Test queuing of disable. */
- code = pwupdate_postcommit_status(config, ctx, princ, 0);
- is_int(0, code, "pwupdate_postcommit_status disable succeeds");
+ code = sync_status(config, ctx, princ, 0);
+ is_int(0, code, "sync_status disable succeeds");
queue = NULL;
now = time(NULL);
for (try = now - 1; try <= now; try++) {
ok(rmdir("queue") == 0, "No other files in queue directory");
/* Shut down the plugin. */
- pwupdate_close(config);
+ sync_close(config);
/* Clean up. */
krb5_free_principal(ctx, princ);
if (code != 0)
bail("cannot parse principal: %s", krb5_get_error_message(ctx, code));
- plan(36);
+ plan(35);
/* Test init. */
- is_int(0, pwupdate_init(ctx, &data), "pwupdate_init succeeds");
+ is_int(0, sync_init(ctx, &data), "pwupdate_init succeeds");
ok(data != NULL, "...and data is non-NULL");
/* Block processing for our test user and then test password change. */
if (fd < 0)
sysbail("cannot create fake queue file");
close(fd);
- code = pwupdate_precommit_password(data, ctx, princ, "foobar",
- strlen("foobar"));
+ code = sync_chpass(data, ctx, princ, "foobar", strlen("foobar"));
is_int(0, code, "pwupdate_precommit_password succeeds");
ok(access("queue/.lock", F_OK) == 0, "...lock file now exists");
queue = NULL;
fclose(file);
}
- /* pwupdate_postcommit_password should do nothing, silently. */
- code = pwupdate_postcommit_password(data, ctx, princ, "foobar",
- strlen("foobar"));
- is_int(0, code, "pwupdate_postcommit_password succeeds");
-
/* Clean up password change queue files. */
ok(unlink("queue/test-ad-password-19700101T000000Z") == 0,
"Sentinel file still exists");
if (fd < 0)
sysbail("cannot create fake queue file");
close(fd);
- code = pwupdate_postcommit_status(data, ctx, princ, 1);
- is_int(0, code, "pwupdate_postcommit_status enable succeeds");
+ code = sync_status(data, ctx, princ, 1);
+ is_int(0, code, "sync_status enable succeeds");
queue = NULL;
now = time(NULL);
for (try = now - 1; try <= now; try++) {
* Do the same thing for disables, which should still be blocked by the
* same marker.
*/
- code = pwupdate_postcommit_status(data, ctx, princ, 0);
- is_int(0, code, "pwupdate_postcommit_status disable succeeds");
+ code = sync_status(data, ctx, princ, 0);
+ is_int(0, code, "sync_status disable succeeds");
queue = NULL;
now = time(NULL);
for (try = now - 1; try <= now; try++) {
ok(rmdir("queue") == 0, "No other files in queue directory");
/* Check failure when there's no queue directory. */
- code = pwupdate_precommit_password(data, ctx, princ, "foobar",
- strlen("foobar"));
- is_int(ENOENT, code,
- "pwupdate_precommit_password fails with no queue");
+ code = sync_chpass(data, ctx, princ, "foobar", strlen("foobar"));
+ is_int(ENOENT, code, "sync_chpass fails with no queue");
message = krb5_get_error_message(ctx, code);
is_int(strncmp("cannot lock queue", message, strlen("cannot lock queue")),
0, "...with correct error message");
krb5_free_error_message(ctx, message);
- code = pwupdate_postcommit_status(data, ctx, princ, 0);
- is_int(ENOENT, code,
- "pwupdate_postcommit_status disable fails with no queue");
+ code = sync_status(data, ctx, princ, 0);
+ is_int(ENOENT, code, "sync_status disable fails with no queue");
message = krb5_get_error_message(ctx, code);
is_int(strncmp("cannot lock queue", message, strlen("cannot lock queue")),
0, "...with correct error message");
krb5_free_error_message(ctx, message);
/* Shut down the plugin. */
- pwupdate_close(data);
+ sync_close(data);
/*
* Change to an empty Kerberos configuration file, and then make sure the
code = krb5_parse_name(ctx, "test@EXAMPLE.COM", &princ);
if (code != 0)
bail("cannot parse principal: %s", krb5_get_error_message(ctx, code));
- is_int(0, pwupdate_init(ctx, &data), "pwupdate_init succeeds");
+ is_int(0, sync_init(ctx, &data), "sync_init succeeds");
ok(data != NULL, "...and data is non-NULL");
- code = pwupdate_precommit_password(data, ctx, princ, "foobar",
- strlen("foobar"));
- is_int(0, code, "pwupdate_precommit_password succeeds");
- code = pwupdate_postcommit_status(data, ctx, princ, 0);
- is_int(0, code, "pwupdate_postcommit_status disable succeeds");
+ code = sync_chpass(data, ctx, princ, "foobar", strlen("foobar"));
+ is_int(0, code, "sync_chpass succeeds");
+ code = sync_status(data, ctx, princ, 0);
+ is_int(0, code, "sync_status disable succeeds");
/* Clean up. */
krb5_free_principal(ctx, princ);
{
krb5_error_code code;
- code = pwupdate_ad_change(config, ctx, principal, password,
- strlen(password));
+ code = sync_ad_chpass(config, ctx, principal, password, strlen(password));
if (code != 0)
die_krb5(ctx, code, "AD password change for %s failed", user);
notice("AD password change for %s succeeded", user);
{
krb5_error_code code;
- code = pwupdate_ad_status(config, ctx, principal, enable);
+ code = sync_ad_status(config, ctx, principal, enable);
if (code != 0)
die_krb5(ctx, code, "AD status change for %s failed", user);
notice("AD status change for %s succeeded", user);
die_krb5(ctx, code, "cannot initialize Kerberos context");
/* Initialize the plugin. */
- code = pwupdate_init(ctx, &config);
+ code = sync_init(ctx, &config);
if (code != 0)
die_krb5(ctx, code, "plugin initialization failed");