diff --git a/.adcli.metadata b/.adcli.metadata
new file mode 100644
index 0000000..877b146
--- /dev/null
+++ b/.adcli.metadata
@@ -0,0 +1 @@
+37e86e0447e9961bb1897ddecfc20445f646ee0f SOURCES/adcli-0.9.1.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..403f165
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/adcli-0.9.1.tar.gz
diff --git a/SOURCES/0001-Fix-for-dont-expire-password-option-and-join.patch b/SOURCES/0001-Fix-for-dont-expire-password-option-and-join.patch
new file mode 100644
index 0000000..92c22f4
--- /dev/null
+++ b/SOURCES/0001-Fix-for-dont-expire-password-option-and-join.patch
@@ -0,0 +1,27 @@
+From 0d8482d4ed83677424f6c9428672d225bfdfe4d9 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Thu, 3 Jun 2021 15:03:20 +0200
+Subject: [PATCH] Fix for dont-expire-password option and join
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1769644
+---
+ library/adenroll.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/library/adenroll.c b/library/adenroll.c
+index 7653f89..f00d179 100644
+--- a/library/adenroll.c
++++ b/library/adenroll.c
+@@ -859,7 +859,8 @@ create_computer_account (adcli_enroll *enroll,
+ 		uac |= UAC_TRUSTED_FOR_DELEGATION;
+ 	}
+ 
+-	if (!adcli_enroll_get_dont_expire_password (enroll)) {
++	if (enroll->dont_expire_password_explicit
++		       && !adcli_enroll_get_dont_expire_password (enroll)) {
+ 		uac &= ~(UAC_DONT_EXPIRE_PASSWORD);
+ 	}
+ 
+-- 
+2.31.1
+
diff --git a/SOURCES/0001-build-add-with-vendor-error-message-configure-option.patch b/SOURCES/0001-build-add-with-vendor-error-message-configure-option.patch
new file mode 100644
index 0000000..75235ee
--- /dev/null
+++ b/SOURCES/0001-build-add-with-vendor-error-message-configure-option.patch
@@ -0,0 +1,60 @@
+From 0353d704879f20983184f8bded4f16538d72f7cc Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 10 Mar 2021 18:12:09 +0100
+Subject: [PATCH] build: add --with-vendor-error-message configure option
+
+With the new configure option --with-vendor-error-message a packager or
+a distribution can add a message if adcli returns with an error.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1889386
+---
+ configure.ac  | 15 +++++++++++++++
+ tools/tools.c |  6 ++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/configure.ac b/configure.ac
+index baa0d3b..7dfba97 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -123,6 +123,21 @@ if test "$sasl_invalid" = "yes"; then
+ 	AC_MSG_ERROR([Couldn't find Cyrus SASL headers])
+ fi
+ 
++# --------------------------------------------------------------------
++# Vendor error message
++
++AC_ARG_WITH([vendor-error-message],
++              [AS_HELP_STRING([--with-vendor-error-message=ARG],
++                            [Add a vendor specific error message shown if a adcli command fails]
++                           )],
++              [AS_IF([test "x$withval" != "x"],
++                     [AC_DEFINE_UNQUOTED([VENDOR_MSG],
++                                         ["$withval"],
++                                         [Vendor specific error message])],
++                     [AC_MSG_ERROR([--with-vendor-error-message requires an argument])]
++                    )],
++              [])
++
+ # --------------------------------------------------------------------
+ # Documentation options
+ 
+diff --git a/tools/tools.c b/tools/tools.c
+index d0dcf98..84bbba9 100644
+--- a/tools/tools.c
++++ b/tools/tools.c
+@@ -538,6 +538,12 @@ main (int argc,
+ 
+ 		if (conn)
+ 			adcli_conn_unref (conn);
++#ifdef VENDOR_MSG
++		if (ret != 0) {
++			fprintf (stderr, VENDOR_MSG"\n");
++		}
++#endif
++
+ 		return ret;
+ 	}
+ 
+-- 
+2.30.2
+
diff --git a/SOURCES/0001-configure-check-for-ns_get16-and-ns_get32-as-well.patch b/SOURCES/0001-configure-check-for-ns_get16-and-ns_get32-as-well.patch
new file mode 100644
index 0000000..22f8a6a
--- /dev/null
+++ b/SOURCES/0001-configure-check-for-ns_get16-and-ns_get32-as-well.patch
@@ -0,0 +1,38 @@
+From e841ba7513f3f8b6393183d2dea9adcbf7ba2e44 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 28 Jul 2021 12:55:16 +0200
+Subject: [PATCH] configure: check for ns_get16 and ns_get32 as well
+
+With newer versions of glibc res_query() might ba already available in
+glibc with ns_get16() and ns_get32() still requires libresolv.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1984891
+---
+ configure.ac | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index c6ff31d..fc6e790 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -98,13 +98,15 @@ AC_SUBST(LDAP_CFLAGS)
+ # -------------------------------------------------------------------
+ # resolv
+ 
+-AC_MSG_CHECKING(for which library has res_query)
++AC_MSG_CHECKING([for which library has res_query, ns_get16 and ns_get32])
+ for lib in "" "-lresolv"; do
+ 	saved_LIBS="$LIBS"
+ 	LIBS="$LIBS $lib"
+ 	AC_LINK_IFELSE([
+ 		AC_LANG_PROGRAM([#include <resolv.h>],
+-		                [res_query (0, 0, 0, 0, 0)])
++		                [res_query (0, 0, 0, 0, 0);
++		                 ns_get32 (NULL);
++		                 ns_get16 (NULL);])
+ 	],
+ 	[ AC_MSG_RESULT(${lib:-libc}); have_res_query="yes"; break; ],
+ 	[ LIBS="$saved_LIBS" ])
+-- 
+2.31.1
+
diff --git a/SOURCES/0001-configure-update-some-macros-for-autoconf-2.71.patch b/SOURCES/0001-configure-update-some-macros-for-autoconf-2.71.patch
new file mode 100644
index 0000000..e9f0bc6
--- /dev/null
+++ b/SOURCES/0001-configure-update-some-macros-for-autoconf-2.71.patch
@@ -0,0 +1,84 @@
+From a8492d71a6db8565544444eef11de8c733c95ef8 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Tue, 6 Apr 2021 19:32:07 +0200
+Subject: [PATCH] configure: update some macros for autoconf-2.71
+
+---
+ configure.ac        | 10 +++++-----
+ library/Makefile.am |  2 +-
+ tools/Makefile.am   |  2 +-
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 7dfba97..c6ff31d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,4 +1,4 @@
+-AC_PREREQ(2.61)
++AC_PREREQ([2.61])
+ 
+ AC_INIT([adcli],
+ 	[0.9.1],
+@@ -33,7 +33,7 @@ LT_INIT([dlopen disable-static])
+ AC_PROG_CC
+ AC_PROG_CPP
+ AM_PROG_CC_C_O
+-AM_PROG_LIBTOOL
++LT_INIT
+ 
+ # -------------------------------------------------------------------
+ # Kerberos
+@@ -143,7 +143,7 @@ AC_ARG_WITH([vendor-error-message],
+ 
+ AC_MSG_CHECKING([whether to build documentation])
+ AC_ARG_ENABLE(doc,
+-              AC_HELP_STRING([--enable-doc],
++              AS_HELP_STRING([--enable-doc],
+                              [Disable building documentation])
+              )
+ 
+@@ -180,7 +180,7 @@ doc_status=$enable_doc
+ 
+ AC_MSG_CHECKING([for debug mode])
+ AC_ARG_ENABLE(debug,
+-              AC_HELP_STRING([--enable-debug=no/default/yes],
++              AS_HELP_STRING([--enable-debug=no/default/yes],
+               [Turn on or off debugging]))
+ 
+ if test "$enable_debug" != "no"; then
+@@ -308,7 +308,7 @@ fi
+ 
+ AC_MSG_CHECKING([where is Samba's net utility])
+ AC_ARG_WITH([samba_data_tool],
+-              AC_HELP_STRING([--with-samba-data-tool=/path],
++              AS_HELP_STRING([--with-samba-data-tool=/path],
+               [Path to Samba's net utility]),
+               [],
+               [with_samba_data_tool=/usr/bin/net])
+diff --git a/library/Makefile.am b/library/Makefile.am
+index 4829555..e046606 100644
+--- a/library/Makefile.am
++++ b/library/Makefile.am
+@@ -1,6 +1,6 @@
+ include $(top_srcdir)/Makefile.decl
+ 
+-INCLUDES = \
++AM_CPPFLAGS = \
+ 	-I$(top_srcdir) \
+ 	-DADCLI_UNSTABLE_API \
+ 	-DHOST_TRIPLET=\"$(host_triplet)\" \
+diff --git a/tools/Makefile.am b/tools/Makefile.am
+index 1cdf451..71ec14d 100644
+--- a/tools/Makefile.am
++++ b/tools/Makefile.am
+@@ -1,6 +1,6 @@
+ include $(top_srcdir)/Makefile.decl
+ 
+-INCLUDES = \
++AM_CPPFLAGS = \
+ 	-I$(top_srcdir) \
+ 	-I$(top_srcdir)/library \
+ 	-DKRB5_CONFIG=\""$(sysconfdir)/krb5.conf"\" \
+-- 
+2.30.2
+
diff --git a/SOURCES/0001-coverity-add-missing-NULL-checks.patch b/SOURCES/0001-coverity-add-missing-NULL-checks.patch
new file mode 100644
index 0000000..cb6c77b
--- /dev/null
+++ b/SOURCES/0001-coverity-add-missing-NULL-checks.patch
@@ -0,0 +1,44 @@
+From 3c652910d05616ee12c710e2071fc884dde4eaea Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 2 Jun 2021 13:39:31 +0200
+Subject: [PATCH 1/2] coverity: add missing NULL checks
+
+---
+ library/adenroll.c | 2 ++
+ library/adldap.c   | 7 +++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/library/adenroll.c b/library/adenroll.c
+index 2b830a4..0f3e8b9 100644
+--- a/library/adenroll.c
++++ b/library/adenroll.c
+@@ -3060,6 +3060,8 @@ adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll,
+ 	krb5_enctype *newval = NULL;
+ 	int len;
+ 
++	return_if_fail (enroll != NULL);
++
+ 	if (value) {
+ 		for (len = 0; value[len] != 0; len++);
+ 		newval = malloc (sizeof (krb5_enctype) * (len + 1));
+diff --git a/library/adldap.c b/library/adldap.c
+index d93efb7..b86014c 100644
+--- a/library/adldap.c
++++ b/library/adldap.c
+@@ -231,6 +231,13 @@ _adcli_ldap_have_in_mod (LDAPMod *mod,
+ 
+ 	vals = malloc (sizeof (struct berval) * (count + 1));
+ 	pvals = malloc (sizeof (struct berval *) * (count + 1));
++	if (vals == NULL || pvals == NULL) {
++		_adcli_err ("Memory allocation failed, assuming attribute must be updated.");
++		free (vals);
++		free (pvals);
++		return 0;
++	}
++
+ 	for (i = 0; i < count; i++) {
+ 		vals[i].bv_val = mod->mod_vals.modv_strvals[i];
+ 		vals[i].bv_len = strlen (vals[i].bv_val);
+-- 
+2.31.1
+
diff --git a/SOURCES/0001-library-move-UAC-flags-to-a-more-common-header-file.patch b/SOURCES/0001-library-move-UAC-flags-to-a-more-common-header-file.patch
new file mode 100644
index 0000000..aea2a99
--- /dev/null
+++ b/SOURCES/0001-library-move-UAC-flags-to-a-more-common-header-file.patch
@@ -0,0 +1,51 @@
+From a7a40ce4f47fe40305624b6d86c135b7d27c387d Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 11 Jun 2021 12:44:36 +0200
+Subject: [PATCH 1/5] library: move UAC flags to a more common header file
+
+---
+ library/adenroll.c  | 8 --------
+ library/adprivate.h | 8 ++++++++
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/library/adenroll.c b/library/adenroll.c
+index f00d179..0b1c066 100644
+--- a/library/adenroll.c
++++ b/library/adenroll.c
+@@ -93,14 +93,6 @@ static char *default_ad_ldap_attrs[] =  {
+ 	NULL,
+ };
+ 
+-/* Some constants for the userAccountControl AD LDAP attribute, see e.g.
+- * https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro
+- * for details. */
+-#define UAC_ACCOUNTDISABLE             0x0002
+-#define UAC_WORKSTATION_TRUST_ACCOUNT  0x1000
+-#define UAC_DONT_EXPIRE_PASSWORD      0x10000
+-#define UAC_TRUSTED_FOR_DELEGATION    0x80000
+-
+ struct _adcli_enroll {
+ 	int refs;
+ 	adcli_conn *conn;
+diff --git a/library/adprivate.h b/library/adprivate.h
+index 55e6234..822f919 100644
+--- a/library/adprivate.h
++++ b/library/adprivate.h
+@@ -39,6 +39,14 @@
+ #define HOST_NAME_MAX 255
+ #endif
+ 
++/* Some constants for the userAccountControl AD LDAP attribute, see e.g.
++ * https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro
++ * for details. */
++#define UAC_ACCOUNTDISABLE             0x0002
++#define UAC_WORKSTATION_TRUST_ACCOUNT  0x1000
++#define UAC_DONT_EXPIRE_PASSWORD      0x10000
++#define UAC_TRUSTED_FOR_DELEGATION    0x80000
++
+ /* Utilities */
+ 
+ #if !defined(__cplusplus) && (__GNUC__ > 2)
+-- 
+2.31.1
+
diff --git a/SOURCES/0002-Add-dont-expire-password-option.patch b/SOURCES/0002-Add-dont-expire-password-option.patch
new file mode 100644
index 0000000..5189f40
--- /dev/null
+++ b/SOURCES/0002-Add-dont-expire-password-option.patch
@@ -0,0 +1,229 @@
+From a78116ba0e608050f391223bad3834d48c9adf1b Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 2 Jun 2021 17:24:07 +0200
+Subject: [PATCH 2/2] Add dont-expire-password option
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1769644
+---
+ doc/adcli.xml      | 28 ++++++++++++++++++++++++++++
+ library/adenroll.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
+ library/adenroll.h |  4 ++++
+ tools/computer.c   | 12 ++++++++++++
+ 4 files changed, 87 insertions(+), 1 deletion(-)
+
+diff --git a/doc/adcli.xml b/doc/adcli.xml
+index 8ec48d4..1ed5d3f 100644
+--- a/doc/adcli.xml
++++ b/doc/adcli.xml
+@@ -347,6 +347,20 @@ Password for Administrator:
+ 			not allow that Kerberos tickets can be forwarded to the
+ 			host.</para></listitem>
+ 		</varlistentry>
++		<varlistentry>
++			<term><option>--dont-expire-password=<parameter>yes|no|true|false</parameter></option></term>
++			<listitem><para>Set or unset the DONT_EXPIRE_PASSWORD
++			flag in the userAccountControl attribute to indicate if
++			the machine account password should expire or not. By
++			default adcli will set this flag while joining the
++			domain which corresponds to the default behavior of
++			Windows clients.</para>
++			<para>Please note that if the password will expire
++			(--dont-expire-password=false) a renewal mechanism has
++			to be enabled on the client to not loose the
++			connectivity to AD if the password expires.</para>
++			</listitem>
++		</varlistentry>
+ 		<varlistentry>
+ 			<term><option>--add-service-principal=<parameter>service/hostname</parameter></option></term>
+ 			<listitem><para>Add a service principal name. In
+@@ -491,6 +505,20 @@ $ adcli update --login-ccache=/tmp/krbcc_123
+ 			not allow that Kerberos tickets can be forwarded to the
+ 			host.</para></listitem>
+ 		</varlistentry>
++		<varlistentry>
++			<term><option>--dont-expire-password=<parameter>yes|no|true|false</parameter></option></term>
++			<listitem><para>Set or unset the DONT_EXPIRE_PASSWORD
++			flag in the userAccountControl attribute to indicate if
++			the machine account password should expire or not. By
++			default adcli will set this flag while joining the
++			domain which corresponds to the default behavior of
++			Windows clients.</para>
++			<para>Please note that if the password will expire
++			(--dont-expire-password=false) a renewal mechanism has
++			to be enabled on the client to not loose the
++			connectivity to AD if the password expires.</para>
++			</listitem>
++		</varlistentry>
+ 		<varlistentry>
+ 			<term><option>--account-disable=<parameter>yes|no|true|false</parameter></option></term>
+ 			<listitem><para>Set or unset the ACCOUNTDISABLE
+diff --git a/library/adenroll.c b/library/adenroll.c
+index 0f3e8b9..7653f89 100644
+--- a/library/adenroll.c
++++ b/library/adenroll.c
+@@ -153,6 +153,8 @@ struct _adcli_enroll {
+ 	char *samba_data_tool;
+ 	bool trusted_for_delegation;
+ 	int trusted_for_delegation_explicit;
++	bool dont_expire_password;
++	int dont_expire_password_explicit;
+ 	bool account_disable;
+ 	int account_disable_explicit;
+ 	char *description;
+@@ -832,6 +834,8 @@ create_computer_account (adcli_enroll *enroll,
+ 	int ret;
+ 	size_t c;
+ 	size_t m;
++	uint32_t uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD ;
++	char *uac_str = NULL;
+ 
+ 	LDAPMod *all_mods[] = {
+ 		&objectClass,
+@@ -852,11 +856,21 @@ create_computer_account (adcli_enroll *enroll,
+ 	LDAPMod *mods[mods_count];
+ 
+ 	if (adcli_enroll_get_trusted_for_delegation (enroll)) {
+-		vals_userAccountControl[0] = "593920"; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD | TRUSTED_FOR_DELEGATION */
++		uac |= UAC_TRUSTED_FOR_DELEGATION;
+ 	}
+ 
++	if (!adcli_enroll_get_dont_expire_password (enroll)) {
++		uac &= ~(UAC_DONT_EXPIRE_PASSWORD);
++	}
++
++	if (asprintf (&uac_str, "%d", uac) < 0) {
++		return_val_if_reached (ADCLI_ERR_UNEXPECTED);
++	}
++	vals_userAccountControl[0] = uac_str;
++
+ 	ret = calculate_enctypes (enroll, &val);
+ 	if (ret != ADCLI_SUCCESS) {
++		free (uac_str);
+ 		return ret;
+ 	}
+ 	vals_supportedEncryptionTypes[0] = val;
+@@ -871,6 +885,7 @@ create_computer_account (adcli_enroll *enroll,
+ 	mods[m] = NULL;
+ 
+ 	ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
++	free (uac_str);
+ 	free (val);
+ 
+ 	/*
+@@ -1577,6 +1592,14 @@ static char *get_user_account_control (adcli_enroll *enroll)
+ 		}
+ 	}
+ 
++	if (enroll->dont_expire_password_explicit) {
++		if (adcli_enroll_get_dont_expire_password (enroll)) {
++			uac |= UAC_DONT_EXPIRE_PASSWORD;
++		} else {
++			uac &= ~(UAC_DONT_EXPIRE_PASSWORD);
++		}
++	}
++
+ 	if (enroll->account_disable_explicit) {
+ 		if (adcli_enroll_get_account_disable (enroll)) {
+ 			uac |= UAC_ACCOUNTDISABLE;
+@@ -1627,6 +1650,7 @@ update_computer_account (adcli_enroll *enroll)
+ 	free (value);
+ 
+ 	if (res == ADCLI_SUCCESS && (enroll->trusted_for_delegation_explicit ||
++	                             enroll->dont_expire_password_explicit ||
+ 	                             enroll->account_disable_explicit)) {
+ 		char *vals_userAccountControl[] = { NULL , NULL };
+ 		LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
+@@ -3208,6 +3232,24 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
+ 	enroll->trusted_for_delegation_explicit = 1;
+ }
+ 
++bool
++adcli_enroll_get_dont_expire_password (adcli_enroll *enroll)
++{
++	return_val_if_fail (enroll != NULL, false);
++
++	return enroll->dont_expire_password;
++}
++
++void
++adcli_enroll_set_dont_expire_password (adcli_enroll *enroll,
++                                       bool value)
++{
++	return_if_fail (enroll != NULL);
++
++	enroll->dont_expire_password = value;
++	enroll->dont_expire_password_explicit = 1;
++}
++
+ bool
+ adcli_enroll_get_account_disable (adcli_enroll *enroll)
+ {
+diff --git a/library/adenroll.h b/library/adenroll.h
+index 8b1c1c7..34dc683 100644
+--- a/library/adenroll.h
++++ b/library/adenroll.h
+@@ -126,6 +126,10 @@ bool               adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll
+ void               adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
+                                                             bool value);
+ 
++bool               adcli_enroll_get_dont_expire_password (adcli_enroll *enroll);
++void               adcli_enroll_set_dont_expire_password (adcli_enroll *enroll,
++                                                          bool value);
++
+ bool               adcli_enroll_get_account_disable     (adcli_enroll *enroll);
+ void               adcli_enroll_set_account_disable     (adcli_enroll *enroll,
+                                                          bool value);
+diff --git a/tools/computer.c b/tools/computer.c
+index 6e309d9..16a1983 100644
+--- a/tools/computer.c
++++ b/tools/computer.c
+@@ -110,6 +110,7 @@ typedef enum {
+ 	opt_add_samba_data,
+ 	opt_samba_data_tool,
+ 	opt_trusted_for_delegation,
++	opt_dont_expire_password,
+ 	opt_add_service_principal,
+ 	opt_remove_service_principal,
+ 	opt_description,
+@@ -144,6 +145,8 @@ static adcli_tool_desc common_usages[] = {
+ 	{ opt_computer_password_lifetime, "lifetime of the host accounts password in days", },
+ 	{ opt_trusted_for_delegation, "set/unset the TRUSTED_FOR_DELEGATION flag\n"
+ 	                              "in the userAccountControl attribute", },
++	{ opt_dont_expire_password, "set/unset the DONT_EXPIRE_PASSWORD flag\n"
++	                            "in the userAccountControl attribute", },
+ 	{ opt_account_disable, "set/unset the ACCOUNTDISABLE flag\n"
+ 	                       "in the userAccountControl attribute", },
+ 	{ opt_add_service_principal, "add the given service principal to the account\n" },
+@@ -307,6 +310,13 @@ parse_option (Option opt,
+ 			adcli_enroll_set_trusted_for_delegation (enroll, false);
+ 		}
+ 		return ADCLI_SUCCESS;
++	case opt_dont_expire_password:
++		if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
++			adcli_enroll_set_dont_expire_password (enroll, true);
++		} else {
++			adcli_enroll_set_dont_expire_password (enroll, false);
++		}
++		return ADCLI_SUCCESS;
+ 	case opt_account_disable:
+ 		if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
+ 			adcli_enroll_set_account_disable (enroll, true);
+@@ -393,6 +403,7 @@ adcli_tool_computer_join (adcli_conn *conn,
+ 		{ "description", optional_argument, NULL, opt_description },
+ 		{ "user-principal", optional_argument, NULL, opt_user_principal },
+ 		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
++		{ "dont-expire-password", required_argument, NULL, opt_dont_expire_password },
+ 		{ "add-service-principal", required_argument, NULL, opt_add_service_principal },
+ 		{ "show-details", no_argument, NULL, opt_show_details },
+ 		{ "show-password", no_argument, NULL, opt_show_password },
+@@ -516,6 +527,7 @@ adcli_tool_computer_update (adcli_conn *conn,
+ 		{ "user-principal", optional_argument, NULL, opt_user_principal },
+ 		{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime },
+ 		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
++		{ "dont-expire-password", required_argument, NULL, opt_dont_expire_password },
+ 		{ "account-disable", required_argument, NULL, opt_account_disable },
+ 		{ "add-service-principal", required_argument, NULL, opt_add_service_principal },
+ 		{ "remove-service-principal", required_argument, NULL, opt_remove_service_principal },
+-- 
+2.31.1
+
diff --git a/SOURCES/0002-adcli_entry-add-entry_attrs-with-userAccountControl-.patch b/SOURCES/0002-adcli_entry-add-entry_attrs-with-userAccountControl-.patch
new file mode 100644
index 0000000..cb92099
--- /dev/null
+++ b/SOURCES/0002-adcli_entry-add-entry_attrs-with-userAccountControl-.patch
@@ -0,0 +1,60 @@
+From 7148ab196d0a96ede9b5ef463b0481d0fe372b21 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 11 Jun 2021 12:46:03 +0200
+Subject: [PATCH 2/5] adcli_entry: add entry_attrs with userAccountControl
+ attribute
+
+---
+ library/adentry.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/library/adentry.c b/library/adentry.c
+index 1cc0518..13dcaf8 100644
+--- a/library/adentry.c
++++ b/library/adentry.c
+@@ -42,6 +42,7 @@ struct _adcli_entry {
+ 	char *entry_dn;
+ 	char *domain_ou;
+ 	char *entry_container;
++	LDAPMessage *entry_attrs;
+ };
+ 
+ static adcli_entry *
+@@ -63,6 +64,7 @@ entry_new (adcli_conn *conn,
+ 
+ 	entry->builder = builder;
+ 	entry->object_class = object_class;
++	entry->entry_attrs = NULL;
+ 	return entry;
+ }
+ 
+@@ -82,6 +84,7 @@ entry_free (adcli_entry *entry)
+ 	free (entry->entry_container);
+ 	free (entry->entry_dn);
+ 	free (entry->domain_ou);
++	ldap_msgfree (entry->entry_attrs);
+ 	adcli_conn_unref (entry->conn);
+ 	free (entry);
+ }
+@@ -102,7 +105,7 @@ static adcli_result
+ update_entry_from_domain (adcli_entry *entry,
+                           LDAP *ldap)
+ {
+-	const char *attrs[] = { "1.1", NULL };
++	const char *attrs[] = { "userAccountControl", NULL };
+ 	LDAPMessage *results;
+ 	LDAPMessage *first;
+ 	const char *base;
+@@ -139,7 +142,8 @@ update_entry_from_domain (adcli_entry *entry,
+ 		return_unexpected_if_fail (entry->entry_dn != NULL);
+ 	}
+ 
+-	ldap_msgfree (results);
++	ldap_msgfree (entry->entry_attrs);
++	entry->entry_attrs = results;
+ 	return ADCLI_SUCCESS;
+ }
+ 
+-- 
+2.31.1
+
diff --git a/SOURCES/0003-entry-add-passwd-user-sub-command.patch b/SOURCES/0003-entry-add-passwd-user-sub-command.patch
new file mode 100644
index 0000000..7ad5111
--- /dev/null
+++ b/SOURCES/0003-entry-add-passwd-user-sub-command.patch
@@ -0,0 +1,366 @@
+From 6a673b236dfdfdf9c73cc3d2ccf3949eb1a5ddd0 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 11 Jun 2021 12:47:37 +0200
+Subject: [PATCH 3/5] entry: add passwd-user sub-command
+
+The new command allows to set or reset a user password with the help of
+an account privileged to set the password.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1952828
+---
+ doc/adcli.xml     |  20 +++++++
+ library/adentry.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++
+ library/adentry.h |   3 +
+ tools/entry.c     |  99 +++++++++++++++++++++++++++++++++
+ tools/tools.c     |   1 +
+ tools/tools.h     |   4 ++
+ 6 files changed, 265 insertions(+)
+
+diff --git a/doc/adcli.xml b/doc/adcli.xml
+index 1ed5d3f..6c36297 100644
+--- a/doc/adcli.xml
++++ b/doc/adcli.xml
+@@ -56,6 +56,11 @@
+ 		<arg choice="opt">--domain=domain.example.com</arg>
+ 		<arg choice="plain">user</arg>
+ 	</cmdsynopsis>
++	<cmdsynopsis>
++		<command>adcli passwd-user</command>
++		<arg choice="opt">--domain=domain.example.com</arg>
++		<arg choice="plain">user</arg>
++	</cmdsynopsis>
+ 	<cmdsynopsis>
+ 		<command>adcli create-group</command>
+ 		<arg choice="opt">--domain=domain.example.com</arg>
+@@ -696,6 +701,21 @@ $ adcli delete-user Fry --domain=domain.example.com
+ 
+ </refsect1>
+ 
++<refsect1 id='passwd_user'>
++	<title>(Re)setting the password of a User with an Administrative Account</title>
++
++	<para><command>adcli passwd-user</command> sets or resets the password
++	of user account. The administrative account used for this operation
++	must have privileges to set a password.</para>
++
++<programlisting>
++$ adcli passwd-user Fry --domain=domain.example.com
++</programlisting>
++
++	<para>The various global options can be used.</para>
++
++</refsect1>
++
+ 
+ <refsect1 id='create_group'>
+ 	<title>Creating a Group</title>
+diff --git a/library/adentry.c b/library/adentry.c
+index 13dcaf8..0d9b9af 100644
+--- a/library/adentry.c
++++ b/library/adentry.c
+@@ -409,6 +409,144 @@ adcli_entry_delete (adcli_entry *entry)
+ 	return ADCLI_SUCCESS;
+ }
+ 
++static adcli_result
++adcli_entry_ensure_enabled (adcli_entry *entry)
++{
++	adcli_result res;
++	LDAP *ldap;
++	adcli_attrs *attrs;
++	uint32_t uac = 0;
++	char *uac_str;
++	unsigned long attr_val;
++	char *end;
++
++	return_unexpected_if_fail (entry->entry_attrs != NULL);
++
++	ldap = adcli_conn_get_ldap_connection (entry->conn);
++	return_unexpected_if_fail (ldap != NULL);
++
++	uac_str = _adcli_ldap_parse_value (ldap, entry->entry_attrs,
++	                                   "userAccountControl");
++	if (uac_str != NULL) {
++		attr_val = strtoul (uac_str, &end, 10);
++		if (*end != '\0' || attr_val > UINT32_MAX) {
++			_adcli_warn ("Invalid userAccountControl '%s' for %s account in directory: %s, assuming 0",
++			            uac_str, entry->object_class, entry->entry_dn);
++		} else {
++			uac = attr_val;
++		}
++		free (uac_str);
++	}
++	if (uac & UAC_ACCOUNTDISABLE) {
++		uac &= ~(UAC_ACCOUNTDISABLE);
++
++		if (asprintf (&uac_str, "%d", uac) < 0) {
++			_adcli_warn ("Cannot enable %s entry %s after password (re)set",
++			             entry->object_class, entry->entry_dn);
++			return ADCLI_ERR_UNEXPECTED;
++		}
++
++		attrs = adcli_attrs_new ();
++		adcli_attrs_replace (attrs, "userAccountControl", uac_str,
++		                     NULL);
++		res = adcli_entry_modify (entry, attrs);
++		if (res == ADCLI_SUCCESS) {
++			_adcli_info ("Enabled %s entry %s after password (re)set",
++			             entry->object_class, entry->entry_dn);
++		} else {
++			_adcli_warn ("Failed to enable %s entry %s after password (re)set",
++			             entry->object_class, entry->entry_dn);
++		}
++		free (uac_str);
++		adcli_attrs_free (attrs);
++	} else {
++		res = ADCLI_SUCCESS;
++	}
++
++	return res;
++}
++
++adcli_result
++adcli_entry_set_passwd (adcli_entry *entry, const char *user_pwd)
++{
++	adcli_result res;
++	LDAP *ldap;
++	krb5_error_code code;
++	krb5_context k5;
++	krb5_ccache ccache;
++	krb5_data result_string = { 0, };
++	krb5_data result_code_string = { 0, };
++	int result_code;
++	char *message;
++	krb5_principal user_principal;
++
++	ldap = adcli_conn_get_ldap_connection (entry->conn);
++	return_unexpected_if_fail (ldap != NULL);
++
++	/* Find the user */
++	res = update_entry_from_domain (entry, ldap);
++	if (res != ADCLI_SUCCESS)
++		return res;
++
++	if (!entry->entry_dn) {
++		_adcli_err ("Cannot find the %s entry %s in the domain",
++		            entry->object_class, entry->sam_name);
++		return ADCLI_ERR_CONFIG;
++	}
++
++	k5 = adcli_conn_get_krb5_context (entry->conn);
++	return_unexpected_if_fail (k5 != NULL);
++
++	code = _adcli_krb5_build_principal (k5, entry->sam_name,
++	                                    adcli_conn_get_domain_realm (entry->conn),
++	                                    &user_principal);
++	return_unexpected_if_fail (code == 0);
++
++	ccache = adcli_conn_get_login_ccache (entry->conn);
++	return_unexpected_if_fail (ccache != NULL);
++
++	memset (&result_string, 0, sizeof (result_string));
++	memset (&result_code_string, 0, sizeof (result_code_string));
++
++	code = krb5_set_password_using_ccache (k5, ccache, user_pwd,
++	                                       user_principal, &result_code,
++	                                       &result_code_string, &result_string);
++
++	if (code != 0) {
++		_adcli_err ("Couldn't set password for %s account: %s: %s",
++		            entry->object_class,
++		            entry->sam_name, krb5_get_error_message (k5, code));
++		/* TODO: Parse out these values */
++		res = ADCLI_ERR_DIRECTORY;
++
++	} else if (result_code != 0) {
++#ifdef HAVE_KRB5_CHPW_MESSAGE
++		if (krb5_chpw_message (k5, &result_string, &message) != 0)
++			message = NULL;
++#else
++		message = NULL;
++		if (result_string.length)
++			message = _adcli_str_dupn (result_string.data, result_string.length);
++#endif
++		_adcli_err ("Cannot set %s password: %.*s%s%s",
++		            entry->object_class,
++		            (int)result_code_string.length, result_code_string.data,
++		            message ? ": " : "", message ? message : "");
++		res = ADCLI_ERR_CREDENTIALS;
++#ifdef HAVE_KRB5_CHPW_MESSAGE
++		krb5_free_string (k5, message);
++#else
++		free (message);
++#endif
++	} else {
++		_adcli_info ("Password (re)setted for %s: %s", entry->object_class, entry->entry_dn);
++
++		res = adcli_entry_ensure_enabled (entry);
++	}
++
++	return res;
++}
++
+ const char *
+ adcli_entry_get_sam_name (adcli_entry *entry)
+ {
+diff --git a/library/adentry.h b/library/adentry.h
+index ae90689..f2382b1 100644
+--- a/library/adentry.h
++++ b/library/adentry.h
+@@ -49,6 +49,9 @@ adcli_result       adcli_entry_modify                   (adcli_entry *entry,
+ 
+ adcli_result       adcli_entry_delete                   (adcli_entry *entry);
+ 
++adcli_result       adcli_entry_set_passwd               (adcli_entry *entry,
++                                                         const char *user_pwd);
++
+ const char *       adcli_entry_get_domain_ou            (adcli_entry *entry);
+ 
+ void               adcli_entry_set_domain_ou            (adcli_entry *entry,
+diff --git a/tools/entry.c b/tools/entry.c
+index 05e4313..52d2546 100644
+--- a/tools/entry.c
++++ b/tools/entry.c
+@@ -24,6 +24,7 @@
+ #include "config.h"
+ 
+ #include "adcli.h"
++#include "adprivate.h"
+ #include "adattrs.h"
+ #include "tools.h"
+ 
+@@ -385,6 +386,104 @@ adcli_tool_user_delete (adcli_conn *conn,
+ 	return 0;
+ }
+ 
++int
++adcli_tool_user_passwd (adcli_conn *conn,
++                        int argc,
++                        char *argv[])
++{
++	adcli_result res;
++	adcli_entry *entry;
++	int opt;
++	char *user_pwd = NULL;
++
++	struct option options[] = {
++		{ "domain", required_argument, NULL, opt_domain },
++		{ "domain-realm", required_argument, NULL, opt_domain_realm },
++		{ "domain-controller", required_argument, NULL, opt_domain_controller },
++		{ "use-ldaps", no_argument, 0, opt_use_ldaps },
++		{ "login-user", required_argument, NULL, opt_login_user },
++		{ "login-ccache", optional_argument, NULL, opt_login_ccache },
++		{ "no-password", no_argument, 0, opt_no_password },
++		{ "stdin-password", no_argument, 0, opt_stdin_password },
++		{ "prompt-password", no_argument, 0, opt_prompt_password },
++		{ "verbose", no_argument, NULL, opt_verbose },
++		{ "help", no_argument, NULL, 'h' },
++		{ 0 },
++	};
++
++	static adcli_tool_desc usages[] = {
++		{ 0, "usage: adcli passwd-user --domain=xxxx user" },
++		{ 0 },
++	};
++
++	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
++		switch (opt) {
++		case 'h':
++		case '?':
++		case ':':
++			adcli_tool_usage (options, usages);
++			adcli_tool_usage (options, common_usages);
++			return opt == 'h' ? 0 : 2;
++		default:
++			res = parse_option ((Option)opt, optarg, conn);
++			if (res != ADCLI_SUCCESS) {
++				return res;
++			}
++			break;
++		}
++	}
++
++	argc -= optind;
++	argv += optind;
++
++	if (argc != 1) {
++		warnx ("specify one user name to (re)set password");
++		return 2;
++	}
++
++	entry = adcli_entry_new_user (conn, argv[0]);
++	if (entry == NULL) {
++		warnx ("unexpected memory problems");
++		return -1;
++	}
++
++	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
++
++	res = adcli_conn_connect (conn);
++	if (res != ADCLI_SUCCESS) {
++		warnx ("couldn't connect to %s domain: %s",
++		       adcli_conn_get_domain_name (conn),
++		       adcli_get_last_error ());
++		adcli_entry_unref (entry);
++		return -res;
++	}
++
++	user_pwd = adcli_prompt_password_func (ADCLI_LOGIN_USER_ACCOUNT,
++	                                       adcli_entry_get_sam_name(entry),
++	                                       0, NULL);
++	if (user_pwd == NULL || *user_pwd == '\0') {
++		warnx ("missing password");
++		_adcli_password_free (user_pwd);
++		adcli_entry_unref (entry);
++		return 2;
++	}
++
++	res = adcli_entry_set_passwd (entry, user_pwd);
++	_adcli_password_free (user_pwd);
++	if (res != ADCLI_SUCCESS) {
++		warnx ("(re)setting password for user %s in domain %s failed: %s",
++		       adcli_entry_get_sam_name (entry),
++		       adcli_conn_get_domain_name (conn),
++		       adcli_get_last_error ());
++		adcli_entry_unref (entry);
++		return -res;
++	}
++
++	adcli_entry_unref (entry);
++
++	return 0;
++}
++
+ int
+ adcli_tool_group_create (adcli_conn *conn,
+                          int argc,
+diff --git a/tools/tools.c b/tools/tools.c
+index 84bbba9..a14b9ca 100644
+--- a/tools/tools.c
++++ b/tools/tools.c
+@@ -63,6 +63,7 @@ struct {
+ 	{ "create-msa", adcli_tool_computer_managed_service_account, "Create a managed service account in the given AD domain", },
+ 	{ "create-user", adcli_tool_user_create, "Create a user account", },
+ 	{ "delete-user", adcli_tool_user_delete, "Delete a user account", },
++	{ "passwd-user", adcli_tool_user_passwd, "(Re)set a user password", },
+ 	{ "create-group", adcli_tool_group_create, "Create a group", },
+ 	{ "delete-group", adcli_tool_group_delete, "Delete a group", },
+ 	{ "add-member", adcli_tool_member_add, "Add users to a group", },
+diff --git a/tools/tools.h b/tools/tools.h
+index 82d5e4e..d38aa32 100644
+--- a/tools/tools.h
++++ b/tools/tools.h
+@@ -94,6 +94,10 @@ int       adcli_tool_user_delete       (adcli_conn *conn,
+                                         int argc,
+                                         char *argv[]);
+ 
++int       adcli_tool_user_passwd       (adcli_conn *conn,
++                                        int argc,
++                                        char *argv[]);
++
+ int       adcli_tool_group_create      (adcli_conn *conn,
+                                         int argc,
+                                         char *argv[]);
+-- 
+2.31.1
+
diff --git a/SOURCES/0004-Add-setattr-option.patch b/SOURCES/0004-Add-setattr-option.patch
new file mode 100644
index 0000000..7976e7c
--- /dev/null
+++ b/SOURCES/0004-Add-setattr-option.patch
@@ -0,0 +1,386 @@
+From c5b0cee2976682b4fc1aeb02636cc9f2c6dbc2a5 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Mon, 14 Jun 2021 07:54:01 +0200
+Subject: [PATCH 4/5] Add setattr option
+
+With the new option common LDAP attributes can be set.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690920
+---
+ doc/adcli.xml      |  34 +++++++++
+ library/adenroll.c | 169 ++++++++++++++++++++++++++++++++++++++++++++-
+ library/adenroll.h |   4 ++
+ tools/computer.c   |  10 +++
+ 4 files changed, 216 insertions(+), 1 deletion(-)
+
+diff --git a/doc/adcli.xml b/doc/adcli.xml
+index 6c36297..8383aa7 100644
+--- a/doc/adcli.xml
++++ b/doc/adcli.xml
+@@ -374,6 +374,23 @@ Password for Administrator:
+ 			service should be accessible with a different host
+ 			name as well.</para></listitem>
+ 		</varlistentry>
++		<varlistentry>
++			<term><option>--setattr=<parameter>name=value</parameter></option></term>
++			<listitem><para>Add the LDAP attribute
++			<option><parameter>name</parameter></option> with the
++			given <option><parameter>value</parameter></option> to
++			the new LDAP host object.
++			This option can be used multiple times to add multiple
++			different attributes. Multi-value attributes are
++			currently not supported.</para>
++			<para>Please note that the account used to join the
++			domain must have the required privileges to add the
++			given attributes. Some attributes might have
++			constraints with respect to syntax and allowed values
++			which must be met as well. Attributes managed by other
++			adcli options cannot be set with this option.</para>
++			</listitem>
++		</varlistentry>
+ 		<varlistentry>
+ 			<term><option>--show-details</option></term>
+ 			<listitem><para>After a successful join print out information
+@@ -543,6 +560,23 @@ $ adcli update --login-ccache=/tmp/krbcc_123
+ 			<listitem><para>Remove a service principal name from
+ 			the keytab and the AD host object.</para></listitem>
+ 		</varlistentry>
++		<varlistentry>
++			<term><option>--setattr=<parameter>name=value</parameter></option></term>
++			<listitem><para>Add the LDAP attribute
++			<option><parameter>name</parameter></option> with the
++			given <option><parameter>value</parameter></option> to
++			the LDAP host object.
++			This option can be used multiple times to add multiple
++			different attributes. Multi-value attributes are
++			currently not supported.</para>
++			<para>Please note that the account used to update the
++			host object must have the required privileges to modify
++			the given attributes. Some attributes might have
++			constraints with respect to syntax and allowed values
++			which must be met as well. Attributes managed by other
++			adcli options cannot be set with this option.</para>
++			</listitem>
++		</varlistentry>
+ 		<varlistentry>
+ 			<term><option>--show-details</option></term>
+ 			<listitem><para>After a successful join print out information
+diff --git a/library/adenroll.c b/library/adenroll.c
+index 0b1c066..dd51567 100644
+--- a/library/adenroll.c
++++ b/library/adenroll.c
+@@ -150,6 +150,7 @@ struct _adcli_enroll {
+ 	bool account_disable;
+ 	int account_disable_explicit;
+ 	char *description;
++	char **setattr;
+ };
+ 
+ static const char *
+@@ -795,6 +796,56 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
+ 	return ADCLI_SUCCESS;
+ }
+ 
++static LDAPMod **
++get_mods_for_attrs (adcli_enroll *enroll, int mod_op)
++{
++	size_t len;
++	size_t c;
++	char *end;
++	LDAPMod **mods = NULL;
++
++	len = _adcli_strv_len (enroll->setattr);
++	if (len == 0) {
++		return NULL;
++	}
++
++	mods = calloc (len + 1, sizeof (LDAPMod *));
++	return_val_if_fail (mods != NULL, NULL);
++
++	for (c = 0; c < len; c++) {
++		end = strchr (enroll->setattr[c], '=');
++		if (end == NULL) {
++			ldap_mods_free (mods, 1);
++			return NULL;
++		}
++
++		mods[c] = calloc (1, sizeof (LDAPMod));
++		if (mods[c] == NULL) {
++			ldap_mods_free (mods, 1);
++			return NULL;
++		}
++
++		mods[c]->mod_op = mod_op;
++		*end = '\0';
++		mods[c]->mod_type = strdup (enroll->setattr[c]);
++		*end = '=';
++		mods[c]->mod_values = calloc (2, sizeof (char *));
++		if (mods[c]->mod_type == NULL || mods[c]->mod_values == NULL) {
++			ldap_mods_free (mods, 1);
++			return NULL;
++		}
++
++		mods[c]->mod_values[0] = strdup (end + 1);
++		if (mods[c]->mod_values[0] == NULL) {
++			ldap_mods_free (mods, 1);
++			return NULL;
++		}
++	}
++
++	return mods;
++}
++
++
+ static adcli_result
+ create_computer_account (adcli_enroll *enroll,
+                          LDAP *ldap)
+@@ -828,6 +879,7 @@ create_computer_account (adcli_enroll *enroll,
+ 	size_t m;
+ 	uint32_t uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD ;
+ 	char *uac_str = NULL;
++	LDAPMod **extra_mods = NULL;
+ 
+ 	LDAPMod *all_mods[] = {
+ 		&objectClass,
+@@ -845,7 +897,7 @@ create_computer_account (adcli_enroll *enroll,
+ 	};
+ 
+ 	size_t mods_count = sizeof (all_mods) / sizeof (LDAPMod *);
+-	LDAPMod *mods[mods_count];
++	LDAPMod **mods;
+ 
+ 	if (adcli_enroll_get_trusted_for_delegation (enroll)) {
+ 		uac |= UAC_TRUSTED_FOR_DELEGATION;
+@@ -868,6 +920,17 @@ create_computer_account (adcli_enroll *enroll,
+ 	}
+ 	vals_supportedEncryptionTypes[0] = val;
+ 
++	if (enroll->setattr != NULL) {
++		extra_mods = get_mods_for_attrs (enroll, LDAP_MOD_ADD);
++		if (extra_mods == NULL) {
++			_adcli_err ("Failed to add setattr attributes, "
++			            "just using defaults");
++		}
++	}
++
++	mods = calloc (mods_count + seq_count (extra_mods) + 1, sizeof (LDAPMod *));
++	return_val_if_fail (mods != NULL, ADCLI_ERR_UNEXPECTED);
++
+ 	m = 0;
+ 	for (c = 0; c < mods_count - 1; c++) {
+ 		/* Skip empty LDAP sttributes */
+@@ -875,9 +938,15 @@ create_computer_account (adcli_enroll *enroll,
+ 			mods[m++] = all_mods[c];
+ 		}
+ 	}
++
++	for (c = 0; c < seq_count (extra_mods); c++) {
++		mods[m++] = extra_mods[c];
++	}
+ 	mods[m] = NULL;
+ 
+ 	ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL);
++	ldap_mods_free (extra_mods, 1);
++	free (mods);
+ 	free (uac_str);
+ 	free (val);
+ 
+@@ -1698,6 +1767,14 @@ update_computer_account (adcli_enroll *enroll)
+ 		res |= update_computer_attribute (enroll, ldap, mods);
+ 	}
+ 
++	if (res == ADCLI_SUCCESS && enroll->setattr != NULL) {
++		LDAPMod **mods = get_mods_for_attrs (enroll, LDAP_MOD_REPLACE);
++		if (mods != NULL) {
++			res |= update_computer_attribute (enroll, ldap, mods);
++			ldap_mods_free (mods, 1);
++		}
++	}
++
+ 	if (res != 0)
+ 		_adcli_info ("Updated existing computer account: %s", enroll->computer_dn);
+ }
+@@ -2751,6 +2828,7 @@ enroll_free (adcli_enroll *enroll)
+ 	free (enroll->user_principal);
+ 	_adcli_strv_free (enroll->service_names);
+ 	_adcli_strv_free (enroll->service_principals);
++	_adcli_strv_free (enroll->setattr);
+ 	_adcli_password_free (enroll->computer_password);
+ 
+ 	adcli_enroll_set_keytab_name (enroll, NULL);
+@@ -3332,6 +3410,72 @@ adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
+ 	return_if_fail (enroll->service_principals_to_remove != NULL);
+ }
+ 
++static int comp_attr_name (const char *s1, const char *s2)
++{
++	size_t c = 0;
++
++	/* empty strings cannot contain an attribute name */
++	if (s1 == NULL || s2 == NULL || *s1 == '\0' || *s2 == '\0') {
++		return 1;
++	}
++
++	for (c = 0 ; s1[c] != '\0' && s2[c] != '\0'; c++) {
++		if (s1[c] == '=' && s2[c] == '=') {
++			return 0;
++		} else if (tolower (s1[c]) != tolower (s2[c])) {
++			return 1;
++		}
++	}
++
++	return 1;
++}
++
++adcli_result
++adcli_enroll_add_setattr (adcli_enroll *enroll, const char *value)
++{
++	char *delim;
++
++	return_val_if_fail (enroll != NULL, ADCLI_ERR_CONFIG);
++	return_val_if_fail (value != NULL, ADCLI_ERR_CONFIG);
++
++	delim = strchr (value, '=');
++	if (delim == NULL) {
++		_adcli_err ("Missing '=' in setattr option [%s]", value);
++		return ADCLI_ERR_CONFIG;
++	}
++
++	if (*(delim + 1) == '\0') {
++		_adcli_err ("Missing value in setattr option [%s]", value);
++		return ADCLI_ERR_CONFIG;
++	}
++
++	*delim = '\0';
++	if (_adcli_strv_has_ex (default_ad_ldap_attrs, value, strcasecmp) == 1) {
++		_adcli_err ("Attribute [%s] cannot be set with setattr", value);
++		return ADCLI_ERR_CONFIG;
++	}
++	*delim = '=';
++
++	if (_adcli_strv_has_ex (enroll->setattr, value, comp_attr_name) == 1) {
++		_adcli_err ("Attribute [%s] already set", value);
++		return ADCLI_ERR_CONFIG;
++	}
++
++	enroll->setattr = _adcli_strv_add (enroll->setattr, strdup (value),
++	                                   NULL);
++	return_val_if_fail (enroll->setattr != NULL, ADCLI_ERR_CONFIG);
++
++	return ADCLI_SUCCESS;
++}
++
++const char **
++adcli_enroll_get_setattr (adcli_enroll *enroll)
++{
++	return_val_if_fail (enroll != NULL, NULL);
++	return (const char **) enroll->setattr;
++}
++
++
+ #ifdef ADENROLL_TESTS
+ 
+ #include "test.h"
+@@ -3401,12 +3545,35 @@ test_adcli_enroll_get_permitted_keytab_enctypes (void)
+ 	adcli_conn_unref (conn);
+ }
+ 
++static void
++test_comp_attr_name (void)
++{
++	assert_num_eq (1, comp_attr_name (NULL ,NULL));
++	assert_num_eq (1, comp_attr_name ("" ,NULL));
++	assert_num_eq (1, comp_attr_name ("" ,""));
++	assert_num_eq (1, comp_attr_name (NULL ,""));
++	assert_num_eq (1, comp_attr_name (NULL ,"abc=xyz"));
++	assert_num_eq (1, comp_attr_name ("" ,"abc=xyz"));
++	assert_num_eq (1, comp_attr_name ("abc=xyz", NULL));
++	assert_num_eq (1, comp_attr_name ("abc=xyz", ""));
++	assert_num_eq (1, comp_attr_name ("abc=xyz", "ab=xyz"));
++	assert_num_eq (1, comp_attr_name ("ab=xyz", "abc=xyz"));
++	assert_num_eq (1, comp_attr_name ("abcxyz", "abc=xyz"));
++	assert_num_eq (1, comp_attr_name ("abc=xyz", "abcxyz"));
++	assert_num_eq (1, comp_attr_name ("abc=xyz", "a"));
++	assert_num_eq (1, comp_attr_name ("a", "abc=xyz"));
++
++	assert_num_eq (0, comp_attr_name ("abc=xyz", "abc=xyz"));
++	assert_num_eq (0, comp_attr_name ("abc=xyz", "abc=123"));
++}
++
+ int
+ main (int argc,
+       char *argv[])
+ {
+ 	test_func (test_adcli_enroll_get_permitted_keytab_enctypes,
+ 	           "/attrs/adcli_enroll_get_permitted_keytab_enctypes");
++	test_func (test_comp_attr_name, "/attrs/comp_attr_name");
+ 	return test_run (argc, argv);
+ }
+ 
+diff --git a/library/adenroll.h b/library/adenroll.h
+index 34dc683..862bb60 100644
+--- a/library/adenroll.h
++++ b/library/adenroll.h
+@@ -138,6 +138,10 @@ const char *       adcli_enroll_get_desciption          (adcli_enroll *enroll);
+ void               adcli_enroll_set_description         (adcli_enroll *enroll,
+                                                          const char *value);
+ 
++const char **      adcli_enroll_get_setattr             (adcli_enroll *enroll);
++adcli_result       adcli_enroll_add_setattr             (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);
+diff --git a/tools/computer.c b/tools/computer.c
+index 16a1983..af38894 100644
+--- a/tools/computer.c
++++ b/tools/computer.c
+@@ -114,6 +114,7 @@ typedef enum {
+ 	opt_add_service_principal,
+ 	opt_remove_service_principal,
+ 	opt_description,
++	opt_setattr,
+ 	opt_use_ldaps,
+ 	opt_account_disable,
+ } Option;
+@@ -152,6 +153,7 @@ static adcli_tool_desc common_usages[] = {
+ 	{ opt_add_service_principal, "add the given service principal to the account\n" },
+ 	{ opt_remove_service_principal, "remove the given service principal from the account\n" },
+ 	{ opt_description, "add a description to the account\n" },
++	{ opt_setattr, "add an attribute with a value\n" },
+ 	{ opt_no_password, "don't prompt for or read a password" },
+ 	{ opt_prompt_password, "prompt for a password if necessary" },
+ 	{ opt_stdin_password, "read a password from stdin (until EOF) if\n"
+@@ -333,6 +335,12 @@ parse_option (Option opt,
+ 	case opt_description:
+ 		adcli_enroll_set_description (enroll, optarg);
+ 		return ADCLI_SUCCESS;
++	case opt_setattr:
++		ret =  adcli_enroll_add_setattr (enroll, optarg);
++		if (ret != ADCLI_SUCCESS) {
++			warnx ("parsing setattr option failed");
++		}
++		return ret;
+ 	case opt_use_ldaps:
+ 		adcli_conn_set_use_ldaps (conn, true);
+ 		return ADCLI_SUCCESS;
+@@ -401,6 +409,7 @@ adcli_tool_computer_join (adcli_conn *conn,
+ 		{ "os-version", required_argument, NULL, opt_os_version },
+ 		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
+ 		{ "description", optional_argument, NULL, opt_description },
++		{ "setattr", required_argument, NULL, opt_setattr },
+ 		{ "user-principal", optional_argument, NULL, opt_user_principal },
+ 		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
+ 		{ "dont-expire-password", required_argument, NULL, opt_dont_expire_password },
+@@ -524,6 +533,7 @@ adcli_tool_computer_update (adcli_conn *conn,
+ 		{ "os-version", required_argument, NULL, opt_os_version },
+ 		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
+ 		{ "description", optional_argument, NULL, opt_description },
++		{ "setattr", required_argument, NULL, opt_setattr },
+ 		{ "user-principal", optional_argument, NULL, opt_user_principal },
+ 		{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime },
+ 		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
+-- 
+2.31.1
+
diff --git a/SOURCES/0005-Add-delattr-option.patch b/SOURCES/0005-Add-delattr-option.patch
new file mode 100644
index 0000000..ee72cfe
--- /dev/null
+++ b/SOURCES/0005-Add-delattr-option.patch
@@ -0,0 +1,192 @@
+From cd5b6cdcf3e6bfc5776f2865f460f608421dfa3f Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Mon, 14 Jun 2021 08:42:21 +0200
+Subject: [PATCH 5/5] Add delattr option
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1690920
+---
+ doc/adcli.xml      | 11 ++++++++
+ library/adenroll.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
+ library/adenroll.h |  4 +++
+ tools/computer.c   |  9 +++++++
+ 4 files changed, 90 insertions(+)
+
+diff --git a/doc/adcli.xml b/doc/adcli.xml
+index 8383aa7..bcf4857 100644
+--- a/doc/adcli.xml
++++ b/doc/adcli.xml
+@@ -577,6 +577,17 @@ $ adcli update --login-ccache=/tmp/krbcc_123
+ 			adcli options cannot be set with this option.</para>
+ 			</listitem>
+ 		</varlistentry>
++		<varlistentry>
++			<term><option>--delattr=<parameter>name</parameter></option></term>
++			<listitem><para>Remove the LDAP attribute
++			<option><parameter>name</parameter></option> from the
++			LDAP host object. This option can be used multiple
++			times to remove multiple different attributes.</para>
++			<para>Please note that the account used to update the
++			host object must have the required privileges to delete
++			the given attributes. Attributes managed by other adcli
++			options cannot be removed.</para></listitem>
++		</varlistentry>
+ 		<varlistentry>
+ 			<term><option>--show-details</option></term>
+ 			<listitem><para>After a successful join print out information
+diff --git a/library/adenroll.c b/library/adenroll.c
+index dd51567..9a06d52 100644
+--- a/library/adenroll.c
++++ b/library/adenroll.c
+@@ -151,6 +151,7 @@ struct _adcli_enroll {
+ 	int account_disable_explicit;
+ 	char *description;
+ 	char **setattr;
++	char **delattr;
+ };
+ 
+ static const char *
+@@ -845,6 +846,39 @@ get_mods_for_attrs (adcli_enroll *enroll, int mod_op)
+ 	return mods;
+ }
+ 
++static LDAPMod **
++get_del_mods_for_attrs (adcli_enroll *enroll, int mod_op)
++{
++	size_t len;
++	size_t c;
++	LDAPMod **mods = NULL;
++
++	len = _adcli_strv_len (enroll->delattr);
++	if (len == 0) {
++		return NULL;
++	}
++
++	mods = calloc (len + 1, sizeof (LDAPMod *));
++	return_val_if_fail (mods != NULL, NULL);
++
++	for (c = 0; c < len; c++) {
++		mods[c] = calloc (1, sizeof (LDAPMod));
++		if (mods[c] == NULL) {
++			ldap_mods_free (mods, 1);
++			return NULL;
++		}
++
++		mods[c]->mod_op = mod_op;
++		mods[c]->mod_type = strdup (enroll->delattr[c]);
++		mods[c]->mod_values = NULL;
++		if (mods[c]->mod_type == NULL) {
++			ldap_mods_free (mods, 1);
++			return NULL;
++		}
++	}
++
++	return mods;
++}
+ 
+ static adcli_result
+ create_computer_account (adcli_enroll *enroll,
+@@ -1775,6 +1809,14 @@ update_computer_account (adcli_enroll *enroll)
+ 		}
+ 	}
+ 
++	if (res == ADCLI_SUCCESS && enroll->delattr != NULL) {
++		LDAPMod **mods = get_del_mods_for_attrs (enroll, LDAP_MOD_DELETE);
++		if (mods != NULL) {
++			res |= update_computer_attribute (enroll, ldap, mods);
++			ldap_mods_free (mods, 1);
++		}
++	}
++
+ 	if (res != 0)
+ 		_adcli_info ("Updated existing computer account: %s", enroll->computer_dn);
+ }
+@@ -3475,6 +3517,30 @@ adcli_enroll_get_setattr (adcli_enroll *enroll)
+ 	return (const char **) enroll->setattr;
+ }
+ 
++adcli_result
++adcli_enroll_add_delattr (adcli_enroll *enroll, const char *value)
++{
++	return_val_if_fail (enroll != NULL, ADCLI_ERR_CONFIG);
++	return_val_if_fail (value != NULL, ADCLI_ERR_CONFIG);
++
++	if (_adcli_strv_has_ex (default_ad_ldap_attrs, value, strcasecmp) == 1) {
++		_adcli_err ("Attribute [%s] cannot be removed with delattr", value);
++		return ADCLI_ERR_CONFIG;
++	}
++
++	enroll->delattr = _adcli_strv_add (enroll->delattr, strdup (value),
++	                                   NULL);
++	return_val_if_fail (enroll->delattr != NULL, ADCLI_ERR_CONFIG);
++
++	return ADCLI_SUCCESS;
++}
++
++const char **
++adcli_enroll_get_delattr (adcli_enroll *enroll)
++{
++	return_val_if_fail (enroll != NULL, NULL);
++	return (const char **) enroll->delattr;
++}
+ 
+ #ifdef ADENROLL_TESTS
+ 
+diff --git a/library/adenroll.h b/library/adenroll.h
+index 862bb60..e3ada33 100644
+--- a/library/adenroll.h
++++ b/library/adenroll.h
+@@ -142,6 +142,10 @@ const char **      adcli_enroll_get_setattr             (adcli_enroll *enroll);
+ adcli_result       adcli_enroll_add_setattr             (adcli_enroll *enroll,
+                                                          const char *value);
+ 
++const char **      adcli_enroll_get_delattr             (adcli_enroll *enroll);
++adcli_result       adcli_enroll_add_delattr             (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);
+diff --git a/tools/computer.c b/tools/computer.c
+index af38894..dffeecb 100644
+--- a/tools/computer.c
++++ b/tools/computer.c
+@@ -115,6 +115,7 @@ typedef enum {
+ 	opt_remove_service_principal,
+ 	opt_description,
+ 	opt_setattr,
++	opt_delattr,
+ 	opt_use_ldaps,
+ 	opt_account_disable,
+ } Option;
+@@ -154,6 +155,7 @@ static adcli_tool_desc common_usages[] = {
+ 	{ opt_remove_service_principal, "remove the given service principal from the account\n" },
+ 	{ opt_description, "add a description to the account\n" },
+ 	{ opt_setattr, "add an attribute with a value\n" },
++	{ opt_delattr, "remove an attribute\n" },
+ 	{ opt_no_password, "don't prompt for or read a password" },
+ 	{ opt_prompt_password, "prompt for a password if necessary" },
+ 	{ opt_stdin_password, "read a password from stdin (until EOF) if\n"
+@@ -341,6 +343,12 @@ parse_option (Option opt,
+ 			warnx ("parsing setattr option failed");
+ 		}
+ 		return ret;
++	case opt_delattr:
++		ret = adcli_enroll_add_delattr (enroll, optarg);
++		if (ret != ADCLI_SUCCESS) {
++			warnx ("parsing delattr option failed");
++		}
++		return ret;
+ 	case opt_use_ldaps:
+ 		adcli_conn_set_use_ldaps (conn, true);
+ 		return ADCLI_SUCCESS;
+@@ -534,6 +542,7 @@ adcli_tool_computer_update (adcli_conn *conn,
+ 		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack },
+ 		{ "description", optional_argument, NULL, opt_description },
+ 		{ "setattr", required_argument, NULL, opt_setattr },
++		{ "delattr", required_argument, NULL, opt_delattr },
+ 		{ "user-principal", optional_argument, NULL, opt_user_principal },
+ 		{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime },
+ 		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
+-- 
+2.31.1
+
diff --git a/SPECS/adcli.spec b/SPECS/adcli.spec
new file mode 100644
index 0000000..42b0d82
--- /dev/null
+++ b/SPECS/adcli.spec
@@ -0,0 +1,284 @@
+Name:    adcli
+Version: 0.9.1
+Release: 7%{?dist}
+Summary: Active Directory enrollment
+License: LGPLv2+
+URL:     https://gitlab.freedesktop.org/realmd/adcli
+Source0: https://gitlab.freedesktop.org/sbose/adcli/uploads/30880d967e79cee789194435e70fbf30/adcli-%{version}.tar.gz
+
+Patch1: 0001-build-add-with-vendor-error-message-configure-option.patch
+
+# rhbz#1977167 - [RFE] adcli should allow to modify DONT_EXPIRE_PASSWORD
+#                attribute
+Patch2: 0001-configure-update-some-macros-for-autoconf-2.71.patch
+Patch3: 0001-coverity-add-missing-NULL-checks.patch
+Patch4: 0002-Add-dont-expire-password-option.patch
+Patch5: 0001-Fix-for-dont-expire-password-option-and-join.patch
+
+# rhbz#1977168 - [RFE] Allow adcli to create AD user with password as well as
+#                set or reset existing user password
+Patch6: 0001-library-move-UAC-flags-to-a-more-common-header-file.patch
+Patch7: 0002-adcli_entry-add-entry_attrs-with-userAccountControl-.patch
+Patch8: 0003-entry-add-passwd-user-sub-command.patch
+
+# rhbz#1977165 - [RFE] add option to populate "managed by" computer attribute
+Patch9: 0004-Add-setattr-option.patch
+Patch10: 0005-Add-delattr-option.patch
+
+# rhbz#1984892 - adcli: FTBFS because of libresolv changes in glibc 2.34
+Patch11: 0001-configure-check-for-ns_get16-and-ns_get32-as-well.patch
+
+BuildRequires: gcc
+BuildRequires: intltool pkgconfig
+BuildRequires: libtool
+BuildRequires: gettext-devel
+BuildRequires: krb5-devel
+BuildRequires: openldap-devel
+BuildRequires: libxslt
+BuildRequires: xmlto
+BuildRequires: make
+
+Requires: cyrus-sasl-gssapi
+Conflicts: adcli-doc < %{version}-%{release}
+
+# adcli no longer has a library of development files
+# the adcli tool itself is to be used by callers
+Obsoletes: adcli-devel < 0.5
+
+%description
+adcli is a tool for joining an Active Directory domain using
+standard LDAP and Kerberos calls.
+
+%define _hardened_build 1
+
+%prep
+%autosetup -p1
+
+%build
+autoreconf --force --install --verbose
+%configure --disable-static --disable-silent-rules \
+%if 0%{?rhel}
+    --with-vendor-error-message='Please check\n    https://red.ht/support_rhel_ad \nto get help for common issues.' \
+%endif
+    %{nil}
+make %{?_smp_mflags}
+
+%check
+make check
+
+%install
+make install DESTDIR=%{buildroot}
+find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
+
+%ldconfig_scriptlets
+
+%files
+%{_sbindir}/adcli
+%doc AUTHORS COPYING ChangeLog NEWS README
+%doc %{_mandir}/*/*
+
+%package doc
+Summary: adcli documentation
+BuildArch: noarch
+Conflicts: adcli < %{version}-%{release}
+
+%description doc
+adcli is a tool for joining an Active Directory domain using
+standard LDAP and Kerberos calls. This package contains its
+documentation.
+
+%files doc
+%doc %{_datadir}/doc/adcli/*
+
+%changelog
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 0.9.1-7
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+  Related: rhbz#1991688
+
+* Wed Jul 28 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-6
+- Add ns_get16() and ns_get32() to configure check
+  Resolves: rhbz#1984892
+
+* Wed Jun 30 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-5
+- Sync with upstream/Fedora/RHEL-8.5
+  Resolves: rhbz#1977168, rhbz#1977167, rhbz#1977165
+
+* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 0.9.1-4
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Mon Mar 29 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-3
+- Add vendor error message
+  Resolves: rhbz#1889386
+
+* Sat Feb 20 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-2
+- Add Conflicts to avoid update/downgrade issues
+
+* Sat Feb 20 2021 Sumit Bose <sbose@redhat.com> - 0.9.1-1
+- Update to upstream release 0.9.1
+
+* Mon Jan 25 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.0-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Fri Nov 13 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-6
+- Include the latest upstream patches with use-ldaps fixes, man page
+  improvements and a new sub-command to create managed service accounts
+
+* Thu Aug 13 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-5
+- man page and help output fixes
+
+* Fri Jul 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.0-4
+- Second attempt - Rebuilt for
+  https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Mon Jun 08 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-2
+- Include the latest upstream patches
+
+* Wed Mar 18 2020 Sumit Bose <sbose@redhat.com> - 0.9.0-1
+- Update to upstream release 0.9.0 and latest patches
+
+* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Mon Aug 26 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-8
+- various fixes and improvements
+  Resolves: rhbz#1683745, rhbz#1738573
+
+* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Fri Jul  5 2019 Jakub Hrozek <jhrozek@redhat.com> - 0.8.2-6
+- Resolves: rhbz#1727144 - adcli join fails with new krb5-libs; adcli
+                           needs to backport patches to only use permitted
+                           enctypes from upstream
+
+* Tue Apr 30 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-5
+- addition patch for rhbz#1630187 and new ones for rhbz#1588596
+  Resolves: rhbz#1630187, rhbz#1588596
+
+* Fri Mar 22 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-4
+- various fixes and improvements
+  Resolves: rhbz#1593240, rhbz#1608212, rhbz#1547014, rhbz#1547014,
+            rhbz#1649868, rhbz#1588596, rhbz#1642546, rhbz#1595911,
+            rhbz#1644311, rhbz#1337489, rhbz#1630187, rhbz#1622583
+
+* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Thu Jul 05 2018 Sumit Bose <sbose@redhat.com> - 0.8.0-1
+- Update to upstream release 0.8.2
+- various other fixes and improvements
+- add option to enable "Trust this computer for delegation"
+  Resolves: rhbz#988349
+- fix typos in the adcli man page
+  Resolves: rhbz#1440533
+
+* Wed Mar 07 2018 Sumit Bose <sbose@redhat.com> - 0.8.0-7
+- Added BuildRequires gcc
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.8.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Thu Dec 17 2015 Sumit Bose <sbose@redhat.com> - 0.8.0-1
+- Update to upstream release 0.8.0
+
+* Mon Oct 19 2015 Stef Walter <stefw@redhat.com> - 0.7.6-1
+- Fix issue with keytab use with sshd
+- Resolves: rhbz#1267319
+- Put documentation in a subpackage
+
+* Tue Jun 16 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.7.5-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Fri Aug 15 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.7.5-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.7.5-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Thu Jan 30 2014 Stef Walter <stefw@redhat.com> - 0.7.5-2
+- Fix incorrect ownership of manual page directory
+
+* Fri Sep 13 2013 Stef Walter <stefw@redhat.com> - 0.7.5-1
+- Update to upstream point release 0.7.5
+- Workaround for discovery via IPv6 address
+- Correctly put IPv6 addresses in temporary krb5.conf
+
+* Mon Sep 09 2013 Stef Walter <stefw@redhat.com> - 0.7.4-1
+- Update to upstream point release 0.7.4
+- Correctly handle truncating long host names
+- Try to contact all available addresses for discovery
+- Build fixes
+
+* Wed Aug 07 2013 Stef Walter <stefw@redhat.com> - 0.7.3-1
+- Update to upstream point release 0.7.3
+- Don't try to set encryption types on Windows 2003
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.7.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Jul 22 2013 Stef Walter <stefw@redhat.com> - 0.7.2-1
+- Update to upstream point release 0.7.2
+- Part of fix for bug [#961244]
+
+* Mon Jul 15 2013 Stef Walter <stefw@redhat.com> - 0.7.1-4
+- Build with verbose output logging
+
+* Tue Jun 11 2013 Stef Walter <stefw@redhat.com> - 0.7.1-3
+- Run 'make check' when building the package
+
+* Mon May 13 2013 Stef Walter <stefw@redhat.com> - 0.7.1-2
+- Bump version to get around botched update
+
+* Mon May 13 2013 Stef Walter <stefw@redhat.com> - 0.7.1-1
+- Update to upstream 0.7.1 release
+- Fix problems with salt discovery [#961399]
+
+* Mon May 06 2013 Stef Walter <stefw@redhat.com> - 0.7-1
+- Work around broken krb5 with empty passwords [#960001]
+- Fix memory corruption issue [#959999]
+- Update to 0.7, fixing various bugs
+
+* Mon Apr 29 2013 Stef Walter <stefw@redhat.com> - 0.6-1
+- Update to 0.6, fixing various bugs
+
+* Wed Apr 10 2013 Stef walter <stefw@redhat.com> - 0.5-2
+- Add appropriate Obsoletes line for libadcli removal
+
+* Wed Apr 10 2013 Stef Walter <stefw@redhat.com> - 0.5-1
+- Update to upstream 0.5 version
+- No more libadcli, and thus no adcli-devel
+- Many new adcli commands
+- Documentation
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Mon Nov 12 2012 Stef Walter <stefw@redhat.com> - 0.4-1
+- Update for 0.4 version, fixing various bugs
+
+* Sat Oct 20 2012 Stef Walter <stefw@redhat.com> - 0.3-1
+- Update for 0.3 version
+
+* Tue Sep 4 2012 Stef Walter <stefw@redhat.com> - 0.2-1
+- Update for 0.2 version
+
+* Wed Aug 15 2012 Stef Walter <stefw@redhat.com> - 0.1-1
+- Initial 0.1 package