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

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