Blame 0003-doc-explain-required-AD-permissions.patch

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