|
|
4d12ff |
From d0d36965cce7a9bdff77c20ce9c9c1252b8c827c Mon Sep 17 00:00:00 2001
|
|
|
4d12ff |
From: Sumit Bose <sbose@redhat.com>
|
|
|
4d12ff |
Date: Thu, 31 May 2018 16:16:08 +0200
|
|
|
4d12ff |
Subject: [PATCH] Find NetBIOS name in keytab while leaving
|
|
|
4d12ff |
|
|
|
4d12ff |
If realmd is used with Samba as membership software, i.e. Samba's net
|
|
|
4d12ff |
utility, the NetBIOS name must be known when leaving a domain. The most
|
|
|
4d12ff |
reliable way to find it is by searching the keytab for NAME$@REALM type
|
|
|
4d12ff |
entries and use the NAME as the NetBIOS name.
|
|
|
4d12ff |
|
|
|
4d12ff |
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1370457
|
|
|
4d12ff |
---
|
|
|
4d12ff |
service/realm-kerberos.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
4d12ff |
service/realm-kerberos.h | 2 ++
|
|
|
4d12ff |
service/realm-samba-enroll.c | 13 ++++++---
|
|
|
4d12ff |
3 files changed, 76 insertions(+), 3 deletions(-)
|
|
|
4d12ff |
|
|
|
4d12ff |
diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c
|
|
|
4d12ff |
index 54d1ed7..d6d109f 100644
|
|
|
4d12ff |
--- a/service/realm-kerberos.c
|
|
|
4d12ff |
+++ b/service/realm-kerberos.c
|
|
|
4d12ff |
@@ -1130,3 +1130,67 @@ realm_kerberos_flush_keytab (const gchar *realm_name,
|
|
|
4d12ff |
return ret;
|
|
|
4d12ff |
|
|
|
4d12ff |
}
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+gchar *
|
|
|
4d12ff |
+realm_kerberos_get_netbios_name_from_keytab (const gchar *realm_name)
|
|
|
4d12ff |
+{
|
|
|
4d12ff |
+ krb5_error_code code;
|
|
|
4d12ff |
+ krb5_keytab keytab = NULL;
|
|
|
4d12ff |
+ krb5_context ctx;
|
|
|
4d12ff |
+ krb5_kt_cursor cursor = NULL;
|
|
|
4d12ff |
+ krb5_keytab_entry entry;
|
|
|
4d12ff |
+ krb5_principal realm_princ = NULL;
|
|
|
4d12ff |
+ gchar *princ_name = NULL;
|
|
|
4d12ff |
+ gchar *netbios_name = NULL;
|
|
|
4d12ff |
+ krb5_data *name_data;
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ code = krb5_init_context (&ctx;;
|
|
|
4d12ff |
+ if (code != 0) {
|
|
|
4d12ff |
+ return NULL;
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ princ_name = g_strdup_printf ("user@%s", realm_name);
|
|
|
4d12ff |
+ code = krb5_parse_name (ctx, princ_name, &realm_princ);
|
|
|
4d12ff |
+ g_free (princ_name);
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ if (code == 0) {
|
|
|
4d12ff |
+ code = krb5_kt_default (ctx, &keytab);
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ if (code == 0) {
|
|
|
4d12ff |
+ code = krb5_kt_start_seq_get (ctx, keytab, &cursor);
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ if (code == 0) {
|
|
|
4d12ff |
+ while (!krb5_kt_next_entry (ctx, keytab, &entry, &cursor) && netbios_name == NULL) {
|
|
|
4d12ff |
+ if (krb5_realm_compare (ctx, realm_princ, entry.principal)) {
|
|
|
4d12ff |
+ name_data = krb5_princ_component (ctx, entry.principal, 0);
|
|
|
4d12ff |
+ if (name_data != NULL
|
|
|
4d12ff |
+ && name_data->length > 0
|
|
|
4d12ff |
+ && name_data->data[name_data->length - 1] == '$') {
|
|
|
4d12ff |
+ netbios_name = g_strndup (name_data->data, name_data->length - 1);
|
|
|
4d12ff |
+ if (netbios_name == NULL) {
|
|
|
4d12ff |
+ code = krb5_kt_free_entry (ctx, &entry);
|
|
|
4d12ff |
+ warn_if_krb5_failed (ctx, code);
|
|
|
4d12ff |
+ break;
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+ code = krb5_kt_free_entry (ctx, &entry);
|
|
|
4d12ff |
+ warn_if_krb5_failed (ctx, code);
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ code = krb5_kt_end_seq_get (ctx, keytab, &cursor);
|
|
|
4d12ff |
+ warn_if_krb5_failed (ctx, code);
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ code = krb5_kt_close (ctx, keytab);
|
|
|
4d12ff |
+ warn_if_krb5_failed (ctx, code);
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ krb5_free_principal (ctx, realm_princ);
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ krb5_free_context (ctx);
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+ return netbios_name;
|
|
|
4d12ff |
+
|
|
|
4d12ff |
+}
|
|
|
4d12ff |
diff --git a/service/realm-kerberos.h b/service/realm-kerberos.h
|
|
|
4d12ff |
index 0447e4d..58cfe07 100644
|
|
|
4d12ff |
--- a/service/realm-kerberos.h
|
|
|
4d12ff |
+++ b/service/realm-kerberos.h
|
|
|
4d12ff |
@@ -88,6 +88,8 @@ gchar * realm_kerberos_format_login (RealmKerberos *self,
|
|
|
4d12ff |
gboolean realm_kerberos_flush_keytab (const gchar *realm_name,
|
|
|
4d12ff |
GError **error);
|
|
|
4d12ff |
|
|
|
4d12ff |
+gchar * realm_kerberos_get_netbios_name_from_keytab (const gchar *realm_name);
|
|
|
4d12ff |
+
|
|
|
4d12ff |
const gchar * realm_kerberos_get_name (RealmKerberos *self);
|
|
|
4d12ff |
|
|
|
4d12ff |
const gchar * realm_kerberos_get_realm_name (RealmKerberos *self);
|
|
|
4d12ff |
diff --git a/service/realm-samba-enroll.c b/service/realm-samba-enroll.c
|
|
|
4d12ff |
index 76e7b79..03f56d0 100644
|
|
|
4d12ff |
--- a/service/realm-samba-enroll.c
|
|
|
4d12ff |
+++ b/service/realm-samba-enroll.c
|
|
|
4d12ff |
@@ -85,7 +85,8 @@ static JoinClosure *
|
|
|
4d12ff |
join_closure_init (GTask *task,
|
|
|
4d12ff |
RealmDisco *disco,
|
|
|
4d12ff |
GVariant *options,
|
|
|
4d12ff |
- GDBusMethodInvocation *invocation)
|
|
|
4d12ff |
+ GDBusMethodInvocation *invocation,
|
|
|
4d12ff |
+ gboolean do_join)
|
|
|
4d12ff |
{
|
|
|
4d12ff |
JoinClosure *join;
|
|
|
4d12ff |
gchar *workgroup;
|
|
|
4d12ff |
@@ -106,6 +107,12 @@ join_closure_init (GTask *task,
|
|
|
4d12ff |
else if (disco->explicit_netbios)
|
|
|
4d12ff |
authid = disco->explicit_netbios;
|
|
|
4d12ff |
|
|
|
4d12ff |
+ /* try to get the NetBIOS name from the keytab as last option while
|
|
|
4d12ff |
+ * leaving the domain */
|
|
|
4d12ff |
+ if (authid == NULL && !do_join) {
|
|
|
4d12ff |
+ authid = realm_kerberos_get_netbios_name_from_keytab(disco->kerberos_realm);
|
|
|
4d12ff |
+ }
|
|
|
4d12ff |
+
|
|
|
4d12ff |
join->config = realm_ini_config_new (REALM_INI_NO_WATCH | REALM_INI_PRIVATE);
|
|
|
4d12ff |
realm_ini_config_set (join->config, REALM_SAMBA_CONFIG_GLOBAL,
|
|
|
4d12ff |
"security", "ads",
|
|
|
4d12ff |
@@ -393,7 +400,7 @@ realm_samba_enroll_join_async (RealmDisco *disco,
|
|
|
4d12ff |
g_return_if_fail (cred != NULL);
|
|
|
4d12ff |
|
|
|
4d12ff |
task = g_task_new (NULL, NULL, callback, user_data);
|
|
|
4d12ff |
- join = join_closure_init (task, disco, options, invocation);
|
|
|
4d12ff |
+ join = join_closure_init (task, disco, options, invocation, TRUE);
|
|
|
4d12ff |
explicit_computer_name = realm_options_computer_name (options, disco->domain_name);
|
|
|
4d12ff |
if (explicit_computer_name != NULL) {
|
|
|
4d12ff |
realm_diagnostics_info (invocation, "Joining using a manual netbios name: %s",
|
|
|
4d12ff |
@@ -462,7 +469,7 @@ realm_samba_enroll_leave_async (RealmDisco *disco,
|
|
|
4d12ff |
JoinClosure *join;
|
|
|
4d12ff |
|
|
|
4d12ff |
task = g_task_new (NULL, NULL, callback, user_data);
|
|
|
4d12ff |
- join = join_closure_init (task, disco, options, invocation);
|
|
|
4d12ff |
+ join = join_closure_init (task, disco, options, invocation, FALSE);
|
|
|
4d12ff |
|
|
|
4d12ff |
switch (cred->type) {
|
|
|
4d12ff |
case REALM_CREDENTIAL_PASSWORD:
|
|
|
4d12ff |
--
|
|
|
4d12ff |
2.14.4
|
|
|
4d12ff |
|