Blame SOURCES/0001-doc-explain-required-AD-permissions.patch

541bac
From fa5c5fb4f8e7bcadf3e5a3798bd060720fd35eaa Mon Sep 17 00:00:00 2001
541bac
From: Sumit Bose <sbose@redhat.com>
541bac
Date: Tue, 20 Oct 2020 13:34:41 +0200
541bac
Subject: [PATCH] doc: explain required AD permissions
541bac
541bac
When using a restricted account with adcli some operations might fail
541bac
because the account might not have all required permissions. The man
541bac
page is extended and now explains which permissions are needed under
541bac
given circumstances.
541bac
541bac
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852080
541bac
Resolves: https://gitlab.freedesktop.org/realmd/adcli/-/issues/20
541bac
---
541bac
 doc/Makefile.am    |  10 ++++
541bac
 doc/adcli.xml      | 132 +++++++++++++++++++++++++++++++++++++++++++++
541bac
 library/adenroll.c |  30 ++++++-----
541bac
 3 files changed, 160 insertions(+), 12 deletions(-)
541bac
541bac
diff --git a/doc/Makefile.am b/doc/Makefile.am
541bac
index 4490688..50fb777 100644
541bac
--- a/doc/Makefile.am
541bac
+++ b/doc/Makefile.am
541bac
@@ -33,14 +33,17 @@ EXTRA_DIST = \
541bac
 	version.xml \
541bac
 	samba_data_tool_path.xml.in \
541bac
 	samba_data_tool_path.xml \
541bac
+	permissions.xml \
541bac
 	$(NULL)
541bac
 
541bac
 CLEANFILES = \
541bac
 	$(man8_MANS) \
541bac
+	permissions.xml \
541bac
 	$(NULL)
541bac
 
541bac
 XSLTPROC_FLAGS = \
541bac
 	--nonet \
541bac
+	--xinclude \
541bac
 	--stringparam man.output.quietly 1 \
541bac
 	--stringparam funcsynopsis.style ansi \
541bac
 	--stringparam man.th.extra1.suppress 1 \
541bac
@@ -50,6 +53,13 @@ XSLTPROC_FLAGS = \
541bac
 XSLTPROC_MAN = \
