Commit 86bf6c33 authored by Rocky Automation's avatar Rocky Automation 📺
Browse files

import adcli-0.8.2-9.el8

parent f7ce3fff
From 2edc26afda17db1a92703deb16658e9de9f79e14 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 3 Sep 2019 14:39:37 +0200
Subject: [PATCH] doc: add missing samba_data_tool_path.xml(.in) to EXTRA_DIST
---
doc/Makefile.am | 2 ++
1 file changed, 2 insertions(+)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 3a53843..4490688 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -31,6 +31,8 @@ EXTRA_DIST = \
static \
version.xml.in \
version.xml \
+ samba_data_tool_path.xml.in \
+ samba_data_tool_path.xml \
$(NULL)
CLEANFILES = \
--
2.28.0
From fa5c5fb4f8e7bcadf3e5a3798bd060720fd35eaa Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 20 Oct 2020 13:34:41 +0200
Subject: [PATCH] doc: explain required AD permissions
When using a restricted account with adcli some operations might fail
because the account might not have all required permissions. The man
page is extended and now explains which permissions are needed under
given circumstances.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852080
Resolves: https://gitlab.freedesktop.org/realmd/adcli/-/issues/20
---
doc/Makefile.am | 10 ++++
doc/adcli.xml | 132 +++++++++++++++++++++++++++++++++++++++++++++
library/adenroll.c | 30 ++++++-----
3 files changed, 160 insertions(+), 12 deletions(-)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 4490688..50fb777 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -33,14 +33,17 @@ EXTRA_DIST = \
version.xml \
samba_data_tool_path.xml.in \
samba_data_tool_path.xml \
+ permissions.xml \
$(NULL)
CLEANFILES = \
$(man8_MANS) \
+ permissions.xml \
$(NULL)
XSLTPROC_FLAGS = \
--nonet \
+ --xinclude \
--stringparam man.output.quietly 1 \
--stringparam funcsynopsis.style ansi \
--stringparam man.th.extra1.suppress 1 \
@@ -50,6 +53,13 @@ XSLTPROC_FLAGS = \
XSLTPROC_MAN = \
$(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl
+permissions.xml: ../library/adenroll.c adcli.xml
+ echo "<itemizedlist>" > $@
+ grep '".*".*/\* :ADPermissions: ' $< | sed -e 's#.*"\(.*\)".*/\* :ADPermissions: \(.*\)\*/$$#<listitem><para>\1</para><itemizedlist><listitem><para>\2</para></listitem></itemizedlist></listitem>#' | sed -e 's#\*#</para></listitem><listitem><para>#g' >> $@
+ echo "</itemizedlist>" >> $@
+
+$(man8_MANS): permissions.xml
+
.xml.8:
$(AM_V_GEN) $(XSLTPROC_MAN) $<
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 1437679..cc44fd8 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -885,6 +885,138 @@ Password for Administrator:
</refsect1>
+<refsect1 id='delegation'>
+ <title>Delegated Permissions</title>
+ <para>It is common practice in AD to not use an account from the Domain
+ Administrators group to join a machine to a domain but use a dedicated
+ account which only has permissions to join a machine to one or more OUs
+ in the Active Directory tree. Giving the needed permissions to a single
+ account or a group in Active Directory is called Delegation. A typical
+ example on how to configured Delegation can be found in the Delegation
+ section of the blog post
+ <ulink url="https://docs.microsoft.com/en-us/archive/blogs/dubaisec/who-can-add-workstation-to-the-domain">Who can add workstation to the domain</ulink>.
+ </para>
+
+ <para>When using an account with delegated permissions with adcli
+ basically the same applies as well. However some aspects are explained
+ here in a bit more details to better illustrate different concepts of
+ Active Directory and to make it more easy to debug permissions issues
+ during the join. Please note that the following is not specific to
+ adcli but applies to all applications which would like to modify
+ certain properties or objects in Active Directory with an account with
+ limited permissions.</para>
+
+ <para>First, as said in the blog post it is sufficient to have
+ <literal>"Create computer object"</literal> permissions to join a
+ computer to a domain. But this would only work as expected if the
+ computer object does not exist in Active Directory before the join.
+ Because only when a new object is created Active Directory does not
+ apply additional permission checks on the attributes of the new
+ computer object. This means the delegated user can add any kind of
+ attribute with any value to a new computer object also long as they
+ meet general constraints like e.g. that the attribute must be defined
+ in the schema and is allowed in a objectclass of the object, the value
+ must match the syntax defined in the schema or that the
+ <option>sAMAccountName</option> must be unique in the domain.</para>
+
+ <para>If you want to use the account with delegated permission to
+ remove computer objects in Active Directory (adcli delete-computer) you
+ should of course make sure that the account has
+ <literal>"Delete computer object"</literal> permissions.</para>
+
+ <para>If the computer object already exists the
+ <literal>"Create computer object"</literal> permission does not apply
+ anymore since now an existing object must be modified. Now permissions
+ on the individual attributes are needed. e.g.
+ <literal>"Read and write Account Restrictions"</literal> or
+ <literal>"Reset Password"</literal>. For some attributes Active
+ Directory has two types of permissions the plain
+ <literal>"Read and Write"</literal> permissions and the
+ <literal>"Validated Write"</literal> permissions. For the latter case
+ there are two specific permissions relevant for adcli, namely
+ <itemizedlist>
+ <listitem><para>Validated write to DNS host name</para></listitem>
+ <listitem><para>Validated write to service principal name</para></listitem>
+ </itemizedlist>
+ Details about the validation of the values can be found in the
+ <literal>"Validated Writes"</literal> section of
+ <literal>[MS-ADTS]</literal>, especially
+ <ulink url="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/5c578b15-d619-408d-ba17-380714b89fd1">dNSHostName</ulink>
+ and
+ <ulink url="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/28ca4eca-0e0b-4666-9175-a37ccb8edada">servicePrincipalName</ulink>.
+ To cut it short for <literal>"Validated write to DNS host name"</literal>
+ the domain part of the fully-qualified hostname must either match the
+ domain name of the domain you want to join to or must be listed in the
+ <option>msDS-AllowedDNSSuffixes</option> attribute. And for
+ <literal>"Validated write to service principal name"</literal> the
+ hostname part of the service principal name must match the name stored
+ in <option>dNSHostName</option> or some other attributes which are
+ not handled by adcli. This also means that
+ <option>dNSHostName</option> cannot be empty or only contain a short
+ name if the service principal name should contain a fully-qualified
+ name.</para>
+
+ <para>To summarize, if you only have validated write permissions you
+ should make sure the domain part of the hostname matches the domain you
+ want to join or use the <option>--host-fqdn</option> with a matching
+ name.</para>
+
+ <para>The plain read write permissions do not run additional
+ validations but the attribute values must still be in agreement with
+ the general constraints mentioned above. If the computer object already
+ exists adcli might need the following permissions which are also needed
+ by Windows clients to modify existing attributes:
+ <itemizedlist>
+ <listitem><para>Reset Password</para></listitem>
+ <listitem><para>Read and write Account Restrictions</para></listitem>
+ <listitem><para>Read and (validated) write to DNS host name</para></listitem>
+ <listitem><para>Read and (validated) write to service principal name</para></listitem>
+ </itemizedlist>
+ additionally adcli needs
+ <itemizedlist>
+ <listitem><para>Read and write msDS-supportedEncryptionTypes</para></listitem>
+ </itemizedlist>
+ This is added for security reasons to avoid that Active Directory
+ stores Kerberos keys with (potentially weaker) encryption types than
+ the client supports since Active Directory is often configured to still
+ support older (weaker) encryption types for compatibility reasons.
+ </para>
+
+ <para>All other attributes are only set or modified on demand, i.e.
+ adcli must be called with an option the would set or modify the given
+ attribute. In the following the attributes adcli can modify together
+ with the required permissions are listed:
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="permissions.xml" />
+ </para>
+
+ <para>For the management of users and groups (adcli create-user,
+ adcli delete-user, adcli create-group, adcli delete-group) the same
+ applies only for different types of objects, i.e. users and groups.
+ Since currently adcli only supports the creation and the removal of
+ user and group objects it is sufficient to have the
+ <literal>"Create/Delete User objects"</literal> and
+ <literal>"Create/Delete Group objects"</literal> permissions.</para>
+
+ <para>If you want to manage group members as well (adcli add-member,
+ adcli remove-member) <literal>"Read/Write Members"</literal> permissions
+ are needed as well.</para>
+
+ <para>Depending on the version of Active Directory the
+ <literal>"Delegation of Control Wizard"</literal> might offer some
+ shortcuts for common task like e.g.
+ <itemizedlist>
+ <listitem><para>Create, delete and manage user accounts</para></listitem>
+ <listitem><para>Create, delete and manage groups</para></listitem>
+ <listitem><para>Modify the membership of a group</para></listitem>
+ </itemizedlist>
+ The first 2 shortcuts will provided full access to user and group
+ objects which, as explained above, is more than currently is needed.
+ After using those shortcut it is a good idea to verify in the
+ <literal>"Security"</literal> tab in the <literal>"Properties"</literal>
+ of the related Active Directory container that the assigned permissions
+ meet the expectations.</para>
+</refsect1>
+
<refsect1 id='bugs'>
<title>Bugs</title>
<para>
diff --git a/library/adenroll.c b/library/adenroll.c
index e745295..98e9786 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -71,19 +71,25 @@ static krb5_enctype v51_earlier_enctypes[] = {
0
};
+/* The following list containst all attributes handled by adcli, some are
+ * read-only and the others can be written as well. To properly document the
+ * required permissions each attribute which adcli tries to modify should have
+ * a comment starting with ':ADPermissions:' and the related permissions in AD
+ * on the same line. Multiple permissions can be seperated with a '*'. For all
+ * other attribute a suitable comment is very welcome. */
static char *default_ad_ldap_attrs[] = {
- "sAMAccountName",
- "userPrincipalName",
- "msDS-KeyVersionNumber",
- "msDS-supportedEncryptionTypes",
- "dNSHostName",
- "servicePrincipalName",
- "operatingSystem",
- "operatingSystemVersion",
- "operatingSystemServicePack",
- "pwdLastSet",
- "userAccountControl",
- "description",
+ "sAMAccountName", /* Only set during creation */
+ "userPrincipalName", /* :ADPermissions: Read/Write userPrincipal Name */
+ "msDS-KeyVersionNumber", /* Manages by AD */
+ "msDS-supportedEncryptionTypes", /* :ADPermissions: Read/Write msDS-SupportedEncryptionTypes */
+ "dNSHostName", /* :ADPermissions: Read/Write dNSHostName * Read and write DNS host name attributes * Validated write to DNS host name */
+ "servicePrincipalName", /* :ADPermissions: Read/Write servicePrincipalName * Validated write to service principal name */
+ "operatingSystem", /* :ADPermissions: Read/Write Operating System */
+ "operatingSystemVersion", /* :ADPermissions: Read/Write Operating System Version */
+ "operatingSystemServicePack", /* :ADPermissions: Read/Write operatingSystemServicePack */
+ "pwdLastSet", /* Managed by AD */
+ "userAccountControl", /* :ADPermissions: Read/Write userAccountControl */
+ "description", /* :ADPermissions: Read/Write Description */
NULL,
};
--
2.28.0
From 4e4dbf8d2b437808863f8be85e7f30865d88c7fc Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 23 Oct 2020 16:46:43 +0200
Subject: [PATCH 1/7] enroll: add is_service member
Add helpers to indicate a managed service account.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112
---
library/adenroll.c | 17 +++++++++++++++++
library/adenroll.h | 4 ++++
2 files changed, 21 insertions(+)
diff --git a/library/adenroll.c b/library/adenroll.c
index 98e9786..5ae1f7b 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -103,6 +103,8 @@ static char *default_ad_ldap_attrs[] = {
struct _adcli_enroll {
int refs;
adcli_conn *conn;
+ bool is_service;
+ bool is_service_explicit;
char *host_fqdn;
int host_fqdn_explicit;
@@ -2942,6 +2944,21 @@ adcli_enroll_get_desciption (adcli_enroll *enroll)
return enroll->description;
}
+void
+adcli_enroll_set_is_service (adcli_enroll *enroll, bool value)
+{
+ return_if_fail (enroll != NULL);
+
+ enroll->is_service = value;
+ enroll->is_service_explicit = true;
+}
+
+bool
+adcli_enroll_get_is_service (adcli_enroll *enroll)
+{
+ return enroll->is_service;
+}
+
const char **
adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll)
{
diff --git a/library/adenroll.h b/library/adenroll.h
index 0606169..7765ed4 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -130,6 +130,10 @@ const char * adcli_enroll_get_desciption (adcli_enroll *enroll);
void adcli_enroll_set_description (adcli_enroll *enroll,
const char *value);
+bool adcli_enroll_get_is_service (adcli_enroll *enroll);
+void adcli_enroll_set_is_service (adcli_enroll *enroll,
+ bool value);
+
krb5_kvno adcli_enroll_get_kvno (adcli_enroll *enroll);
void adcli_enroll_set_kvno (adcli_enroll *enroll,
--
2.28.0
From beb7abfacc0010987d2cd8ab70f7c373d309eed9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 15 Oct 2020 18:01:12 +0200
Subject: [PATCH] join/update: set dNSHostName if not set
If during a join or update an existing AD computer object does not have
the dNSHostName attribute set it will be set with the current hostname.
This is important for cases where the user doing the join or update only
has "Validated write to service principal name" for the computer object.
The validated write with fully-qualified names can only be successful if
dNSHostName is set, see [MS-ADTS] section 3.1.1.5.3.1.1.4 "Validated
Writes - servicePrincipalName" for details.
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1734764
---
library/adenroll.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 246f658..e745295 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1403,21 +1403,29 @@ update_computer_account (adcli_enroll *enroll)
{
int res = 0;
LDAP *ldap;
+ char *value = NULL;
ldap = adcli_conn_get_ldap_connection (enroll->conn);
return_if_fail (ldap != NULL);
/* Only update attributes which are explicitly given on the command
- * line. Otherwise 'adcli update' must be always called with the same
- * set of options to make sure existing attributes are not deleted or
- * overwritten with different values. */
- if (enroll->host_fqdn_explicit) {
+ * line or not set in the existing AD object. Otherwise 'adcli update'
+ * must be always called with the same set of options to make sure
+ * existing attributes are not deleted or overwritten with different
+ * values. */
+ if (enroll->computer_attributes != NULL) {
+ value = _adcli_ldap_parse_value (ldap,
+ enroll->computer_attributes,
+ "dNSHostName");
+ }
+ if (enroll->host_fqdn_explicit || value == NULL ) {
char *vals_dNSHostName[] = { enroll->host_fqdn, NULL };
LDAPMod dNSHostName = { LDAP_MOD_REPLACE, "dNSHostName", { vals_dNSHostName, } };
LDAPMod *mods[] = { &dNSHostName, NULL };
res |= update_computer_attribute (enroll, ldap, mods);
}
+ free (value);
if (res == ADCLI_SUCCESS && enroll->trusted_for_delegation_explicit) {
char *vals_userAccountControl[] = { NULL , NULL };
--
2.28.0
From 637cc53953ef61c90530ae5eaf26eb4911336465 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 10 Dec 2020 18:29:18 +0100
Subject: [PATCH] service-account: fix typo in the man page entry
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1906303
---
doc/adcli.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 14921f9..a64687a 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -943,7 +943,7 @@ Password for Administrator:
of the managed service account as a suffix. On most systems it would be
<filename>/etc/krb5.keytab</filename> with a suffix of
'domain.example.com', e.g.
- <filename>/etc/krb5.keytad.domain.example.com</filename>.</para>
+ <filename>/etc/krb5.keytab.domain.example.com</filename>.</para>
<para><command>adcli create-msa</command> can be called multiple
times to reset the password of the managed service account. To identify
@@ -955,7 +955,7 @@ Password for Administrator:
<para>The managed service account password can be updated with
<programlisting>
-$ adcli update --domain=domain.example.com --host-keytab=/etc/krb5.keytad.domain.example.com
+$ adcli update --domain=domain.example.com --host-keytab=/etc/krb5.keytab.domain.example.com
</programlisting>
and the managed service account can be deleted with
<programlisting>
--
2.29.2
From 76ca1e6737742208d83e016d43a3379e378f8d90 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 14 Oct 2020 17:44:10 +0200
Subject: [PATCH] tools: add missing use-ldaps option to update and testjoin
When adding the use-ldaps option the update and testjoin sub-commands
were forgotten.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1883467
---
tools/computer.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/computer.c b/tools/computer.c
index 24ea258..5a97d8b 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -491,6 +491,7 @@ adcli_tool_computer_update (adcli_conn *conn,
struct option options[] = {
{ "domain", required_argument, NULL, opt_domain },
{ "domain-controller", required_argument, NULL, opt_domain_controller },
+ { "use-ldaps", no_argument, 0, opt_use_ldaps },
{ "host-fqdn", required_argument, 0, opt_host_fqdn },
{ "computer-name", required_argument, 0, opt_computer_name },
{ "host-keytab", required_argument, 0, opt_host_keytab },
@@ -612,6 +613,7 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
struct option options[] = {
{ "domain", required_argument, NULL, opt_domain },
{ "domain-controller", required_argument, NULL, opt_domain_controller },
+ { "use-ldaps", no_argument, 0, opt_use_ldaps },
{ "host-keytab", required_argument, 0, opt_host_keytab },
{ "verbose", no_argument, NULL, opt_verbose },
{ "help", no_argument, NULL, 'h' },
--
2.28.0
This diff is collapsed.
From eea6a8071b5e5df74808903bb15b30acf820ce3f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 23 Oct 2020 16:55:11 +0200
Subject: [PATCH 3/7] enroll: use 'computer' or 'service' in debug messages
Use proper account type in debug messages.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112
---
library/adenroll.c | 115 ++++++++++++++++++++++++++++-----------------
1 file changed, 72 insertions(+), 43 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index dbfda36..9cdc79b 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -155,6 +155,12 @@ struct _adcli_enroll {
char *description;
};
+static const char *
+s_or_c (adcli_enroll *enroll)
+{
+ return enroll->is_service ? "service" : "computer";
+}
+
static void
check_if_service (adcli_enroll *enroll,
LDAP *ldap,
@@ -203,13 +209,15 @@ ensure_computer_name (adcli_result res,
return res;
if (enroll->computer_name) {
- _adcli_info ("Enrolling computer name: %s",
+ _adcli_info ("Enrolling %s name: %s",
+ s_or_c (enroll),
enroll->computer_name);
return ADCLI_SUCCESS;
}
if (!enroll->host_fqdn) {
- _adcli_err ("No host name from which to determine the computer name");
+ _adcli_err ("No host name from which to determine the %s name",
+ s_or_c (enroll));
return ADCLI_ERR_CONFIG;
}
@@ -603,7 +611,8 @@ lookup_computer_container (adcli_enroll *enroll,
} else if (ret != LDAP_SUCCESS) {
return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY,
- "Couldn't lookup computer container: %s", base);
+ "Couldn't lookup %s container: %s",
+ s_or_c (enroll), base);
}
values = _adcli_ldap_parse_values (ldap, results, attrs[0]);
@@ -614,8 +623,8 @@ lookup_computer_container (adcli_enroll *enroll,
if (strncmp (values[i], prefix, prefix_len) == 0) {
enroll->computer_container = strdup (values[i] + prefix_len);
return_unexpected_if_fail (enroll->computer_container != NULL);
- _adcli_info ("Found well known computer container at: %s",
- enroll->computer_container);
+ _adcli_info ("Found well known %s container at: %s",
+ s_or_c (enroll), enroll->computer_container);
break;
}
}
@@ -629,8 +638,9 @@ lookup_computer_container (adcli_enroll *enroll,
if (ret == LDAP_SUCCESS) {
enroll->computer_container = _adcli_ldap_parse_dn (ldap, results);
if (enroll->computer_container) {
- _adcli_info ("Well known computer container not "
+ _adcli_info ("Well known %s container not "
"found, but found suitable one at: %s",
+ s_or_c (enroll),
enroll->computer_container);
}
}
@@ -646,7 +656,8 @@ lookup_computer_container (adcli_enroll *enroll,
}
if (!enroll->computer_container) {
- _adcli_err ("Couldn't find location to create computer accounts");
+ _adcli_err ("Couldn't find location to create %s accounts",
+ s_or_c (enroll));
return ADCLI_ERR_DIRECTORY;
}
@@ -674,7 +685,8 @@ calculate_computer_account (adcli_enroll *enroll,
if (asprintf (&enroll->computer_dn, "CN=%s,%s", enroll->computer_name, enroll->computer_container) < 0)
return_unexpected_if_reached ();
- _adcli_info ("Calculated computer account: %s", enroll->computer_dn);
+ _adcli_info ("Calculated %s account: %s",
+ s_or_c (enroll), enroll->computer_dn);
return ADCLI_SUCCESS;
}
@@ -861,7 +873,8 @@ create_computer_account (adcli_enroll *enroll,
enroll->computer_dn);
}
- _adcli_info ("Created computer account: %s", enroll->computer_dn);
+ _adcli_info ("Created %s account: %s", s_or_c (enroll),
+ enroll->computer_dn);
return ADCLI_SUCCESS;
}
@@ -908,17 +921,17 @@ validate_computer_account (adcli_enroll *enroll,
assert (enroll->computer_dn != NULL);
if (already_exists && !allow_overwrite) {
- _adcli_err ("The computer account %s already exists",
- enroll->computer_name);
+ _adcli_err ("The %s account %s already exists",
+ s_or_c (enroll), enroll->computer_name);
return ADCLI_ERR_CONFIG;
}
/* Do we have an explicitly requested ou? */
if (enroll->domain_ou && enroll->domain_ou_explicit && already_exists) {
if (!_adcli_ldap_dn_has_ancestor (enroll->computer_dn, enroll->domain_ou)) {
- _adcli_err ("The computer account %s already exists, "
+ _adcli_err ("The %s account %s already exists, "
"but is not in the desired organizational unit.",
- enroll->computer_name);
+ s_or_c (enroll), enroll->computer_name);
return ADCLI_ERR_CONFIG;
}
}
@@ -943,7 +956,8 @@ delete_computer_account (adcli_enroll *enroll,
"Couldn't delete computer account: %s",
enroll->computer_dn);
} else {
- _adcli_info ("Deleted computer account at: %s", enroll->computer_dn);
+ _adcli_info ("Deleted %s account at: %s", s_or_c (enroll),
+ enroll->computer_dn);
}