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