541bac
 	$(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl
541bac
 
541bac
+permissions.xml: ../library/adenroll.c adcli.xml
541bac
+	echo "<itemizedlist>" > $@
541bac
+	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' >> $@
541bac
+	echo "</itemizedlist>" >> $@
541bac
+
541bac
+$(man8_MANS): permissions.xml
541bac
+
541bac
 .xml.8:
541bac
 	$(AM_V_GEN) $(XSLTPROC_MAN) $<
541bac
 
541bac
diff --git a/doc/adcli.xml b/doc/adcli.xml
541bac
index 1437679..cc44fd8 100644
541bac
--- a/doc/adcli.xml
541bac
+++ b/doc/adcli.xml
541bac
@@ -885,6 +885,138 @@ Password for Administrator:
541bac
 
541bac
 </refsect1>
541bac
 
541bac
+<refsect1 id='delegation'>
541bac
+	<title>Delegated Permissions</title>
541bac
+	<para>It is common practice in AD to not use an account from the Domain
541bac
+	Administrators group to join a machine to a domain but use a dedicated
541bac
+	account which only has permissions to join a machine to one or more OUs
541bac
+	in the Active Directory tree. Giving the needed permissions to a single
541bac
+	account or a group in Active Directory is called Delegation. A typical
541bac
+	example on how to configured Delegation can be found in the Delegation
541bac
+	section of the blog post
541bac
+	<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>.
541bac
+	</para>
541bac
+
541bac
+	<para>When using an account with delegated permissions with adcli
541bac
+	basically the same applies as well. However some aspects are explained
541bac
+	here in a bit more details to better illustrate different concepts of
541bac
+	Active Directory and to make it more easy to debug permissions issues
541bac
+	during the join. Please note that the following is not specific to
541bac
+	adcli but applies to all applications which would like to modify
541bac
+	certain properties or objects in Active Directory with an account with
541bac
+	limited permissions.</para>
541bac
+
541bac
+	<para>First, as said in the blog post it is sufficient to have
541bac
+	<literal>"Create computer object"</literal> permissions to join a
541bac
+	computer to a domain. But this would only work as expected if the
541bac
+	computer object does not exist in Active Directory before the join.
541bac
+	Because only when a new object is created Active Directory does not
541bac
+	apply additional permission checks on the attributes of the new
541bac
+	computer object. This means the delegated user can add any kind of
541bac
+	attribute with any value to a new computer object also long as they
541bac
+	meet general constraints like e.g. that the attribute must be defined
541bac
+	in the schema and is allowed in a objectclass of the object, the value
541bac
+	must match the syntax defined in the schema or that the
541bac
+	<option>sAMAccountName</option> must be unique in the domain.</para>
541bac
+
541bac
+	<para>If you want to use the account with delegated permission to
541bac
+	remove computer objects in Active Directory (adcli delete-computer) you
541bac
+	should of course make sure that the account has
541bac
+	<literal>"Delete computer object"</literal> permissions.</para>
541bac
+
541bac
+	<para>If the computer object already exists the
541bac
+	<literal>"Create computer object"</literal> permission does not apply
541bac
+	anymore since now an existing object must be modified. Now permissions
541bac
+	on the individual attributes are needed. e.g.
541bac
+	<literal>"Read and write Account Restrictions"</literal> or
541bac
+	<literal>"Reset Password"</literal>. For some attributes Active
541bac
+	Directory has two types of permissions the plain
541bac
+	<literal>"Read and Write"</literal> permissions and the
541bac
+	<literal>"Validated Write"</literal> permissions. For the latter case
541bac
+	there are two specific permissions relevant for adcli, namely
541bac
+		<itemizedlist>
541bac
+			<listitem><para>Validated write to DNS host name</para></listitem>
541bac
+			<listitem><para>Validated write to service principal name</para></listitem>
541bac
+		</itemizedlist>
541bac
+	Details about the validation of the values can be found in the
541bac
+	<literal>"Validated Writes"</literal> section of
541bac
+	<literal>[MS-ADTS]</literal>, especially
541bac
+	<ulink url="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/5c578b15-d619-408d-ba17-380714b89fd1">dNSHostName</ulink>
541bac
+	and
541bac
+	<ulink url="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/28ca4eca-0e0b-4666-9175-a37ccb8edada">servicePrincipalName</ulink>.
541bac
+	To cut it short for <literal>"Validated write to DNS host name"</literal>
541bac
+	the domain part of the fully-qualified hostname must either match the
541bac
+	domain name of the domain you want to join to or must be listed in the
541bac
+	<option>msDS-AllowedDNSSuffixes</option> attribute. And for
541bac
+	<literal>"Validated write to service principal name"</literal> the
541bac
+	hostname part of the service principal name must match the name stored
541bac
+	in <option>dNSHostName</option> or some other attributes which are
541bac
+	not handled by adcli. This also means that
541bac
+	<option>dNSHostName</option> cannot be empty or only contain a short
541bac
+	name if the service principal name should contain a fully-qualified
541bac
+	name.</para>
541bac
+
541bac
+	<para>To summarize, if you only have validated write permissions you
541bac
+	should make sure the domain part of the hostname matches the domain you
541bac
+	want to join or use the <option>--host-fqdn</option> with a matching
541bac
+	name.</para>
541bac
+
541bac
+	<para>The plain read write permissions do not run additional
541bac
+	validations but the attribute values must still be in agreement with
541bac
+	the general constraints mentioned above. If the computer object already
541bac
+	exists adcli might need the following permissions which are also needed
541bac
+	by Windows clients to modify existing attributes:
541bac
+		<itemizedlist>
541bac
+			<listitem><para>Reset Password</para></listitem>
541bac
+			<listitem><para>Read and write Account Restrictions</para></listitem>
541bac
+			<listitem><para>Read and (validated) write to DNS host name</para></listitem>
541bac
+			<listitem><para>Read and (validated) write to service principal name</para></listitem>
541bac
+		</itemizedlist>
541bac
+	additionally adcli needs
541bac
+		<itemizedlist>
541bac
+			<listitem><para>Read and write msDS-supportedEncryptionTypes</para></listitem>
541bac
+		</itemizedlist>
541bac
+	This is added for security reasons to avoid that Active Directory
541bac
+	stores Kerberos keys with (potentially weaker) encryption types than
541bac
+	the client supports since Active Directory is often configured to still
541bac
+	support older (weaker) encryption types for compatibility reasons.
541bac
+	</para>
541bac
+
541bac
+	<para>All other attributes are only set or modified on demand, i.e.
541bac
+	adcli must be called with an option the would set or modify the given
541bac
+	attribute. In the following the attributes adcli can modify together
541bac
+	with the required permissions are listed:
541bac
+	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="permissions.xml" />
541bac
+	</para>
541bac
+
541bac
+	<para>For the management of users and groups (adcli create-user,
541bac
+	adcli delete-user, adcli create-group, adcli delete-group) the same
541bac
+	applies only for different types of objects, i.e. users and groups.
541bac
+	Since currently adcli only supports the creation and the removal of
541bac
+	user and group objects it is sufficient to have the
541bac
+	<literal>"Create/Delete User objects"</literal> and
541bac
+	<literal>"Create/Delete Group objects"</literal> permissions.</para>
541bac
+
541bac
+	<para>If you want to manage group members as well (adcli add-member,
541bac
+	adcli remove-member) <literal>"Read/Write Members"</literal> permissions
541bac
+	are needed as well.</para>
541bac
+
541bac
+	<para>Depending on the version of Active Directory the
541bac
+	<literal>"Delegation of Control Wizard"</literal> might offer some
541bac
+	shortcuts for common task like e.g.
541bac
+		<itemizedlist>
541bac
+			<listitem><para>Create, delete and manage user accounts</para></listitem>
541bac
+			<listitem><para>Create, delete and manage groups</para></listitem>
541bac
+			<listitem><para>Modify the membership of a group</para></listitem>
541bac
+		</itemizedlist>
541bac
+	The first 2 shortcuts will provided full access to user and group
541bac
+	objects which, as explained above, is more than currently is needed.
541bac
+	After using those shortcut it is a good idea to verify in the
541bac
+	<literal>"Security"</literal> tab in the <literal>"Properties"</literal>
541bac
+	of the related Active Directory container that the assigned permissions
541bac
+	meet the expectations.</para>
541bac
+</refsect1>
541bac
+
541bac
 <refsect1 id='bugs'>
541bac
 	<title>Bugs</title>
541bac
 	<para>
541bac
diff --git a/library/adenroll.c b/library/adenroll.c
541bac
index e745295..98e9786 100644
541bac
--- a/library/adenroll.c
541bac
+++ b/library/adenroll.c
541bac
@@ -71,19 +71,25 @@ static krb5_enctype v51_earlier_enctypes[] = {
541bac
 	0
541bac
 };
541bac
 
541bac
+/* The following list containst all attributes handled by adcli, some are
541bac
+ * read-only and the others can be written as well. To properly document the
541bac
+ * required permissions each attribute which adcli tries to modify should have
541bac
+ * a comment starting with ':ADPermissions:' and the related permissions in AD
541bac
+ * on the same line. Multiple permissions can be seperated with a '*'. For all
541bac
+ * other attribute a suitable comment is very welcome. */
541bac
 static char *default_ad_ldap_attrs[] =  {
541bac
-	"sAMAccountName",
541bac
-	"userPrincipalName",
541bac
-	"msDS-KeyVersionNumber",
541bac
-	"msDS-supportedEncryptionTypes",
541bac
-	"dNSHostName",
541bac
-	"servicePrincipalName",
541bac
-	"operatingSystem",
541bac
-	"operatingSystemVersion",
541bac
-	"operatingSystemServicePack",
541bac
-	"pwdLastSet",
541bac
-	"userAccountControl",
541bac
-	"description",
541bac
+	"sAMAccountName", /* Only set during creation */
541bac
+	"userPrincipalName",   /* :ADPermissions: Read/Write userPrincipal Name */
541bac
+	"msDS-KeyVersionNumber", /* Manages by AD */
541bac
+	"msDS-supportedEncryptionTypes", /* :ADPermissions: Read/Write msDS-SupportedEncryptionTypes */
541bac
+	"dNSHostName", /* :ADPermissions: Read/Write dNSHostName * Read and write DNS host name attributes * Validated write to DNS host name */
541bac
+	"servicePrincipalName", /* :ADPermissions: Read/Write servicePrincipalName * Validated write to service principal name */
541bac
+	"operatingSystem", /* :ADPermissions: Read/Write Operating System */
541bac
+	"operatingSystemVersion", /* :ADPermissions: Read/Write Operating System Version */
541bac
+	"operatingSystemServicePack", /* :ADPermissions: Read/Write operatingSystemServicePack */
541bac
+	"pwdLastSet", /* Managed by AD */
541bac
+	"userAccountControl", /* :ADPermissions: Read/Write userAccountControl */
541bac
+	"description", /* :ADPermissions: Read/Write Description */
541bac
 	NULL,
541bac
 };
541bac
 
541bac
-- 
541bac
2.28.0
541bac