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

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